]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-105107: Remove PyCFunction_Call() function (#105181)
authorVictor Stinner <vstinner@python.org>
Thu, 1 Jun 2023 09:25:55 +0000 (11:25 +0200)
committerGitHub <noreply@github.com>
Thu, 1 Jun 2023 09:25:55 +0000 (11:25 +0200)
* Keep the function in the stable ABI.
* Add unit tests on PyCFunction_Call() since it remains supported in
  the stable ABI.

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

index 17b291fd4d0fa48a5440a8c4983999c9ebc26e3f..84523525e2631e1752faf7d93616b51eac159348 100644 (file)
@@ -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,,
index cdc48a547ce2671cf8a51ae792aa9b4cfc8afa17..1f1172493cb232f195dfd49fe6bb6b39223e1461 100644 (file)
@@ -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`.)
 
index 72af5ad933df7fd752ac7e0ce585baf47e8f8384..2381e8482b82a8b3d71cafe6ba0a111df398a1cb 100644 (file)
@@ -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 */
index 12759c53bb662c19e2b5f7a7be527c5dad866fcf..5410131a7dfd891ad480ce2571e5da207d4a331f 100644 (file)
@@ -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()
index 8423f4742ce2e972a23423bdd7aa1722b4bb8d5d..6cc758cb83962bcba2eef02fa747b448ebbd2276 100644 (file)
@@ -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.
index 7ff4da9a1f7b6a290db9334d03f5630b22f844b5..fac59c97f4bf9f5b2c29d1be279b7778f3db8ab6 100644 (file)
     added = '3.2'
 [function.PyCFunction_Call]
     added = '3.2'
+    abi_only = true
 [function.PyCFunction_GetFlags]
     added = '3.2'
 [function.PyCFunction_GetFunction]
index 86b6dc3b36fe7d55093ceea704b250d8700b2c4c..d7c89f48f792ed8498607f0321d7cc2163c6c60b 100644 (file)
@@ -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},
index 4658cf1f56bb7dcde1e00f863bc563b46140ad0b..40eccefb4a6c8d6cbf32465bc6d4b46850ae0c3f 100644 (file)
@@ -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);
 }