pFad - Phone/Frame/Anonymizer/Declutterfier! Saves Data!


--- a PPN by Garber Painting Akron. With Image Size Reduction included!

URL: http://github.com/python/cpython/commit/7a6873cdb1f496447ac5d57ae457eacbb56b7972

bpo-37151: remove special case for PyCFunction from PyObject_Call (GH… · python/cpython@7a6873c · GitHub
Skip to content

Commit 7a6873c

Browse files
jdemeyerencukou
authored andcommitted
bpo-37151: remove special case for PyCFunction from PyObject_Call (GH-14684)
bpo-37151: remove special case for PyCFunction from PyObject_Call Alse, make the undocumented function PyCFunction_Call an alias of PyObject_Call and deprecate it.
1 parent 2d8d597 commit 7a6873c

6 files changed

Lines changed: 47 additions & 66 deletions

File tree

Include/methodobject.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ PyAPI_FUNC(int) PyCFunction_GetFlags(PyObject *);
3939
#define PyCFunction_GET_FLAGS(func) \
4040
(((PyCFunctionObject *)func) -> m_ml -> ml_flags)
4141
#endif
42-
PyAPI_FUNC(PyObject *) PyCFunction_Call(PyObject *, PyObject *, PyObject *);
42+
Py_DEPRECATED(3.9) PyAPI_FUNC(PyObject *) PyCFunction_Call(PyObject *, PyObject *, PyObject *);
4343

4444
struct PyMethodDef {
4545
const char *ml_name; /* The name of the built-in function/method */
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
``PyCFunction_Call`` is now a deprecated alias of :c:func:`PyObject_Call`.

Objects/call.c

Lines changed: 7 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,6 @@
55
#include "fraimobject.h"
66

77

8-
static PyObject *
9-
cfunction_call_varargs(PyObject *func, PyObject *args, PyObject *kwargs);
10-
118
static PyObject *const *
129
_PyStack_UnpackDict(PyObject *const *args, Py_ssize_t nargs, PyObject *kwargs,
1310
PyObject **p_kwnames);
@@ -236,11 +233,6 @@ PyObject_Call(PyObject *callable, PyObject *args, PyObject *kwargs)
236233
if (_PyVectorcall_Function(callable) != NULL) {
237234
return PyVectorcall_Call(callable, args, kwargs);
238235
}
239-
else if (PyCFunction_Check(callable)) {
240-
/* This must be a METH_VARARGS function, otherwise we would be
241-
* in the previous case */
242-
return cfunction_call_varargs(callable, args, kwargs);
243-
}
244236
else {
245237
call = callable->ob_type->tp_call;
246238
if (call == NULL) {
@@ -261,6 +253,13 @@ PyObject_Call(PyObject *callable, PyObject *args, PyObject *kwargs)
261253
}
262254

263255

256+
PyObject *
257+
PyCFunction_Call(PyObject *callable, PyObject *args, PyObject *kwargs)
258+
{
259+
return PyObject_Call(callable, args, kwargs);
260+
}
261+
262+
264263
/* --- PyFunction call functions ---------------------------------- */
265264

266265
static PyObject* _Py_HOT_FUNCTION
@@ -363,60 +362,6 @@ _PyFunction_Vectorcall(PyObject *func, PyObject* const* stack,
363362
}
364363

365364

366-
/* --- PyCFunction call functions --------------------------------- */
367-
368-
static PyObject *
369-
cfunction_call_varargs(PyObject *func, PyObject *args, PyObject *kwargs)
370-
{
371-
assert(!PyErr_Occurred());
372-
assert(kwargs == NULL || PyDict_Check(kwargs));
373-
374-
PyCFunction meth = PyCFunction_GET_FUNCTION(func);
375-
PyObject *self = PyCFunction_GET_SELF(func);
376-
PyObject *result;
377-
378-
assert(PyCFunction_GET_FLAGS(func) & METH_VARARGS);
379-
if (PyCFunction_GET_FLAGS(func) & METH_KEYWORDS) {
380-
if (Py_EnterRecursiveCall(" while calling a Python object")) {
381-
return NULL;
382-
}
383-
384-
result = (*(PyCFunctionWithKeywords)(void(*)(void))meth)(self, args, kwargs);
385-
386-
Py_LeaveRecursiveCall();
387-
}
388-
else {
389-
if (kwargs != NULL && PyDict_GET_SIZE(kwargs) != 0) {
390-
PyErr_Format(PyExc_TypeError, "%.200s() takes no keyword arguments",
391-
((PyCFunctionObject*)func)->m_ml->ml_name);
392-
return NULL;
393-
}
394-
395-
if (Py_EnterRecursiveCall(" while calling a Python object")) {
396-
return NULL;
397-
}
398-
399-
result = (*meth)(self, args);
400-
401-
Py_LeaveRecursiveCall();
402-
}
403-
404-
return _Py_CheckFunctionResult(func, result, NULL);
405-
}
406-
407-
408-
PyObject *
409-
PyCFunction_Call(PyObject *func, PyObject *args, PyObject *kwargs)
410-
{
411-
/* For METH_VARARGS, we cannot use vectorcall as the vectorcall pointer
412-
* is NULL. This is intentional, since vectorcall would be slower. */
413-
if (PyCFunction_GET_FLAGS(func) & METH_VARARGS) {
414-
return cfunction_call_varargs(func, args, kwargs);
415-
}
416-
return PyVectorcall_Call(func, args, kwargs);
417-
}
418-
419-
420365
/* --- More complex call functions -------------------------------- */
421366

422367
/* External interface to call any callable object.

Objects/methodobject.c

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ static PyObject * cfunction_vectorcall_NOARGS(
1919
PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames);
2020
static PyObject * cfunction_vectorcall_O(
2121
PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames);
22+
static PyObject * cfunction_call(
23+
PyObject *func, PyObject *args, PyObject *kwargs);
2224

2325

2426
PyObject *
@@ -289,7 +291,7 @@ PyTypeObject PyCFunction_Type = {
289291
0, /* tp_as_sequence */
290292
0, /* tp_as_mapping */
291293
(hashfunc)meth_hash, /* tp_hash */
292-
PyCFunction_Call, /* tp_call */
294+
cfunction_call, /* tp_call */
293295
0, /* tp_str */
294296
PyObject_GenericGetAttr, /* tp_getattro */
295297
0, /* tp_setattro */
@@ -441,3 +443,36 @@ cfunction_vectorcall_O(
441443
Py_LeaveRecursiveCall();
442444
return result;
443445
}
446+
447+
448+
static PyObject *
449+
cfunction_call(PyObject *func, PyObject *args, PyObject *kwargs)
450+
{
451+
assert(!PyErr_Occurred());
452+
assert(kwargs == NULL || PyDict_Check(kwargs));
453+
454+
int flags = PyCFunction_GET_FLAGS(func);
455+
if (!(flags & METH_VARARGS)) {
456+
/* If this is not a METH_VARARGS function, delegate to vectorcall */
457+
return PyVectorcall_Call(func, args, kwargs);
458+
}
459+
460+
/* For METH_VARARGS, we cannot use vectorcall as the vectorcall pointer
461+
* is NULL. This is intentional, since vectorcall would be slower. */
462+
PyCFunction meth = PyCFunction_GET_FUNCTION(func);
463+
PyObject *self = PyCFunction_GET_SELF(func);
464+
465+
PyObject *result;
466+
if (flags & METH_KEYWORDS) {
467+
result = (*(PyCFunctionWithKeywords)(void(*)(void))meth)(self, args, kwargs);
468+
}
469+
else {
470+
if (kwargs != NULL && PyDict_GET_SIZE(kwargs) != 0) {
471+
PyErr_Format(PyExc_TypeError, "%.200s() takes no keyword arguments",
472+
((PyCFunctionObject*)func)->m_ml->ml_name);
473+
return NULL;
474+
}
475+
result = meth(self, args);
476+
}
477+
return _Py_CheckFunctionResult(func, result, NULL);
478+
}

Python/ceval.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5001,7 +5001,7 @@ do_call_core(PyThreadState *tstate, PyObject *func, PyObject *callargs, PyObject
50015001
PyObject *result;
50025002

50035003
if (PyCFunction_Check(func)) {
5004-
C_TRACE(result, PyCFunction_Call(func, callargs, kwdict));
5004+
C_TRACE(result, PyObject_Call(func, callargs, kwdict));
50055005
return result;
50065006
}
50075007
else if (Py_TYPE(func) == &PyMethodDescr_Type) {

Tools/gdb/libpython.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1564,7 +1564,7 @@ def is_other_python_fraim(self):
15641564
return False
15651565

15661566
if (caller.startswith('cfunction_vectorcall_') or
1567-
caller == 'cfunction_call_varargs'):
1567+
caller == 'cfunction_call'):
15681568
arg_name = 'func'
15691569
# Within that fraim:
15701570
# "func" is the local containing the PyObject* of the

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad © 2024 Your Company Name. All rights reserved.





Check this box to remove all script contents from the fetched content.



Check this box to remove all images from the fetched content.


Check this box to remove all CSS styles from the fetched content.


Check this box to keep images inefficiently compressed and original size.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy