Skip to content
This repository was archived by the owner on Feb 13, 2025. It is now read-only.

Commit c89ef82

Browse files
committed
PyCFunction_Call() now calls _PyCFunction_FastCallDict()
Issue python#29259. We had 3 versions of similar code: * PyCFunction_Call() * _PyCFunction_FastCallDict() * _PyCFunction_FastCallKeywords() PyCFunction_Call() now calls _PyCFunction_FastCallDict() to factorize the code.
1 parent 250e4b0 commit c89ef82

File tree

1 file changed

+5
-70
lines changed

1 file changed

+5
-70
lines changed

Objects/methodobject.c

Lines changed: 5 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -78,77 +78,12 @@ PyCFunction_GetFlags(PyObject *op)
7878
}
7979

8080
PyObject *
81-
PyCFunction_Call(PyObject *func, PyObject *args, PyObject *kwds)
81+
PyCFunction_Call(PyObject *func, PyObject *args, PyObject *kwargs)
8282
{
83-
PyCFunctionObject* f = (PyCFunctionObject*)func;
84-
PyCFunction meth = PyCFunction_GET_FUNCTION(func);
85-
PyObject *self = PyCFunction_GET_SELF(func);
86-
PyObject *arg, *res;
87-
Py_ssize_t size;
88-
int flags;
89-
90-
assert(kwds == NULL || PyDict_Check(kwds));
91-
/* PyCFunction_Call() must not be called with an exception set,
92-
because it can clear it (directly or indirectly) and so the
93-
caller loses its exception */
94-
assert(!PyErr_Occurred());
95-
96-
flags = PyCFunction_GET_FLAGS(func) & ~(METH_CLASS | METH_STATIC | METH_COEXIST);
97-
98-
if (flags == (METH_VARARGS | METH_KEYWORDS)) {
99-
res = (*(PyCFunctionWithKeywords)meth)(self, args, kwds);
100-
}
101-
else if (flags == METH_FASTCALL) {
102-
PyObject **stack = &PyTuple_GET_ITEM(args, 0);
103-
Py_ssize_t nargs = PyTuple_GET_SIZE(args);
104-
res = _PyCFunction_FastCallDict(func, stack, nargs, kwds);
105-
}
106-
else {
107-
if (kwds != NULL && PyDict_GET_SIZE(kwds) != 0) {
108-
PyErr_Format(PyExc_TypeError, "%.200s() takes no keyword arguments",
109-
f->m_ml->ml_name);
110-
return NULL;
111-
}
112-
113-
switch (flags) {
114-
case METH_VARARGS:
115-
res = (*meth)(self, args);
116-
break;
117-
118-
case METH_NOARGS:
119-
size = PyTuple_GET_SIZE(args);
120-
if (size != 0) {
121-
PyErr_Format(PyExc_TypeError,
122-
"%.200s() takes no arguments (%zd given)",
123-
f->m_ml->ml_name, size);
124-
return NULL;
125-
}
126-
127-
res = (*meth)(self, NULL);
128-
break;
129-
130-
case METH_O:
131-
size = PyTuple_GET_SIZE(args);
132-
if (size != 1) {
133-
PyErr_Format(PyExc_TypeError,
134-
"%.200s() takes exactly one argument (%zd given)",
135-
f->m_ml->ml_name, size);
136-
return NULL;
137-
}
138-
139-
arg = PyTuple_GET_ITEM(args, 0);
140-
res = (*meth)(self, arg);
141-
break;
142-
143-
default:
144-
PyErr_SetString(PyExc_SystemError,
145-
"Bad call flags in PyCFunction_Call. "
146-
"METH_OLDARGS is no longer supported!");
147-
return NULL;
148-
}
149-
}
150-
151-
return _Py_CheckFunctionResult(func, res, NULL);
83+
return _PyCFunction_FastCallDict(func,
84+
&PyTuple_GET_ITEM(args, 0),
85+
PyTuple_GET_SIZE(args),
86+
kwargs);
15287
}
15388

15489
PyObject *

0 commit comments

Comments
 (0)