@@ -78,68 +78,71 @@ PyCFunction_GetFlags(PyObject *op)
7878}
7979
8080PyObject *
81- PyCFunction_Call (PyObject * func , PyObject * arg , PyObject * kw )
81+ PyCFunction_Call (PyObject * func , PyObject * args , PyObject * kwds )
8282{
83- #define CHECK_RESULT (res ) assert(res != NULL || PyErr_Occurred())
84-
8583 PyCFunctionObject * f = (PyCFunctionObject * )func ;
8684 PyCFunction meth = PyCFunction_GET_FUNCTION (func );
8785 PyObject * self = PyCFunction_GET_SELF (func );
88- PyObject * res ;
86+ PyObject * arg , * res ;
8987 Py_ssize_t size ;
88+ int flags ;
9089
91- switch (PyCFunction_GET_FLAGS (func ) & ~(METH_CLASS | METH_STATIC | METH_COEXIST )) {
92- case METH_VARARGS :
93- if (kw == NULL || PyDict_Size (kw ) == 0 ) {
94- res = (* meth )(self , arg );
95- CHECK_RESULT (res );
96- return res ;
97- }
98- break ;
99- case METH_VARARGS | METH_KEYWORDS :
100- res = (* (PyCFunctionWithKeywords )meth )(self , arg , kw );
101- CHECK_RESULT (res );
102- return res ;
103- case METH_NOARGS :
104- if (kw == NULL || PyDict_Size (kw ) == 0 ) {
105- size = PyTuple_GET_SIZE (arg );
106- if (size == 0 ) {
107- res = (* meth )(self , NULL );
108- CHECK_RESULT (res );
109- return res ;
110- }
111- PyErr_Format (PyExc_TypeError ,
112- "%.200s() takes no arguments (%zd given)" ,
113- f -> m_ml -> ml_name , size );
90+ /* PyCFunction_Call() must not be called with an exception set,
91+ because it may clear it (directly or indirectly) and so the
92+ caller looses its exception */
93+ assert (!PyErr_Occurred ());
94+
95+ flags = PyCFunction_GET_FLAGS (func ) & ~(METH_CLASS | METH_STATIC | METH_COEXIST );
96+
97+ if (flags == (METH_VARARGS | METH_KEYWORDS )) {
98+ res = (* (PyCFunctionWithKeywords )meth )(self , args , kwds );
99+ }
100+ else {
101+ if (kwds != NULL && PyDict_Size (kwds ) != 0 ) {
102+ PyErr_Format (PyExc_TypeError , "%.200s() takes no keyword arguments" ,
103+ f -> m_ml -> ml_name );
114104 return NULL ;
115105 }
116- break ;
117- case METH_O :
118- if (kw == NULL || PyDict_Size (kw ) == 0 ) {
119- size = PyTuple_GET_SIZE (arg );
120- if (size == 1 ) {
121- res = (* meth )(self , PyTuple_GET_ITEM (arg , 0 ));
122- CHECK_RESULT (res );
123- return res ;
106+
107+ switch (flags ) {
108+ case METH_VARARGS :
109+ res = (* meth )(self , args );
110+ break ;
111+
112+ case METH_NOARGS :
113+ size = PyTuple_GET_SIZE (args );
114+ if (size != 0 ) {
115+ PyErr_Format (PyExc_TypeError ,
116+ "%.200s() takes no arguments (%zd given)" ,
117+ f -> m_ml -> ml_name , size );
118+ return NULL ;
124119 }
125- PyErr_Format (PyExc_TypeError ,
126- "%.200s() takes exactly one argument (%zd given)" ,
127- f -> m_ml -> ml_name , size );
120+
121+ res = (* meth )(self , NULL );
122+ break ;
123+
124+ case METH_O :
125+ size = PyTuple_GET_SIZE (args );
126+ if (size != 1 ) {
127+ PyErr_Format (PyExc_TypeError ,
128+ "%.200s() takes exactly one argument (%zd given)" ,
129+ f -> m_ml -> ml_name , size );
130+ return NULL ;
131+ }
132+
133+ arg = PyTuple_GET_ITEM (args , 0 );
134+ res = (* meth )(self , arg );
135+ break ;
136+
137+ default :
138+ PyErr_SetString (PyExc_SystemError ,
139+ "Bad call flags in PyCFunction_Call. "
140+ "METH_OLDARGS is no longer supported!" );
128141 return NULL ;
129142 }
130- break ;
131- default :
132- PyErr_SetString (PyExc_SystemError , "Bad call flags in "
133- "PyCFunction_Call. METH_OLDARGS is no "
134- "longer supported!" );
135-
136- return NULL ;
137143 }
138- PyErr_Format (PyExc_TypeError , "%.200s() takes no keyword arguments" ,
139- f -> m_ml -> ml_name );
140- return NULL ;
141144
142- #undef CHECK_RESULT
145+ return _Py_CheckFunctionResult ( res , "PyCFunction_Call" );
143146}
144147
145148/* Methods (the standard built-in methods, that is) */
0 commit comments