-
Notifications
You must be signed in to change notification settings - Fork 952
Description
Bug Description
(Found by claude, verified by me)
There is a race condition where a thread can begin executing Python code before Py_InitializeEx() has finished importing site.py, resulting in an incomplete Python environment (missing sys.path entries, etc.).
Root Cause
CPython sets runtime->initialized = 1 (which makes Py_IsInitialized() return true) before importing site.py:
// cpython/Python/pylifecycle.c, init_interp_main()
interp->runtime->initialized = 1; // line 1333
if (config->site_import) {
status = init_import_site(); // line 1337 — AFTER initialized=1PyO3's try_attach() (src/internal/state.rs:83-116) trusts Py_IsInitialized() to mean the interpreter is fully initialized and ready for use. It bypasses the std::sync::Once guard in initialize() (src/interpreter_lifecycle.rs:7-20) that serializes the actual Py_InitializeEx() call.
Race Window
-
Thread A calls
Python::attach()→try_attach()seesPy_IsInitialized() == 0→ returnsNotInitialized→ callsensure_initialized()→ enterscall_once_force→ callsPy_InitializeEx(0). -
Inside
Py_InitializeEx(0), CPython setsruntime->initialized = 1(line 1333), then begins importingsite.py(line 1337). -
During the
site.pyimport, the GIL can be temporarily released, particularly ifsite.pyexecutes for long periods (e.g., many.pthfiles). -
Thread B calls
Python::attach()→try_attach()checksPy_IsInitialized()atstate.rs:98— it returns1. Thread B proceeds todo_attach_unchecked()→PyGILState_Ensure()→ acquires the GIL whilesite.pyhas released it. -
Thread B is now executing Python code while
site.pyhasn't finished.sys.pathis incomplete, ,.pthfiles are only partially processed, etc. -
Eventually Thread B releases the GIL,
site.pyresumes and finishes,Py_InitializeEx(0)returns, and Thread A callsPyEval_SaveThread()— but by then Thread B may have already observed or acted on the incomplete state.
Steps to Reproduce
I haven't written a minimal reproducer yet, I've just observed the symptoms and stared hard (with Claude).
Backtrace
Your operating system and version
n/a
Your Python version (python --version)
n/a
Your Rust version (rustc --version)
n/a
Your PyO3 version
masater
How did you install python? Did you use a virtualenv?
n/a
Additional Info
No response