summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTravis Oliphant <oliphant@enthought.com>2005-12-06 00:49:43 +0000
committerTravis Oliphant <oliphant@enthought.com>2005-12-06 00:49:43 +0000
commitcb2f58fe323d9753b45ecd9f877f6acb99c7c94b (patch)
tree3fcace566a0808e8d2897c31078faa4334ba041d
parent4772f10191f87a3446f4862de6d4b953e0dd95ff (diff)
downloadnumpy-cb2f58fe323d9753b45ecd9f877f6acb99c7c94b.tar.gz
Field specification possible with two-kinds of dictionaries
-rw-r--r--scipy/base/_internal.py47
-rw-r--r--scipy/base/numeric.py4
-rw-r--r--scipy/base/src/arraymethods.c2
-rw-r--r--scipy/base/src/arrayobject.c132
-rw-r--r--scipy/base/src/arraytypes.inc.src4
-rw-r--r--scipy/base/src/multiarraymodule.c39
-rw-r--r--scipy/base/src/scalartypes.inc.src9
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,