diff --git a/Misc/NEWS.d/next/Library/2026-03-03-23-21-40.gh-issue-145446.0c-TJX.rst b/Misc/NEWS.d/next/Library/2026-03-03-23-21-40.gh-issue-145446.0c-TJX.rst new file mode 100644 index 00000000000000..96eb0d9ddb07ab --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-03-03-23-21-40.gh-issue-145446.0c-TJX.rst @@ -0,0 +1 @@ +Now :mod:`functools` is safer in free-threaded build when using keywords in :func:`functools.partial` diff --git a/Modules/_functoolsmodule.c b/Modules/_functoolsmodule.c index d779376b191a5e..00c5b33acf2c02 100644 --- a/Modules/_functoolsmodule.c +++ b/Modules/_functoolsmodule.c @@ -646,6 +646,8 @@ partial_repr(PyObject *self) } } /* Pack keyword arguments */ + int error = 0; + Py_BEGIN_CRITICAL_SECTION(kw); for (i = 0; PyDict_Next(kw, &i, &key, &value);) { /* Prevent key.__str__ from deleting the value. */ Py_INCREF(value); @@ -653,9 +655,14 @@ partial_repr(PyObject *self) key, value)); Py_DECREF(value); if (arglist == NULL) { - goto done; + error = 1; + break; } } + Py_END_CRITICAL_SECTION(); + if (error) { + goto done; + } mod = PyType_GetModuleName(Py_TYPE(pto)); if (mod == NULL) {