]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-154043: Fix a data race when iterating a shared `types.GenericAlias` iterator...
authorIvy Xu <fakeshadow1337@gmail.com>
Sat, 25 Jul 2026 08:29:59 +0000 (16:29 +0800)
committerGitHub <noreply@github.com>
Sat, 25 Jul 2026 08:29:59 +0000 (13:59 +0530)
Misc/NEWS.d/next/Core_and_Builtins/2026-07-19-19-14-39.gh-issue-154043.Kych7F.rst [new file with mode: 0644]
Objects/genericaliasobject.c

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 (file)
index 0000000..d37e63e
--- /dev/null
@@ -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`.
index 71d946a637df1c913f857c4ac0c307c0b4fad5e1..348c7dd6967a3972f55bd78b6146b6af8232d7c3 100644 (file)
@@ -942,17 +942,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;
 }