/* Descriptors -- a new, flexible way to describe attributes */ #include "Python.h"#include "structmember.h" /* Why is this not included in Python.h? */ static voiddescr_dealloc(PyDescrObject *descr){ _PyObject_GC_UNTRACK(descr); Py_XDECREF(descr->d_type); Py_XDECREF(descr->d_name); PyObject_GC_Del(descr);} static char *descr_name(PyDescrObject *descr){ if (descr->d_name != NULL && PyString_Check(descr->d_name)) return PyString_AS_STRING(descr->d_name); else return "?";} static PyObject *descr_repr(PyDescrObject *descr, char *format){ return PyString_FromFormat(format, descr_name(descr), descr->d_type->tp_name);} static PyObject *method_repr(PyMethodDescrObject *descr){ return descr_repr((PyDescrObject *)descr, "<method '%s' of '%s' objects>");} static PyObject *member_repr(PyMemberDescrObject *descr){ return descr_repr((PyDescrObject *)descr, "<member '%s' of '%s' objects>");} static PyObject *getset_repr(PyGetSetDescrObject *descr){ return descr_repr((PyDescrObject *)descr, "<attribute '%s' of '%s' objects>");} static PyObject *wrapperdescr_repr(PyWrapperDescrObject *descr){ return descr_repr((PyDescrObject *)descr, "<slot wrapper '%s' of '%s' objects>");} static intdescr_check(PyDescrObject *descr, PyObject *obj, PyObject **pres){ if (obj == NULL) { Py_INCREF(descr); *pres = (PyObject *)descr; return 1; } if (!PyObject_TypeCheck(obj, descr->d_type)) { PyErr_Format(PyExc_TypeError, "descriptor '%s' for '%s' objects " "doesn't apply to '%s' object", descr_name((PyDescrObject *)descr), descr->d_type->tp_name, obj->ob_type->tp_name); *pres = NULL; return 1; } return 0;} static PyObject *classmethod_get(PyMethodDescrObject *descr, PyObject *obj, PyObject *type){ /* Ensure a valid type. Class methods ignore obj. */ if (type == NULL) { if (obj != NULL) type = (PyObject *)obj->ob_type; else { /* Wot - no type?! */ PyErr_Format(PyExc_TypeError, "descriptor '%s' for type '%s' " "needs either an object or a type", descr_name((PyDescrObject *)descr), descr->d_type->tp_name); return NULL; } } if (!PyType_Check(type)) { PyErr_Format(PyExc_TypeError, "descriptor '%s' for type '%s' " "needs a type, not a '%s' as arg 2", descr_name((PyDescrObject *)descr), descr->d_type->tp_name, type->ob_type->tp_name); return NULL; } if (!PyType_IsSubtype((PyTypeObject *)type, descr->d_type)) { PyErr_Format(PyExc_TypeError, "descriptor '%s' for type '%s' " "doesn't apply to type '%s'", descr_name((PyDescrObject *)descr), descr->d_type->tp_name, ((PyTypeObject *)type)->tp_name); return NULL; } return PyCFunction_New(descr->d_method, type);} static PyObject *method_get(PyMethodDescrObject *descr, PyObject *obj, PyObject *type){ PyObject *res; if (descr_check((PyDescrObject *)descr, obj, &res)) return res; return PyCFunction_New(descr->d_method, obj);} static PyObject *member_get(PyMemberDescrObject *descr, PyObject *obj, PyObject *type){ PyObject *res; if (descr_check((PyDescrObject *)descr, obj, &res)) return res; return PyMember_GetOne((char *)obj, descr->d_member);} static PyObject *getset_get(PyGetSetDescrObject *descr, PyObject *obj, PyObject *type){ PyObject *res; if (descr_check((PyDescrObject *)descr, obj, &res)) return res; if (descr->d_getset->get != NULL) return descr->d_getset->get(obj, descr->d_getset->closure); PyErr_Format(PyExc_AttributeError, "attribute '%.300s' of '%.100s' objects is not readable", descr_name((PyDescrObject *)descr), descr->d_type->tp_name); return NULL;} static PyObject *wrapperdescr_get(PyWrapperDescrObject *descr, PyObject *obj, PyObject *type){ PyObject *res; if (descr_check((PyDescrObject *)descr, obj, &res)) return res; return PyWrapper_New((PyObject *)descr, obj);} static intdescr_setcheck(PyDescrObject *descr, PyObject *obj, PyObject *value, int *pres){ assert(obj != NULL); if (!PyObject_IsInstance(obj, (PyObject *)(descr->d_type))) { PyErr_Format(PyExc_TypeError, "descriptor '%.200s' for '%.100s' objects " "doesn't apply to '%.100s' object", descr_name(descr), descr->d_type->tp_name, obj->ob_type->tp_name); *pres = -1; return 1; } return 0;} static intmember_set(PyMemberDescrObject *descr, PyObject *obj, PyObject *value){ int res; if (descr_setcheck((PyDescrObject *)descr, obj, value, &res)) return res; return PyMember_SetOne((char *)obj, descr->d_member, value);} static intgetset_set(PyGetSetDescrObject *descr, PyObject *obj, PyObject *value){ int res; if (descr_setcheck((PyDescrObject *)descr, obj, value, &res)) return res; if (descr->d_getset->set != NULL) return descr->d_getset->set(obj, value, descr->d_getset->closure); PyErr_Format(PyExc_AttributeError, "attribute '%.300s' of '%.100s' objects is not writable", descr_name((PyDescrObject *)descr), descr->d_type->tp_name); return -1;} static PyObject *methoddescr_call(PyMethodDescrObject *descr, PyObject *args, PyObject *kwds){ Py_ssize_t argc; PyObject *self, *func, *result; /* Make sure that the first argument is acceptable as 'self' */ assert(PyTuple_Check(args)); argc = PyTuple_GET_SIZE(args); if (argc < 1) { PyErr_Format(PyExc_TypeError, "descriptor '%.300s' of '%.100s' " "object needs an argument", descr_name((PyDescrObject *)descr), descr->d_type->tp_name); return NULL; } self = PyTuple_GET_ITEM(args, 0); if (!PyObject_IsInstance(self, (PyObject *)(descr->d_type))) { PyErr_Format(PyExc_TypeError, "descriptor '%.200s' " "requires a '%.100s' object " "but received a '%.100s'", descr_name((PyDescrObject *)descr), descr->d_type->tp_name, self->ob_type->tp_name); return NULL; } func = PyCFunction_New(descr->d_method, self); if (func == NULL) return NULL; args = PyTuple_GetSlice(args, 1, argc); if (args == NULL) { Py_DECREF(func); return NULL; } result = PyEval_CallObjectWithKeywords(func, args, kwds); Py_DECREF(args); Py_DECREF(func); return result;} static PyObject *classmethoddescr_call(PyMethodDescrObject *descr, PyObject *args, PyObject *kwds){ PyObject *func, *result; func = PyCFunction_New(descr->d_method, (PyObject *)descr->d_type); if (func == NULL) return NULL; result = PyEval_CallObjectWithKeywords(func, args, kwds); Py_DECREF(func); return result;} static PyObject *wrapperdescr_call(PyWrapperDescrObject *descr, PyObject *args, PyObject *kwds){ Py_ssize_t argc; PyObject *self, *func, *result; /* Make sure that the first argument is acceptable as 'self' */ assert(PyTuple_Check(args)); argc = PyTuple_GET_SIZE(args); if (argc < 1) { PyErr_Format(PyExc_TypeError, "descriptor '%.300s' of '%.100s' " "object needs an argument", descr_name((PyDescrObject *)descr), descr->d_type->tp_name); return NULL; } self = PyTuple_GET_ITEM(args, 0); if (!PyObject_IsInstance(self, (PyObject *)(descr->d_type))) { PyErr_Format(PyExc_TypeError, "descriptor '%.200s' " "requires a '%.100s' object " "but received a '%.100s'", descr_name((PyDescrObject *)descr), descr->d_type->tp_name, self->ob_type->tp_name); return NULL; } func = PyWrapper_New((PyObject *)descr, self); if (func == NULL) return NULL; args = PyTuple_GetSlice(args, 1, argc); if (args == NULL) { Py_DECREF(func); return NULL; } result = PyEval_CallObjectWithKeywords(func, args, kwds); Py_DECREF(args); Py_DECREF(func); return result;} static PyObject *method_get_doc(PyMethodDescrObject *descr, void *closure){ if (descr->d_method->ml_doc == NULL) { Py_INCREF(Py_None); return Py_None; } return PyString_FromString(descr->d_method->ml_doc);} static PyMemberDef descr_members[] = { {"__objclass__", T_OBJECT, offsetof(PyDescrObject, d_type), READONLY}, {"__name__", T_OBJECT, offsetof(PyDescrObject, d_name), READONLY}, {0}}; static PyGetSetDef method_getset[] = { {"__doc__", (getter)method_get_doc}, {0}}; static PyObject *member_get_doc(PyMemberDescrObject *descr, void *closure){ if (descr->d_member->doc == NULL) { Py_INCREF(Py_None); return Py_None; } return PyString_FromString(descr->d_member->doc);} static PyGetSetDef member_getset[] = { {"__doc__", (getter)member_get_doc}, {0}}; static PyObject *getset_get_doc(PyGetSetDescrObject *descr, void *closure){ if (descr->d_getset->doc == NULL) { Py_INCREF(Py_None); return Py_None; } return PyString_FromString(descr->d_getset->doc);} static PyGetSetDef getset_getset[] = { {"__doc__", (getter)getset_get_doc}, {0}}; static PyObject *wrapperdescr_get_doc(PyWrapperDescrObject *descr, void *closure){ if (descr->d_base->doc == NULL) { Py_INCREF(Py_None); return Py_None; } return PyString_FromString(descr->d_base->doc);} static PyGetSetDef wrapperdescr_getset[] = { {"__doc__", (getter)wrapperdescr_get_doc}, {0}}; static intdescr_traverse(PyObject *self, visitproc visit, void *arg){ PyDescrObject *descr = (PyDescrObject *)self; Py_VISIT(descr->d_type); return 0;} static PyTypeObject PyMethodDescr_Type = { PyObject_HEAD_INIT(&PyType_Type) 0, "method_descriptor", sizeof(PyMethodDescrObject), 0, (destructor)descr_dealloc, /* tp_dealloc */ 0, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_compare */ (reprfunc)method_repr, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ 0, /* tp_as_mapping */ 0, /* tp_hash */ (ternaryfunc)methoddescr_call, /* tp_call */ 0, /* tp_str */ PyObject_GenericGetAttr, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ 0, /* tp_doc */ descr_traverse, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ 0, /* tp_iter */ 0, /* tp_iternext */ 0, /* tp_methods */ descr_members, /* tp_members */ method_getset, /* tp_getset */ 0, /* tp_base */ 0, /* tp_dict */ (descrgetfunc)method_get, /* tp_descr_get */ 0, /* tp_descr_set */}; /* This is for METH_CLASS in C, not for "f = classmethod(f)" in Python! */static PyTypeObject PyClassMethodDescr_Type = { PyObject_HEAD_INIT(&PyType_Type) 0, "classmethod_descriptor", sizeof(PyMethodDescrObject), 0, (destructor)descr_dealloc, /* tp_dealloc */ 0, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_compare */ (reprfunc)method_repr, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ 0, /* tp_as_mapping */ 0, /* tp_hash */ (ternaryfunc)classmethoddescr_call, /* tp_call */ 0, /* tp_str */ PyObject_GenericGetAttr, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ 0, /* tp_doc */ descr_traverse, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ 0, /* tp_iter */ 0, /* tp_iternext */ 0, /* tp_methods */ descr_members, /* tp_members */ method_getset, /* tp_getset */ 0, /* tp_base */ 0, /* tp_dict */ (descrgetfunc)classmethod_get, /* tp_descr_get */ 0, /* tp_descr_set */}; static PyTypeObject PyMemberDescr_Type = { PyObject_HEAD_INIT(&PyType_Type) 0, "member_descriptor", sizeof(PyMemberDescrObject), 0, (destructor)descr_dealloc, /* tp_dealloc */ 0, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_compare */ (reprfunc)member_repr, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ 0, /* tp_as_mapping */ 0, /* tp_hash */ 0, /* tp_call */ 0, /* tp_str */ PyObject_GenericGetAttr, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ 0, /* tp_doc */ descr_traverse, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ 0, /* tp_iter */ 0, /* tp_iternext */ 0, /* tp_methods */ descr_members, /* tp_members */ member_getset, /* tp_getset */ 0, /* tp_base */ 0, /* tp_dict */ (descrgetfunc)member_get, /* tp_descr_get */ (descrsetfunc)member_set, /* tp_descr_set */}; static PyTypeObject PyGetSetDescr_Type = { PyObject_HEAD_INIT(&PyType_Type)Lines 1–500 of 1283. Load more
/* Descriptors -- a new, flexible way to describe attributes */ #include "Python.h" #include "structmember.h" /* Why is this not included in Python.h? */ static void descr_dealloc(PyDescrObject *descr) { _PyObject_GC_UNTRACK(descr); Py_XDECREF(descr->d_type); Py_XDECREF(descr->d_name); PyObject_GC_Del(descr); } static char * descr_name(PyDescrObject *descr) { if (descr->d_name != NULL && PyString_Check(descr->d_name)) return PyString_AS_STRING(descr->d_name); else return "?"; } static PyObject * descr_repr(PyDescrObject *descr, char *format) { return PyString_FromFormat(format, descr_name(descr), descr->d_type->tp_name); } static PyObject * method_repr(PyMethodDescrObject *descr) { return descr_repr((PyDescrObject *)descr, "<method '%s' of '%s' objects>"); } static PyObject * member_repr(PyMemberDescrObject *descr) { return descr_repr((PyDescrObject *)descr, "<member '%s' of '%s' objects>"); } static PyObject * getset_repr(PyGetSetDescrObject *descr) { return descr_repr((PyDescrObject *)descr, "<attribute '%s' of '%s' objects>"); } static PyObject * wrapperdescr_repr(PyWrapperDescrObject *descr) { return descr_repr((PyDescrObject *)descr, "<slot wrapper '%s' of '%s' objects>"); } static int descr_check(PyDescrObject *descr, PyObject *obj, PyObject **pres) { if (obj == NULL) { Py_INCREF(descr); *pres = (PyObject *)descr; return 1; } if (!PyObject_TypeCheck(obj, descr->d_type)) { PyErr_Format(PyExc_TypeError, "descriptor '%s' for '%s' objects " "doesn't apply to '%s' object", descr_name((PyDescrObject *)descr), descr->d_type->tp_name, obj->ob_type->tp_name); *pres = NULL; return 1; } return 0; } static PyObject * classmethod_get(PyMethodDescrObject *descr, PyObject *obj, PyObject *type) { /* Ensure a valid type. Class methods ignore obj. */ if (type == NULL) { if (obj != NULL) type = (PyObject *)obj->ob_type; else { /* Wot - no type?! */ PyErr_Format(PyExc_TypeError, "descriptor '%s' for type '%s' " "needs either an object or a type", descr_name((PyDescrObject *)descr), descr->d_type->tp_name); return NULL; } } if (!PyType_Check(type)) { PyErr_Format(PyExc_TypeError, "descriptor '%s' for type '%s' " "needs a type, not a '%s' as arg 2", descr_name((PyDescrObject *)descr), descr->d_type->tp_name, type->ob_type->tp_name); return NULL; } if (!PyType_IsSubtype((PyTypeObject *)type, descr->d_type)) { PyErr_Format(PyExc_TypeError, "descriptor '%s' for type '%s' " "doesn't apply to type '%s'", descr_name((PyDescrObject *)descr), descr->d_type->tp_name, ((PyTypeObject *)type)->tp_name); return NULL; } return PyCFunction_New(descr->d_method, type); } static PyObject * method_get(PyMethodDescrObject *descr, PyObject *obj, PyObject *type) { PyObject *res; if (descr_check((PyDescrObject *)descr, obj, &res)) return res; return PyCFunction_New(descr->d_method, obj); } static PyObject * member_get(PyMemberDescrObject *descr, PyObject *obj, PyObject *type) { PyObject *res; if (descr_check((PyDescrObject *)descr, obj, &res)) return res; return PyMember_GetOne((char *)obj, descr->d_member); } static PyObject * getset_get(PyGetSetDescrObject *descr, PyObject *obj, PyObject *type) { PyObject *res; if (descr_check((PyDescrObject *)descr, obj, &res)) return res; if (descr->d_getset->get != NULL) return descr->d_getset->get(obj, descr->d_getset->closure); PyErr_Format(PyExc_AttributeError, "attribute '%.300s' of '%.100s' objects is not readable", descr_name((PyDescrObject *)descr), descr->d_type->tp_name); return NULL; } static PyObject * wrapperdescr_get(PyWrapperDescrObject *descr, PyObject *obj, PyObject *type) { PyObject *res; if (descr_check((PyDescrObject *)descr, obj, &res)) return res; return PyWrapper_New((PyObject *)descr, obj); } static int descr_setcheck(PyDescrObject *descr, PyObject *obj, PyObject *value, int *pres) { assert(obj != NULL); if (!PyObject_IsInstance(obj, (PyObject *)(descr->d_type))) { PyErr_Format(PyExc_TypeError, "descriptor '%.200s' for '%.100s' objects " "doesn't apply to '%.100s' object", descr_name(descr), descr->d_type->tp_name, obj->ob_type->tp_name); *pres = -1; return 1; } return 0; } static int member_set(PyMemberDescrObject *descr, PyObject *obj, PyObject *value) { int res; if (descr_setcheck((PyDescrObject *)descr, obj, value, &res)) return res; return PyMember_SetOne((char *)obj, descr->d_member, value); } static int getset_set(PyGetSetDescrObject *descr, PyObject *obj, PyObject *value) { int res; if (descr_setcheck((PyDescrObject *)descr, obj, value, &res)) return res; if (descr->d_getset->set != NULL) return descr->d_getset->set(obj, value, descr->d_getset->closure); PyErr_Format(PyExc_AttributeError, "attribute '%.300s' of '%.100s' objects is not writable", descr_name((PyDescrObject *)descr), descr->d_type->tp_name); return -1; } static PyObject * methoddescr_call(PyMethodDescrObject *descr, PyObject *args, PyObject *kwds) { Py_ssize_t argc; PyObject *self, *func, *result; /* Make sure that the first argument is acceptable as 'self' */ assert(PyTuple_Check(args)); argc = PyTuple_GET_SIZE(args); if (argc < 1) { PyErr_Format(PyExc_TypeError, "descriptor '%.300s' of '%.100s' " "object needs an argument", descr_name((PyDescrObject *)descr), descr->d_type->tp_name); return NULL; } self = PyTuple_GET_ITEM(args, 0); if (!PyObject_IsInstance(self, (PyObject *)(descr->d_type))) { PyErr_Format(PyExc_TypeError, "descriptor '%.200s' " "requires a '%.100s' object " "but received a '%.100s'", descr_name((PyDescrObject *)descr), descr->d_type->tp_name, self->ob_type->tp_name); return NULL; } func = PyCFunction_New(descr->d_method, self); if (func == NULL) return NULL; args = PyTuple_GetSlice(args, 1, argc); if (args == NULL) { Py_DECREF(func); return NULL; } result = PyEval_CallObjectWithKeywords(func, args, kwds); Py_DECREF(args); Py_DECREF(func); return result; } static PyObject * classmethoddescr_call(PyMethodDescrObject *descr, PyObject *args, PyObject *kwds) { PyObject *func, *result; func = PyCFunction_New(descr->d_method, (PyObject *)descr->d_type); if (func == NULL) return NULL; result = PyEval_CallObjectWithKeywords(func, args, kwds); Py_DECREF(func); return result; } static PyObject * wrapperdescr_call(PyWrapperDescrObject *descr, PyObject *args, PyObject *kwds) { Py_ssize_t argc; PyObject *self, *func, *result; /* Make sure that the first argument is acceptable as 'self' */ assert(PyTuple_Check(args)); argc = PyTuple_GET_SIZE(args); if (argc < 1) { PyErr_Format(PyExc_TypeError, "descriptor '%.300s' of '%.100s' " "object needs an argument", descr_name((PyDescrObject *)descr), descr->d_type->tp_name); return NULL; } self = PyTuple_GET_ITEM(args, 0); if (!PyObject_IsInstance(self, (PyObject *)(descr->d_type))) { PyErr_Format(PyExc_TypeError, "descriptor '%.200s' " "requires a '%.100s' object " "but received a '%.100s'", descr_name((PyDescrObject *)descr), descr->d_type->tp_name, self->ob_type->tp_name); return NULL; } func = PyWrapper_New((PyObject *)descr, self); if (func == NULL) return NULL; args = PyTuple_GetSlice(args, 1, argc); if (args == NULL) { Py_DECREF(func); return NULL; } result = PyEval_CallObjectWithKeywords(func, args, kwds); Py_DECREF(args); Py_DECREF(func); return result; } static PyObject * method_get_doc(PyMethodDescrObject *descr, void *closure) { if (descr->d_method->ml_doc == NULL) { Py_INCREF(Py_None); return Py_None; } return PyString_FromString(descr->d_method->ml_doc); } static PyMemberDef descr_members[] = { {"__objclass__", T_OBJECT, offsetof(PyDescrObject, d_type), READONLY}, {"__name__", T_OBJECT, offsetof(PyDescrObject, d_name), READONLY}, {0} }; static PyGetSetDef method_getset[] = { {"__doc__", (getter)method_get_doc}, {0} }; static PyObject * member_get_doc(PyMemberDescrObject *descr, void *closure) { if (descr->d_member->doc == NULL) { Py_INCREF(Py_None); return Py_None; } return PyString_FromString(descr->d_member->doc); } static PyGetSetDef member_getset[] = { {"__doc__", (getter)member_get_doc}, {0} }; static PyObject * getset_get_doc(PyGetSetDescrObject *descr, void *closure) { if (descr->d_getset->doc == NULL) { Py_INCREF(Py_None); return Py_None; } return PyString_FromString(descr->d_getset->doc); } static PyGetSetDef getset_getset[] = { {"__doc__", (getter)getset_get_doc}, {0} }; static PyObject * wrapperdescr_get_doc(PyWrapperDescrObject *descr, void *closure) { if (descr->d_base->doc == NULL) { Py_INCREF(Py_None); return Py_None; } return PyString_FromString(descr->d_base->doc); } static PyGetSetDef wrapperdescr_getset[] = { {"__doc__", (getter)wrapperdescr_get_doc}, {0} }; static int descr_traverse(PyObject *self, visitproc visit, void *arg) { PyDescrObject *descr = (PyDescrObject *)self; Py_VISIT(descr->d_type); return 0; } static PyTypeObject PyMethodDescr_Type = { PyObject_HEAD_INIT(&PyType_Type) 0, "method_descriptor", sizeof(PyMethodDescrObject), 0, (destructor)descr_dealloc, /* tp_dealloc */ 0, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_compare */ (reprfunc)method_repr, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ 0, /* tp_as_mapping */ 0, /* tp_hash */ (ternaryfunc)methoddescr_call, /* tp_call */ 0, /* tp_str */ PyObject_GenericGetAttr, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ 0, /* tp_doc */ descr_traverse, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ 0, /* tp_iter */ 0, /* tp_iternext */ 0, /* tp_methods */ descr_members, /* tp_members */ method_getset, /* tp_getset */ 0, /* tp_base */ 0, /* tp_dict */ (descrgetfunc)method_get, /* tp_descr_get */ 0, /* tp_descr_set */ }; /* This is for METH_CLASS in C, not for "f = classmethod(f)" in Python! */ static PyTypeObject PyClassMethodDescr_Type = { PyObject_HEAD_INIT(&PyType_Type) 0, "classmethod_descriptor", sizeof(PyMethodDescrObject), 0, (destructor)descr_dealloc, /* tp_dealloc */ 0, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_compare */ (reprfunc)method_repr, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ 0, /* tp_as_mapping */ 0, /* tp_hash */ (ternaryfunc)classmethoddescr_call, /* tp_call */ 0, /* tp_str */ PyObject_GenericGetAttr, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ 0, /* tp_doc */ descr_traverse, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ 0, /* tp_iter */ 0, /* tp_iternext */ 0, /* tp_methods */ descr_members, /* tp_members */ method_getset, /* tp_getset */ 0, /* tp_base */ 0, /* tp_dict */ (descrgetfunc)classmethod_get, /* tp_descr_get */ 0, /* tp_descr_set */ }; static PyTypeObject PyMemberDescr_Type = { PyObject_HEAD_INIT(&PyType_Type) 0, "member_descriptor", sizeof(PyMemberDescrObject), 0, (destructor)descr_dealloc, /* tp_dealloc */ 0, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_compare */ (reprfunc)member_repr, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ 0, /* tp_as_mapping */ 0, /* tp_hash */ 0, /* tp_call */ 0, /* tp_str */ PyObject_GenericGetAttr, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ 0, /* tp_doc */ descr_traverse, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ 0, /* tp_iter */ 0, /* tp_iternext */ 0, /* tp_methods */ descr_members, /* tp_members */ member_getset, /* tp_getset */ 0, /* tp_base */ 0, /* tp_dict */ (descrgetfunc)member_get, /* tp_descr_get */ (descrsetfunc)member_set, /* tp_descr_set */ }; static PyTypeObject PyGetSetDescr_Type = { PyObject_HEAD_INIT(&PyType_Type)