@@ -77,13 +77,59 @@ PyCFunction_GetFlags(PyObject *op)
77
77
return PyCFunction_GET_FLAGS (op );
78
78
}
79
79
80
+ static PyObject *
81
+ cfunction_call_varargs (PyObject * func , PyObject * args , PyObject * kwargs )
82
+ {
83
+ assert (!PyErr_Occurred ());
84
+
85
+ PyCFunction meth = PyCFunction_GET_FUNCTION (func );
86
+ PyObject * self = PyCFunction_GET_SELF (func );
87
+ PyObject * result ;
88
+
89
+ if (PyCFunction_GET_FLAGS (func ) & METH_KEYWORDS ) {
90
+ if (Py_EnterRecursiveCall (" while calling a Python object" )) {
91
+ return NULL ;
92
+ }
93
+
94
+ result = (* (PyCFunctionWithKeywords )meth )(self , args , kwargs );
95
+
96
+ Py_LeaveRecursiveCall ();
97
+ }
98
+ else {
99
+ if (kwargs != NULL && PyDict_Size (kwargs ) != 0 ) {
100
+ PyErr_Format (PyExc_TypeError , "%.200s() takes no keyword arguments" ,
101
+ ((PyCFunctionObject * )func )-> m_ml -> ml_name );
102
+ return NULL ;
103
+ }
104
+
105
+ if (Py_EnterRecursiveCall (" while calling a Python object" )) {
106
+ return NULL ;
107
+ }
108
+
109
+ result = (* meth )(self , args );
110
+
111
+ Py_LeaveRecursiveCall ();
112
+ }
113
+
114
+ return _Py_CheckFunctionResult (func , result , NULL );
115
+ }
116
+
117
+
80
118
PyObject *
81
119
PyCFunction_Call (PyObject * func , PyObject * args , PyObject * kwargs )
82
120
{
83
- return _PyCFunction_FastCallDict (func ,
84
- & PyTuple_GET_ITEM (args , 0 ),
85
- PyTuple_GET_SIZE (args ),
86
- kwargs );
121
+ /* first try METH_VARARGS to pass directly args tuple unchanged.
122
+ _PyMethodDef_RawFastCallDict() creates a new temporary tuple
123
+ for METH_VARARGS. */
124
+ if (PyCFunction_GET_FLAGS (func ) & METH_VARARGS ) {
125
+ return cfunction_call_varargs (func , args , kwargs );
126
+ }
127
+ else {
128
+ return _PyCFunction_FastCallDict (func ,
129
+ & PyTuple_GET_ITEM (args , 0 ),
130
+ PyTuple_GET_SIZE (args ),
131
+ kwargs );
132
+ }
87
133
}
88
134
89
135
PyObject *
0 commit comments