mirror of
https://github.com/AdaCore/cpython.git
synced 2026-02-12 12:57:15 -08:00
Being able to overload a sys.module entry during import of a module was broken by this changeset.
This commit is contained in:
@@ -984,12 +984,12 @@ def _find_and_load(name, import_):
|
||||
loader = _find_module(name, path)
|
||||
if loader is None:
|
||||
raise ImportError(_ERR_MSG.format(name), name=name)
|
||||
elif name in sys.modules:
|
||||
# The parent module already imported this module.
|
||||
module = sys.modules[name]
|
||||
else:
|
||||
module = loader.load_module(name)
|
||||
elif name not in sys.modules:
|
||||
# The parent import may have already imported this module.
|
||||
loader.load_module(name)
|
||||
verbose_message('import {!r} # {!r}', name, loader)
|
||||
# Backwards-compatibility; be nicer to skip the dict lookup.
|
||||
module = sys.modules[name]
|
||||
if parent:
|
||||
# Set the module as an attribute on its parent.
|
||||
parent_module = sys.modules[parent]
|
||||
@@ -1088,11 +1088,7 @@ def __import__(name, globals={}, locals={}, fromlist=[], level=0):
|
||||
# Return up to the first dot in 'name'. This is complicated by the fact
|
||||
# that 'name' may be relative.
|
||||
if level == 0:
|
||||
index = name.find('.')
|
||||
if index == -1:
|
||||
return module
|
||||
else:
|
||||
return sys.modules[name[:index]]
|
||||
return sys.modules[name.partition('.')[0]]
|
||||
elif not name:
|
||||
return module
|
||||
else:
|
||||
|
||||
@@ -47,12 +47,36 @@ class UseCache(unittest.TestCase):
|
||||
mock.load_module = MethodType(load_module, mock)
|
||||
return mock
|
||||
|
||||
def test_using_loader_return(self):
|
||||
loader_return = 'hi there!'
|
||||
with self.create_mock('module', return_=loader_return) as mock:
|
||||
# __import__ inconsistent between loaders and built-in import when it comes
|
||||
# to when to use the module in sys.modules and when not to.
|
||||
@import_util.importlib_only
|
||||
def test_using_cache_after_loader(self):
|
||||
# [from cache on return]
|
||||
with self.create_mock('module') as mock:
|
||||
with util.import_state(meta_path=[mock]):
|
||||
module = import_util.import_('module')
|
||||
self.assertEqual(module, loader_return)
|
||||
self.assertEqual(id(module), id(sys.modules['module']))
|
||||
|
||||
# See test_using_cache_after_loader() for reasoning.
|
||||
@import_util.importlib_only
|
||||
def test_using_cache_for_assigning_to_attribute(self):
|
||||
# [from cache to attribute]
|
||||
with self.create_mock('pkg.__init__', 'pkg.module') as importer:
|
||||
with util.import_state(meta_path=[importer]):
|
||||
module = import_util.import_('pkg.module')
|
||||
self.assertTrue(hasattr(module, 'module'))
|
||||
self.assertTrue(id(module.module), id(sys.modules['pkg.module']))
|
||||
|
||||
# See test_using_cache_after_loader() for reasoning.
|
||||
@import_util.importlib_only
|
||||
def test_using_cache_for_fromlist(self):
|
||||
# [from cache for fromlist]
|
||||
with self.create_mock('pkg.__init__', 'pkg.module') as importer:
|
||||
with util.import_state(meta_path=[importer]):
|
||||
module = import_util.import_('pkg', fromlist=['module'])
|
||||
self.assertTrue(hasattr(module, 'module'))
|
||||
self.assertEqual(id(module.module),
|
||||
id(sys.modules['pkg.module']))
|
||||
|
||||
|
||||
def test_main():
|
||||
|
||||
@@ -23,9 +23,6 @@ Core and Builtins
|
||||
fails to import now uses the new path and name attributes from
|
||||
Issue #1559549.
|
||||
|
||||
- Issue #14582: Import directly returns the module as returned by a loader when
|
||||
possible instead of fetching it from sys.modules.
|
||||
|
||||
- Issue #13889: Check and (if necessary) set FPU control word before calling
|
||||
any of the dtoa.c string <-> float conversion functions, on MSVC builds of
|
||||
Python. This fixes issues when embedding Python in a Delphi app.
|
||||
|
||||
@@ -2447,22 +2447,15 @@ PyImport_ImportModuleLevelObject(PyObject *name, PyObject *given_globals,
|
||||
Py_DECREF(partition);
|
||||
|
||||
if (level == 0) {
|
||||
if (PyUnicode_GET_LENGTH(name) ==
|
||||
PyUnicode_GET_LENGTH(front)) {
|
||||
final_mod = mod;
|
||||
}
|
||||
else {
|
||||
final_mod = PyDict_GetItem(interp->modules, front);
|
||||
if (final_mod == NULL) {
|
||||
PyErr_Format(PyExc_KeyError,
|
||||
"%R not in sys.modules as expected", front);
|
||||
}
|
||||
}
|
||||
final_mod = PyDict_GetItem(interp->modules, front);
|
||||
Py_DECREF(front);
|
||||
if (final_mod == NULL) {
|
||||
goto error_with_unlock;
|
||||
PyErr_Format(PyExc_KeyError,
|
||||
"%R not in sys.modules as expected", front);
|
||||
}
|
||||
else {
|
||||
Py_INCREF(final_mod);
|
||||
}
|
||||
Py_INCREF(final_mod);
|
||||
}
|
||||
else {
|
||||
Py_ssize_t cut_off = PyUnicode_GET_LENGTH(name) -
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user