diff options
author | Travis Oliphant <oliphant@enthought.com> | 2006-01-03 09:55:18 +0000 |
---|---|---|
committer | Travis Oliphant <oliphant@enthought.com> | 2006-01-03 09:55:18 +0000 |
commit | 95fc4486e429c82a872f3debcf09b0273fe2523e (patch) | |
tree | 73607005ea3d6985c55ebdd719945eb110cfe9be /scipy/base/src | |
parent | 4712a37b93832933a46376ee99339f9040ba3670 (diff) | |
download | numpy-95fc4486e429c82a872f3debcf09b0273fe2523e.tar.gz |
Forced fields to be a proxy object (read-only from Python) and added ability to document dynamically object attributes.
Diffstat (limited to 'scipy/base/src')
-rw-r--r-- | scipy/base/src/_compiled_base.c | 83 | ||||
-rw-r--r-- | scipy/base/src/arrayobject.c | 27 |
2 files changed, 76 insertions, 34 deletions
diff --git a/scipy/base/src/_compiled_base.c b/scipy/base/src/_compiled_base.c index 73637203f..3ce3743d7 100644 --- a/scipy/base/src/_compiled_base.c +++ b/scipy/base/src/_compiled_base.c @@ -1,4 +1,5 @@ #include "Python.h" +#include "structmember.h" #include "scipy/arrayobject.h" static PyObject *ErrorObject; @@ -335,6 +336,10 @@ arr_insert(PyObject *self, PyObject *args, PyObject *kwdict) return NULL; } + +static PyTypeObject *PyMemberDescr_TypePtr=NULL; +static PyTypeObject *PyGetSetDescr_TypePtr=NULL; + /* Can only be called if doc is currently NULL */ static PyObject * @@ -342,38 +347,47 @@ arr_add_docstring(PyObject *dummy, PyObject *args) { PyObject *obj; PyObject *str; + char *docstr; + static char *msg = "already has a docstring"; if (!PyArg_ParseTuple(args, "OO!", &obj, &PyString_Type, &str)) return NULL; - if (obj->ob_type == &PyCFunction_Type) { - if (!((PyCFunctionObject *)obj)->m_ml->ml_doc) { - ((PyCFunctionObject *)obj)->m_ml->ml_doc = \ - PyString_AS_STRING(str); - Py_INCREF(str); - } - else { + docstr = PyString_AS_STRING(str); + +#define _TESTDOC1(typebase) (obj->ob_type == &Py##typebase##_Type) +#define _TESTDOC2(typebase) (obj->ob_type == Py##typebase##_TypePtr) +#define _ADDDOC(typebase, doc, name) { \ + Py##typebase##Object *new = (Py##typebase##Object *)obj; \ + if (!(doc)) { \ + doc = docstr; \ + } \ + else { \ PyErr_Format(PyExc_RuntimeError, \ - "%s method already has a docstring", - ((PyCFunctionObject *)obj) \ - ->m_ml->ml_name); - return NULL; - } + "%s method %s",name, msg); \ + return NULL; \ + } \ } - else if (obj->ob_type == &PyType_Type) { - if (!((PyTypeObject *)obj)->tp_doc) { - ((PyTypeObject *)obj)->tp_doc = \ - PyString_AS_STRING(str); - Py_INCREF(str); - } - else { - PyErr_Format(PyExc_RuntimeError, \ - "%s type already has a docstring", - ((PyTypeObject *)obj)->tp_name); - return NULL; - } + + if _TESTDOC1(CFunction) + _ADDDOC(CFunction, new->m_ml->ml_doc, new->m_ml->ml_name) + else if _TESTDOC1(Type) + _ADDDOC(Type, new->tp_doc, new->tp_name) + else if _TESTDOC2(MemberDescr) + _ADDDOC(MemberDescr, new->d_member->doc, new->d_member->name) + else if _TESTDOC2(GetSetDescr) + _ADDDOC(GetSetDescr, new->d_getset->doc, new->d_getset->name) + else { + PyErr_SetString(PyExc_TypeError, + "Cannot set a docstring for that object"); + return NULL; } + +#undef _TESTDOC1 +#undef _TESTDOC2 +#undef _ADDDOC + Py_INCREF(str); Py_INCREF(Py_None); return Py_None; } @@ -390,6 +404,23 @@ static struct PyMethodDef methods[] = { {NULL, NULL} /* sentinel */ }; +static void +define_types(void) +{ + PyObject *tp_dict; + PyObject *myobj; + + tp_dict = PyArrayDescr_Type.tp_dict; + /* Get "subdescr" */ + myobj = PyDict_GetItemString(tp_dict, "fields"); + if (myobj == NULL) return; + PyGetSetDescr_TypePtr = myobj->ob_type; + myobj = PyDict_GetItemString(tp_dict, "alignment"); + if (myobj == NULL) return; + PyMemberDescr_TypePtr = myobj->ob_type; + return; +} + /* Initialization function for the module (*must* be called initArray) */ DL_EXPORT(void) init_compiled_base(void) { @@ -412,6 +443,10 @@ DL_EXPORT(void) init_compiled_base(void) { PyDict_SetItemString(d, "error", ErrorObject); Py_DECREF(ErrorObject); + + /* define PyGetSetDescr_Type and PyMemberDescr_Type */ + define_types(); + /* Check for errors */ if (PyErr_Occurred()) Py_FatalError("can't initialize module _compiled_base"); diff --git a/scipy/base/src/arrayobject.c b/scipy/base/src/arrayobject.c index bf218ae60..68b843fd6 100644 --- a/scipy/base/src/arrayobject.c +++ b/scipy/base/src/arrayobject.c @@ -7940,22 +7940,15 @@ arraydescr_dealloc(PyArray_Descr *self) /* we need to be careful about setting attributes because these objects are pointed to by arrays that depend on them for interpreting data. Currently no attributes of dtypedescr objects can be set. - *except* problematically the field attribute is a regular dictionary that - can be changed by the user. - - We have to trust the user not to do this... - Probably should make the fields dictionary a special "only-settable" from - C dictionary or something. */ static PyMemberDef arraydescr_members[] = { {"dtype", T_OBJECT, offsetof(PyArray_Descr, typeobj), RO, NULL}, - {"dtypekind", T_CHAR, offsetof(PyArray_Descr, kind), RO, NULL}, - {"dtypechar", T_CHAR, offsetof(PyArray_Descr, type), RO, NULL}, - {"dtypenum", T_INT, offsetof(PyArray_Descr, type_num), RO, NULL}, + {"kind", T_CHAR, offsetof(PyArray_Descr, kind), RO, NULL}, + {"char", T_CHAR, offsetof(PyArray_Descr, type), RO, NULL}, + {"num", T_INT, offsetof(PyArray_Descr, type_num), RO, NULL}, {"byteorder", T_CHAR, offsetof(PyArray_Descr, byteorder), RO, NULL}, {"itemsize", T_INT, offsetof(PyArray_Descr, elsize), RO, NULL}, {"alignment", T_INT, offsetof(PyArray_Descr, alignment), RO, NULL}, - {"fields", T_OBJECT, offsetof(PyArray_Descr, fields), RO, NULL}, {NULL}, }; @@ -8031,6 +8024,16 @@ arraydescr_isnative_get(PyArray_Descr *self) return ret; } +static PyObject * +arraydescr_fields_get(PyArray_Descr *self) +{ + if (self->fields == NULL || self->fields == Py_None) { + Py_INCREF(Py_None); + return Py_None; + } + return PyDictProxy_New(self->fields); +} + static PyGetSetDef arraydescr_getsets[] = { {"subdescr", (getter)arraydescr_subdescr_get, @@ -8052,6 +8055,10 @@ static PyGetSetDef arraydescr_getsets[] = { (getter)arraydescr_isnative_get, NULL, "Is the byte-order of this descriptor native?"}, + {"fields", + (getter)arraydescr_fields_get, + NULL, + NULL}, {NULL, NULL, NULL, NULL}, }; |