-
-
Notifications
You must be signed in to change notification settings - Fork 34.1k
bpo-37151: remove special case for PyCFunction from PyObject_Call #14684
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| ``PyCFunction_Call`` is now a deprecated alias of :c:func:`PyObject_Call`. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -5,9 +5,6 @@ | |
| #include "frameobject.h" | ||
|
|
||
|
|
||
| static PyObject * | ||
| cfunction_call_varargs(PyObject *func, PyObject *args, PyObject *kwargs); | ||
|
|
||
| static PyObject *const * | ||
| _PyStack_UnpackDict(PyObject *const *args, Py_ssize_t nargs, PyObject *kwargs, | ||
| PyObject **p_kwnames); | ||
|
|
@@ -236,11 +233,6 @@ PyObject_Call(PyObject *callable, PyObject *args, PyObject *kwargs) | |
| if (_PyVectorcall_Function(callable) != NULL) { | ||
| return PyVectorcall_Call(callable, args, kwargs); | ||
| } | ||
| else if (PyCFunction_Check(callable)) { | ||
| /* This must be a METH_VARARGS function, otherwise we would be | ||
| * in the previous case */ | ||
| return cfunction_call_varargs(callable, args, kwargs); | ||
| } | ||
| else { | ||
| call = callable->ob_type->tp_call; | ||
| if (call == NULL) { | ||
|
|
@@ -261,6 +253,13 @@ PyObject_Call(PyObject *callable, PyObject *args, PyObject *kwargs) | |
| } | ||
|
|
||
|
|
||
| PyObject * | ||
| PyCFunction_Call(PyObject *callable, PyObject *args, PyObject *kwargs) | ||
| { | ||
| return PyObject_Call(callable, args, kwargs); | ||
| } | ||
|
|
||
|
|
||
| /* --- PyFunction call functions ---------------------------------- */ | ||
|
|
||
| static PyObject* _Py_HOT_FUNCTION | ||
|
|
@@ -364,60 +363,6 @@ _PyFunction_Vectorcall(PyObject *func, PyObject* const* stack, | |
| } | ||
|
|
||
|
|
||
| /* --- PyCFunction call functions --------------------------------- */ | ||
|
|
||
| static PyObject * | ||
| cfunction_call_varargs(PyObject *func, PyObject *args, PyObject *kwargs) | ||
| { | ||
| assert(!PyErr_Occurred()); | ||
| assert(kwargs == NULL || PyDict_Check(kwargs)); | ||
|
|
||
| PyCFunction meth = PyCFunction_GET_FUNCTION(func); | ||
| PyObject *self = PyCFunction_GET_SELF(func); | ||
| PyObject *result; | ||
|
|
||
| assert(PyCFunction_GET_FLAGS(func) & METH_VARARGS); | ||
| if (PyCFunction_GET_FLAGS(func) & METH_KEYWORDS) { | ||
| if (Py_EnterRecursiveCall(" while calling a Python object")) { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The recursion check is gone now. Was that intentional? Any reason why you think we don't need it any more?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The recursion check is gone from Note that |
||
| return NULL; | ||
| } | ||
|
|
||
| result = (*(PyCFunctionWithKeywords)(void(*)(void))meth)(self, args, kwargs); | ||
|
|
||
| Py_LeaveRecursiveCall(); | ||
| } | ||
| else { | ||
| if (kwargs != NULL && PyDict_GET_SIZE(kwargs) != 0) { | ||
| PyErr_Format(PyExc_TypeError, "%.200s() takes no keyword arguments", | ||
| ((PyCFunctionObject*)func)->m_ml->ml_name); | ||
| return NULL; | ||
| } | ||
|
|
||
| if (Py_EnterRecursiveCall(" while calling a Python object")) { | ||
| return NULL; | ||
| } | ||
|
|
||
| result = (*meth)(self, args); | ||
|
|
||
| Py_LeaveRecursiveCall(); | ||
| } | ||
|
|
||
| return _Py_CheckFunctionResult(func, result, NULL); | ||
| } | ||
|
|
||
|
|
||
| PyObject * | ||
| PyCFunction_Call(PyObject *func, PyObject *args, PyObject *kwargs) | ||
| { | ||
| /* For METH_VARARGS, we cannot use vectorcall as the vectorcall pointer | ||
| * is NULL. This is intentional, since vectorcall would be slower. */ | ||
| if (PyCFunction_GET_FLAGS(func) & METH_VARARGS) { | ||
| return cfunction_call_varargs(func, args, kwargs); | ||
| } | ||
| return PyVectorcall_Call(func, args, kwargs); | ||
| } | ||
|
|
||
|
|
||
| /* --- More complex call functions -------------------------------- */ | ||
|
|
||
| /* External interface to call any callable object. | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@vstinner, is this the right way to deprecate an undocumented part of the stable ABI?
(I'll merge regardless, but I wanted to bring this to your attention.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The stable ABI is supposed to remain unchanged :-) "Py_DEPRECATED(3.9) PyAPI_FUNC(PyObject *) PyCFunction_Call" is the right usage of Py_DEPRECATED().
I don't know why PyCFunction_Call "leaked" into the stable ABI. I'm in favor of removing it. Start with a deprecation is a good start ;)