diff options
author | Nick Coghlan <ncoghlan@gmail.com> | 2015-09-05 11:05:05 (GMT) |
---|---|---|
committer | Nick Coghlan <ncoghlan@gmail.com> | 2015-09-05 11:05:05 (GMT) |
commit | 9d3c61c86a20678d604c96a68bbf4a966877f0b9 (patch) | |
tree | 77e38b72e9258da435606d28543cc0362787eeff /Lib | |
parent | 1b6691053701e92490c6b68171d6d6a645f8e708 (diff) | |
download | cpython-9d3c61c86a20678d604c96a68bbf4a966877f0b9.zip cpython-9d3c61c86a20678d604c96a68bbf4a966877f0b9.tar.gz cpython-9d3c61c86a20678d604c96a68bbf4a966877f0b9.tar.bz2 |
Close #24748: Restore imp.load_dynamic compatibility
To resolve a compatibility problem found with py2exe and
pywin32, imp.load_dynamic() once again ignores previously loaded modules
to support Python modules replacing themselves with extension modules.
Patch by Petr Viktorin.
Diffstat (limited to 'Lib')
-rw-r--r-- | Lib/imp.py | 8 | ||||
-rw-r--r-- | Lib/test/imp_dummy.py | 3 | ||||
-rw-r--r-- | Lib/test/test_imp.py | 24 |
3 files changed, 34 insertions, 1 deletions
@@ -334,6 +334,12 @@ if create_dynamic: """ import importlib.machinery loader = importlib.machinery.ExtensionFileLoader(name, path) - return loader.load_module() + + # Issue #24748: Skip the sys.modules check in _load_module_shim; + # always load new extension + spec = importlib.machinery.ModuleSpec( + name=name, loader=loader, origin=path) + return _load(spec) + else: load_dynamic = None diff --git a/Lib/test/imp_dummy.py b/Lib/test/imp_dummy.py new file mode 100644 index 0000000..2a4deb4 --- /dev/null +++ b/Lib/test/imp_dummy.py @@ -0,0 +1,3 @@ +# Fodder for test of issue24748 in test_imp + +dummy_name = True diff --git a/Lib/test/test_imp.py b/Lib/test/test_imp.py index 47bf1de..ee9ee1a 100644 --- a/Lib/test/test_imp.py +++ b/Lib/test/test_imp.py @@ -3,6 +3,7 @@ try: except ImportError: _thread = None import importlib +import importlib.util import os import os.path import shutil @@ -275,6 +276,29 @@ class ImportTests(unittest.TestCase): self.skipTest("found module doesn't appear to be a C extension") imp.load_module(name, None, *found[1:]) + @requires_load_dynamic + def test_issue24748_load_module_skips_sys_modules_check(self): + name = 'test.imp_dummy' + try: + del sys.modules[name] + except KeyError: + pass + try: + module = importlib.import_module(name) + spec = importlib.util.find_spec('_testmultiphase') + module = imp.load_dynamic(name, spec.origin) + self.assertEqual(module.__name__, name) + self.assertEqual(module.__spec__.name, name) + self.assertEqual(module.__spec__.origin, spec.origin) + self.assertRaises(AttributeError, getattr, module, 'dummy_name') + self.assertEqual(module.int_const, 1969) + self.assertIs(sys.modules[name], module) + finally: + try: + del sys.modules[name] + except KeyError: + pass + @unittest.skipIf(sys.dont_write_bytecode, "test meaningful only when writing bytecode") def test_bug7732(self): |