diff options
author | Travis Oliphant <oliphant@enthought.com> | 2005-12-06 00:49:43 +0000 |
---|---|---|
committer | Travis Oliphant <oliphant@enthought.com> | 2005-12-06 00:49:43 +0000 |
commit | cb2f58fe323d9753b45ecd9f877f6acb99c7c94b (patch) | |
tree | 3fcace566a0808e8d2897c31078faa4334ba041d | |
parent | 4772f10191f87a3446f4862de6d4b953e0dd95ff (diff) | |
download | numpy-cb2f58fe323d9753b45ecd9f877f6acb99c7c94b.tar.gz |
Field specification possible with two-kinds of dictionaries
-rw-r--r-- | scipy/base/_internal.py | 47 | ||||
-rw-r--r-- | scipy/base/numeric.py | 4 | ||||
-rw-r--r-- | scipy/base/src/arraymethods.c | 2 | ||||
-rw-r--r-- | scipy/base/src/arrayobject.c | 132 | ||||
-rw-r--r-- | scipy/base/src/arraytypes.inc.src | 4 | ||||
-rw-r--r-- | scipy/base/src/multiarraymodule.c | 39 | ||||
-rw-r--r-- | scipy/base/src/scalartypes.inc.src | 9 |
7 files changed, 155 insertions, 82 deletions
diff --git a/scipy/base/_internal.py b/scipy/base/_internal.py index 6d3aa611e..626a8439f 100644 --- a/scipy/base/_internal.py +++ b/scipy/base/_internal.py @@ -1,6 +1,6 @@ -from multiarray import _flagdict +from multiarray import _flagdict, dtypedescr _defflags = _flagdict.keys() @@ -186,3 +186,48 @@ class flagsobj(dict): carray = property(get_carray, None, "") farray = property(get_farray, None, "") + + +# make sure the tuple entries are PyArray_Descr +# or convert them +# +# make sure offsets are all interpretable +# as positive integers and +# convert them to positive integers if so +# +# +# return totalsize from last offset and size + +def _usefields(adict): + names = [] + formats = [] + offsets = [] + titles = [] + fnames = adict.keys() + for fname in fnames: + obj = adict[fname] + n = len(obj) + if not isinstance(obj, tuple) or n not in [2,3]: + raise ValueError, "entry not a 2- or 3- tuple" + if (n > 2) and (obj[2] == fname): + continue + num = int(obj[1]) + if (num < 0): + raise ValueError, "invalid offset." + names.append(fname) + offsets.append(num) + formats.append(dtypedescr(obj[0])) + if (n > 2): + title = obj[2] + else: + title = None + titles.append(title) + return dtypedescr({"names" : names, + "formats" : formats, + "offsets" : offsets, + "titles" : titles}) + + + + + diff --git a/scipy/base/numeric.py b/scipy/base/numeric.py index 28e351d66..895b5ce02 100644 --- a/scipy/base/numeric.py +++ b/scipy/base/numeric.py @@ -1,5 +1,5 @@ __all__ = ['newaxis', 'ndarray', 'bigndarray', 'flatiter', 'ufunc', - 'arange', 'array', 'zeros', 'empty', 'broadcast', 'datadescr', + 'arange', 'array', 'zeros', 'empty', 'broadcast', 'dtypedescr', 'fromstring', 'fromfile', 'frombuffer','newbuffer','getbuffer', 'where', 'concatenate', 'fastCopyAndTranspose', 'register_dtype', 'set_numeric_ops', 'can_cast', @@ -48,7 +48,7 @@ ndarray = multiarray.ndarray bigndarray = multiarray.bigndarray flatiter = multiarray.flatiter broadcast = multiarray.broadcast -datadescr=multiarray.datadescr +dtypedescr=multiarray.dtypedescr ufunc = type(sin) arange = multiarray.arange diff --git a/scipy/base/src/arraymethods.c b/scipy/base/src/arraymethods.c index d4b366709..48979599e 100644 --- a/scipy/base/src/arraymethods.c +++ b/scipy/base/src/arraymethods.c @@ -249,8 +249,6 @@ array_swapaxes(PyArrayObject *self, PyObject *args) return PyArray_SwapAxes(self, axis1, axis2); } -static int array_type_set(PyArrayObject *, PyObject *); - static char doc_getfield[] = "m.getfield(dtype, offset) returns a field "\ " of the given array as a certain type. A field is a view of "\ " the array's data with each itemsize determined by the given type"\ diff --git a/scipy/base/src/arrayobject.c b/scipy/base/src/arrayobject.c index 739fd5a68..bbcd99a6b 100644 --- a/scipy/base/src/arrayobject.c +++ b/scipy/base/src/arrayobject.c @@ -1828,7 +1828,6 @@ array_ass_sub(PyArrayObject *self, PyObject *index, PyObject *op) return -1; } - if (PyString_Check(index) || PyUnicode_Check(index)) { if (self->descr->fields) { PyObject *obj; @@ -4141,57 +4140,6 @@ array_descr_get(PyArrayObject *self) return (PyObject *)self->descr; } -static PyObject * -array_protocol_descr_get(PyArrayObject *self) -{ - PyObject *res; - PyObject *dobj; - - /* hand this off to the typeobject */ - /* or give default */ - if (PyArray_ISUSERDEF(self)) { - res = PyObject_GetAttrString((PyObject *)self->descr->typeobj, - "__array_descr__"); - if (res) return res; - PyErr_Clear(); - } - /* get default */ - dobj = PyTuple_New(2); - if (dobj == NULL) return NULL; - PyTuple_SET_ITEM(dobj, 0, PyString_FromString("")); - PyTuple_SET_ITEM(dobj, 1, array_typestr_get(self)); - res = PyList_New(1); - if (res == NULL) {Py_DECREF(dobj); return NULL;} - PyList_SET_ITEM(res, 0, dobj); - return res; -} - -static PyObject * -array_struct_get(PyArrayObject *self) -{ - PyArrayInterface *inter; - - inter = (PyArrayInterface *)malloc(sizeof(PyArrayInterface)); - inter->version = 2; - inter->nd = self->nd; - inter->typekind = self->descr->kind; - inter->itemsize = self->descr->elsize; - inter->flags = self->flags; - /* reset unused flags */ - inter->flags &= ~(UPDATEIFCOPY | OWNDATA); - inter->strides = self->strides; - inter->shape = self->dimensions; - inter->data = self->data; - Py_INCREF(self); - return PyCObject_FromVoidPtrAndDesc(inter, self, gentype_struct_free); -} - -static PyObject * -array_type_get(PyArrayObject *self) -{ - Py_INCREF(self->descr->typeobj); - return (PyObject *)self->descr->typeobj; -} /* If the type is changed. Also needing change: strides, itemsize @@ -4204,7 +4152,7 @@ array_type_get(PyArrayObject *self) */ static int -array_type_set(PyArrayObject *self, PyObject *arg) +array_descr_set(PyArrayObject *self, PyObject *arg) { PyArray_Descr *newtype=NULL; intp newdim; @@ -4263,16 +4211,25 @@ array_type_set(PyArrayObject *self, PyObject *arg) self->dimensions = temp->dimensions; self->nd = temp->nd; self->strides = temp->strides; - self->descr = temp->descr; + Py_DECREF(newtype); + newtype = temp->descr; /* Fool deallocator */ temp->nd = 0; temp->dimensions = NULL; temp->descr = NULL; Py_DECREF(temp); } - else { - self->descr = newtype; /* steal the reference */ - } + + if ((self->descr->elsize == newtype->elsize) && newtype->fields) { + PyArray_Descr *_thetype; + _thetype = PyArray_DescrNew(self->descr); + Py_XDECREF(_thetype->fields); + Py_INCREF(newtype->fields); + _thetype->fields = newtype->fields; + Py_DECREF(newtype); + newtype = _thetype; + } + self->descr = newtype; PyArray_UpdateFlags(self, UPDATE_ALL_FLAGS); return 0; @@ -4283,6 +4240,59 @@ array_type_set(PyArrayObject *self, PyObject *arg) return -1; } +static PyObject * +array_protocol_descr_get(PyArrayObject *self) +{ + PyObject *res; + PyObject *dobj; + + /* hand this off to the typeobject */ + /* or give default */ + if (PyArray_ISUSERDEF(self)) { + res = PyObject_GetAttrString((PyObject *)self->descr->typeobj, + "__array_descr__"); + if (res) return res; + PyErr_Clear(); + } + /* get default */ + dobj = PyTuple_New(2); + if (dobj == NULL) return NULL; + PyTuple_SET_ITEM(dobj, 0, PyString_FromString("")); + PyTuple_SET_ITEM(dobj, 1, array_typestr_get(self)); + res = PyList_New(1); + if (res == NULL) {Py_DECREF(dobj); return NULL;} + PyList_SET_ITEM(res, 0, dobj); + return res; +} + +static PyObject * +array_struct_get(PyArrayObject *self) +{ + PyArrayInterface *inter; + + inter = (PyArrayInterface *)malloc(sizeof(PyArrayInterface)); + inter->version = 2; + inter->nd = self->nd; + inter->typekind = self->descr->kind; + inter->itemsize = self->descr->elsize; + inter->flags = self->flags; + /* reset unused flags */ + inter->flags &= ~(UPDATEIFCOPY | OWNDATA); + inter->strides = self->strides; + inter->shape = self->dimensions; + inter->data = self->data; + Py_INCREF(self); + return PyCObject_FromVoidPtrAndDesc(inter, self, gentype_struct_free); +} + +static PyObject * +array_type_get(PyArrayObject *self) +{ + Py_INCREF(self->descr->typeobj); + return (PyObject *)self->descr->typeobj; +} + + static PyObject * array_base_get(PyArrayObject *self) @@ -4537,7 +4547,7 @@ static PyGetSetDef array_getsetlist[] = { "base object"}, {"dtype", (getter)array_type_get, - (setter)array_type_set, + NULL, "get array type class"}, {"dtypechar", (getter)array_typechar_get, @@ -4547,10 +4557,10 @@ static PyGetSetDef array_getsetlist[] = { (getter)array_typestr_get, NULL, "get array type string"}, - {"descr", + {"dtypedescr", (getter)array_descr_get, - NULL, - "get type descriptor for array"}, + (setter)array_descr_set, + "get(set) data-type-descriptor for array"}, {"real", (getter)array_real_get, (setter)array_real_set, diff --git a/scipy/base/src/arraytypes.inc.src b/scipy/base/src/arraytypes.inc.src index 04ac493ac..898d391b8 100644 --- a/scipy/base/src/arraytypes.inc.src +++ b/scipy/base/src/arraytypes.inc.src @@ -1474,7 +1474,7 @@ static PyArray_Descr @from@_Descr = { PyArray_@from@, 0, _ALIGN(@align@), NULL, - Py_NotImplemented, + NULL, { (PyArray_VectorUnaryFunc*)@from@_to_BOOL, @@ -1533,7 +1533,7 @@ static PyArray_Descr @from@_Descr = { @num@*sizeof(@fromtyp@), _ALIGN(@fromtyp@), NULL, - Py_NotImplemented, + NULL, { (PyArray_VectorUnaryFunc*)@from@_to_BOOL, diff --git a/scipy/base/src/multiarraymodule.c b/scipy/base/src/multiarraymodule.c index bfa4967a6..d8fd4bedf 100644 --- a/scipy/base/src/multiarraymodule.c +++ b/scipy/base/src/multiarraymodule.c @@ -2775,9 +2775,25 @@ arbitrary. What does distinguish a title, however, is that if it is not None, it will be placed at the end of the tuple inserted into the fields dictionary. + +If the dictionary does not have "names" and "formats" entries, +then it will be checked for conformity and used directly. */ static PyArray_Descr * +_use_fields_dict(PyObject *obj) +{ + static PyObject *module=NULL; + + if (module==NULL) { + module = PyImport_ImportModule("scipy.base._internal"); + if (module == NULL) return NULL; + } + return (PyArray_Descr *)PyObject_CallMethod(module, "_usefields", + "O", obj); +} + +static PyArray_Descr * _convert_from_dict(PyObject *obj) { PyArray_Descr *new; @@ -2786,23 +2802,19 @@ _convert_from_dict(PyObject *obj) int n, i; int totalsize; - new = PyArray_DescrNewFromType(PyArray_VOID); - if (new == NULL) return NULL; fields = PyDict_New(); - if (fields == NULL) goto fail; - + if (fields == NULL) return (PyArray_Descr *)PyErr_NoMemory(); + names = PyDict_GetItemString(obj, "names"); descrs = PyDict_GetItemString(obj, "formats"); - offsets = PyDict_GetItemString(obj, "offsets"); - titles = PyDict_GetItemString(obj, "titles"); if (!names || !descrs) { - PyErr_SetString(PyExc_ValueError, - "dictionary must have at least 'names', and"\ - " 'descrs' as keys"); - goto fail; + Py_DECREF(fields); + return _use_fields_dict(obj); } n = PyObject_Length(names); + offsets = PyDict_GetItemString(obj, "offsets"); + titles = PyDict_GetItemString(obj, "titles"); if ((n > PyObject_Length(descrs)) || \ (offsets && (n > PyObject_Length(offsets))) || \ (titles && (n > PyObject_Length(titles)))) { @@ -2851,12 +2863,13 @@ _convert_from_dict(PyObject *obj) if ((ret == PY_FAIL) || (newdescr->elsize == 0)) goto fail; } + new = PyArray_DescrNewFromType(PyArray_VOID); + if (new == NULL) goto fail; new->elsize = totalsize; new->fields = fields; return new; fail: - Py_XDECREF(new); Py_XDECREF(fields); return NULL; } @@ -4290,8 +4303,6 @@ setup_scalartypes(PyObject *dict) /* Clean up string and unicode array types so they act more like strings -- get their tables from the standard types. - - */ } @@ -4401,7 +4412,7 @@ DL_EXPORT(void) initmultiarray(void) { PyDict_SetItemString(d, "broadcast", (PyObject *)&PyArrayMultiIter_Type); Py_INCREF(&PyArrayDescr_Type); - PyDict_SetItemString(d, "datadescr", (PyObject *)&PyArrayDescr_Type); + PyDict_SetItemString(d, "dtypedescr", (PyObject *)&PyArrayDescr_Type); /* Doesn't need to be exposed to Python Py_INCREF(&PyArrayMapIter_Type); diff --git a/scipy/base/src/scalartypes.inc.src b/scipy/base/src/scalartypes.inc.src index c73bea9af..2fdec9b84 100644 --- a/scipy/base/src/scalartypes.inc.src +++ b/scipy/base/src/scalartypes.inc.src @@ -758,6 +758,11 @@ gentype_type_get(PyObject *self) return (PyObject *)self->ob_type; } +static PyObject * +gentype_typedescr_get(PyObject *self) +{ + return (PyObject *)PyArray_DescrFromScalar(self); +} static PyObject * gentype_base_get(PyObject *self) @@ -890,6 +895,10 @@ static PyGetSetDef gentype_getsets[] = { (getter)gentype_typestr_get, NULL, "get array type string"}, + {"dtypedescr", + (getter)gentype_typedescr_get, + NULL, + "get array data-descriptor"}, {"real", (getter)gentype_real_get, (setter)0, |