Skip to content

Commit f07e2b6

Browse files
bpo-31642: Restore blocking "from" import by setting None in sys.modules. (#3834)
1 parent 73ffd3f commit f07e2b6

File tree

4 files changed

+262
-243
lines changed

4 files changed

+262
-243
lines changed

Lib/importlib/_bootstrap.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1019,7 +1019,8 @@ def _handle_fromlist(module, fromlist, import_):
10191019
# Backwards-compatibility dictates we ignore failed
10201020
# imports triggered by fromlist for modules that don't
10211021
# exist.
1022-
if exc.name == from_name:
1022+
if (exc.name == from_name and
1023+
sys.modules.get(from_name, _NEEDS_LOADING) is not None):
10231024
continue
10241025
raise
10251026
return module

Lib/test/test_importlib/import_/test_api.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,20 @@ def test_fromlist_load_error_propagates(self):
8282
self.__import__(PKG_NAME,
8383
fromlist=[SUBMOD_NAME.rpartition('.')[-1]])
8484

85+
def test_blocked_fromlist(self):
86+
# If fromlist entry is None, let a ModuleNotFoundError propagate.
87+
# issue31642
88+
mod = types.ModuleType(PKG_NAME)
89+
mod.__path__ = []
90+
with util.import_state(meta_path=[self.bad_finder_loader]):
91+
with util.uncache(PKG_NAME, SUBMOD_NAME):
92+
sys.modules[PKG_NAME] = mod
93+
sys.modules[SUBMOD_NAME] = None
94+
with self.assertRaises(ModuleNotFoundError) as cm:
95+
self.__import__(PKG_NAME,
96+
fromlist=[SUBMOD_NAME.rpartition('.')[-1]])
97+
self.assertEqual(cm.exception.name, SUBMOD_NAME)
98+
8599

86100
class OldAPITests(APITest):
87101
bad_finder_loader = BadLoaderFinder
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Restored blocking "from package import module" by setting
2+
sys.modules["package.module"] to None.

0 commit comments

Comments
 (0)