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:
parent
1b66910537
commit
9d3c61c86a
|
@ -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
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
# Fodder for test of issue24748 in test_imp
|
||||
|
||||
dummy_name = True
|
|
@ -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):
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue