@@ -5814,6 +5814,29 @@ static PyTypeObject Generic_Type = {
5814
5814
5815
5815
/* Test PEP 590 */
5816
5816
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
+
5817
5840
static PyObject *
5818
5841
func_descr_get (PyObject * func , PyObject * obj , PyObject * type )
5819
5842
{
@@ -5831,10 +5854,22 @@ nop_descr_get(PyObject *func, PyObject *obj, PyObject *type)
5831
5854
return func ;
5832
5855
}
5833
5856
5857
+ static PyObject *
5858
+ call_return_args (PyObject * self , PyObject * args , PyObject * kwargs )
5859
+ {
5860
+ Py_INCREF (args );
5861
+ return args ;
5862
+ }
5863
+
5834
5864
static PyTypeObject MethodDescriptorBase_Type = {
5835
5865
PyVarObject_HEAD_INIT (NULL , 0 )
5836
5866
"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 ,
5838
5873
.tp_descr_get = func_descr_get ,
5839
5874
};
5840
5875
@@ -5848,9 +5883,34 @@ static PyTypeObject MethodDescriptorNopGet_Type = {
5848
5883
PyVarObject_HEAD_INIT (NULL , 0 )
5849
5884
"MethodDescriptorNopGet" ,
5850
5885
.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE ,
5886
+ .tp_call = call_return_args ,
5851
5887
.tp_descr_get = nop_descr_get ,
5852
5888
};
5853
5889
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
+
5854
5914
5855
5915
static struct PyModuleDef _testcapimodule = {
5856
5916
PyModuleDef_HEAD_INIT ,
@@ -5916,6 +5976,12 @@ PyInit__testcapi(void)
5916
5976
Py_INCREF (& MethodDescriptorNopGet_Type );
5917
5977
PyModule_AddObject (m , "MethodDescriptorNopGet" , (PyObject * )& MethodDescriptorNopGet_Type );
5918
5978
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
+
5919
5985
if (PyType_Ready (& GenericAlias_Type ) < 0 )
5920
5986
return NULL ;
5921
5987
Py_INCREF (& GenericAlias_Type );
0 commit comments