diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-08-10-16-57-53.gh-issue-154916.6ozWLF.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-08-10-16-57-53.gh-issue-154916.6ozWLF.rst new file mode 100644 index 000000000000000..3e2782c911995a6 --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2026-08-10-16-57-53.gh-issue-154916.6ozWLF.rst @@ -0,0 +1,2 @@ +Fix data race when calling :meth:`~object.__reduce__` on a shared :class:`types.GenericAlias` iterator +under the :term:`free-threaded build`. diff --git a/Objects/genericaliasobject.c b/Objects/genericaliasobject.c index 348c7dd6967a397..c24c0e118a802e4 100644 --- a/Objects/genericaliasobject.c +++ b/Objects/genericaliasobject.c @@ -992,13 +992,14 @@ ga_iter_reduce(PyObject *self, PyObject *Py_UNUSED(ignored)) { PyObject *iter = _PyEval_GetBuiltin(&_Py_ID(iter)); gaiterobject *gi = (gaiterobject *)self; + PyObject *obj = FT_ATOMIC_LOAD_PTR(gi->obj); /* _PyEval_GetBuiltin can invoke arbitrary code, * call must be before access of iterator pointers. * see issue #101765 */ - if (gi->obj) - return Py_BuildValue("N(O)", iter, gi->obj); + if (obj) + return Py_BuildValue("N(O)", iter, obj); else return Py_BuildValue("N(())", iter); }