mirror of
https://github.com/python/cpython
synced 2026-09-29 12:10:30 +03:00
Being able to overload a sys.module entry during import of a module was broken by this changeset.
This commit is contained in:
parent
da20cd2b6b
commit
d76bc7abac
5 changed files with 504 additions and 498 deletions
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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():
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue