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.
This commit is contained in:
Nick Coghlan 2015-09-05 21:05:05 +10:00
parent 1b66910537
commit 9d3c61c86a
5 changed files with 49 additions and 1 deletions

View File

@ -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

3
Lib/test/imp_dummy.py Normal file
View File

@ -0,0 +1,3 @@
# Fodder for test of issue24748 in test_imp
dummy_name = True

View File

@ -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):

View File

@ -15,6 +15,11 @@ Core and Builtins
Library
-------
- Issue #24748: 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.
- Issue #24635: Fixed a bug in typing.py where isinstance([], typing.Iterable)
would return True once, then False on subsequent calls.

View File

@ -582,3 +582,13 @@ PyInit__testmultiphase_exec_unreported_exception(PyObject *spec)
{
return PyModuleDef_Init(&def_exec_unreported_exception);
}
/*** Helper for imp test ***/
static PyModuleDef imp_dummy_def = TEST_MODULE_DEF("imp_dummy", main_slots, testexport_methods);
PyMODINIT_FUNC
PyInit_imp_dummy(PyObject *spec)
{
return PyModuleDef_Init(&imp_dummy_def);
}