[Python-checkins] r57172 - sandbox/trunk/import_in_py/NOTES sandbox/trunk/import_in_py/_importlib.py
brett.cannon
python-checkins at python.org
Sat Aug 18 04:33:12 CEST 2007
Author: brett.cannon
Date: Sat Aug 18 04:32:42 2007
New Revision: 57172
Modified:
sandbox/trunk/import_in_py/NOTES
sandbox/trunk/import_in_py/_importlib.py
Log:
Untested implementation of new source handler.
Modified: sandbox/trunk/import_in_py/NOTES
==============================================================================
--- sandbox/trunk/import_in_py/NOTES (original)
+++ sandbox/trunk/import_in_py/NOTES Sat Aug 18 04:32:42 2007
@@ -2,13 +2,12 @@
* mod_time(module_name) -> int
Find out the modification time for a source module. If no source module
exists, raise XXX.
-* source(module_name) -> str
- Return the text for a source module.
- XXX Consider just using get_source from PEP 302 optional extensions.
-* bytecode(module_name) -> bytes
+* get_source(module_name) -> str
+ Return the text for a source module. Defined as part of PEP 302's optional
+ extensions.
+* get_bytecode(module_name) -> bytes
Return the bytes for a bytecode-stored module (including timestamp and
cookie).
- XXX Rename to get_bytecode if get_source is viable for source().
* write_bytecode(module_name, data:bytes) -> bool
Write out the new representation of a bytecode module. Returns a boolean
representing whether the bytes were actually written out or not.
Modified: sandbox/trunk/import_in_py/_importlib.py
==============================================================================
--- sandbox/trunk/import_in_py/_importlib.py (original)
+++ sandbox/trunk/import_in_py/_importlib.py Sat Aug 18 04:32:42 2007
@@ -273,7 +273,64 @@
def handle_py(loader, name, path, source_exists, bytecode_exists, is_pkg):
"""Handle the initialization of a module by Python source or bytecode."""
- raise NotImplementedError
+ assert source_exists or bytecode_exists
+ source_timestamp = None
+ module = sys.modules.get(name)
+ if module is None:
+ module = self.new_module(name)
+ sys.modules[mod_name] = module
+ # __file__, __path__, and __loader__ *must* be set on the module before
+ # any code is executed by the import. __name__ is set by new_module.
+ module.__loader__ = loader
+ # XXX Will always be to the source if it exists, even if the module is
+ # initialized from source thanks to the importer always searching for
+ # source first.
+ module.__file__ = path
+ if is_pkg:
+ module.__path__ = [path.rsplit(path_sep, 1)[0]]
+ # Try to use bytecode if it is available.
+ if bytecode_exists:
+ pyc_data = loader.get_bytecode(name)
+ magic, pyc_timestamp, bytecode = data[:4], _r_long(data[4:8]), data[8:]
+ try:
+ # Verify that the magic number is valid.
+ if imp.get_magic() != magic:
+ raise ImportError("bad magic number")
+ # Verify that the bytecode is not stale.
+ if source_exists:
+ # Keep in a variable so that if bytecode turns out to be bad
+ # then the value can be reused when re-generating bytecode.
+ source_timestamp = loader.mod_time(name)
+ if pyc_timestamp < source_timestamp:
+ raise ImportError("bytcode is stale")
+ # Bytecode seems fine, so try to use it.
+ try:
+ exec marshal.loads(bytecode) in module.__dict__
+ return module
+ except ValueError:
+ # XXX Does this have to be true?
+ # Since bad bytecode halts the import entirely, having the
+ # source code is useless. Signal this fact by setting
+ # bytecode_exists to None.
+ bytecode_exists = None
+ raise ImportError('Non-code object in %s' %
+ except ImportError:
+ # If the exception is from the bytecode being corrupt, let it
+ # propagate.
+ if not source_exists or bytecode_exists is None:
+ raise
+ # Use the source.
+ source = loader.get_source(name)
+ code_object = compile(source, path, 'exec')
+ exec code_object in module.__dict__
+ # Generate bytecode and write it out.
+ if source_timestamp is None: # May have from bytecode verification.
+ source_timestamp = loader.mod_time(source_path)
+ data = imp.get_magic()
+ data += _w_long(source_timestamp)
+ data += marshal.dumps(code_object)
+ loader.write_bytecode(name, data)
+ return module
class _PyFileLoader(object):
More information about the Python-checkins
mailing list