@@ -300,16 +300,19 @@ _PyMethodDescr_Vectorcall(PyObject *descrobj,
300300 return result ;
301301}
302302
303+ /* Instances of classmethod_descriptor are unlikely to be called directly.
304+ For one, the analogous class "classmethod" (for Python classes) is not
305+ callable. Second, users are not likely to access a classmethod_descriptor
306+ directly, since it means pulling it from the class __dict__.
307+
308+ This is just an excuse to say that this doesn't need to be optimized:
309+ we implement this simply by calling __get__ and then calling the result.
310+ */
303311static PyObject *
304312classmethoddescr_call (PyMethodDescrObject * descr , PyObject * args ,
305313 PyObject * kwds )
306314{
307- Py_ssize_t argc ;
308- PyObject * self , * result ;
309-
310- /* Make sure that the first argument is acceptable as 'self' */
311- assert (PyTuple_Check (args ));
312- argc = PyTuple_GET_SIZE (args );
315+ Py_ssize_t argc = PyTuple_GET_SIZE (args );
313316 if (argc < 1 ) {
314317 PyErr_Format (PyExc_TypeError ,
315318 "descriptor '%V' of '%.100s' "
@@ -318,30 +321,15 @@ classmethoddescr_call(PyMethodDescrObject *descr, PyObject *args,
318321 PyDescr_TYPE (descr )-> tp_name );
319322 return NULL ;
320323 }
321- self = PyTuple_GET_ITEM (args , 0 );
322- if (!PyType_Check (self )) {
323- PyErr_Format (PyExc_TypeError ,
324- "descriptor '%V' requires a type "
325- "but received a '%.100s' instance" ,
326- descr_name ((PyDescrObject * )descr ), "?" ,
327- self -> ob_type -> tp_name );
328- return NULL ;
329- }
330- if (!PyType_IsSubtype ((PyTypeObject * )self , PyDescr_TYPE (descr ))) {
331- PyErr_Format (PyExc_TypeError ,
332- "descriptor '%V' requires a subtype of '%.100s' "
333- "but received '%.100s'" ,
334- descr_name ((PyDescrObject * )descr ), "?" ,
335- PyDescr_TYPE (descr )-> tp_name ,
336- ((PyTypeObject * )self )-> tp_name );
324+ PyObject * self = PyTuple_GET_ITEM (args , 0 );
325+ PyObject * bound = classmethod_get (descr , NULL , self );
326+ if (bound == NULL ) {
337327 return NULL ;
338328 }
339-
340- result = _PyMethodDef_RawFastCallDict (descr -> d_method , self ,
341- & _PyTuple_ITEMS (args )[1 ], argc - 1 ,
342- kwds );
343- result = _Py_CheckFunctionResult ((PyObject * )descr , result , NULL );
344- return result ;
329+ PyObject * res = _PyObject_FastCallDict (bound , _PyTuple_ITEMS (args )+ 1 ,
330+ argc - 1 , kwds );
331+ Py_DECREF (bound );
332+ return res ;
345333}
346334
347335Py_LOCAL_INLINE (PyObject * )
0 commit comments