[Python-checkins] gh-105107: Remove PyCFunction_Call() function (#105181)

vstinner webhook-mailer at python.org
Thu Jun 1 05:26:40 EDT 2023


https://github.com/python/cpython/commit/27f9491c60606460209c109fc8ad8a6dcfd02f79
commit: 27f9491c60606460209c109fc8ad8a6dcfd02f79
branch: main
author: Victor Stinner <vstinner at python.org>
committer: vstinner <vstinner at python.org>
date: 2023-06-01T11:25:55+02:00
summary:

gh-105107: Remove PyCFunction_Call() function (#105181)

* Keep the function in the stable ABI.
* Add unit tests on PyCFunction_Call() since it remains supported in
  the stable ABI.

files:
M Doc/data/stable_abi.dat
M Doc/whatsnew/3.13.rst
M Include/methodobject.h
M Lib/test/test_call.py
M Misc/NEWS.d/next/C API/2023-05-30-19-11-09.gh-issue-105107.YQwMnm.rst
M Misc/stable_abi.toml
M Modules/_testcapimodule.c
M Objects/call.c

diff --git a/Doc/data/stable_abi.dat b/Doc/data/stable_abi.dat
index 17b291fd4d0f..84523525e263 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 cdc48a547ce2..1f1172493cb2 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 72af5ad933df..2381e8482b82 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 12759c53bb66..5410131a7dfd 100644
--- a/Lib/test/test_call.py
+++ b/Lib/test/test_call.py
@@ -966,6 +966,7 @@ def c_py_recurse(m):
         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 @@ def test_function_with_many_args(self):
                 self.assertEqual(l['f'](*range(N)), N//2)
 
 
+ at 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 8423f4742ce2..6cc758cb8396 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 7ff4da9a1f7b..fac59c97f4bf 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 86b6dc3b36fe..d7c89f48f792 100644
--- a/Modules/_testcapimodule.c
+++ b/Modules/_testcapimodule.c
@@ -2362,6 +2362,19 @@ meth_fastcall_keywords(PyObject* self, PyObject* const* args,
     return Py_BuildValue("NNN", _null_to_none(self), pyargs, pykwargs);
 }
 
+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)
 {
@@ -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 4658cf1f56bb..40eccefb4a6c 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);
 }
 
 



More information about the Python-checkins mailing list