Skip to content

Commit 48734db

Browse files
committed
Test the import of a parent package removed before its submodule loads
1 parent a1269ba commit 48734db

1 file changed

Lines changed: 24 additions & 0 deletions

File tree

‎Lib/test/test_importlib/test_threaded_import.py‎

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -909,6 +909,30 @@ def stalling_resolve_parents(name, import_):
909909
self.assertEqual(errors, [])
910910
self.assertEqual(sys.modules["stall_pkg.leaf"].X, 1)
911911

912+
def test_parent_removed_before_submodule_is_loaded(self):
913+
# The parent package leaves sys.modules after it was imported but
914+
# before the submodule is loaded, as when its import failed in
915+
# another thread. The parent must be imported again rather than
916+
# the submodule's import failing with KeyError.
917+
self._setup_package_tree({
918+
"gone_pkg/__init__.py": "",
919+
"gone_pkg/mod.py": "X = 1\n",
920+
})
921+
resolve_parents = importlib._bootstrap._resolve_parents
922+
removed = []
923+
924+
def removing_resolve_parents(name, import_):
925+
resolve_parents(name, import_)
926+
if name == "gone_pkg.mod":
927+
removed.append(sys.modules.pop("gone_pkg"))
928+
929+
with support.swap_attr(importlib._bootstrap, "_resolve_parents",
930+
removing_resolve_parents):
931+
import gone_pkg.mod
932+
self.assertEqual(len(removed), 1)
933+
self.assertIsNot(sys.modules["gone_pkg"], removed[0])
934+
self.assertEqual(sys.modules["gone_pkg"].mod.X, 1)
935+
912936
def test_waiter_retries_after_failed_submodule_import(self):
913937
# Thread 2 waits for thread 1's import of pkg.mod, whose first
914938
# execution then fails. Thread 2 must load pkg.mod itself and not

0 commit comments

Comments
 (0)