[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