[Python-checkins] cpython (3.2): Issue #13591: import_module potentially imports a module twice.

meador.inge python-checkins at python.org
Thu Dec 15 05:28:04 CET 2011


http://hg.python.org/cpython/rev/d2504d30f259
changeset: 73973:d2504d30f259
branch: 3.2
parent: 73971:f1fe411bfd6b
user: Meador Inge <meadori at gmail.com>
date: Wed Dec 14 22:23:46 2011 -0600
summary:
 Issue #13591: import_module potentially imports a module twice.
files:
 Lib/importlib/_bootstrap.py | 4 +++-
 Lib/importlib/test/test_api.py | 17 +++++++++++++++++
 Lib/importlib/test/util.py | 7 ++++++-
 Misc/NEWS | 3 +++
 4 files changed, 29 insertions(+), 2 deletions(-)
diff --git a/Lib/importlib/_bootstrap.py b/Lib/importlib/_bootstrap.py
--- a/Lib/importlib/_bootstrap.py
+++ b/Lib/importlib/_bootstrap.py
@@ -816,7 +816,9 @@
 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))
diff --git a/Lib/importlib/test/test_api.py b/Lib/importlib/test/test_api.py
--- a/Lib/importlib/test/test_api.py
+++ b/Lib/importlib/test/test_api.py
@@ -67,6 +67,23 @@
 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)
diff --git a/Lib/importlib/test/util.py b/Lib/importlib/test/util.py
--- a/Lib/importlib/test/util.py
+++ b/Lib/importlib/test/util.py
@@ -84,8 +84,9 @@
 
 """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 @@
 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 @@
 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):
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -1868,6 +1868,9 @@
 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
-- 
Repository URL: http://hg.python.org/cpython


More information about the Python-checkins mailing list

AltStyle によって変換されたページ (->オリジナル) /