summaryrefslogtreecommitdiffstats
path: root/Python/structmember.c
diff options
context:
space:
mode:
authorGuido van Rossum <guido@python.org>2001-09-20 20:46:19 (GMT)
committerGuido van Rossum <guido@python.org>2001-09-20 20:46:19 (GMT)
commit6f7993765ac0989b5d13084240797913627a31d8 (patch)
tree51dd234049db1eb78c6dd25d23ec687bf91d817c /Python/structmember.c
parente0af35eb694179d8da5d3208ffdfb92e5356335f (diff)
downloadcpython-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.c415
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, &copy);
}
}
-
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, &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
+#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;
+}