rollback 005fd1fe31ab (see #14609 and #14582)

Being able to overload a sys.module entry during import of a module was broken
by this changeset.
This commit is contained in:
Benjamin Peterson 2012-04-18 10:55:43 -04:00
parent da20cd2b6b
commit d76bc7abac
5 changed files with 504 additions and 498 deletions

View file

@ -984,12 +984,12 @@ def _find_and_load(name, import_):
loader = _find_module(name, path)
if loader is None:
raise ImportError(_ERR_MSG.format(name), name=name)
elif name in sys.modules:
# The parent module already imported this module.
module = sys.modules[name]
else:
module = loader.load_module(name)
elif name not in sys.modules:
# The parent import may have already imported this module.
loader.load_module(name)
verbose_message('import {!r} # {!r}', name, loader)
# Backwards-compatibility; be nicer to skip the dict lookup.
module = sys.modules[name]
if parent:
# Set the module as an attribute on its parent.
parent_module = sys.modules[parent]
@ -1088,11 +1088,7 @@ def __import__(name, globals={}, locals={}, fromlist=[], level=0):
# Return up to the first dot in 'name'. This is complicated by the fact
# that 'name' may be relative.
if level == 0:
index = name.find('.')
if index == -1:
return module
else:
return sys.modules[name[:index]]
return sys.modules[name.partition('.')[0]]
elif not name:
return module
else:

View file

@ -47,12 +47,36 @@ class UseCache(unittest.TestCase):
mock.load_module = MethodType(load_module, mock)
return mock
def test_using_loader_return(self):
loader_return = 'hi there!'
with self.create_mock('module', return_=loader_return) as mock:
# __import__ inconsistent between loaders and built-in import when it comes
# to when to use the module in sys.modules and when not to.
@import_util.importlib_only
def test_using_cache_after_loader(self):
# [from cache on return]
with self.create_mock('module') as mock:
with util.import_state(meta_path=[mock]):
module = import_util.import_('module')
self.assertEqual(module, loader_return)
self.assertEqual(id(module), id(sys.modules['module']))
# See test_using_cache_after_loader() for reasoning.
@import_util.importlib_only
def test_using_cache_for_assigning_to_attribute(self):
# [from cache to attribute]
with self.create_mock('pkg.__init__', 'pkg.module') as importer:
with util.import_state(meta_path=[importer]):
module = import_util.import_('pkg.module')
self.assertTrue(hasattr(module, 'module'))
self.assertTrue(id(module.module), id(sys.modules['pkg.module']))
# See test_using_cache_after_loader() for reasoning.
@import_util.importlib_only
def test_using_cache_for_fromlist(self):
# [from cache for fromlist]
with self.create_mock('pkg.__init__', 'pkg.module') as importer:
with util.import_state(meta_path=[importer]):
module = import_util.import_('pkg', fromlist=['module'])
self.assertTrue(hasattr(module, 'module'))
self.assertEqual(id(module.module),
id(sys.modules['pkg.module']))
def test_main():