extern DL_IMPORT(PyObject *) PyDescr_NewMethod(PyTypeObject *, PyMethodDef *);
extern DL_IMPORT(PyObject *) PyDescr_NewMember(PyTypeObject *,
- struct memberlist *);
+ struct PyMemberDef *);
extern DL_IMPORT(PyObject *) PyDescr_NewGetSet(PyTypeObject *,
struct getsetlist *);
extern DL_IMPORT(PyObject *) PyDescr_NewWrapper(PyTypeObject *,
/* Attribute descriptor and subclassing stuff */
struct PyMethodDef *tp_methods;
- struct memberlist *tp_members;
+ struct PyMemberDef *tp_members;
struct getsetlist *tp_getset;
struct _typeobject *tp_base;
PyObject *tp_dict;
pointer is NULL. */
struct memberlist {
+ /* Obsolete version, for binary backwards compatibility */
char *name;
int type;
int offset;
int flags;
};
+typedef struct PyMemberDef {
+ /* Current version, use this */
+ char *name;
+ int type;
+ int offset;
+ int flags;
+ char *doc;
+} PyMemberDef;
+
/* Types */
#define T_SHORT 0
#define T_INT 1
#define RESTRICTED (READ_RESTRICTED | WRITE_RESTRICTED)
+/* Obsolete API, for binary backwards compatibility */
DL_IMPORT(PyObject *) PyMember_Get(char *, struct memberlist *, char *);
DL_IMPORT(int) PyMember_Set(char *, struct memberlist *, char *, PyObject *);
+/* Current API, use this */
+DL_IMPORT(PyObject *) PyMember_GetOne(char *, struct PyMemberDef *);
+DL_IMPORT(int) PyMember_SetOne(char *, struct PyMemberDef *, PyObject *);
+
+
#ifdef __cplusplus
}
#endif
return 0;
}
-static struct memberlist spamdict_members[] = {
- {"state", T_INT, offsetof(spamdictobject, state), READONLY},
+static PyMemberDef spamdict_members[] = {
+ {"state", T_INT, offsetof(spamdictobject, state), READONLY,
+ "an int variable for demonstration purposes"},
{0}
};
#define OFF(x) offsetof(PyMethodObject, x)
-static struct memberlist instancemethod_memberlist[] = {
- {"im_class", T_OBJECT, OFF(im_class), READONLY|RESTRICTED},
- {"im_func", T_OBJECT, OFF(im_func), READONLY|RESTRICTED},
- {"im_self", T_OBJECT, OFF(im_self), READONLY|RESTRICTED},
+static PyMemberDef instancemethod_memberlist[] = {
+ {"im_class", T_OBJECT, OFF(im_class), READONLY|RESTRICTED,
+ "the class associated with a method"},
+ {"im_func", T_OBJECT, OFF(im_func), READONLY|RESTRICTED,
+ "the function (or other callable) implementing a method"},
+ {"im_self", T_OBJECT, OFF(im_self), READONLY|RESTRICTED,
+ "the instance to which a method is bound; None for unbound methods"},
{NULL} /* Sentinel */
};
{NULL, NULL} /* sentinel */
};
-static struct memberlist complex_members[] = {
- {"real", T_DOUBLE, offsetof(PyComplexObject, cval.real), 0},
- {"imag", T_DOUBLE, offsetof(PyComplexObject, cval.imag), 0},
+static PyMemberDef complex_members[] = {
+ {"real", T_DOUBLE, offsetof(PyComplexObject, cval.real), 0,
+ "the real part of a complex number"},
+ {"imag", T_DOUBLE, offsetof(PyComplexObject, cval.imag), 0,
+ "the imaginary part of a complex number"},
{0},
};
typedef struct {
COMMON;
- struct memberlist *d_member;
+ PyMemberDef *d_member;
} PyMemberDescrObject;
typedef struct {
if (descr_check((PyDescrObject *)descr, obj, type, &res))
return res;
- return PyMember_Get((char *)obj, descr->d_member,
- descr->d_member->name);
+ return PyMember_GetOne((char *)obj, descr->d_member);
}
static PyObject *
if (descr_setcheck((PyDescrObject *)descr, obj, value, &res))
return res;
- return PyMember_Set((char *)obj, descr->d_member,
- descr->d_member->name, value);
+ return PyMember_SetOne((char *)obj, descr->d_member, value);
}
static int
}
static PyObject *
-member_get_doc(PyMethodDescrObject *descr, void *closure)
+method_get_doc(PyMethodDescrObject *descr, void *closure)
{
if (descr->d_method->ml_doc == NULL) {
Py_INCREF(Py_None);
return PyString_FromString(descr->d_method->ml_doc);
}
-static struct memberlist descr_members[] = {
+static PyMemberDef descr_members[] = {
{"__objclass__", T_OBJECT, offsetof(PyDescrObject, d_type), READONLY},
{"__name__", T_OBJECT, offsetof(PyDescrObject, d_name), READONLY},
{0}
};
+static struct getsetlist 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 struct getsetlist member_getset[] = {
{"__doc__", (getter)member_get_doc},
{0}
0, /* tp_iternext */
0, /* tp_methods */
descr_members, /* tp_members */
- member_getset, /* tp_getset */
+ method_getset, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
(descrgetfunc)method_get, /* tp_descr_get */
0, /* tp_iternext */
0, /* tp_methods */
descr_members, /* tp_members */
- 0, /* tp_getset */
+ member_getset, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
(descrgetfunc)member_get, /* tp_descr_get */
}
PyObject *
-PyDescr_NewMember(PyTypeObject *type, struct memberlist *member)
+PyDescr_NewMember(PyTypeObject *type, PyMemberDef *member)
{
PyMemberDescrObject *descr;
#define OFF(x) offsetof(PyFileObject, x)
-static struct memberlist file_memberlist[] = {
- {"softspace", T_INT, OFF(f_softspace)},
- {"mode", T_OBJECT, OFF(f_mode), RO},
- {"name", T_OBJECT, OFF(f_name), RO},
+static PyMemberDef file_memberlist[] = {
+ {"softspace", T_INT, OFF(f_softspace), 0,
+ "flag indicating that a space needs to be printed; used by print"},
+ {"mode", T_OBJECT, OFF(f_mode), RO,
+ "file mode ('r', 'w', 'a', possibly with 'b' or '+' added)"},
+ {"name", T_OBJECT, OFF(f_name), RO,
+ "file name"},
/* getattr(f, "closed") is implemented without this table */
{NULL} /* Sentinel */
};
#define OFF(x) offsetof(PyFrameObject, x)
-static struct memberlist frame_memberlist[] = {
+static PyMemberDef frame_memberlist[] = {
{"f_back", T_OBJECT, OFF(f_back), RO},
{"f_code", T_OBJECT, OFF(f_code), RO},
{"f_builtins", T_OBJECT, OFF(f_builtins),RO},
#define RR ()
-static struct memberlist func_memberlist[] = {
+static PyMemberDef func_memberlist[] = {
{"func_closure", T_OBJECT, OFF(func_closure),
RESTRICTED|READONLY},
{"func_doc", T_OBJECT, OFF(func_doc), WRITE_RESTRICTED},
PyObject *md_dict;
} PyModuleObject;
-struct memberlist module_members[] = {
+PyMemberDef module_members[] = {
{"__dict__", T_OBJECT, offsetof(PyModuleObject, md_dict), READONLY},
{0}
};
return s;
}
-static struct memberlist slice_members[] = {
+static PyMemberDef slice_members[] = {
{"start", T_OBJECT, offsetof(PySliceObject, start), READONLY},
{"stop", T_OBJECT, offsetof(PySliceObject, stop), READONLY},
{"step", T_OBJECT, offsetof(PySliceObject, step), READONLY},
#include "Python.h"
#include "structmember.h"
-static struct memberlist type_members[] = {
+static PyMemberDef type_members[] = {
{"__basicsize__", T_INT, offsetof(PyTypeObject,tp_basicsize),READONLY},
{"__itemsize__", T_INT, offsetof(PyTypeObject, tp_itemsize), READONLY},
{"__flags__", T_LONG, offsetof(PyTypeObject, tp_flags), READONLY},
PyMappingMethods as_mapping;
PyBufferProcs as_buffer;
PyObject *name, *slots;
- struct memberlist members[1];
+ PyMemberDef members[1];
} etype;
/* type test with subclassing support */
PyObject *slots, *tmp;
PyTypeObject *type, *base, *tmptype, *winner;
etype *et;
- struct memberlist *mp;
+ PyMemberDef *mp;
int i, nbases, nslots, slotoffset, dynamic, add_dict, add_weak;
/* Special case: type(x) should return x->ob_type */
0, /* ob_size */
"type", /* tp_name */
sizeof(etype), /* tp_basicsize */
- sizeof(struct memberlist), /* tp_itemsize */
+ sizeof(PyMemberDef), /* tp_itemsize */
(destructor)type_dealloc, /* tp_dealloc */
0, /* tp_print */
0, /* tp_getattr */
PyObject_Del(self);
}
-static struct memberlist object_members[] = {
+static PyMemberDef object_members[] = {
{"__class__", T_OBJECT, offsetof(PyObject, ob_type), READONLY},
{0}
};
}
static int
-add_members(PyTypeObject *type, struct memberlist *memb)
+add_members(PyTypeObject *type, PyMemberDef *memb)
{
PyObject *dict = type->tp_defined;
PyObject *obj;
} superobject;
-static struct memberlist super_members[] = {
- {"__type__", T_OBJECT, offsetof(superobject, type), READONLY},
- {"__obj__", T_OBJECT, offsetof(superobject, obj), READONLY},
+static PyMemberDef super_members[] = {
+ {"__thisclass__", T_OBJECT, offsetof(superobject, type), READONLY,
+ "the class invoking super()"},
+ {"__self__", T_OBJECT, offsetof(superobject, obj), READONLY,
+ "the instance invoking super(); may be None"},
{0}
};
{NULL, NULL} /* Sentinel */
};
-static struct memberlist gen_memberlist[] = {
+static PyMemberDef gen_memberlist[] = {
{"gi_frame", T_OBJECT, offsetof(genobject, gi_frame), RO},
{"gi_running", T_INT, offsetof(genobject, gi_running), RO},
{NULL} /* Sentinel */
#define OFF(x) offsetof(PyCodeObject, x)
-static struct memberlist code_memberlist[] = {
+static PyMemberDef code_memberlist[] = {
{"co_argcount", T_INT, OFF(co_argcount), READONLY},
{"co_nlocals", T_INT, OFF(co_nlocals), READONLY},
{"co_stacksize",T_INT, OFF(co_stacksize), READONLY},
PyMember_Get(char *addr, struct memberlist *mlist, char *name)
{
struct memberlist *l;
-
+
if (strcmp(name, "__members__") == 0)
return listmembers(mlist);
for (l = mlist; l->name != NULL; l++) {
if (strcmp(l->name, name) == 0) {
- PyObject *v;
- if ((l->flags & READ_RESTRICTED) &&
- PyEval_GetRestricted()) {
- PyErr_SetString(PyExc_RuntimeError,
- "restricted attribute");
- return NULL;
- }
- addr += l->offset;
- switch (l->type) {
- case T_BYTE:
- v = PyInt_FromLong((long)
- (((*(char*)addr & 0xff)
- ^ 0x80) - 0x80));
- break;
- case T_UBYTE:
- v = PyInt_FromLong((long) *(char*)addr & 0xff);
- break;
- case T_SHORT:
- v = PyInt_FromLong((long) *(short*)addr);
- break;
- case T_USHORT:
- v = PyInt_FromLong((long)
- *(unsigned short*)addr);
- break;
- case T_INT:
- v = PyInt_FromLong((long) *(int*)addr);
- break;
- case T_UINT:
- v = PyInt_FromLong((long)
- *(unsigned int*)addr);
- break;
- case T_LONG:
- v = PyInt_FromLong(*(long*)addr);
- break;
- case T_ULONG:
- v = PyLong_FromDouble((double)
- *(unsigned long*)addr);
- break;
- case T_FLOAT:
- v = PyFloat_FromDouble((double)*(float*)addr);
- break;
- case T_DOUBLE:
- v = PyFloat_FromDouble(*(double*)addr);
- break;
- case T_STRING:
- if (*(char**)addr == NULL) {
- Py_INCREF(Py_None);
- v = Py_None;
- }
- else
- v = PyString_FromString(*(char**)addr);
- break;
- case T_STRING_INPLACE:
- v = PyString_FromString((char*)addr);
- break;
-#ifdef macintosh
- case T_PSTRING:
- if (*(char**)addr == NULL) {
- Py_INCREF(Py_None);
- v = Py_None;
- }
- else
- v = PyString_FromStringAndSize(
- (*(char**)addr)+1,
- **(unsigned char**)addr);
- break;
- case T_PSTRING_INPLACE:
- v = PyString_FromStringAndSize(
- ((char*)addr)+1,
- *(unsigned char*)addr);
- break;
-#endif /* macintosh */
- case T_CHAR:
- v = PyString_FromStringAndSize((char*)addr, 1);
- break;
- case T_OBJECT:
- v = *(PyObject **)addr;
- if (v == NULL)
- v = Py_None;
- Py_INCREF(v);
- break;
- default:
- PyErr_SetString(PyExc_SystemError,
- "bad memberlist type");
- v = NULL;
- }
- return v;
+ PyMemberDef copy;
+ copy.name = l->name;
+ copy.type = l->type;
+ copy.offset = l->offset;
+ copy.flags = l->flags;
+ copy.doc = NULL;
+ return PyMember_GetOne(addr, ©);
}
}
-
PyErr_SetString(PyExc_AttributeError, name);
return NULL;
}
+PyObject *
+PyMember_GetOne(char *addr, PyMemberDef *l)
+{
+ PyObject *v;
+ if ((l->flags & READ_RESTRICTED) &&
+ PyEval_GetRestricted()) {
+ PyErr_SetString(PyExc_RuntimeError, "restricted attribute");
+ return NULL;
+ }
+ addr += l->offset;
+ switch (l->type) {
+ case T_BYTE:
+ v = PyInt_FromLong(
+ (long) (((*(char*)addr & 0xff) ^ 0x80) - 0x80));
+ break;
+ case T_UBYTE:
+ v = PyInt_FromLong((long) *(char*)addr & 0xff);
+ break;
+ case T_SHORT:
+ v = PyInt_FromLong((long) *(short*)addr);
+ break;
+ case T_USHORT:
+ v = PyInt_FromLong((long) *(unsigned short*)addr);
+ break;
+ case T_INT:
+ v = PyInt_FromLong((long) *(int*)addr);
+ break;
+ case T_UINT:
+ v = PyInt_FromLong((long) *(unsigned int*)addr);
+ break;
+ case T_LONG:
+ v = PyInt_FromLong(*(long*)addr);
+ break;
+ case T_ULONG:
+ v = PyLong_FromDouble((double) *(unsigned long*)addr);
+ break;
+ case T_FLOAT:
+ v = PyFloat_FromDouble((double)*(float*)addr);
+ break;
+ case T_DOUBLE:
+ v = PyFloat_FromDouble(*(double*)addr);
+ break;
+ case T_STRING:
+ if (*(char**)addr == NULL) {
+ Py_INCREF(Py_None);
+ v = Py_None;
+ }
+ else
+ v = PyString_FromString(*(char**)addr);
+ break;
+ case T_STRING_INPLACE:
+ v = PyString_FromString((char*)addr);
+ break;
+#ifdef macintosh
+ case T_PSTRING:
+ if (*(char**)addr == NULL) {
+ Py_INCREF(Py_None);
+ v = Py_None;
+ }
+ else
+ v = PyString_FromStringAndSize(
+ (*(char**)addr)+1,
+ **(unsigned char**)addr);
+ break;
+ case T_PSTRING_INPLACE:
+ v = PyString_FromStringAndSize(
+ ((char*)addr)+1,
+ *(unsigned char*)addr);
+ break;
+#endif /* macintosh */
+ case T_CHAR:
+ v = PyString_FromStringAndSize((char*)addr, 1);
+ break;
+ case T_OBJECT:
+ v = *(PyObject **)addr;
+ if (v == NULL)
+ v = Py_None;
+ Py_INCREF(v);
+ break;
+ default:
+ PyErr_SetString(PyExc_SystemError, "bad memberdescr type");
+ v = NULL;
+ }
+ return v;
+}
+
int
PyMember_Set(char *addr, struct memberlist *mlist, char *name, PyObject *v)
{
struct memberlist *l;
- PyObject *oldv;
-
+
for (l = mlist; l->name != NULL; l++) {
if (strcmp(l->name, name) == 0) {
- if ((l->flags & READONLY) || l->type == T_STRING
-#ifdef macintosh
- || l->type == T_PSTRING
-#endif
- )
- {
- PyErr_SetString(PyExc_TypeError,
- "readonly attribute");
- return -1;
- }
- if ((l->flags & WRITE_RESTRICTED) &&
- PyEval_GetRestricted()) {
- PyErr_SetString(PyExc_RuntimeError,
- "restricted attribute");
- return -1;
- }
- if (v == NULL && l->type != T_OBJECT) {
- PyErr_SetString(PyExc_TypeError,
- "can't delete numeric/char attribute");
- return -1;
- }
- addr += l->offset;
- switch (l->type) {
- case T_BYTE:
- case T_UBYTE:
- if (!PyInt_Check(v)) {
- PyErr_BadArgument();
- return -1;
- }
- *(char*)addr = (char) PyInt_AsLong(v);
- break;
- case T_SHORT:
- case T_USHORT:
- if (!PyInt_Check(v)) {
- PyErr_BadArgument();
- return -1;
- }
- *(short*)addr = (short) PyInt_AsLong(v);
- break;
- case T_UINT:
- case T_INT:
- if (!PyInt_Check(v)) {
- PyErr_BadArgument();
- return -1;
- }
- *(int*)addr = (int) PyInt_AsLong(v);
- break;
- case T_LONG:
- if (!PyInt_Check(v)) {
- PyErr_BadArgument();
- return -1;
- }
- *(long*)addr = PyInt_AsLong(v);
- break;
- case T_ULONG:
- if (PyInt_Check(v))
- *(long*)addr = PyInt_AsLong(v);
- else if (PyLong_Check(v))
- *(long*)addr = PyLong_AsLong(v);
- else {
- PyErr_BadArgument();
- return -1;
- }
- break;
- case T_FLOAT:
- if (PyInt_Check(v))
- *(float*)addr =
- (float) PyInt_AsLong(v);
- else if (PyFloat_Check(v))
- *(float*)addr =
- (float) PyFloat_AsDouble(v);
- else {
- PyErr_BadArgument();
- return -1;
- }
- break;
- case T_DOUBLE:
- if (PyInt_Check(v))
- *(double*)addr =
- (double) PyInt_AsLong(v);
- else if (PyFloat_Check(v))
- *(double*)addr = PyFloat_AsDouble(v);
- else {
- PyErr_BadArgument();
- return -1;
- }
- break;
- case T_OBJECT:
- Py_XINCREF(v);
- oldv = *(PyObject **)addr;
- *(PyObject **)addr = v;
- Py_XDECREF(oldv);
- break;
- case T_CHAR:
- if (PyString_Check(v) &&
- PyString_Size(v) == 1) {
- *(char*)addr =
- PyString_AsString(v)[0];
- }
- else {
- PyErr_BadArgument();
- return -1;
- }
- break;
- default:
- PyErr_SetString(PyExc_SystemError,
- "bad memberlist type");
- return -1;
- }
- return 0;
+ PyMemberDef copy;
+ copy.name = l->name;
+ copy.type = l->type;
+ copy.offset = l->offset;
+ copy.flags = l->flags;
+ copy.doc = NULL;
+ return PyMember_SetOne(addr, ©, v);
}
}
-
+
PyErr_SetString(PyExc_AttributeError, name);
return -1;
}
+
+int
+PyMember_SetOne(char *addr, PyMemberDef *l, PyObject *v)
+{
+ PyObject *oldv;
+
+ if ((l->flags & READONLY) || l->type == T_STRING
+#ifdef macintosh
+ || l->type == T_PSTRING
+#endif
+ )
+ {
+ PyErr_SetString(PyExc_TypeError, "readonly attribute");
+ return -1;
+ }
+ if ((l->flags & WRITE_RESTRICTED) && PyEval_GetRestricted()) {
+ PyErr_SetString(PyExc_RuntimeError, "restricted attribute");
+ return -1;
+ }
+ if (v == NULL && l->type != T_OBJECT) {
+ PyErr_SetString(PyExc_TypeError,
+ "can't delete numeric/char attribute");
+ return -1;
+ }
+ addr += l->offset;
+ switch (l->type) {
+ case T_BYTE:
+ case T_UBYTE:
+ if (!PyInt_Check(v)) {
+ PyErr_BadArgument();
+ return -1;
+ }
+ *(char*)addr = (char) PyInt_AsLong(v);
+ break;
+ case T_SHORT:
+ case T_USHORT:
+ if (!PyInt_Check(v)) {
+ PyErr_BadArgument();
+ return -1;
+ }
+ *(short*)addr = (short) PyInt_AsLong(v);
+ break;
+ case T_UINT:
+ case T_INT:
+ if (!PyInt_Check(v)) {
+ PyErr_BadArgument();
+ return -1;
+ }
+ *(int*)addr = (int) PyInt_AsLong(v);
+ break;
+ case T_LONG:
+ if (!PyInt_Check(v)) {
+ PyErr_BadArgument();
+ return -1;
+ }
+ *(long*)addr = PyInt_AsLong(v);
+ break;
+ case T_ULONG:
+ if (PyInt_Check(v))
+ *(long*)addr = PyInt_AsLong(v);
+ else if (PyLong_Check(v))
+ *(long*)addr = PyLong_AsLong(v);
+ else {
+ PyErr_BadArgument();
+ return -1;
+ }
+ break;
+ case T_FLOAT:
+ if (PyInt_Check(v))
+ *(float*)addr =
+ (float) PyInt_AsLong(v);
+ else if (PyFloat_Check(v))
+ *(float*)addr =
+ (float) PyFloat_AsDouble(v);
+ else {
+ PyErr_BadArgument();
+ return -1;
+ }
+ break;
+ case T_DOUBLE:
+ if (PyInt_Check(v))
+ *(double*)addr = (double) PyInt_AsLong(v);
+ else if (PyFloat_Check(v))
+ *(double*)addr = PyFloat_AsDouble(v);
+ else {
+ PyErr_BadArgument();
+ return -1;
+ }
+ break;
+ case T_OBJECT:
+ Py_XINCREF(v);
+ oldv = *(PyObject **)addr;
+ *(PyObject **)addr = v;
+ Py_XDECREF(oldv);
+ break;
+ case T_CHAR:
+ if (PyString_Check(v) && PyString_Size(v) == 1) {
+ *(char*)addr = PyString_AsString(v)[0];
+ }
+ else {
+ PyErr_BadArgument();
+ return -1;
+ }
+ break;
+ default:
+ PyErr_SetString(PyExc_SystemError, "bad memberdescr type");
+ return -1;
+ }
+ return 0;
+}
#define OFF(x) offsetof(PySymtableEntryObject, x)
-static struct memberlist ste_memberlist[] = {
+static PyMemberDef ste_memberlist[] = {
{"id", T_OBJECT, OFF(ste_id), READONLY},
{"name", T_OBJECT, OFF(ste_name), READONLY},
{"symbols", T_OBJECT, OFF(ste_symbols), READONLY},
{NULL}
};
-static PyObject *
-ste_getattr(PySymtableEntryObject *ste, char *name)
-{
- return PyMember_Get((char *)ste, ste_memberlist, name);
-}
-
PyTypeObject PySymtableEntry_Type = {
PyObject_HEAD_INIT(&PyType_Type)
0,
0,
(destructor)ste_dealloc, /* tp_dealloc */
0, /* tp_print */
- (getattrfunc)ste_getattr, /* tp_getattr */
+ 0, /* tp_getattr */
0, /* tp_setattr */
0, /* tp_compare */
(reprfunc)ste_repr, /* tp_repr */
0, /* tp_hash */
0, /* tp_call */
0, /* tp_str */
- 0, /* tp_getattro */
+ PyObject_GenericGetAttr, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT, /* tp_flags */
0, /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ 0, /* tp_methods */
+ ste_memberlist, /* tp_members */
+ 0, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ 0, /* tp_init */
+ 0, /* tp_alloc */
+ 0, /* tp_new */
};