From 8a5888b147022b4586d30dcd7159e4fa6a31ec0e Mon Sep 17 00:00:00 2001 From: "Benjamin A. Beasley" Date: Sun, 16 Jun 2024 08:15:17 -0400 Subject: [PATCH] Work around _PyArg_NoKeywords moving to a private header in CPython 3.13 See: https://github.com/python/cpython/issues/110964 Fixes: #11499 --- lib/sqlalchemy/cextension/resultproxy.c | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/lib/sqlalchemy/cextension/resultproxy.c b/lib/sqlalchemy/cextension/resultproxy.c index 8e8b6f9e4f..a88af0ede9 100644 --- a/lib/sqlalchemy/cextension/resultproxy.c +++ b/lib/sqlalchemy/cextension/resultproxy.c @@ -821,6 +821,29 @@ typedef struct { static PyTypeObject tuplegetter_type; +static int +PyArg_NoKeywords(const char *funcname, PyObject *kwargs) +{ +#if PY_MAJOR_VERSION >= 3 && PY_MINOR_VERSION >= 13 + /* Based on the one in CPython, removed from the public headers in 3.13 + * (https://github.com/python/cpython/issues/110964) + */ + if (kwargs == NULL) + return 1; + if (!PyDict_CheckExact(kwargs)) { + PyErr_BadInternalCall(); + return 0; + } + if (PyDict_GET_SIZE(kwargs) == 0) + return 1; + + PyErr_Format(PyExc_TypeError, "%.200s() takes no keyword arguments", funcname); + return 0; +#else + return _PyArg_NoKeywords(funcname, kwargs); +#endif +} + static PyObject * tuplegetter_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { @@ -828,7 +851,7 @@ tuplegetter_new(PyTypeObject *type, PyObject *args, PyObject *kwds) PyObject *item; Py_ssize_t nitems; - if (!_PyArg_NoKeywords("tuplegetter", kwds)) + if (!PyArg_NoKeywords("tuplegetter", kwds)) return NULL; nitems = PyTuple_GET_SIZE(args); -- 2.47.3