[Python-checkins] r57173 - in sandbox/trunk/import_in_py: _importlib.py tests/test_fs_loader.py
brett.cannon
python-checkins at python.org
Sat Aug 18 05:08:39 CEST 2007
Author: brett.cannon
Date: Sat Aug 18 05:08:20 2007
New Revision: 57173
Modified:
sandbox/trunk/import_in_py/_importlib.py
sandbox/trunk/import_in_py/tests/test_fs_loader.py
Log:
Several things:
+ Extension loader
- Implement PEP 302 optional extensions.
- Stick in test stubs to remember to write the tests.
+ Source loader
- Fix some initial typos in the code.
- Write stubs for PEP 302 optional extensions and methods needed by source
handler.
- Write initial tests.
* Failing thanks to loader stub methods not being implemented.
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 05:08:20 2007
@@ -264,6 +264,19 @@
del sys.modules[fullname]
raise
+ def is_package(self, fullname):
+ """Return False as an extension module can never be a package."""
+ return False
+
+ def get_code(self, fullname):
+ """Return None as an extension module cannot create just a code
+ object."""
+ return None
+
+ def get_source(self, fullname):
+ """Return None as extension modules have no source code."""
+ return None
+
def suffix_list(suffix_type):
"""Return a list of suffixes for a specific type of file."""
@@ -277,8 +290,8 @@
source_timestamp = None
module = sys.modules.get(name)
if module is None:
- module = self.new_module(name)
- sys.modules[mod_name] = module
+ module = imp.new_module(name)
+ sys.modules[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
@@ -313,7 +326,7 @@
# source code is useless. Signal this fact by setting
# bytecode_exists to None.
bytecode_exists = None
- raise ImportError('Non-code object in %s' %
+ raise ImportError('Non-code object found')
except ImportError:
# If the exception is from the bytecode being corrupt, let it
# propagate.
@@ -333,6 +346,19 @@
return module
+def check_name(method):
+ """Decorator to verify that the module being requested matches the one the
+ loader can handle."""
+ def inner(self, name, *args, **kwargs):
+ if self._name != name:
+ raise ImportError("loader cannot handle %s" % name)
+ return method(self, name, *args, **kwargs)
+ inner.__name__ = method.__name__
+ inner.__doc__ = method.__doc__
+ inner.__dict__.update(method.__dict__)
+ return inner
+
+
class _PyFileLoader(object):
"""Load a Python source or bytecode file."""
@@ -348,7 +374,7 @@
def load_module(self, fullname):
"""Load a Python source or bytecode file."""
- assert self_name == fullname
+ assert self._name == fullname
source_exists, bytecode_exists = None, None
for suffix in suffix_list(imp.PY_SOURCE):
if self._path.endswith(suffix):
@@ -374,14 +400,80 @@
source_exists = False
bytecode_exists = True
try:
- return self._handler(fullname, self_path, source_exists,
- bytecode_exists, self_is_pkg)
+ return self._handler(fullname, self._path, source_exists,
+ bytecode_exists, self._is_pkg)
except:
# Don't leave a partially initialized module in sys.modules.
if fullname in sys.modules:
del sys.modules[fullname]
raise
+ @check_name
+ def mod_time(self, name):
+ """Return the modification time of the source for the specified module.
+
+ Raise ValueError if no source exists or ImportError (like get_source)
+ if the loader cannot handle the module.
+
+ """
+ raise NotImplementedError
+
+ @check_name
+ def get_source(self, fullname):
+ """Return the source for the specified module (using universal
+ newlines), or None if it is not available.
+
+ Raises ImportError if the loader cannot handle the module.
+
+ """
+ # XXX Why return ImportError?
+ raise NotImplementedError
+
+ @check_name
+ def get_bytecode(self, name):
+ """Return the bytecode for the module, or None if it is not available.
+
+ Raises ImportError (just like get_source) if the laoder cannot handle
+ the module.
+
+ """
+ raise NotImplementedError
+
+ @check_name
+ def write_bytecode(self, name, data):
+ """Write out 'data' for the specified module, returning a boolean
+ signifying if the write-out actually occurred.
+
+ Raises ImportError (just like get_source) if the specified module
+ cannot be handled by the loader.
+
+ """
+ raise NotImplementedError
+
+ def get_data(self, path):
+ """Return the data from path as raw bytes."""
+ raise NotImplementedError
+
+ @check_name
+ def is_package(self, fullname):
+ """Return a boolean based on whether the module is a package.
+
+ Raises ImportError (like get_source) if the loader cannot handle the
+ package.
+
+ """
+ raise NotImplementedError
+
+ @check_name
+ def get_code(self, fullname):
+ """Return a code object for the module.
+
+ Raise ImportError (like get_source) if the load cannot handle the
+ specified module.
+
+ """
+ raise NotImplementedError
+
class FileImporter(object):
Modified: sandbox/trunk/import_in_py/tests/test_fs_loader.py
==============================================================================
--- sandbox/trunk/import_in_py/tests/test_fs_loader.py (original)
+++ sandbox/trunk/import_in_py/tests/test_fs_loader.py Sat Aug 18 05:08:20 2007
@@ -1,6 +1,7 @@
import importlib
from tests.ext_help import find_ext_location
+from tests.py_help import TestPyPycPackages
import os
import sys
@@ -25,11 +26,11 @@
# A module, after being loaded, should appear in sys.modules.
if name in sys.modules:
del sys.modules[name]
- loaded = loader.load_module(name)
- self.assert_(loaded is sys.modules[name])
- self.assertEqual(loaded.__name__, name)
- self.assertEqual(loaded.__file__, path)
- self.assertEqual(loaded.__loader__, loader)
+ loaded = loader.load_module(name)
+ self.assert_(loaded is sys.modules[name])
+ self.assertEqual(loaded.__name__, name)
+ self.assertEqual(loaded.__file__, path)
+ self.assertEqual(loaded.__loader__, loader)
class ExtensionFileLoaderTests(LoaderBasics):
@@ -51,9 +52,32 @@
False)
self.reload_test(loader, test_ext_module)
+ def test_is_package(self):
+ # Should always be False.
+ raise NotImplementedError
+
+ def test_get_code(self):
+ # Should always be None.
+ raise NotImplementedError
+
+ def test_get_source(self):
+ # Should always be None.
+ raise NotImplementedError
+
+
+class PyFileLoaderTests(LoaderBasics, TestPyPycPackages):
+
+ def test_basic(self):
+ loader = importlib._PyFileLoader(self.module_name, self.py_path, False)
+ self.basic_test(loader, self.module_name, self.py_path)
+
+ def test_reload(self):
+ loader = importlib._PyFileLoader(self.module_name, self.py_path, False)
+ self.reload_test(loader, self.module_name)
+
def test_main():
- test_support.run_unittest(ExtensionFileLoaderTests)
+ test_support.run_unittest(ExtensionFileLoaderTests, PyFileLoaderTests)
if __name__ == '__main__':
More information about the Python-checkins
mailing list