@@ -177,16 +177,21 @@ static PyObject* CPyFunction_Vectorcall(PyObject *func, PyObject *const *args, s
177177 PyCFunction meth = ((PyCFunctionObject * )f )-> m_ml -> ml_meth ;
178178
179179 self = ((PyCFunctionObject * )f )-> m_self ;
180+ if (!self ) {
181+ self = args [0 ];
182+ args += 1 ;
183+ nargs -= 1 ;
184+ }
180185 return ((_PyCFunctionFastWithKeywords )(void (* )(void ))meth )(self , args , nargs , kwnames );
181186}
182187
183188
184189static CPyFunction * CPyFunction_Init (CPyFunction * op , PyMethodDef * ml , PyObject * name ,
185- PyObject * module , PyObject * code ) {
190+ PyObject * module , PyObject * code , bool set_self ) {
186191 PyCFunctionObject * cf = (PyCFunctionObject * )op ;
187192 CPyFunction_weakreflist (op ) = NULL ;
188193 cf -> m_ml = ml ;
189- cf -> m_self = (PyObject * ) op ;
194+ cf -> m_self = set_self ? (PyObject * ) op : NULL ;
190195
191196 Py_XINCREF (module );
192197 cf -> m_module = module ;
@@ -226,9 +231,10 @@ static PyMethodDef* CPyMethodDef_New(const char *name, PyCFunction func, int fla
226231
227232PyObject * CPyFunction_New (PyObject * module , const char * filename , const char * funcname ,
228233 PyCFunction func , int func_flags , const char * func_doc ,
229- int first_line , int code_flags ) {
234+ int first_line , int code_flags , bool has_self_arg ) {
230235 PyMethodDef * method = NULL ;
231236 PyObject * code = NULL , * op = NULL ;
237+ bool set_self = false;
232238
233239 if (!CPyFunctionType ) {
234240 CPyFunctionType = (PyTypeObject * )PyType_FromSpec (& CPyFunction_spec );
@@ -245,8 +251,15 @@ PyObject* CPyFunction_New(PyObject *module, const char *filename, const char *fu
245251 if (unlikely (!code )) {
246252 goto err ;
247253 }
254+
255+ // Set m_self inside the function wrapper only if the wrapped function has no self arg
256+ // to pass m_self as the self arg when the function is called.
257+ // When the function has a self arg, it will come in the args vector passed to the
258+ // vectorcall handler.
259+ set_self = !has_self_arg ;
248260 op = (PyObject * )CPyFunction_Init (PyObject_GC_New (CPyFunction , CPyFunctionType ),
249- method , PyUnicode_FromString (funcname ), module , code );
261+ method , PyUnicode_FromString (funcname ), module ,
262+ code , set_self );
250263 if (unlikely (!op )) {
251264 goto err ;
252265 }
0 commit comments