[Python-checkins] r52760 - sandbox/trunk/import_in_py/importer.py sandbox/trunk/import_in_py/test_importer.py
brett.cannon
python-checkins at python.org
Thu Nov 16 00:00:45 CET 2006
Author: brett.cannon
Date: Thu Nov 16 00:00:44 2006
New Revision: 52760
Modified:
sandbox/trunk/import_in_py/importer.py
sandbox/trunk/import_in_py/test_importer.py
Log:
Temporarily implement Python version of marshal.w_long and marshal.r_long.
Also begin writing tests that were left out because the functionality was
initially missing.
Modified: sandbox/trunk/import_in_py/importer.py
==============================================================================
--- sandbox/trunk/import_in_py/importer.py (original)
+++ sandbox/trunk/import_in_py/importer.py Thu Nov 16 00:00:44 2006
@@ -70,11 +70,18 @@
entries for __path__ for package) do not have 'path' set to anything (but
still have the full name of the module passed in)
[pep 302 and introspection(Python/import.c:1278)].
+
+
+Semantic notes
+==============
+XXX
+* What to do when magic number and timestamp works, but bytecode is bad?
Things to be exposed at the Python level
========================================
* Python/marshal.c:r_long()/w_long()
+ + Using own version temporarily.
Py3k
@@ -163,6 +170,31 @@
_set__import__ was called previously)."""
__builtins__['__import__'] = original__import__
+def w_long(x):
+ """Convert a 32-bit integer to little-endian.
+
+ XXX Temporary until marshal's long functions are exposed.
+
+ """
+ bytes = []
+ bytes.append(x & 0xFF)
+ bytes.append((x >> 8) & 0xFF)
+ bytes.append((x >> 16) & 0xFF)
+ bytes.append((x >> 24) & 0xFF)
+ return ''.join(chr(x) for x in bytes)
+
+def r_long(bytes):
+ """Convert 4 bytes in little-endian to an integer.
+
+ XXX Temporary until marshal's long function are exposed.
+
+ """
+ x = ord(bytes[0])
+ x |= ord(bytes[1]) << 8
+ x |= ord(bytes[2]) << 16
+ x |= ord(bytes[3]) << 24
+ return x
+
class BuiltinFrozenBaseImporter(object):
@@ -397,15 +429,11 @@
def parse_pyc(self, data):
"""Split data into magic number, timestamp, and bytecode."""
- # XXX Does not work properly until unmarshaling longs works.
- #return int(data[:4]), int(data[4:8]), data[8:]
- return imp.get_magic(), 0, data[8:]
-
+ return data[:4], r_long(data[4:8]), data[8:]
+
def check_magic(self, magic):
"""Check whether the magic number is valid or not."""
- return True
- # XXX cannot work until can unmarshal long.
- #return imp.get_magic() == magic
+ return imp.get_magic() == magic
def code_from_bytecode(self, bytecode):
"""Create a code object from bytecode."""
@@ -417,9 +445,8 @@
def create_pyc(self, bytecode, timestamp):
"""Create data for a .pyc file."""
- #XXX Does not work properly until direct marshaling of longs is possible.
- data = imp.get_magic().zfill(4)
- data += str(timestamp).zfill(4)
+ data = imp.get_magic()
+ data += w_long(timestamp)
data += marshal.dumps(bytecode)
return data
@@ -460,6 +487,8 @@
module.__file__ = path
if package is not None:
module.__path__ = [package]
+ # Store the module in sys.modules so as to prevent any circular import
+ # dependency problems.
sys.modules[mod_name] = module
base_path, type_ = loader.split_path(path)
if type_ in self.bytecode_handles:
@@ -480,9 +509,7 @@
# Verify that the bytecode is not stale.
if source_path:
source_timestamp = loader.mod_time(source_path)
- # XXX Check does not work until long (un)marshaling.
- # XXX if pyc_timestamp < source_timestamp:
- if False:
+ if pyc_timestamp < source_timestamp:
raise ImportError("bytcode is stale")
# Bytecode is valid.
module.__file__ = path
Modified: sandbox/trunk/import_in_py/test_importer.py
==============================================================================
--- sandbox/trunk/import_in_py/test_importer.py (original)
+++ sandbox/trunk/import_in_py/test_importer.py Thu Nov 16 00:00:44 2006
@@ -531,8 +531,6 @@
def test_parse_pyc(self):
# Split up data from .pyc file for the magic number, timestamp,
# and bytecode.
- pass
- # XXX Can't fully test until unmarshaling longs is available.
with open(self.pyc_path, 'rb') as bytecode_file:
pyc = bytecode_file.read()
magic, timestamp, bytecode = self.handler.parse_pyc(pyc)
@@ -543,12 +541,12 @@
def test_check_magic(self):
# Compare a number against the magic number.
- # XXX Cannot properly test until can unmarshal numbers.
- #magic_number = imp.get_magic()
- #self.failUnless(self.handler.check_magic(magic_number))
- #self.failUnless(not self.handler.check_magic(magic_number-1))
- #self.failUnless(not self.handler.check_magic(magic_number+1))
- pass
+ magic_number = imp.get_magic()
+ self.failUnless(self.handler.check_magic(magic_number))
+ smaller_number = magic_number[:3] + chr(ord(magic_number[3]) - 1)
+ self.failUnless(not self.handler.check_magic(smaller_number))
+ larger_number = magic_number[:3] + chr(ord(magic_number[3]) + 1)
+ self.failUnless(not self.handler.check_magic(larger_number))
def test_code_from_bytecode(self):
# Create a code object from bytecode.
@@ -566,8 +564,13 @@
def test_create_pyc(self):
# Test creating bytes for creating a .pyc file.
- # XXX Cannot test until marshaling longs is possible.
- pass
+ bytecode = 'bytecode'
+ timestamp = 42
+ data = self.handler.create_pyc(bytecode, timestamp)
+ self.failUnlessEqual(imp.get_magic(), data[:4])
+ # XXX Using importer module's marshal long function.
+ self.failUnlessEqual(timestamp, importer.r_long(data[4:8]))
+ self.failUnlessEqual(marshal.dumps(bytecode), data[8:])
class PyPycHandlerHandleCodeTests(unittest.TestCase):
@@ -585,13 +588,18 @@
# Bytecode should not be written.
self.failUnless("write_data" not in loader.log)
- def test_bad_magic_no_py(self):
- # XXX Can't test until can unmarshal magic number from pyc.
+ def XXX_test_bad_magic_no_py(self):
+ # ImportError should be raised when a .pyc has a bad magic number and
+ # there is no corresponding .py file.
pass
def test_bad_timestamp_no_py(self):
# XXX Can't test until can unmarshal timestamp from pyc.
pass
+
+ def test_bad_bytecode_no_py(self):
+ # XXX
+ pass
def test_bad_magic_w_py(self):
# XXX Can't test until can unmarhsal magic number from pyc.
@@ -600,6 +608,10 @@
def test_bad_magic_w_py(self):
# XXX Can't test until can unmarshal timestamp from pyc.
pass
+
+ def test_bad_bytecode_w_py(self):
+ # XXX
+ pass
def test_py_no_pyc(self):
# Test importing a .py file where no .pyc path is available.
More information about the Python-checkins
mailing list