summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Doc/data/stable_abi.dat1
-rw-r--r--Doc/whatsnew/3.13.rst1
-rw-r--r--Include/methodobject.h2
-rw-r--r--Lib/test/test_call.py20
-rw-r--r--Misc/NEWS.d/next/C API/2023-05-30-19-11-09.gh-issue-105107.YQwMnm.rst1
-rw-r--r--Misc/stable_abi.toml1
-rw-r--r--Modules/_testcapimodule.c14
-rw-r--r--Objects/call.c6
8 files changed, 40 insertions, 6 deletions
diff --git a/Doc/data/stable_abi.dat b/Doc/data/stable_abi.dat
index 17b291f..8452352 100644
--- a/Doc/data/stable_abi.dat
+++ b/Doc/data/stable_abi.dat
@@ -43,7 +43,6 @@ function,PyBytes_Size,3.2,,
var,PyBytes_Type,3.2,,
type,PyCFunction,3.2,,
type,PyCFunctionWithKeywords,3.2,,
-function,PyCFunction_Call,3.2,,
function,PyCFunction_GetFlags,3.2,,
function,PyCFunction_GetFunction,3.2,,
function,PyCFunction_GetSelf,3.2,,
diff --git a/Doc/whatsnew/3.13.rst b/Doc/whatsnew/3.13.rst
index cdc48a5..1f11724 100644
--- a/Doc/whatsnew/3.13.rst
+++ b/Doc/whatsnew/3.13.rst
@@ -373,6 +373,7 @@ Removed
:c:func:`PyTuple_New(0) <PyTuple_New>`.
* ``PyEval_CallFunction()``: use :c:func:`PyObject_CallFunction` instead.
* ``PyEval_CallMethod()``: use :c:func:`PyObject_CallMethod` instead.
+ * ``PyCFunction_Call()``: use :c:func:`PyObject_Call` instead.
(Contributed by Victor Stinner in :gh:`105107`.)
diff --git a/Include/methodobject.h b/Include/methodobject.h
index 72af5ad..2381e84 100644
--- a/Include/methodobject.h
+++ b/Include/methodobject.h
@@ -49,8 +49,6 @@ PyAPI_FUNC(PyCFunction) PyCFunction_GetFunction(PyObject *);
PyAPI_FUNC(PyObject *) PyCFunction_GetSelf(PyObject *);
PyAPI_FUNC(int) PyCFunction_GetFlags(PyObject *);
-Py_DEPRECATED(3.9) PyAPI_FUNC(PyObject *) PyCFunction_Call(PyObject *, PyObject *, PyObject *);
-
struct PyMethodDef {
const char *ml_name; /* The name of the built-in function/method */
PyCFunction ml_meth; /* The C function that implements it */
diff --git a/Lib/test/test_call.py b/Lib/test/test_call.py
index 12759c5..5410131 100644
--- a/Lib/test/test_call.py
+++ b/Lib/test/test_call.py
@@ -966,6 +966,7 @@ class TestRecursion(unittest.TestCase):
finally:
sys.setrecursionlimit(depth)
+
class TestFunctionWithManyArgs(unittest.TestCase):
def test_function_with_many_args(self):
for N in (10, 500, 1000):
@@ -977,5 +978,24 @@ class TestFunctionWithManyArgs(unittest.TestCase):
self.assertEqual(l['f'](*range(N)), N//2)
+@unittest.skipIf(_testcapi is None, 'need _testcapi')
+class TestCAPI(unittest.TestCase):
+ def test_cfunction_call(self):
+ def func(*args, **kwargs):
+ return (args, kwargs)
+
+ # PyCFunction_Call() was removed in Python 3.13 API, but was kept in
+ # the stable ABI.
+ def PyCFunction_Call(func, *args, **kwargs):
+ if kwargs:
+ return _testcapi.pycfunction_call(func, args, kwargs)
+ else:
+ return _testcapi.pycfunction_call(func, args)
+
+ self.assertEqual(PyCFunction_Call(func), ((), {}))
+ self.assertEqual(PyCFunction_Call(func, 1, 2, 3), ((1, 2, 3), {}))
+ self.assertEqual(PyCFunction_Call(func, "arg", num=5), (("arg",), {'num': 5}))
+
+
if __name__ == "__main__":
unittest.main()
diff --git a/Misc/NEWS.d/next/C API/2023-05-30-19-11-09.gh-issue-105107.YQwMnm.rst b/Misc/NEWS.d/next/C API/2023-05-30-19-11-09.gh-issue-105107.YQwMnm.rst
index 8423f47..6cc758c 100644
--- a/Misc/NEWS.d/next/C API/2023-05-30-19-11-09.gh-issue-105107.YQwMnm.rst
+++ b/Misc/NEWS.d/next/C API/2023-05-30-19-11-09.gh-issue-105107.YQwMnm.rst
@@ -5,5 +5,6 @@ Remove functions deprecated in Python 3.9.
arguments must not be *NULL*) instead.
* ``PyEval_CallFunction()``: use :c:func:`PyObject_CallFunction` instead.
* ``PyEval_CallMethod()``: use :c:func:`PyObject_CallMethod` instead.
+* ``PyCFunction_Call()``: use :c:func:`PyObject_Call` instead.
Patch by Victor Stinner.
diff --git a/Misc/stable_abi.toml b/Misc/stable_abi.toml
index 7ff4da9..fac59c9 100644
--- a/Misc/stable_abi.toml
+++ b/Misc/stable_abi.toml
@@ -447,6 +447,7 @@
added = '3.2'
[function.PyCFunction_Call]
added = '3.2'
+ abi_only = true
[function.PyCFunction_GetFlags]
added = '3.2'
[function.PyCFunction_GetFunction]
diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c
index 86b6dc3..d7c89f4 100644
--- a/Modules/_testcapimodule.c
+++ b/Modules/_testcapimodule.c
@@ -2363,6 +2363,19 @@ meth_fastcall_keywords(PyObject* self, PyObject* const* args,
}
static PyObject*
+test_pycfunction_call(PyObject *module, PyObject *args)
+{
+ // Function removed in the Python 3.13 API but was kept in the stable ABI.
+ extern PyObject* PyCFunction_Call(PyObject *callable, PyObject *args, PyObject *kwargs);
+
+ PyObject *func, *pos_args, *kwargs = NULL;
+ if (!PyArg_ParseTuple(args, "OO!|O!", &func, &PyTuple_Type, &pos_args, &PyDict_Type, &kwargs)) {
+ return NULL;
+ }
+ return PyCFunction_Call(func, pos_args, kwargs);
+}
+
+static PyObject*
pynumber_tobase(PyObject *module, PyObject *args)
{
PyObject *obj;
@@ -3369,6 +3382,7 @@ static PyMethodDef TestMethods[] = {
{"meth_noargs", meth_noargs, METH_NOARGS},
{"meth_fastcall", _PyCFunction_CAST(meth_fastcall), METH_FASTCALL},
{"meth_fastcall_keywords", _PyCFunction_CAST(meth_fastcall_keywords), METH_FASTCALL|METH_KEYWORDS},
+ {"pycfunction_call", test_pycfunction_call, METH_VARARGS},
{"pynumber_tobase", pynumber_tobase, METH_VARARGS},
{"test_set_type_size", test_set_type_size, METH_NOARGS},
{"test_py_clear", test_py_clear, METH_NOARGS},
diff --git a/Objects/call.c b/Objects/call.c
index 4658cf1..40eccef 100644
--- a/Objects/call.c
+++ b/Objects/call.c
@@ -380,11 +380,11 @@ PyObject_Call(PyObject *callable, PyObject *args, PyObject *kwargs)
}
-PyObject *
+/* Function removed in the Python 3.13 API but kept in the stable ABI. */
+PyAPI_FUNC(PyObject *)
PyCFunction_Call(PyObject *callable, PyObject *args, PyObject *kwargs)
{
- PyThreadState *tstate = _PyThreadState_GET();
- return _PyObject_Call(tstate, callable, args, kwargs);
+ return PyObject_Call(callable, args, kwargs);
}