[Python-checkins] r52771 - sandbox/trunk/import_in_py/importer.py sandbox/trunk/import_in_py/test_importer.py
brett.cannon
python-checkins at python.org
Fri Nov 17 00:39:32 CET 2006
Author: brett.cannon
Date: Fri Nov 17 00:39:31 2006
New Revision: 52771
Modified:
sandbox/trunk/import_in_py/importer.py
sandbox/trunk/import_in_py/test_importer.py
Log:
Handle redirection entries (i.e., entries in sys.modules with a value of None).
Modified: sandbox/trunk/import_in_py/importer.py
==============================================================================
--- sandbox/trunk/import_in_py/importer.py (original)
+++ sandbox/trunk/import_in_py/importer.py Fri Nov 17 00:39:31 2006
@@ -44,11 +44,6 @@
+ Bytecode handles pulling every attribute off of module.
+ Do need to make sure all entries in __all__ are an attribute of the
module, though.
-* Modules in sys.modules with a value of None are for redirection to a
- top-level module that was imported in a submodule [pacakge essay].
- + If classic relative import fails but absolute import succeeds, create
- redirection entry in sys.modules for resolved relative name.
- + If both imports fail then no need to create redirection entry.
Bytecode
--------
@@ -766,17 +761,25 @@
# Handle the classic style of import: relative first, then
# absolute.
if level == -1:
- imported_name = self.classic_resolve_name(name, caller_name,
+ relative_name = self.classic_resolve_name(name, caller_name,
is_pkg)
+ imported_name = relative_name
try:
- # Try a relative import first.
+ # 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)
- # XXX Probably need to do something about values of None
- # being in sys.modules here.
except ImportError:
- # If the relative import fails, try an absolute import.
+ # If the relative import fails (or is redirected), try an
+ # absolute import.
imported_name = name
self.import_full_module(name)
+ # Redirection entry for resolved relative name to instead
+ # redirect to the absolute import.
+ sys.modules[relative_name] = None
# If using absolute imports with a relative path, only attempt with
# the fully-resolved module name.
else:
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 Fri Nov 17 00:39:31 2006
@@ -866,6 +866,31 @@
# ImportError.
self.failUnlessRaises(ImportError, self.importer.resolve_name,
self.child_name, self.parent_name, False, 1)
+
+ def test_relative_import_redirection(self):
+ # Having a relative module name resolve to a name that has a value of
+ # None in sys.modules should redirect to import an absolute import for
+ # the specified name.
+ module_name = '<to import>'
+ pkg_name = '<pkg>'
+ resolved_relative_name = module_name + '.' + pkg_name
+ expected_module = mock_importer.MockModule(module_name)
+ sys.modules[resolved_relative_name] = None
+ sys.modules[module_name] = expected_module
+ importing_globals = {'__name__':pkg_name, '__path__':['some path']}
+ imported = self.importer(module_name, importing_globals, level=-1)
+ self.failUnless(imported is expected_module)
+
+ def test_None_not_set_for_import_failure(self):
+ # If an import that is tried both relative and absolute fails there
+ # should be an entry of None for the resolved relative name.
+ module_name = '<should fail>'
+ pkg_name = '<non-existent package>'
+ resolved_name = module_name + '.' + pkg_name
+ importing_globals = {'__name__':pkg_name, '__path__':['path']}
+ self.failUnlessRaises(ImportError, self.importer, module_name,
+ importing_globals, {}, [], -1)
+ self.failUnless(resolved_name not in sys.modules)
class ImportMetaPathTests(ImportHelper):
@@ -1155,12 +1180,15 @@
def test_absolute_name_in_classic_relative_context(self):
# Importing a module that happens to be ambiguous in terms of being
# relative or absolute, but only exists in an absolute name context,
- # should work.
+ # should work. It should also lead to a value for None in sys.modules
+ # for the resolved relative name.
package_module_globals = {'__name__':self.pkg_module_name}
module = self.import_(self.top_level_module_name,
package_module_globals, level=-1)
+ resolved_name = self.pkg_name + '.' + self.top_level_module_name
self.verify_package(module)
self.failUnlessEqual(module.__name__, self.top_level_module_name)
+ self.failUnless(sys.modules[resolved_name] is None)
def test_relative_import_in_package_init(self):
# Importing a module with a relative name in a package's __init__ file
More information about the Python-checkins
mailing list