Repository navigation
Race condition when importing collections.abc #125245
Description
Bug report
Bug description:
Discovered alongside #125243 with similar steps to reproduce. I don't have a simpler way to trigger this than "run the PyO3 tests in a loop" because I think it requires many threads accessing the python runtime simulatenously.
To trigger it, have a rust toolchain and Python installed, clone the PyO3 repo and execute the following command:
while RUST_BACKTRACE=1 UNSAFE_PYO3_BUILD_FREE_THREADED=1 cargo test --lib --features=full -- --test-threads=100; do :; done
You may also hit some other test failures related to ZoneInfo, see the other issue I opened about that.
You will eventually see a test failure with the following text:
---- exceptions::socket::tests::gaierror stdout ----
thread 'exceptions::socket::tests::gaierror' panicked at src/impl_/exceptions.rs:26:17:
failed to import exception socket.gaierror: ImportError: cannot import name 'Mapping' from 'collections.abc' (/Users/goldbaum/.pyenv/versions/3.13.0t/lib/python3.13t/collections/abc.py)
I slightly modified PyO3 to get a traceback as well (hidden because it's a distractingly long diff):
Details
diff --git a/src/impl_/exceptions.rs b/src/impl_/exceptions.rs
index 15b6f53b..de63ad59 100644
--- a/src/impl_/exceptions.rs
+++ b/src/impl_/exceptions.rs
@@ -1,4 +1,8 @@
-use crate::{sync::GILOnceCell, types::PyType, Bound, Py, Python};
+use crate::{
+ sync::GILOnceCell,
+ types::{PyTracebackMethods, PyType},
+ Bound, Py, Python,
+};
pub struct ImportedExceptionTypeObject {
imported_value: GILOnceCell<Py<PyType>>,
@@ -20,8 +24,11 @@ impl ImportedExceptionTypeObject {
.import(py, self.module, self.name)
.unwrap_or_else(|e| {
panic!(
- "failed to import exception {}.{}: {}",
- self.module, self.name, e
+ "failed to import exception {}.{}: {}\n{}",
+ self.module,
+ self.name,
+ e,
+ e.traceback(py).unwrap().format().unwrap(),
)
})
}
And the traceback is:
Traceback (most recent call last):
File "/Users/goldbaum/.pyenv/versions/3.13.0t/lib/python3.13t/socket.py", line 55, in <module>
import os, sys, io, selectors
File "/Users/goldbaum/.pyenv/versions/3.13.0t/lib/python3.13t/selectors.py", line 10, in <module>
from collections.abc import Mapping
So somehow during setup of the socket module, Mapping isn't available yet, but only if many threads are simultaneously touching the Python runtime.
(ping @davidhewitt, we probably want to disable the socket error tests on the free-threaded build as well)
CPython versions tested on:
3.13
Operating systems tested on:
macOS
Activity
pythongh-125245: Fix ZoneInfo data race in free threading build
colesbury commentedon Oct 10, 2024
EDIT: Commented on wrong issue
colesbury commentedon Oct 11, 2024
There's a race condition that I believe was introduced in #123613. The
sys.modules[__name__] = _collections_abcis not safe with the longstanding importlib optimization that avoids_ModuleLockManagerif the module is already initialized:cpython/Lib/importlib/_bootstrap.py
Lines 1351 to 1355 in a726ce7
I think this may affect the default (with GIL) build as well depending on when the GIL-switch happens, but it definitely will happen more often on the free threading build.
The problematic execution when two threads (T1, T2) run
import collections.abc:Lib/collections/abc.py, setssys.modules["collections.abc"]module = sys.modules["collections.abc"](line 1353 above). This points to theLib/collections/abc.pymodule.collections/abc.py,sys.modules["collections.abc"]now points to theLib/_collections_abc.pymodule.module. __spec__. _initializing(line 1355) on the . This module is finished initializing, so it's returned. Note that at this pointsys.modules["collections.abc"]points to the correct_collections_abc.pymodule, but the local variablemodulestill points to thecollections/abc.pymodule.T2 now incorrectly has the Python
collections.abcmodule.cc @serhiy-storchaka
EDIT:
Lib/_collections_abc.pyis also a Python modulecolesbury commentedon Oct 11, 2024
I think we can do something like:
[-]Importing the socket module fails on free-threaded build[/-][+]Race condition when importing `collections.abc`[/+]pythongh-125245: Fix race condition when importing `collections.abc`
hroncok commentedon Oct 16, 2024
Indeed. We see this in Fedora with the default (with GIL) build as well.
ngoldbaum commentedon Oct 24, 2024
This is fixed now.
colesbury commentedon Oct 24, 2024
There's an open PR, but it's not merged yet. I don't think the underlying issue is fixed.
I'm waiting on more feedback regarding the issue that Serhiy raised on the PR:
#125415 (review)
ngoldbaum commentedon Oct 24, 2024
Oops, I'm sorry!
gh-125245: Fix race condition when importing `collections.abc` (#125415)
pythongh-125245: Fix race condition when importing `collections.abc` (p…
[3.13] gh-125245: Fix race condition when importing `collections.abc` (…
colesbury commentedon Oct 25, 2024
The PRs are merged now
pythongh-125245: Fix race condition when importing `collections.abc` (p…