Commit 6f799376 authored by Guido van Rossum's avatar Guido van Rossum

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.
parent e0af35eb
...@@ -21,7 +21,7 @@ struct wrapperbase { ...@@ -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 *,
......
...@@ -274,7 +274,7 @@ typedef struct _typeobject { ...@@ -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;
......
...@@ -28,12 +28,22 @@ extern "C" { ...@@ -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 { ...@@ -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
......
...@@ -148,8 +148,9 @@ spamdict_init(spamdictobject *self, PyObject *args, PyObject *kwds) ...@@ -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}
}; };
......
...@@ -2006,10 +2006,13 @@ PyMethod_New(PyObject *func, PyObject *self, PyObject *class) ...@@ -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 */
}; };
......
...@@ -625,9 +625,11 @@ static PyMethodDef complex_methods[] = { ...@@ -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},
}; };
......
...@@ -21,7 +21,7 @@ typedef struct { ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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 = { ...@@ -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 = { ...@@ -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) ...@@ -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;
......
...@@ -1383,10 +1383,13 @@ static PyMethodDef file_methods[] = { ...@@ -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 */
}; };
......
...@@ -10,7 +10,7 @@ ...@@ -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},
......
...@@ -129,7 +129,7 @@ PyFunction_SetClosure(PyObject *op, PyObject *closure) ...@@ -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},
......
...@@ -9,7 +9,7 @@ typedef struct { ...@@ -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}
}; };
......
...@@ -129,7 +129,7 @@ slice_repr(PySliceObject *r) ...@@ -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},
......
...@@ -4,7 +4,7 @@ ...@@ -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 { ...@@ -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) ...@@ -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 = { ...@@ -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) ...@@ -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) ...@@ -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 { ...@@ -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}
}; };
......
...@@ -192,7 +192,7 @@ static struct PyMethodDef gen_methods[] = { ...@@ -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 */
......
...@@ -73,7 +73,7 @@ int Py_OptimizeFlag = 0; ...@@ -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},
......
...@@ -37,19 +37,33 @@ PyMember_Get(char *addr, struct memberlist *mlist, char *name) ...@@ -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) ...@@ -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) ...@@ -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;
}
int
PyMember_Set(char *addr, struct memberlist *mlist, char *name, PyObject *v)
{
struct memberlist *l;
for (l = mlist; l->name != NULL; l++) {
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); PyErr_SetString(PyExc_AttributeError, name);
return NULL; return -1;
} }
int int
PyMember_Set(char *addr, struct memberlist *mlist, char *name, PyObject *v) PyMember_SetOne(char *addr, PyMemberDef *l, PyObject *v)
{ {
struct memberlist *l;
PyObject *oldv; PyObject *oldv;
for (l = mlist; l->name != NULL; l++) {
if (strcmp(l->name, name) == 0) {
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) ...@@ -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) ...@@ -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) ...@@ -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;
} }
...@@ -106,7 +106,7 @@ ste_dealloc(PySymtableEntryObject *ste) ...@@ -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[] = { ...@@ -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 = { ...@@ -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 = { ...@@ -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 */
}; };
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment