Skip to content

Commit 27f9491

Browse files
authored
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.
1 parent 7f5afec commit 27f9491

File tree

8 files changed

+40
-6
lines changed

8 files changed

+40
-6
lines changed

Doc/data/stable_abi.dat

Lines changed: 0 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Doc/whatsnew/3.13.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -373,6 +373,7 @@ Removed
373373
:c:func:`PyTuple_New(0) <PyTuple_New>`.
374374
* ``PyEval_CallFunction()``: use :c:func:`PyObject_CallFunction` instead.
375375
* ``PyEval_CallMethod()``: use :c:func:`PyObject_CallMethod` instead.
376+
* ``PyCFunction_Call()``: use :c:func:`PyObject_Call` instead.
376377

377378
(Contributed by Victor Stinner in :gh:`105107`.)
378379

Include/methodobject.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,6 @@ PyAPI_FUNC(PyCFunction) PyCFunction_GetFunction(PyObject *);
4949
PyAPI_FUNC(PyObject *) PyCFunction_GetSelf(PyObject *);
5050
PyAPI_FUNC(int) PyCFunction_GetFlags(PyObject *);
5151

52-
Py_DEPRECATED(3.9) PyAPI_FUNC(PyObject *) PyCFunction_Call(PyObject *, PyObject *, PyObject *);
53-
5452
struct PyMethodDef {
5553
const char *ml_name; /* The name of the built-in function/method */
5654
PyCFunction ml_meth; /* The C function that implements it */

Lib/test/test_call.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -966,6 +966,7 @@ def c_py_recurse(m):
966966
finally:
967967
sys.setrecursionlimit(depth)
968968

969+
969970
class TestFunctionWithManyArgs(unittest.TestCase):
970971
def test_function_with_many_args(self):
971972
for N in (10, 500, 1000):
@@ -977,5 +978,24 @@ def test_function_with_many_args(self):
977978
self.assertEqual(l['f'](*range(N)), N//2)
978979

979980

981+
@unittest.skipIf(_testcapi is None, 'need _testcapi')
982+
class TestCAPI(unittest.TestCase):
983+
def test_cfunction_call(self):
984+
def func(*args, **kwargs):
985+
return (args, kwargs)
986+
987+
# PyCFunction_Call() was removed in Python 3.13 API, but was kept in
988+
# the stable ABI.
989+
def PyCFunction_Call(func, *args, **kwargs):
990+
if kwargs:
991+
return _testcapi.pycfunction_call(func, args, kwargs)
992+
else:
993+
return _testcapi.pycfunction_call(func, args)
994+
995+
self.assertEqual(PyCFunction_Call(func), ((), {}))
996+
self.assertEqual(PyCFunction_Call(func, 1, 2, 3), ((1, 2, 3), {}))
997+
self.assertEqual(PyCFunction_Call(func, "arg", num=5), (("arg",), {'num': 5}))
998+
999+
9801000
if __name__ == "__main__":
9811001
unittest.main()

Misc/NEWS.d/next/C API/2023-05-30-19-11-09.gh-issue-105107.YQwMnm.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,6 @@ Remove functions deprecated in Python 3.9.
55
arguments must not be *NULL*) instead.
66
* ``PyEval_CallFunction()``: use :c:func:`PyObject_CallFunction` instead.
77
* ``PyEval_CallMethod()``: use :c:func:`PyObject_CallMethod` instead.
8+
* ``PyCFunction_Call()``: use :c:func:`PyObject_Call` instead.
89

910
Patch by Victor Stinner.

Misc/stable_abi.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -447,6 +447,7 @@
447447
added = '3.2'
448448
[function.PyCFunction_Call]
449449
added = '3.2'
450+
abi_only = true
450451
[function.PyCFunction_GetFlags]
451452
added = '3.2'
452453
[function.PyCFunction_GetFunction]

Modules/_testcapimodule.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2362,6 +2362,19 @@ meth_fastcall_keywords(PyObject* self, PyObject* const* args,
23622362
return Py_BuildValue("NNN", _null_to_none(self), pyargs, pykwargs);
23632363
}
23642364

2365+
static PyObject*
2366+
test_pycfunction_call(PyObject *module, PyObject *args)
2367+
{
2368+
// Function removed in the Python 3.13 API but was kept in the stable ABI.
2369+
extern PyObject* PyCFunction_Call(PyObject *callable, PyObject *args, PyObject *kwargs);
2370+
2371+
PyObject *func, *pos_args, *kwargs = NULL;
2372+
if (!PyArg_ParseTuple(args, "OO!|O!", &func, &PyTuple_Type, &pos_args, &PyDict_Type, &kwargs)) {
2373+
return NULL;
2374+
}
2375+
return PyCFunction_Call(func, pos_args, kwargs);
2376+
}
2377+
23652378
static PyObject*
23662379
pynumber_tobase(PyObject *module, PyObject *args)
23672380
{
@@ -3369,6 +3382,7 @@ static PyMethodDef TestMethods[] = {
33693382
{"meth_noargs", meth_noargs, METH_NOARGS},
33703383
{"meth_fastcall", _PyCFunction_CAST(meth_fastcall), METH_FASTCALL},
33713384
{"meth_fastcall_keywords", _PyCFunction_CAST(meth_fastcall_keywords), METH_FASTCALL|METH_KEYWORDS},
3385+
{"pycfunction_call", test_pycfunction_call, METH_VARARGS},
33723386
{"pynumber_tobase", pynumber_tobase, METH_VARARGS},
33733387
{"test_set_type_size", test_set_type_size, METH_NOARGS},
33743388
{"test_py_clear", test_py_clear, METH_NOARGS},

Objects/call.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -380,11 +380,11 @@ PyObject_Call(PyObject *callable, PyObject *args, PyObject *kwargs)
380380
}
381381

382382

383-
PyObject *
383+
/* Function removed in the Python 3.13 API but kept in the stable ABI. */
384+
PyAPI_FUNC(PyObject *)
384385
PyCFunction_Call(PyObject *callable, PyObject *args, PyObject *kwargs)
385386
{
386-
PyThreadState *tstate = _PyThreadState_GET();
387-
return _PyObject_Call(tstate, callable, args, kwargs);
387+
return PyObject_Call(callable, args, kwargs);
388388
}
389389

390390

0 commit comments

Comments
 (0)