@@ -5814,6 +5814,29 @@ static PyTypeObject Generic_Type = {
58145814
58155815/* Test PEP 590 */
58165816
5817+ typedef struct {
5818+ PyObject_HEAD
5819+ vectorcallfunc vectorcall ;
5820+ } MethodDescriptorObject ;
5821+
5822+ static PyObject *
5823+ MethodDescriptor_vectorcall (PyObject * callable , PyObject * const * args ,
5824+ size_t nargsf , PyObject * kwnames )
5825+ {
5826+ /* True if using the vectorcall function in MethodDescriptorObject
5827+ * but False for MethodDescriptor2Object */
5828+ MethodDescriptorObject * md = (MethodDescriptorObject * )callable ;
5829+ return PyBool_FromLong (md -> vectorcall != NULL );
5830+ }
5831+
5832+ static PyObject *
5833+ MethodDescriptor_new (PyTypeObject * type , PyObject * args , PyObject * kw )
5834+ {
5835+ MethodDescriptorObject * op = PyObject_New (MethodDescriptorObject , type );
5836+ op -> vectorcall = MethodDescriptor_vectorcall ;
5837+ return (PyObject * )op ;
5838+ }
5839+
58175840static PyObject *
58185841func_descr_get (PyObject * func , PyObject * obj , PyObject * type )
58195842{
@@ -5831,10 +5854,22 @@ nop_descr_get(PyObject *func, PyObject *obj, PyObject *type)
58315854 return func ;
58325855}
58335856
5857+ static PyObject *
5858+ call_return_args (PyObject * self , PyObject * args , PyObject * kwargs )
5859+ {
5860+ Py_INCREF (args );
5861+ return args ;
5862+ }
5863+
58345864static PyTypeObject MethodDescriptorBase_Type = {
58355865 PyVarObject_HEAD_INIT (NULL , 0 )
58365866 "MethodDescriptorBase" ,
5837- .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_METHOD_DESCRIPTOR ,
5867+ sizeof (MethodDescriptorObject ),
5868+ .tp_new = MethodDescriptor_new ,
5869+ .tp_call = PyVectorcall_Call ,
5870+ .tp_vectorcall_offset = offsetof(MethodDescriptorObject , vectorcall ),
5871+ .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
5872+ Py_TPFLAGS_METHOD_DESCRIPTOR | _Py_TPFLAGS_HAVE_VECTORCALL ,
58385873 .tp_descr_get = func_descr_get ,
58395874};
58405875
@@ -5848,9 +5883,34 @@ static PyTypeObject MethodDescriptorNopGet_Type = {
58485883 PyVarObject_HEAD_INIT (NULL , 0 )
58495884 "MethodDescriptorNopGet" ,
58505885 .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE ,
5886+ .tp_call = call_return_args ,
58515887 .tp_descr_get = nop_descr_get ,
58525888};
58535889
5890+ typedef struct {
5891+ MethodDescriptorObject base ;
5892+ vectorcallfunc vectorcall ;
5893+ } MethodDescriptor2Object ;
5894+
5895+ static PyObject *
5896+ MethodDescriptor2_new (PyTypeObject * type , PyObject * args , PyObject * kw )
5897+ {
5898+ MethodDescriptor2Object * op = PyObject_New (MethodDescriptor2Object , type );
5899+ op -> base .vectorcall = NULL ;
5900+ op -> vectorcall = MethodDescriptor_vectorcall ;
5901+ return (PyObject * )op ;
5902+ }
5903+
5904+ static PyTypeObject MethodDescriptor2_Type = {
5905+ PyVarObject_HEAD_INIT (NULL , 0 )
5906+ "MethodDescriptor2" ,
5907+ sizeof (MethodDescriptor2Object ),
5908+ .tp_new = MethodDescriptor2_new ,
5909+ .tp_call = PyVectorcall_Call ,
5910+ .tp_vectorcall_offset = offsetof(MethodDescriptor2Object , vectorcall ),
5911+ .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | _Py_TPFLAGS_HAVE_VECTORCALL ,
5912+ };
5913+
58545914
58555915static struct PyModuleDef _testcapimodule = {
58565916 PyModuleDef_HEAD_INIT ,
@@ -5916,6 +5976,12 @@ PyInit__testcapi(void)
59165976 Py_INCREF (& MethodDescriptorNopGet_Type );
59175977 PyModule_AddObject (m , "MethodDescriptorNopGet" , (PyObject * )& MethodDescriptorNopGet_Type );
59185978
5979+ MethodDescriptor2_Type .tp_base = & MethodDescriptorBase_Type ;
5980+ if (PyType_Ready (& MethodDescriptor2_Type ) < 0 )
5981+ return NULL ;
5982+ Py_INCREF (& MethodDescriptor2_Type );
5983+ PyModule_AddObject (m , "MethodDescriptor2" , (PyObject * )& MethodDescriptor2_Type );
5984+
59195985 if (PyType_Ready (& GenericAlias_Type ) < 0 )
59205986 return NULL ;
59215987 Py_INCREF (& GenericAlias_Type );
0 commit comments