Add optional docstrings to member descriptors. For backwards

compatibility, this required all places where an array of "struct
memberlist" structures was declared that is referenced from a type's
tp_members slot to change the type of the structure to PyMemberDef;
"struct memberlist" is now only used by old code that still calls
PyMember_Get/Set.  The code in PyObject_GenericGetAttr/SetAttr now
calls the new APIs PyMember_GetOne/SetOne, which take a PyMemberDef
argument.

As examples, I added actual docstrings to the attributes of a few
types: file, complex, instance method, super, and xxsubtype.spamlist.

Also converted the symtable to new style getattr.
This commit is contained in:
Guido van Rossum 2001-09-20 20:46:19 +00:00
parent e0af35eb69
commit 6f7993765a
17 changed files with 313 additions and 251 deletions

View File

@ -21,7 +21,7 @@ struct wrapperbase {
extern DL_IMPORT(PyObject *) PyDescr_NewMethod(PyTypeObject *, PyMethodDef *); extern DL_IMPORT(PyObject *) PyDescr_NewMethod(PyTypeObject *, PyMethodDef *);
extern DL_IMPORT(PyObject *) PyDescr_NewMember(PyTypeObject *, extern DL_IMPORT(PyObject *) PyDescr_NewMember(PyTypeObject *,
struct memberlist *); struct PyMemberDef *);
extern DL_IMPORT(PyObject *) PyDescr_NewGetSet(PyTypeObject *, extern DL_IMPORT(PyObject *) PyDescr_NewGetSet(PyTypeObject *,
struct getsetlist *); struct getsetlist *);
extern DL_IMPORT(PyObject *) PyDescr_NewWrapper(PyTypeObject *, extern DL_IMPORT(PyObject *) PyDescr_NewWrapper(PyTypeObject *,

View File

@ -274,7 +274,7 @@ typedef struct _typeobject {
/* Attribute descriptor and subclassing stuff */ /* Attribute descriptor and subclassing stuff */
struct PyMethodDef *tp_methods; struct PyMethodDef *tp_methods;
struct memberlist *tp_members; struct PyMemberDef *tp_members;
struct getsetlist *tp_getset; struct getsetlist *tp_getset;
struct _typeobject *tp_base; struct _typeobject *tp_base;
PyObject *tp_dict; PyObject *tp_dict;

View File

@ -28,12 +28,22 @@ extern "C" {
pointer is NULL. */ pointer is NULL. */
struct memberlist { struct memberlist {
/* Obsolete version, for binary backwards compatibility */
char *name; char *name;
int type; int type;
int offset; int offset;
int flags; int flags;
}; };
typedef struct PyMemberDef {
/* Current version, use this */
char *name;
int type;
int offset;
int flags;
char *doc;
} PyMemberDef;
/* Types */ /* Types */
#define T_SHORT 0 #define T_SHORT 0
#define T_INT 1 #define T_INT 1
@ -66,9 +76,15 @@ struct memberlist {
#define RESTRICTED (READ_RESTRICTED | WRITE_RESTRICTED) #define RESTRICTED (READ_RESTRICTED | WRITE_RESTRICTED)
/* Obsolete API, for binary backwards compatibility */
DL_IMPORT(PyObject *) PyMember_Get(char *, struct memberlist *, char *); DL_IMPORT(PyObject *) PyMember_Get(char *, struct memberlist *, char *);
DL_IMPORT(int) PyMember_Set(char *, struct memberlist *, char *, PyObject *); 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 #ifdef __cplusplus
} }
#endif #endif

View File

@ -148,8 +148,9 @@ spamdict_init(spamdictobject *self, PyObject *args, PyObject *kwds)
return 0; return 0;
} }
static struct memberlist spamdict_members[] = { static PyMemberDef spamdict_members[] = {
{"state", T_INT, offsetof(spamdictobject, state), READONLY}, {"state", T_INT, offsetof(spamdictobject, state), READONLY,
"an int variable for demonstration purposes"},
{0} {0}
}; };

View File

@ -2006,10 +2006,13 @@ PyMethod_New(PyObject *func, PyObject *self, PyObject *class)
#define OFF(x) offsetof(PyMethodObject, x) #define OFF(x) offsetof(PyMethodObject, x)
static struct memberlist instancemethod_memberlist[] = { static PyMemberDef instancemethod_memberlist[] = {
{"im_class", T_OBJECT, OFF(im_class), READONLY|RESTRICTED}, {"im_class", T_OBJECT, OFF(im_class), READONLY|RESTRICTED,
{"im_func", T_OBJECT, OFF(im_func), READONLY|RESTRICTED}, "the class associated with a method"},
{"im_self", T_OBJECT, OFF(im_self), READONLY|RESTRICTED}, {"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} /* Sentinel */
}; };

View File

@ -625,9 +625,11 @@ static PyMethodDef complex_methods[] = {
{NULL, NULL} /* sentinel */ {NULL, NULL} /* sentinel */
}; };
static struct memberlist complex_members[] = { static PyMemberDef complex_members[] = {
{"real", T_DOUBLE, offsetof(PyComplexObject, cval.real), 0}, {"real", T_DOUBLE, offsetof(PyComplexObject, cval.real), 0,
{"imag", T_DOUBLE, offsetof(PyComplexObject, cval.imag), 0}, "the real part of a complex number"},
{"imag", T_DOUBLE, offsetof(PyComplexObject, cval.imag), 0,
"the imaginary part of a complex number"},
{0}, {0},
}; };

View File

@ -21,7 +21,7 @@ typedef struct {
typedef struct { typedef struct {
COMMON; COMMON;
struct memberlist *d_member; PyMemberDef *d_member;
} PyMemberDescrObject; } PyMemberDescrObject;
typedef struct { typedef struct {
@ -126,8 +126,7 @@ member_get(PyMemberDescrObject *descr, PyObject *obj, PyTypeObject *type)
if (descr_check((PyDescrObject *)descr, obj, type, &res)) if (descr_check((PyDescrObject *)descr, obj, type, &res))
return res; return res;
return PyMember_Get((char *)obj, descr->d_member, return PyMember_GetOne((char *)obj, descr->d_member);
descr->d_member->name);
} }
static PyObject * static PyObject *
@ -181,8 +180,7 @@ member_set(PyMemberDescrObject *descr, PyObject *obj, PyObject *value)
if (descr_setcheck((PyDescrObject *)descr, obj, value, &res)) if (descr_setcheck((PyDescrObject *)descr, obj, value, &res))
return res; return res;
return PyMember_Set((char *)obj, descr->d_member, return PyMember_SetOne((char *)obj, descr->d_member, value);
descr->d_member->name, value);
} }
static int static int
@ -289,7 +287,7 @@ wrapperdescr_call(PyWrapperDescrObject *descr, PyObject *args, PyObject *kwds)
} }
static PyObject * static PyObject *
member_get_doc(PyMethodDescrObject *descr, void *closure) method_get_doc(PyMethodDescrObject *descr, void *closure)
{ {
if (descr->d_method->ml_doc == NULL) { if (descr->d_method->ml_doc == NULL) {
Py_INCREF(Py_None); Py_INCREF(Py_None);
@ -298,12 +296,27 @@ member_get_doc(PyMethodDescrObject *descr, void *closure)
return PyString_FromString(descr->d_method->ml_doc); 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}, {"__objclass__", T_OBJECT, offsetof(PyDescrObject, d_type), READONLY},
{"__name__", T_OBJECT, offsetof(PyDescrObject, d_name), READONLY}, {"__name__", T_OBJECT, offsetof(PyDescrObject, d_name), READONLY},
{0} {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[] = { static struct getsetlist member_getset[] = {
{"__doc__", (getter)member_get_doc}, {"__doc__", (getter)member_get_doc},
{0} {0}
@ -355,7 +368,7 @@ static PyTypeObject PyMethodDescr_Type = {
0, /* tp_iternext */ 0, /* tp_iternext */
0, /* tp_methods */ 0, /* tp_methods */
descr_members, /* tp_members */ descr_members, /* tp_members */
member_getset, /* tp_getset */ method_getset, /* tp_getset */
0, /* tp_base */ 0, /* tp_base */
0, /* tp_dict */ 0, /* tp_dict */
(descrgetfunc)method_get, /* tp_descr_get */ (descrgetfunc)method_get, /* tp_descr_get */
@ -393,7 +406,7 @@ static PyTypeObject PyMemberDescr_Type = {
0, /* tp_iternext */ 0, /* tp_iternext */
0, /* tp_methods */ 0, /* tp_methods */
descr_members, /* tp_members */ descr_members, /* tp_members */
0, /* tp_getset */ member_getset, /* tp_getset */
0, /* tp_base */ 0, /* tp_base */
0, /* tp_dict */ 0, /* tp_dict */
(descrgetfunc)member_get, /* tp_descr_get */ (descrgetfunc)member_get, /* tp_descr_get */
@ -507,7 +520,7 @@ PyDescr_NewMethod(PyTypeObject *type, PyMethodDef *method)
} }
PyObject * PyObject *
PyDescr_NewMember(PyTypeObject *type, struct memberlist *member) PyDescr_NewMember(PyTypeObject *type, PyMemberDef *member)
{ {
PyMemberDescrObject *descr; PyMemberDescrObject *descr;

View File

@ -1383,10 +1383,13 @@ static PyMethodDef file_methods[] = {
#define OFF(x) offsetof(PyFileObject, x) #define OFF(x) offsetof(PyFileObject, x)
static struct memberlist file_memberlist[] = { static PyMemberDef file_memberlist[] = {
{"softspace", T_INT, OFF(f_softspace)}, {"softspace", T_INT, OFF(f_softspace), 0,
{"mode", T_OBJECT, OFF(f_mode), RO}, "flag indicating that a space needs to be printed; used by print"},
{"name", T_OBJECT, OFF(f_name), RO}, {"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 */ /* getattr(f, "closed") is implemented without this table */
{NULL} /* Sentinel */ {NULL} /* Sentinel */
}; };

View File

@ -10,7 +10,7 @@
#define OFF(x) offsetof(PyFrameObject, x) #define OFF(x) offsetof(PyFrameObject, x)
static struct memberlist frame_memberlist[] = { static PyMemberDef frame_memberlist[] = {
{"f_back", T_OBJECT, OFF(f_back), RO}, {"f_back", T_OBJECT, OFF(f_back), RO},
{"f_code", T_OBJECT, OFF(f_code), RO}, {"f_code", T_OBJECT, OFF(f_code), RO},
{"f_builtins", T_OBJECT, OFF(f_builtins),RO}, {"f_builtins", T_OBJECT, OFF(f_builtins),RO},

View File

@ -129,7 +129,7 @@ PyFunction_SetClosure(PyObject *op, PyObject *closure)
#define RR () #define RR ()
static struct memberlist func_memberlist[] = { static PyMemberDef func_memberlist[] = {
{"func_closure", T_OBJECT, OFF(func_closure), {"func_closure", T_OBJECT, OFF(func_closure),
RESTRICTED|READONLY}, RESTRICTED|READONLY},
{"func_doc", T_OBJECT, OFF(func_doc), WRITE_RESTRICTED}, {"func_doc", T_OBJECT, OFF(func_doc), WRITE_RESTRICTED},

View File

@ -9,7 +9,7 @@ typedef struct {
PyObject *md_dict; PyObject *md_dict;
} PyModuleObject; } PyModuleObject;
struct memberlist module_members[] = { PyMemberDef module_members[] = {
{"__dict__", T_OBJECT, offsetof(PyModuleObject, md_dict), READONLY}, {"__dict__", T_OBJECT, offsetof(PyModuleObject, md_dict), READONLY},
{0} {0}
}; };

View File

@ -129,7 +129,7 @@ slice_repr(PySliceObject *r)
return s; return s;
} }
static struct memberlist slice_members[] = { static PyMemberDef slice_members[] = {
{"start", T_OBJECT, offsetof(PySliceObject, start), READONLY}, {"start", T_OBJECT, offsetof(PySliceObject, start), READONLY},
{"stop", T_OBJECT, offsetof(PySliceObject, stop), READONLY}, {"stop", T_OBJECT, offsetof(PySliceObject, stop), READONLY},
{"step", T_OBJECT, offsetof(PySliceObject, step), READONLY}, {"step", T_OBJECT, offsetof(PySliceObject, step), READONLY},

View File

@ -4,7 +4,7 @@
#include "Python.h" #include "Python.h"
#include "structmember.h" #include "structmember.h"
static struct memberlist type_members[] = { static PyMemberDef type_members[] = {
{"__basicsize__", T_INT, offsetof(PyTypeObject,tp_basicsize),READONLY}, {"__basicsize__", T_INT, offsetof(PyTypeObject,tp_basicsize),READONLY},
{"__itemsize__", T_INT, offsetof(PyTypeObject, tp_itemsize), READONLY}, {"__itemsize__", T_INT, offsetof(PyTypeObject, tp_itemsize), READONLY},
{"__flags__", T_LONG, offsetof(PyTypeObject, tp_flags), READONLY}, {"__flags__", T_LONG, offsetof(PyTypeObject, tp_flags), READONLY},
@ -263,7 +263,7 @@ typedef struct {
PyMappingMethods as_mapping; PyMappingMethods as_mapping;
PyBufferProcs as_buffer; PyBufferProcs as_buffer;
PyObject *name, *slots; PyObject *name, *slots;
struct memberlist members[1]; PyMemberDef members[1];
} etype; } etype;
/* type test with subclassing support */ /* type test with subclassing support */
@ -672,7 +672,7 @@ type_new(PyTypeObject *metatype, PyObject *args, PyObject *kwds)
PyObject *slots, *tmp; PyObject *slots, *tmp;
PyTypeObject *type, *base, *tmptype, *winner; PyTypeObject *type, *base, *tmptype, *winner;
etype *et; etype *et;
struct memberlist *mp; PyMemberDef *mp;
int i, nbases, nslots, slotoffset, dynamic, add_dict, add_weak; int i, nbases, nslots, slotoffset, dynamic, add_dict, add_weak;
/* Special case: type(x) should return x->ob_type */ /* Special case: type(x) should return x->ob_type */
@ -1087,7 +1087,7 @@ PyTypeObject PyType_Type = {
0, /* ob_size */ 0, /* ob_size */
"type", /* tp_name */ "type", /* tp_name */
sizeof(etype), /* tp_basicsize */ sizeof(etype), /* tp_basicsize */
sizeof(struct memberlist), /* tp_itemsize */ sizeof(PyMemberDef), /* tp_itemsize */
(destructor)type_dealloc, /* tp_dealloc */ (destructor)type_dealloc, /* tp_dealloc */
0, /* tp_print */ 0, /* tp_print */
0, /* tp_getattr */ 0, /* tp_getattr */
@ -1192,7 +1192,7 @@ object_free(PyObject *self)
PyObject_Del(self); PyObject_Del(self);
} }
static struct memberlist object_members[] = { static PyMemberDef object_members[] = {
{"__class__", T_OBJECT, offsetof(PyObject, ob_type), READONLY}, {"__class__", T_OBJECT, offsetof(PyObject, ob_type), READONLY},
{0} {0}
}; };
@ -1263,7 +1263,7 @@ add_methods(PyTypeObject *type, PyMethodDef *meth)
} }
static int static int
add_members(PyTypeObject *type, struct memberlist *memb) add_members(PyTypeObject *type, PyMemberDef *memb)
{ {
PyObject *dict = type->tp_defined; PyObject *dict = type->tp_defined;
@ -3221,9 +3221,11 @@ typedef struct {
PyObject *obj; PyObject *obj;
} superobject; } superobject;
static struct memberlist super_members[] = { static PyMemberDef super_members[] = {
{"__type__", T_OBJECT, offsetof(superobject, type), READONLY}, {"__thisclass__", T_OBJECT, offsetof(superobject, type), READONLY,
{"__obj__", T_OBJECT, offsetof(superobject, obj), READONLY}, "the class invoking super()"},
{"__self__", T_OBJECT, offsetof(superobject, obj), READONLY,
"the instance invoking super(); may be None"},
{0} {0}
}; };

View File

@ -192,7 +192,7 @@ static struct PyMethodDef gen_methods[] = {
{NULL, NULL} /* Sentinel */ {NULL, NULL} /* Sentinel */
}; };
static struct memberlist gen_memberlist[] = { static PyMemberDef gen_memberlist[] = {
{"gi_frame", T_OBJECT, offsetof(genobject, gi_frame), RO}, {"gi_frame", T_OBJECT, offsetof(genobject, gi_frame), RO},
{"gi_running", T_INT, offsetof(genobject, gi_running), RO}, {"gi_running", T_INT, offsetof(genobject, gi_running), RO},
{NULL} /* Sentinel */ {NULL} /* Sentinel */

View File

@ -73,7 +73,7 @@ int Py_OptimizeFlag = 0;
#define OFF(x) offsetof(PyCodeObject, x) #define OFF(x) offsetof(PyCodeObject, x)
static struct memberlist code_memberlist[] = { static PyMemberDef code_memberlist[] = {
{"co_argcount", T_INT, OFF(co_argcount), READONLY}, {"co_argcount", T_INT, OFF(co_argcount), READONLY},
{"co_nlocals", T_INT, OFF(co_nlocals), READONLY}, {"co_nlocals", T_INT, OFF(co_nlocals), READONLY},
{"co_stacksize",T_INT, OFF(co_stacksize), READONLY}, {"co_stacksize",T_INT, OFF(co_stacksize), READONLY},

View File

@ -37,19 +37,33 @@ PyMember_Get(char *addr, struct memberlist *mlist, char *name)
return listmembers(mlist); return listmembers(mlist);
for (l = mlist; l->name != NULL; l++) { for (l = mlist; l->name != NULL; l++) {
if (strcmp(l->name, name) == 0) { if (strcmp(l->name, name) == 0) {
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, &copy);
}
}
PyErr_SetString(PyExc_AttributeError, name);
return NULL;
}
PyObject *
PyMember_GetOne(char *addr, PyMemberDef *l)
{
PyObject *v; PyObject *v;
if ((l->flags & READ_RESTRICTED) && if ((l->flags & READ_RESTRICTED) &&
PyEval_GetRestricted()) { PyEval_GetRestricted()) {
PyErr_SetString(PyExc_RuntimeError, PyErr_SetString(PyExc_RuntimeError, "restricted attribute");
"restricted attribute");
return NULL; return NULL;
} }
addr += l->offset; addr += l->offset;
switch (l->type) { switch (l->type) {
case T_BYTE: case T_BYTE:
v = PyInt_FromLong((long) v = PyInt_FromLong(
(((*(char*)addr & 0xff) (long) (((*(char*)addr & 0xff) ^ 0x80) - 0x80));
^ 0x80) - 0x80));
break; break;
case T_UBYTE: case T_UBYTE:
v = PyInt_FromLong((long) *(char*)addr & 0xff); v = PyInt_FromLong((long) *(char*)addr & 0xff);
@ -58,22 +72,19 @@ PyMember_Get(char *addr, struct memberlist *mlist, char *name)
v = PyInt_FromLong((long) *(short*)addr); v = PyInt_FromLong((long) *(short*)addr);
break; break;
case T_USHORT: case T_USHORT:
v = PyInt_FromLong((long) v = PyInt_FromLong((long) *(unsigned short*)addr);
*(unsigned short*)addr);
break; break;
case T_INT: case T_INT:
v = PyInt_FromLong((long) *(int*)addr); v = PyInt_FromLong((long) *(int*)addr);
break; break;
case T_UINT: case T_UINT:
v = PyInt_FromLong((long) v = PyInt_FromLong((long) *(unsigned int*)addr);
*(unsigned int*)addr);
break; break;
case T_LONG: case T_LONG:
v = PyInt_FromLong(*(long*)addr); v = PyInt_FromLong(*(long*)addr);
break; break;
case T_ULONG: case T_ULONG:
v = PyLong_FromDouble((double) v = PyLong_FromDouble((double) *(unsigned long*)addr);
*(unsigned long*)addr);
break; break;
case T_FLOAT: case T_FLOAT:
v = PyFloat_FromDouble((double)*(float*)addr); v = PyFloat_FromDouble((double)*(float*)addr);
@ -119,40 +130,49 @@ PyMember_Get(char *addr, struct memberlist *mlist, char *name)
Py_INCREF(v); Py_INCREF(v);
break; break;
default: default:
PyErr_SetString(PyExc_SystemError, PyErr_SetString(PyExc_SystemError, "bad memberdescr type");
"bad memberlist type");
v = NULL; v = NULL;
} }
return v; return v;
}
}
PyErr_SetString(PyExc_AttributeError, name);
return NULL;
} }
int int
PyMember_Set(char *addr, struct memberlist *mlist, char *name, PyObject *v) PyMember_Set(char *addr, struct memberlist *mlist, char *name, PyObject *v)
{ {
struct memberlist *l; struct memberlist *l;
PyObject *oldv;
for (l = mlist; l->name != NULL; l++) { for (l = mlist; l->name != NULL; l++) {
if (strcmp(l->name, name) == 0) { if (strcmp(l->name, name) == 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, &copy, 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 if ((l->flags & READONLY) || l->type == T_STRING
#ifdef macintosh #ifdef macintosh
|| l->type == T_PSTRING || l->type == T_PSTRING
#endif #endif
) )
{ {
PyErr_SetString(PyExc_TypeError, PyErr_SetString(PyExc_TypeError, "readonly attribute");
"readonly attribute");
return -1; return -1;
} }
if ((l->flags & WRITE_RESTRICTED) && if ((l->flags & WRITE_RESTRICTED) && PyEval_GetRestricted()) {
PyEval_GetRestricted()) { PyErr_SetString(PyExc_RuntimeError, "restricted attribute");
PyErr_SetString(PyExc_RuntimeError,
"restricted attribute");
return -1; return -1;
} }
if (v == NULL && l->type != T_OBJECT) { if (v == NULL && l->type != T_OBJECT) {
@ -217,8 +237,7 @@ PyMember_Set(char *addr, struct memberlist *mlist, char *name, PyObject *v)
break; break;
case T_DOUBLE: case T_DOUBLE:
if (PyInt_Check(v)) if (PyInt_Check(v))
*(double*)addr = *(double*)addr = (double) PyInt_AsLong(v);
(double) PyInt_AsLong(v);
else if (PyFloat_Check(v)) else if (PyFloat_Check(v))
*(double*)addr = PyFloat_AsDouble(v); *(double*)addr = PyFloat_AsDouble(v);
else { else {
@ -233,10 +252,8 @@ PyMember_Set(char *addr, struct memberlist *mlist, char *name, PyObject *v)
Py_XDECREF(oldv); Py_XDECREF(oldv);
break; break;
case T_CHAR: case T_CHAR:
if (PyString_Check(v) && if (PyString_Check(v) && PyString_Size(v) == 1) {
PyString_Size(v) == 1) { *(char*)addr = PyString_AsString(v)[0];
*(char*)addr =
PyString_AsString(v)[0];
} }
else { else {
PyErr_BadArgument(); PyErr_BadArgument();
@ -244,14 +261,8 @@ PyMember_Set(char *addr, struct memberlist *mlist, char *name, PyObject *v)
} }
break; break;
default: default:
PyErr_SetString(PyExc_SystemError, PyErr_SetString(PyExc_SystemError, "bad memberdescr type");
"bad memberlist type");
return -1; return -1;
} }
return 0; return 0;
}
}
PyErr_SetString(PyExc_AttributeError, name);
return -1;
} }

View File

@ -106,7 +106,7 @@ ste_dealloc(PySymtableEntryObject *ste)
#define OFF(x) offsetof(PySymtableEntryObject, x) #define OFF(x) offsetof(PySymtableEntryObject, x)
static struct memberlist ste_memberlist[] = { static PyMemberDef ste_memberlist[] = {
{"id", T_OBJECT, OFF(ste_id), READONLY}, {"id", T_OBJECT, OFF(ste_id), READONLY},
{"name", T_OBJECT, OFF(ste_name), READONLY}, {"name", T_OBJECT, OFF(ste_name), READONLY},
{"symbols", T_OBJECT, OFF(ste_symbols), READONLY}, {"symbols", T_OBJECT, OFF(ste_symbols), READONLY},
@ -119,12 +119,6 @@ static struct memberlist ste_memberlist[] = {
{NULL} {NULL}
}; };
static PyObject *
ste_getattr(PySymtableEntryObject *ste, char *name)
{
return PyMember_Get((char *)ste, ste_memberlist, name);
}
PyTypeObject PySymtableEntry_Type = { PyTypeObject PySymtableEntry_Type = {
PyObject_HEAD_INIT(&PyType_Type) PyObject_HEAD_INIT(&PyType_Type)
0, 0,
@ -133,7 +127,7 @@ PyTypeObject PySymtableEntry_Type = {
0, 0,
(destructor)ste_dealloc, /* tp_dealloc */ (destructor)ste_dealloc, /* tp_dealloc */
0, /* tp_print */ 0, /* tp_print */
(getattrfunc)ste_getattr, /* tp_getattr */ 0, /* tp_getattr */
0, /* tp_setattr */ 0, /* tp_setattr */
0, /* tp_compare */ 0, /* tp_compare */
(reprfunc)ste_repr, /* tp_repr */ (reprfunc)ste_repr, /* tp_repr */
@ -143,9 +137,26 @@ PyTypeObject PySymtableEntry_Type = {
0, /* tp_hash */ 0, /* tp_hash */
0, /* tp_call */ 0, /* tp_call */
0, /* tp_str */ 0, /* tp_str */
0, /* tp_getattro */ PyObject_GenericGetAttr, /* tp_getattro */
0, /* tp_setattro */ 0, /* tp_setattro */
0, /* tp_as_buffer */ 0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT, /* tp_flags */ Py_TPFLAGS_DEFAULT, /* tp_flags */
0, /* tp_doc */ 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 */
}; };