From 81cc077ad035947a3429c245f1e28c8b43c6dcc6 Mon Sep 17 00:00:00 2001 From: da-woods Date: Sat, 2 Sep 2023 10:32:59 +0100 Subject: [PATCH] Fix invalid fastcall dict when keywords are passed Fixes #5665 I'm slightly surprised this hasn't caused more bugs. We're passing a dict where we should be passing a tuple of names. Replacement should hopefully be right, but I don't know how optimized or otherwise it is. --- Cython/Utility/ObjectHandling.c | 36 +++++++++++++++++++-------------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/Cython/Utility/ObjectHandling.c b/Cython/Utility/ObjectHandling.c index 8ea5be42935..507fb94f605 100644 --- a/Cython/Utility/ObjectHandling.c +++ b/Cython/Utility/ObjectHandling.c @@ -2328,27 +2328,33 @@ static CYTHON_INLINE PyObject* __Pyx_PyObject_FastCallDict(PyObject *func, PyObj #endif #endif - #if CYTHON_VECTORCALL - #if Py_VERSION_HEX < 0x03090000 - vectorcallfunc f = _PyVectorcall_Function(func); - #else - vectorcallfunc f = PyVectorcall_Function(func); - #endif - if (f) { - return f(func, args, (size_t)nargs, kwargs); - } - #elif defined(__Pyx_CyFunction_USED) && CYTHON_BACKPORT_VECTORCALL - // exclude fused functions for now - if (__Pyx_CyFunction_CheckExact(func)) { - __pyx_vectorcallfunc f = __Pyx_CyFunction_func_vectorcall(func); - if (f) return f(func, args, (size_t)nargs, kwargs); + if (kwargs == NULL) { + #if CYTHON_VECTORCALL + #if Py_VERSION_HEX < 0x03090000 + vectorcallfunc f = _PyVectorcall_Function(func); + #else + vectorcallfunc f = PyVectorcall_Function(func); + #endif + if (f) { + return f(func, args, (size_t)nargs, NULL); + } + #elif defined(__Pyx_CyFunction_USED) && CYTHON_BACKPORT_VECTORCALL + // exclude fused functions for now + if (__Pyx_CyFunction_CheckExact(func)) { + __pyx_vectorcallfunc f = __Pyx_CyFunction_func_vectorcall(func); + if (f) return f(func, args, (size_t)nargs, NULL); + } + #endif } - #endif if (nargs == 0) { return __Pyx_PyObject_Call(func, $empty_tuple, kwargs); } + #if PY_VERSION_HEX >= 0x03090000 && !CYTHON_COMPILING_IN_LIMITED_API + return PyObject_VectorcallDict(func, args, nargs, kwargs); + #else return __Pyx_PyObject_FastCall_fallback(func, args, (size_t)nargs, kwargs); + #endif }