-
-
Notifications
You must be signed in to change notification settings - Fork 33.9k
Open
Labels
interpreter-core(Objects, Python, Grammar, and Parser dirs)(Objects, Python, Grammar, and Parser dirs)stdlibStandard Library Python modules in the Lib/ directoryStandard Library Python modules in the Lib/ directorytopic-importlibtype-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error
Description
When a module import fails, other threads can receive a stale module reference that is no longer in sys.modules.
Race condition
- Thread 1 starts importing module X, adds it to
sys.modules - Thread 2 checks
sys.modules, finds module X, takes the "skip lock" fast path - Thread 1's import fails, removes module X from
sys.modules - Thread 2 returns the stale module reference (not in
sys.modules)
Affected code paths
Lib/importlib/_bootstrap.py:_find_and_load()lines 1268-1282Python/import.c:PyImport_GetModule()Python/import.c:PyImport_ImportModuleLevelObject()
All three have an optimization that skips locking when a module appears already loaded, but none verify the module is still valid after checking _initializing.
Reproducer
import sys
import threading
import tempfile
import os
with tempfile.TemporaryDirectory() as tmpdir:
sys.path.insert(0, tmpdir)
# Module that partially initializes then fails
with open(os.path.join(tmpdir, "failing_mod.py"), "w") as f:
f.write("import time; time.sleep(0.05); raise RuntimeError('fail')")
results = []
def do_import(delay):
import time; time.sleep(delay)
try:
mod = __import__("failing_mod")
if "failing_mod" not in sys.modules:
results.append("RACE: got module not in sys.modules")
except RuntimeError:
results.append("ok")
t1 = threading.Thread(target=do_import, args=(0,))
t2 = threading.Thread(target=do_import, args=(0.01,))
t1.start(); t2.start(); t1.join(); t2.join()
print(results) # May show "RACE" on affected buildsLinked PRs
Metadata
Metadata
Assignees
Labels
interpreter-core(Objects, Python, Grammar, and Parser dirs)(Objects, Python, Grammar, and Parser dirs)stdlibStandard Library Python modules in the Lib/ directoryStandard Library Python modules in the Lib/ directorytopic-importlibtype-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error