From 3be22c2d0c23ec0a0331471b253b8c8cbff2cb6e Mon Sep 17 00:00:00 2001 From: Jukka Lehtosalo Date: Sat, 4 Jul 2026 14:57:37 +0100 Subject: [PATCH] [mypyc] Fix memory safety of list.count on free-threaded builds --- mypyc/lib-rt/pythonsupport.h | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/mypyc/lib-rt/pythonsupport.h b/mypyc/lib-rt/pythonsupport.h index 1b0583543fe48..35f1e78df3915 100644 --- a/mypyc/lib-rt/pythonsupport.h +++ b/mypyc/lib-rt/pythonsupport.h @@ -205,6 +205,25 @@ list_count(PyListObject *self, PyObject *value) Py_ssize_t count = 0; Py_ssize_t i; +#ifdef Py_GIL_DISABLED + for (i = 0; i < PyList_GET_SIZE(self); i++) { + PyObject *item = PyList_GetItemRef((PyObject *)self, i); + if (unlikely(item == NULL)) { + // Race condition: list shrank between size read and get item + if (PyErr_ExceptionMatches(PyExc_IndexError)) { + PyErr_Clear(); + break; + } + return CPY_INT_TAG; + } + int cmp = PyObject_RichCompareBool(item, value, Py_EQ); + Py_DECREF(item); + if (cmp > 0) + count++; + else if (cmp < 0) + return CPY_INT_TAG; + } +#else for (i = 0; i < Py_SIZE(self); i++) { int cmp = PyObject_RichCompareBool(self->ob_item[i], value, Py_EQ); if (cmp > 0) @@ -212,6 +231,7 @@ list_count(PyListObject *self, PyObject *value) else if (cmp < 0) return CPY_INT_TAG; } +#endif return CPyTagged_ShortFromSsize_t(count); }