diff options
author | Guido van Rossum <guido@python.org> | 2001-09-20 20:46:19 (GMT) |
---|---|---|
committer | Guido van Rossum <guido@python.org> | 2001-09-20 20:46:19 (GMT) |
commit | 6f7993765ac0989b5d13084240797913627a31d8 (patch) | |
tree | 51dd234049db1eb78c6dd25d23ec687bf91d817c /Python/structmember.c | |
parent | e0af35eb694179d8da5d3208ffdfb92e5356335f (diff) | |
download | cpython-6f7993765ac0989b5d13084240797913627a31d8.zip cpython-6f7993765ac0989b5d13084240797913627a31d8.tar.gz cpython-6f7993765ac0989b5d13084240797913627a31d8.tar.bz2 |
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.
Diffstat (limited to 'Python/structmember.c')
-rw-r--r-- | Python/structmember.c | 415 |
1 files changed, 213 insertions, 202 deletions
diff --git a/Python/structmember.c b/Python/structmember.c index ed34783..077be70 100644 --- a/Python/structmember.c +++ b/Python/structmember.c @@ -32,226 +32,237 @@ PyObject * 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; +} |