Issue #15828: Restore support for C extension modules in imp.load_module()
This commit is contained in:
parent
2d337c7061
commit
5d0612411e
|
@ -153,13 +153,15 @@ def load_module(name, file, filename, details):
|
||||||
warnings.simplefilter('ignore')
|
warnings.simplefilter('ignore')
|
||||||
if mode and (not mode.startswith(('r', 'U')) or '+' in mode):
|
if mode and (not mode.startswith(('r', 'U')) or '+' in mode):
|
||||||
raise ValueError('invalid file open mode {!r}'.format(mode))
|
raise ValueError('invalid file open mode {!r}'.format(mode))
|
||||||
elif file is None and type_ in {PY_SOURCE, PY_COMPILED}:
|
elif file is None and type_ in {PY_SOURCE, PY_COMPILED, C_EXTENSION}:
|
||||||
msg = 'file object required for import (type code {})'.format(type_)
|
msg = 'file object required for import (type code {})'.format(type_)
|
||||||
raise ValueError(msg)
|
raise ValueError(msg)
|
||||||
elif type_ == PY_SOURCE:
|
elif type_ == PY_SOURCE:
|
||||||
return load_source(name, filename, file)
|
return load_source(name, filename, file)
|
||||||
elif type_ == PY_COMPILED:
|
elif type_ == PY_COMPILED:
|
||||||
return load_compiled(name, filename, file)
|
return load_compiled(name, filename, file)
|
||||||
|
elif type_ == C_EXTENSION:
|
||||||
|
return load_dynamic(name, filename, file)
|
||||||
elif type_ == PKG_DIRECTORY:
|
elif type_ == PKG_DIRECTORY:
|
||||||
return load_package(name, filename)
|
return load_package(name, filename)
|
||||||
elif type_ == C_BUILTIN:
|
elif type_ == C_BUILTIN:
|
||||||
|
@ -167,7 +169,7 @@ def load_module(name, file, filename, details):
|
||||||
elif type_ == PY_FROZEN:
|
elif type_ == PY_FROZEN:
|
||||||
return init_frozen(name)
|
return init_frozen(name)
|
||||||
else:
|
else:
|
||||||
msg = "Don't know how to import {} (type code {}".format(name, type_)
|
msg = "Don't know how to import {} (type code {})".format(name, type_)
|
||||||
raise ImportError(msg, name=name)
|
raise ImportError(msg, name=name)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -186,6 +186,35 @@ class ImportTests(unittest.TestCase):
|
||||||
self.assertRaises(SyntaxError,
|
self.assertRaises(SyntaxError,
|
||||||
imp.find_module, "badsyntax_pep3120", [path])
|
imp.find_module, "badsyntax_pep3120", [path])
|
||||||
|
|
||||||
|
def test_load_from_source(self):
|
||||||
|
# Verify that the imp module can correctly load and find .py files
|
||||||
|
# XXX (ncoghlan): It would be nice to use support.CleanImport
|
||||||
|
# here, but that breaks because the os module registers some
|
||||||
|
# handlers in copy_reg on import. Since CleanImport doesn't
|
||||||
|
# revert that registration, the module is left in a broken
|
||||||
|
# state after reversion. Reinitialising the module contents
|
||||||
|
# and just reverting os.environ to its previous state is an OK
|
||||||
|
# workaround
|
||||||
|
orig_path = os.path
|
||||||
|
orig_getenv = os.getenv
|
||||||
|
with support.EnvironmentVarGuard():
|
||||||
|
x = imp.find_module("os")
|
||||||
|
self.addCleanup(x[0].close)
|
||||||
|
new_os = imp.load_module("os", *x)
|
||||||
|
self.assertIs(os, new_os)
|
||||||
|
self.assertIs(orig_path, new_os.path)
|
||||||
|
self.assertIsNot(orig_getenv, new_os.getenv)
|
||||||
|
|
||||||
|
@support.cpython_only
|
||||||
|
def test_issue15828_load_extensions(self):
|
||||||
|
# Issue 15828 picked up that the adapter between the old imp API
|
||||||
|
# and importlib couldn't handle C extensions
|
||||||
|
example = "_heapq"
|
||||||
|
x = imp.find_module(example)
|
||||||
|
self.addCleanup(x[0].close)
|
||||||
|
mod = imp.load_module(example, *x)
|
||||||
|
self.assertEqual(mod.__name__, example)
|
||||||
|
|
||||||
def test_load_dynamic_ImportError_path(self):
|
def test_load_dynamic_ImportError_path(self):
|
||||||
# Issue #1559549 added `name` and `path` attributes to ImportError
|
# Issue #1559549 added `name` and `path` attributes to ImportError
|
||||||
# in order to provide better detail. Issue #10854 implemented those
|
# in order to provide better detail. Issue #10854 implemented those
|
||||||
|
|
|
@ -149,25 +149,6 @@ class ImportTests(unittest.TestCase):
|
||||||
|
|
||||||
self.assertEqual(oct(stat.S_IMODE(stat_info.st_mode)), oct(mode))
|
self.assertEqual(oct(stat.S_IMODE(stat_info.st_mode)), oct(mode))
|
||||||
|
|
||||||
def test_imp_module(self):
|
|
||||||
# Verify that the imp module can correctly load and find .py files
|
|
||||||
# XXX (ncoghlan): It would be nice to use support.CleanImport
|
|
||||||
# here, but that breaks because the os module registers some
|
|
||||||
# handlers in copy_reg on import. Since CleanImport doesn't
|
|
||||||
# revert that registration, the module is left in a broken
|
|
||||||
# state after reversion. Reinitialising the module contents
|
|
||||||
# and just reverting os.environ to its previous state is an OK
|
|
||||||
# workaround
|
|
||||||
orig_path = os.path
|
|
||||||
orig_getenv = os.getenv
|
|
||||||
with EnvironmentVarGuard():
|
|
||||||
x = imp.find_module("os")
|
|
||||||
self.addCleanup(x[0].close)
|
|
||||||
new_os = imp.load_module("os", *x)
|
|
||||||
self.assertIs(os, new_os)
|
|
||||||
self.assertIs(orig_path, new_os.path)
|
|
||||||
self.assertIsNot(orig_getenv, new_os.getenv)
|
|
||||||
|
|
||||||
def test_bug7732(self):
|
def test_bug7732(self):
|
||||||
source = TESTFN + '.py'
|
source = TESTFN + '.py'
|
||||||
os.mkdir(source)
|
os.mkdir(source)
|
||||||
|
|
|
@ -54,6 +54,8 @@ Core and Builtins
|
||||||
Library
|
Library
|
||||||
-------
|
-------
|
||||||
|
|
||||||
|
- Issue #15828: Restore support for C extensions in imp.load_module()
|
||||||
|
|
||||||
- Issue #10650: Deprecate the watchexp parameter of the Decimal.quantize()
|
- Issue #10650: Deprecate the watchexp parameter of the Decimal.quantize()
|
||||||
method.
|
method.
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue