[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

AltStyle によって変換されたページ (->オリジナル) /