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.
This commit is contained in:
Victor Stinner 2023-06-01 11:25:55 +02:00 committed by GitHub
parent 7f5afecfd7
commit 27f9491c60
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 40 additions and 6 deletions

View 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,,

View 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`.)

View 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 */

View 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()

View 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.

View File

@ -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]

View 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},

View 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);
}