The `methodcaller` C vectorcall implementation uses an arguments array
that is shared across calls. The first argument is modified on every
invocation. This isn't thread-safe in the free threading build. I think
it's also not safe in general, but for now just disable it in the free
threading build.
--- /dev/null
+Fix crash when calling a :func:`operator.methodcaller` instance from
+multiple threads in the free threading build.
vectorcallfunc vectorcall;
} methodcallerobject;
+#ifndef Py_GIL_DISABLED
static int _methodcaller_initialize_vectorcall(methodcallerobject* mc)
{
PyObject* args = mc->xargs;
(PyTuple_GET_SIZE(mc->xargs)) | PY_VECTORCALL_ARGUMENTS_OFFSET,
mc->vectorcall_kwnames);
}
+#endif
/* AC 3.5: variable number of arguments, not currently support by AC */
mc->vectorcall_args = 0;
+#ifdef Py_GIL_DISABLED
+ // gh-127065: The current implementation of methodcaller_vectorcall
+ // is not thread-safe because it modifies the `vectorcall_args` array,
+ // which is shared across calls.
+ mc->vectorcall = NULL;
+#else
mc->vectorcall = (vectorcallfunc)methodcaller_vectorcall;
+#endif
PyObject_GC_Track(mc);
return (PyObject *)mc;