bpo-36922: implement PEP-590 Py_TPFLAGS_METHOD_DESCRIPTOR (GH-13338)

Co-authored-by: Mark Shannon <mark@hotpy.org>
This commit is contained in:
Jeroen Demeyer 2019-05-28 14:42:53 +02:00 committed by Petr Viktorin
parent 0811f2d81a
commit eb65e2443a
10 changed files with 132 additions and 7 deletions

View file

@ -5787,6 +5787,46 @@ static PyTypeObject Generic_Type = {
};
/* Test PEP 590 */
static PyObject *
func_descr_get(PyObject *func, PyObject *obj, PyObject *type)
{
if (obj == Py_None || obj == NULL) {
Py_INCREF(func);
return func;
}
return PyMethod_New(func, obj);
}
static PyObject *
nop_descr_get(PyObject *func, PyObject *obj, PyObject *type)
{
Py_INCREF(func);
return func;
}
static PyTypeObject MethodDescriptorBase_Type = {
PyVarObject_HEAD_INIT(NULL, 0)
"MethodDescriptorBase",
.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_METHOD_DESCRIPTOR,
.tp_descr_get = func_descr_get,
};
static PyTypeObject MethodDescriptorDerived_Type = {
PyVarObject_HEAD_INIT(NULL, 0)
"MethodDescriptorDerived",
.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
};
static PyTypeObject MethodDescriptorNopGet_Type = {
PyVarObject_HEAD_INIT(NULL, 0)
"MethodDescriptorNopGet",
.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
.tp_descr_get = nop_descr_get,
};
static struct PyModuleDef _testcapimodule = {
PyModuleDef_HEAD_INIT,
"_testcapi",
@ -5834,6 +5874,23 @@ PyInit__testcapi(void)
Py_INCREF(&MyList_Type);
PyModule_AddObject(m, "MyList", (PyObject *)&MyList_Type);
if (PyType_Ready(&MethodDescriptorBase_Type) < 0)
return NULL;
Py_INCREF(&MethodDescriptorBase_Type);
PyModule_AddObject(m, "MethodDescriptorBase", (PyObject *)&MethodDescriptorBase_Type);
MethodDescriptorDerived_Type.tp_base = &MethodDescriptorBase_Type;
if (PyType_Ready(&MethodDescriptorDerived_Type) < 0)
return NULL;
Py_INCREF(&MethodDescriptorDerived_Type);
PyModule_AddObject(m, "MethodDescriptorDerived", (PyObject *)&MethodDescriptorDerived_Type);
MethodDescriptorNopGet_Type.tp_base = &MethodDescriptorBase_Type;
if (PyType_Ready(&MethodDescriptorNopGet_Type) < 0)
return NULL;
Py_INCREF(&MethodDescriptorNopGet_Type);
PyModule_AddObject(m, "MethodDescriptorNopGet", (PyObject *)&MethodDescriptorNopGet_Type);
if (PyType_Ready(&GenericAlias_Type) < 0)
return NULL;
Py_INCREF(&GenericAlias_Type);