[Python-checkins] r57167 - in sandbox/trunk/import_in_py: _importlib.py tests/test_fs_importer.py tests/test_fs_loader.py

brett.cannon python-checkins at python.org
Sat Aug 18 01:38:32 CEST 2007


Author: brett.cannon
Date: Sat Aug 18 01:38:11 2007
New Revision: 57167

Modified:
   sandbox/trunk/import_in_py/_importlib.py
   sandbox/trunk/import_in_py/tests/test_fs_importer.py
   sandbox/trunk/import_in_py/tests/test_fs_loader.py
Log:
Flesh out (but with no tests) the source loader.

This led to two other changes.  One was not directly exposes the source and
extension module loaders to the outside world.  This is because they are
heavily dependent on their respective importers.

Second, the arguments passed to the loaders by FileImporter has been expanded.
Now all information gathered by FileImporter.find_module is passed as an
argument.


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 01:38:11 2007
@@ -242,15 +242,18 @@
             raise ImportError("can only handle directories")
 
 
-class ExtensionFileLoader(object):
+class _ExtensionFileLoader(object):
 
     """Provide the ability to load an extension module."""
 
-    def __init__(self, path):
+    def __init__(self, name, path, is_pkg):
+        """Initialize the loader, ignoring the is_pkg argument."""
+        self._name = name
         self._path = path
 
     def load_module(self, fullname):
         """Load an extension module."""
+        assert self._name == fullname
         try:
             module = imp.load_dynamic(fullname, self._path)
             module.__loader__ = self
@@ -268,17 +271,45 @@
             if suffix[2] == suffix_type]
 
 
-class PyFileLoader(object):
+class _PyFileLoader(object):
 
     # XXX Take in fullname from importer to make sure loader is not called for
     # another module?
-    def __init__(self, path):
+    def __init__(self, name, path, is_pkg):
+        self._name = name
         self._path = path
+        self._is_pkg = is_pkg
 
     def load_module(self, fullname):
         """Load a Python source or bytecode file."""
+        assert self_name == fullname
+        source_exists, bytecode_exists = None, None
+        for suffix in suffix_list(imp.PY_SOURCE):
+            if self._path.endswith(suffix):
+                # Source was found, but we don't know about the bytecode as the
+                # importer guarantees to check for source first.
+                source_exists = True
+                self._source_path = self._path
+                base_path = self._path[:len(suffix)]
+                for suffix in suffix_list(imp.PY_COMPILED):
+                    bytecode_path = base_path + suffix
+                    if _path_exists(bytecode_path):
+                        bytecode_exists = True
+                        self._bytecode_path = bytecode_path
+                        break
+                else:
+                    # Source was found, but no corresponding bytecode exists.
+                    bytecode_exists = False
+                # Since source was found, the loop should be stopped.
+                break
+        else:
+            # The loader is being asked to load a bytecode file since it was
+            # not asked to load a source file and that is searched for first.
+            source_exists = False
+            bytecode_exists = True
         try:
-            return handle_py(self, fullname, self_path, XXX, XXX, XXX)
+            return handle_py(self, 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:
@@ -297,8 +328,9 @@
     * _possible_package
         True if importer should check for packages.
     * _loader
-        A callable that takes the found file path to the requested module and
-        returns a loader for the module found at that path.
+        A callable that takes the module name, a file path, and whether
+        the path points to a package and returns a loader for the module found
+        at that path.
 
     """
 
@@ -321,14 +353,14 @@
                 if (_path_isfile(package_init) and
                         _case_ok(self._path_entry, tail_module) and
                         _case_ok(package_directory, init_filename)):
-                    return self._loader(package_init)
+                    return self._loader(fullname, package_init, True)
         for ext in self._suffixes:
             file_name = tail_module + ext
             file_path = _path_join(self._path_entry, file_name)
             if (_path_isfile(file_path) and
                     _case_ok(self._path_entry, file_name)):
                 # XXX Pass in importer as well to access attributes?
-                return self._loader(file_path)
+                return self._loader(fullname, file_path, False)
         else:
             # Raise a warning if it matches a directory w/o an __init__ file.
             if (_path_isdir(package_directory) and
@@ -344,7 +376,7 @@
     """Importer for extension files."""
 
     _possible_package = False
-    _loader = ExtensionFileLoader
+    _loader = _ExtensionFileLoader
 
     def __init__(self, path_entry):
         # Assigning to _suffixes here instead of at the class level because
@@ -358,7 +390,7 @@
     """Importer for source/bytecode files."""
 
     _possible_package = True
-    _loader = lambda path: FileSystemLoader(path, PyPycHandler)
+    _loader = _PyFileLoader
 
     def __init__(self, path_entry):
         # Lack of imp during class creation means _suffixes is set here.
@@ -1065,3 +1097,7 @@
                 self._import_full_module(name)
             relative_name = '' if imported_name == name else name
             return self._return_module(imported_name, relative_name, fromlist)
+
+# XXX Eventually replace with a proper __all__ value (i.e., don't expose os
+# replacements but do expose _ExtensionFileLoader, etc. for testing).
+__all__ = globals().keys()

Modified: sandbox/trunk/import_in_py/tests/test_fs_importer.py
==============================================================================
--- sandbox/trunk/import_in_py/tests/test_fs_importer.py	(original)
+++ sandbox/trunk/import_in_py/tests/test_fs_importer.py	Sat Aug 18 01:38:11 2007
@@ -30,7 +30,7 @@
     def setUp(self):
         TestPyPycPackages.setUp(self, faked_names=False)
         self.importer = importlib.PyFileImporter(self.directory)
-        self.importer._loader = lambda x: x
+        self.importer._loader = lambda name, path, is_pkg: path
 
     def tearDown(self):
         TestPyPycPackages.tearDown(self)
@@ -184,7 +184,7 @@
         search_for = 'datetime'
         extension_dir, filename = find_ext_location(search_for)
         importer = importlib.ExtensionFileImporter(extension_dir)
-        importer._loader = lambda x: x
+        importer._loader = lambda name, path, is_pkg: path
         found = importer.find_module(search_for)
         self.assert_(found is not None)
         self.assert_(search_for in found)

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 01:38:11 2007
@@ -38,14 +38,17 @@
         # Should be able to import an extension module.
         path, filename = find_ext_location(test_ext_module)
         module_path = os.path.join(path, filename)
-        loader = importlib.ExtensionFileLoader(module_path)
+        loader = importlib._ExtensionFileLoader(test_ext_module, module_path,
+                                                False)
         self.basic_test(loader, test_ext_module, module_path)
 
     def test_reload(self):
         # A module that is already in sys.modules should be reused and be
         # re-initialized.
         path, filename = find_ext_location(test_ext_module)
-        loader = importlib.ExtensionFileLoader(os.path.join(path, filename))
+        loader = importlib._ExtensionFileLoader(test_ext_module,
+                                                os.path.join(path, filename),
+                                                False)
         self.reload_test(loader, test_ext_module)
 
 


More information about the Python-checkins mailing list