[Python-checkins] r52937 - sandbox/trunk/import_in_py/importer.py sandbox/trunk/import_in_py/test_importer.py

brett.cannon python-checkins at python.org
Wed Dec 6 23:16:21 CET 2006


Author: brett.cannon
Date: Wed Dec  6 23:16:20 2006
New Revision: 52937

Modified:
   sandbox/trunk/import_in_py/importer.py
   sandbox/trunk/import_in_py/test_importer.py
Log:
Raise ValueError when an empty string is passed in.

Also shift the functionality for handling values of None in sys.modules to
Import.import_module() to handle relative imports that should redirect to
absolute imports when being triggered directly by the import that started it
all (yes, that was wordy and convoluted as was figuring out the problem).


Modified: sandbox/trunk/import_in_py/importer.py
==============================================================================
--- sandbox/trunk/import_in_py/importer.py	(original)
+++ sandbox/trunk/import_in_py/importer.py	Wed Dec  6 23:16:20 2006
@@ -649,12 +649,18 @@
             raise ImportError("%s not found on sys.path" % name)
             
     def import_module(self, name, path=None):
-        """Import the specified module with no handling of parent modules."""
-        try:
-            # Attempt to get a cached version of the module from sys.modules.
-            return sys.modules[name]
-        except KeyError:
-            pass
+        """Import the specified module with no handling of parent modules.
+        
+        If None is set for a value in sys.modules (to signify that a relative
+        import was attempted and failed) then ImportError is raised.
+        
+        """
+        if name in sys.modules:
+            value = sys.modules[name]
+            if value is None:
+                raise ImportError("relative import redirect")
+            else:
+                return value
         try:
             # Attempt to find a loader on sys.meta_path.
             loader = self.search_meta_path(name, path)
@@ -716,6 +722,25 @@
                                 "pacakge")
         base_name = caller_name.rsplit('.', level)[0]
         return base_name + '.' + name
+        
+    def return_module(self, requested_name, absolute_name, fromlist,
+                        caller_is_package):
+        """Return the proper module based on what module was requested (and its
+        absolute module name), who is
+        requesting it, and whether any speicific attributes were specified.
+        
+        The semantics of this method revolve around 'fromlist'.  When it is
+        empty, the module up to the first dot in 'requested_name' is returned.
+        If 'requested_name' happens to be an absolute name then it must be
+        properly resolved between the absolute name and how the corresponds to
+        the module specified up to the first dot in 'requested_name'.
+        
+        When fromlist is not empty and the caller is a package, then the values
+        in fromlist need to be checked for.  If a value is not a pre-existing
+        attribute 
+        
+        """
+        pass
 
     def __call__(self, name, globals={}, locals={}, fromlist=[], level=-1):
         """Import a module.
@@ -737,7 +762,7 @@
         attributes on the module, attempting a module import relative to 'name'
         to set that attribute.
         
-        When 'name' is a dotted name and fromlist is not empty,
+        When 'name' is a dotted name,
         there are two
         different situations to consider for the return value.  One is when
         the fromlist is empty.
@@ -753,6 +778,8 @@
         (e.g. has a value of 2 for ``from .. import foo``).
 
         """
+        if not name:
+            raise ValueError("Empty module name")
         is_pkg = True if '__path__' in globals else False
         caller_name = globals.get('__name__')
         imp.acquire_lock()
@@ -765,18 +792,13 @@
                                                                 is_pkg)
                     imported_name = relative_name
                     try:
-                        # Check that a redirection entry does not already exist for
-                        # the relative import name.
-                        if (relative_name in sys.modules and
-                                sys.modules[relative_name] is None):
-                            raise ImportError("import redirection")
                         # Try a relative import.
                         self.import_full_module(imported_name)
                     except ImportError:
                         # If the relative import fails (or is redirected), try an
                         # absolute import.
                         imported_name = name
-                        self.import_full_module(name)
+                        self.import_full_module(imported_name)
                         # Redirection entry for resolved relative name to instead
                         # redirect to the absolute import.
                         sys.modules[relative_name] = None

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	Wed Dec  6 23:16:20 2006
@@ -784,6 +784,13 @@
         module = self.importer.import_module(self.parent_name)
         self.failUnless(module is self.parent_module)
         
+    def test_sys_module_None(self):
+        # If sys.modules contains None for a module name, then raise ImportError.
+        module_name = '<module>'
+        sys.modules[module_name] = None
+        self.failUnlessRaises(ImportError, self.importer.import_module,
+                                module_name)
+        
     def test_parent_missing(self):
         # An import should fail if a parent module cannot be found.
         sys.modules[self.full_child_name] = self.child_module
@@ -989,6 +996,10 @@
         self.failUnless(hasattr(module, module_name))
         relative_module = getattr(module, module_name)
         self.failUnlessEqual(relative_module.__name__, full_module_name)
+        
+    def test_empty_string(self):
+        # An empty string should raise ValueError.
+        self.failUnlessRaises(ValueError, self.importer, '')
 
           
 class ImportMetaPathTests(ImportHelper):


More information about the Python-checkins mailing list