Skip to content

Commit 9e3729b

Browse files
davidhewittencukou
andauthored
gh-114626: add PyCFunctionFast and PyCFunctionFastWithKeywords (GH-114627)
Co-authored-by: Petr Viktorin <encukou@gmail.com>
1 parent 32f8ab1 commit 9e3729b

10 files changed

+57
-41
lines changed

Doc/c-api/structures.rst

+11-11
Original file line numberDiff line numberDiff line change
@@ -187,26 +187,26 @@ Implementing functions and methods
187187
PyObject *kwargs);
188188
189189
190-
.. c:type:: _PyCFunctionFast
190+
.. c:type:: PyCFunctionFast
191191
192192
Type of the functions used to implement Python callables in C
193193
with signature :c:macro:`METH_FASTCALL`.
194194
The function signature is::
195195
196-
PyObject *_PyCFunctionFast(PyObject *self,
197-
PyObject *const *args,
198-
Py_ssize_t nargs);
196+
PyObject *PyCFunctionFast(PyObject *self,
197+
PyObject *const *args,
198+
Py_ssize_t nargs);
199199
200-
.. c:type:: _PyCFunctionFastWithKeywords
200+
.. c:type:: PyCFunctionFastWithKeywords
201201
202202
Type of the functions used to implement Python callables in C
203203
with signature :ref:`METH_FASTCALL | METH_KEYWORDS <METH_FASTCALL-METH_KEYWORDS>`.
204204
The function signature is::
205205
206-
PyObject *_PyCFunctionFastWithKeywords(PyObject *self,
207-
PyObject *const *args,
208-
Py_ssize_t nargs,
209-
PyObject *kwnames);
206+
PyObject *PyCFunctionFastWithKeywords(PyObject *self,
207+
PyObject *const *args,
208+
Py_ssize_t nargs,
209+
PyObject *kwnames);
210210
211211
.. c:type:: PyCMethod
212212
@@ -290,7 +290,7 @@ There are these calling conventions:
290290
.. c:macro:: METH_FASTCALL
291291
292292
Fast calling convention supporting only positional arguments.
293-
The methods have the type :c:type:`_PyCFunctionFast`.
293+
The methods have the type :c:type:`PyCFunctionFast`.
294294
The first parameter is *self*, the second parameter is a C array
295295
of :c:expr:`PyObject*` values indicating the arguments and the third
296296
parameter is the number of arguments (the length of the array).
@@ -306,7 +306,7 @@ There are these calling conventions:
306306
307307
:c:expr:`METH_FASTCALL | METH_KEYWORDS`
308308
Extension of :c:macro:`METH_FASTCALL` supporting also keyword arguments,
309-
with methods of type :c:type:`_PyCFunctionFastWithKeywords`.
309+
with methods of type :c:type:`PyCFunctionFastWithKeywords`.
310310
Keyword arguments are passed the same way as in the
311311
:ref:`vectorcall protocol <vectorcall>`:
312312
there is an additional fourth :c:expr:`PyObject*` parameter

Doc/data/stable_abi.dat

+2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Include/methodobject.h

+11-4
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,22 @@ PyAPI_DATA(PyTypeObject) PyCFunction_Type;
1717
#define PyCFunction_Check(op) PyObject_TypeCheck((op), &PyCFunction_Type)
1818

1919
typedef PyObject *(*PyCFunction)(PyObject *, PyObject *);
20-
typedef PyObject *(*_PyCFunctionFast) (PyObject *, PyObject *const *, Py_ssize_t);
20+
typedef PyObject *(*PyCFunctionFast) (PyObject *, PyObject *const *, Py_ssize_t);
2121
typedef PyObject *(*PyCFunctionWithKeywords)(PyObject *, PyObject *,
2222
PyObject *);
23-
typedef PyObject *(*_PyCFunctionFastWithKeywords) (PyObject *,
24-
PyObject *const *, Py_ssize_t,
25-
PyObject *);
23+
typedef PyObject *(*PyCFunctionFastWithKeywords) (PyObject *,
24+
PyObject *const *, Py_ssize_t,
25+
PyObject *);
2626
typedef PyObject *(*PyCMethod)(PyObject *, PyTypeObject *, PyObject *const *,
2727
size_t, PyObject *);
2828

29+
// For backwards compatibility. `METH_FASTCALL` was added to the stable API in
30+
// 3.10 alongside `_PyCFunctionFastWithKeywords` and `_PyCFunctionFast`.
31+
// Note that the underscore-prefixed names were documented in public docs;
32+
// people may be using them.
33+
typedef PyCFunctionFast _PyCFunctionFast;
34+
typedef PyCFunctionWithKeywords _PyCFunctionWithKeywords;
35+
2936
// Cast an function to the PyCFunction type to use it with PyMethodDef.
3037
//
3138
// This macro can be used to prevent compiler warnings if the first parameter
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Add ``PyCFunctionFast`` and ``PyCFunctionFastWithKeywords`` typedefs (identical to the existing ``_PyCFunctionFast`` and ``_PyCFunctionFastWithKeywords`` typedefs, just without a leading ``_`` prefix).

Misc/stable_abi.toml

+7
Original file line numberDiff line numberDiff line change
@@ -2489,3 +2489,10 @@
24892489
added = '3.13'
24902490
[function.PyList_GetItemRef]
24912491
added = '3.13'
2492+
[typedef.PyCFunctionFast]
2493+
added = '3.13'
2494+
# "abi-only" since 3.10. (Callback type names aren't used in C code,
2495+
# but this function signature was expected with METH_FASTCALL.)
2496+
[typedef.PyCFunctionFastWithKeywords]
2497+
added = '3.13'
2498+
# "abi-only" since 3.10. (Same story as PyCFunctionFast.)

Objects/descrobject.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -393,7 +393,7 @@ method_vectorcall_FASTCALL(
393393
if (method_check_args(func, args, nargs, kwnames)) {
394394
return NULL;
395395
}
396-
_PyCFunctionFast meth = (_PyCFunctionFast)
396+
PyCFunctionFast meth = (PyCFunctionFast)
397397
method_enter_call(tstate, func);
398398
if (meth == NULL) {
399399
return NULL;
@@ -412,7 +412,7 @@ method_vectorcall_FASTCALL_KEYWORDS(
412412
if (method_check_args(func, args, nargs, NULL)) {
413413
return NULL;
414414
}
415-
_PyCFunctionFastWithKeywords meth = (_PyCFunctionFastWithKeywords)
415+
PyCFunctionFastWithKeywords meth = (PyCFunctionFastWithKeywords)
416416
method_enter_call(tstate, func);
417417
if (meth == NULL) {
418418
return NULL;

Objects/methodobject.c

+2-3
Original file line numberDiff line numberDiff line change
@@ -417,7 +417,7 @@ cfunction_vectorcall_FASTCALL(
417417
return NULL;
418418
}
419419
Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
420-
_PyCFunctionFast meth = (_PyCFunctionFast)
420+
PyCFunctionFast meth = (PyCFunctionFast)
421421
cfunction_enter_call(tstate, func);
422422
if (meth == NULL) {
423423
return NULL;
@@ -433,7 +433,7 @@ cfunction_vectorcall_FASTCALL_KEYWORDS(
433433
{
434434
PyThreadState *tstate = _PyThreadState_GET();
435435
Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
436-
_PyCFunctionFastWithKeywords meth = (_PyCFunctionFastWithKeywords)
436+
PyCFunctionFastWithKeywords meth = (PyCFunctionFastWithKeywords)
437437
cfunction_enter_call(tstate, func);
438438
if (meth == NULL) {
439439
return NULL;
@@ -552,4 +552,3 @@ cfunction_call(PyObject *func, PyObject *args, PyObject *kwargs)
552552
}
553553
return _Py_CheckFunctionResult(tstate, func, result, NULL);
554554
}
555-

Python/bytecodes.c

+7-7
Original file line numberDiff line numberDiff line change
@@ -3376,7 +3376,7 @@ dummy_func(
33763376
STAT_INC(CALL, hit);
33773377
PyCFunction cfunc = PyCFunction_GET_FUNCTION(callable);
33783378
/* res = func(self, args, nargs) */
3379-
res = ((_PyCFunctionFast)(void(*)(void))cfunc)(
3379+
res = ((PyCFunctionFast)(void(*)(void))cfunc)(
33803380
PyCFunction_GET_SELF(callable),
33813381
args,
33823382
total_args);
@@ -3407,8 +3407,8 @@ dummy_func(
34073407
DEOPT_IF(PyCFunction_GET_FLAGS(callable) != (METH_FASTCALL | METH_KEYWORDS));
34083408
STAT_INC(CALL, hit);
34093409
/* res = func(self, args, nargs, kwnames) */
3410-
_PyCFunctionFastWithKeywords cfunc =
3411-
(_PyCFunctionFastWithKeywords)(void(*)(void))
3410+
PyCFunctionFastWithKeywords cfunc =
3411+
(PyCFunctionFastWithKeywords)(void(*)(void))
34123412
PyCFunction_GET_FUNCTION(callable);
34133413
res = cfunc(PyCFunction_GET_SELF(callable), args, total_args, NULL);
34143414
assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL));
@@ -3539,8 +3539,8 @@ dummy_func(
35393539
DEOPT_IF(!Py_IS_TYPE(self, d_type));
35403540
STAT_INC(CALL, hit);
35413541
int nargs = total_args - 1;
3542-
_PyCFunctionFastWithKeywords cfunc =
3543-
(_PyCFunctionFastWithKeywords)(void(*)(void))meth->ml_meth;
3542+
PyCFunctionFastWithKeywords cfunc =
3543+
(PyCFunctionFastWithKeywords)(void(*)(void))meth->ml_meth;
35443544
res = cfunc(self, args + 1, nargs, NULL);
35453545
assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL));
35463546

@@ -3597,8 +3597,8 @@ dummy_func(
35973597
PyObject *self = args[0];
35983598
DEOPT_IF(!Py_IS_TYPE(self, method->d_common.d_type));
35993599
STAT_INC(CALL, hit);
3600-
_PyCFunctionFast cfunc =
3601-
(_PyCFunctionFast)(void(*)(void))meth->ml_meth;
3600+
PyCFunctionFast cfunc =
3601+
(PyCFunctionFast)(void(*)(void))meth->ml_meth;
36023602
int nargs = total_args - 1;
36033603
res = cfunc(self, args + 1, nargs);
36043604
assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL));

Python/executor_cases.c.h

+7-7
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Python/generated_cases.c.h

+7-7
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)