diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-07-19-19-14-39.gh-issue-154043.Kych7F.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-07-19-19-14-39.gh-issue-154043.Kych7F.rst new file mode 100644 index 000000000000000..d37e63e6116a593 --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2026-07-19-19-14-39.gh-issue-154043.Kych7F.rst @@ -0,0 +1,2 @@ +Fix a data race when iterating a shared :class:`types.GenericAlias` iterator +from multiple threads under the :term:`free-threaded build`. diff --git a/Objects/genericaliasobject.c b/Objects/genericaliasobject.c index 4e85927def7ea78..9480a0e16116ef3 100644 --- a/Objects/genericaliasobject.c +++ b/Objects/genericaliasobject.c @@ -939,17 +939,23 @@ static PyObject * ga_iternext(PyObject *op) { gaiterobject *gi = (gaiterobject*)op; - if (gi->obj == NULL) { +#ifdef Py_GIL_DISABLED + PyObject *obj = _Py_atomic_exchange_ptr(&gi->obj, NULL); +#else + PyObject* obj = gi->obj; + gi->obj = NULL; +#endif + if (obj == NULL) { PyErr_SetNone(PyExc_StopIteration); return NULL; } - gaobject *alias = (gaobject *)gi->obj; + gaobject *alias = (gaobject *)obj; PyObject *starred_alias = Py_GenericAlias(alias->origin, alias->args); + Py_DECREF(obj); if (starred_alias == NULL) { return NULL; } ((gaobject *)starred_alias)->starred = true; - Py_SETREF(gi->obj, NULL); return starred_alias; }