Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit eca8518

Browse files
committed
Merge heads
2 parents ec9bac4 + d76bc7a commit eca8518

5 files changed

Lines changed: 503 additions & 497 deletions

File tree

Lib/importlib/_bootstrap.py

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -984,12 +984,12 @@ def _find_and_load(name, import_):
984984
loader = _find_module(name, path)
985985
if loader is None:
986986
raise ImportError(_ERR_MSG.format(name), name=name)
987-
elif name in sys.modules:
988-
# The parent module already imported this module.
989-
module = sys.modules[name]
990-
else:
991-
module = loader.load_module(name)
987+
elif name not in sys.modules:
988+
# The parent import may have already imported this module.
989+
loader.load_module(name)
992990
verbose_message('import {!r} # {!r}', name, loader)
991+
# Backwards-compatibility; be nicer to skip the dict lookup.
992+
module = sys.modules[name]
993993
if parent:
994994
# Set the module as an attribute on its parent.
995995
parent_module = sys.modules[parent]
@@ -1088,11 +1088,7 @@ def __import__(name, globals={}, locals={}, fromlist=[], level=0):
10881088
# Return up to the first dot in 'name'. This is complicated by the fact
10891089
# that 'name' may be relative.
10901090
if level == 0:
1091-
index = name.find('.')
1092-
if index == -1:
1093-
return module
1094-
else:
1095-
return sys.modules[name[:index]]
1091+
return sys.modules[name.partition('.')[0]]
10961092
elif not name:
10971093
return module
10981094
else:

Lib/importlib/test/import_/test_caching.py

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,12 +47,36 @@ def load_module(self, fullname):
4747
mock.load_module = MethodType(load_module, mock)
4848
return mock
4949

50-
def test_using_loader_return(self):
51-
loader_return = 'hi there!'
52-
with self.create_mock('module', return_=loader_return) as mock:
50+
# __import__ inconsistent between loaders and built-in import when it comes
51+
# to when to use the module in sys.modules and when not to.
52+
@import_util.importlib_only
53+
def test_using_cache_after_loader(self):
54+
# [from cache on return]
55+
with self.create_mock('module') as mock:
5356
with util.import_state(meta_path=[mock]):
5457
module = import_util.import_('module')
55-
self.assertEqual(module, loader_return)
58+
self.assertEqual(id(module), id(sys.modules['module']))
59+
60+
# See test_using_cache_after_loader() for reasoning.
61+
@import_util.importlib_only
62+
def test_using_cache_for_assigning_to_attribute(self):
63+
# [from cache to attribute]
64+
with self.create_mock('pkg.__init__', 'pkg.module') as importer:
65+
with util.import_state(meta_path=[importer]):
66+
module = import_util.import_('pkg.module')
67+
self.assertTrue(hasattr(module, 'module'))
68+
self.assertTrue(id(module.module), id(sys.modules['pkg.module']))
69+
70+
# See test_using_cache_after_loader() for reasoning.
71+
@import_util.importlib_only
72+
def test_using_cache_for_fromlist(self):
73+
# [from cache for fromlist]
74+
with self.create_mock('pkg.__init__', 'pkg.module') as importer:
75+
with util.import_state(meta_path=[importer]):
76+
module = import_util.import_('pkg', fromlist=['module'])
77+
self.assertTrue(hasattr(module, 'module'))
78+
self.assertEqual(id(module.module),
79+
id(sys.modules['pkg.module']))
5680

5781

5882
def test_main():

Misc/NEWS

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,6 @@ Core and Builtins
2323
fails to import now uses the new path and name attributes from
2424
Issue #1559549.
2525

26-
- Issue #14582: Import directly returns the module as returned by a loader when
27-
possible instead of fetching it from sys.modules.
28-
2926
- Issue #13889: Check and (if necessary) set FPU control word before calling
3027
any of the dtoa.c string <-> float conversion functions, on MSVC builds of
3128
Python. This fixes issues when embedding Python in a Delphi app.

Python/import.c

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2447,22 +2447,15 @@ PyImport_ImportModuleLevelObject(PyObject *name, PyObject *given_globals,
24472447
Py_DECREF(partition);
24482448

24492449
if (level == 0) {
2450-
if (PyUnicode_GET_LENGTH(name) ==
2451-
PyUnicode_GET_LENGTH(front)) {
2452-
final_mod = mod;
2453-
}
2454-
else {
2455-
final_mod = PyDict_GetItem(interp->modules, front);
2456-
if (final_mod == NULL) {
2457-
PyErr_Format(PyExc_KeyError,
2458-
"%R not in sys.modules as expected", front);
2459-
}
2460-
}
2450+
final_mod = PyDict_GetItem(interp->modules, front);
24612451
Py_DECREF(front);
24622452
if (final_mod == NULL) {
2463-
goto error_with_unlock;
2453+
PyErr_Format(PyExc_KeyError,
2454+
"%R not in sys.modules as expected", front);
2455+
}
2456+
else {
2457+
Py_INCREF(final_mod);
24642458
}
2465-
Py_INCREF(final_mod);
24662459
}
24672460
else {
24682461
Py_ssize_t cut_off = PyUnicode_GET_LENGTH(name) -

0 commit comments

Comments
 (0)