Commit 416f12dd authored by Meador Inge's avatar Meador Inge

Issue #13591: import_module potentially imports a module twice.

parent 061c0289
......@@ -816,7 +816,9 @@ def _gcd_import(name, package=None, level=0):
for finder in meta_path:
loader = finder.find_module(name, path)
if loader is not None:
loader.load_module(name)
# The parent import may have already imported this module.
if name not in sys.modules:
loader.load_module(name)
break
else:
raise ImportError(_ERR_MSG.format(name))
......
......@@ -67,6 +67,23 @@ class ImportModuleTests(unittest.TestCase):
importlib.import_module('.support')
def test_loaded_once(self):
# Issue #13591: Modules should only be loaded once when
# initializing the parent package attempts to import the
# module currently being imported.
b_load_count = 0
def load_a():
importlib.import_module('a.b')
def load_b():
nonlocal b_load_count
b_load_count += 1
code = {'a': load_a, 'a.b': load_b}
modules = ['a.__init__', 'a.b']
with util.mock_modules(*modules, module_code=code) as mock:
with util.import_state(meta_path=[mock]):
importlib.import_module('a.b')
self.assertEqual(b_load_count, 1)
def test_main():
from test.support import run_unittest
run_unittest(ImportModuleTests)
......
......@@ -84,8 +84,9 @@ class mock_modules:
"""A mock importer/loader."""
def __init__(self, *names):
def __init__(self, *names, module_code={}):
self.modules = {}
self.module_code = {}
for name in names:
if not name.endswith('.__init__'):
import_name = name
......@@ -105,6 +106,8 @@ class mock_modules:
if import_name != name:
module.__path__ = ['<mock __path__>']
self.modules[import_name] = module
if import_name in module_code:
self.module_code[import_name] = module_code[import_name]
def __getitem__(self, name):
return self.modules[name]
......@@ -120,6 +123,8 @@ class mock_modules:
raise ImportError
else:
sys.modules[fullname] = self.modules[fullname]
if fullname in self.module_code:
self.module_code[fullname]()
return self.modules[fullname]
def __enter__(self):
......
......@@ -1868,6 +1868,9 @@ Core and Builtins
Library
-------
- Issue #13591: A bug in importlib has been fixed that caused import_module
to load a module twice.
- logging: added "handler of last resort". See http://bit.ly/last-resort-handler
- test.support: Added TestHandler and Matcher classes for better support of
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment