diff options
Diffstat (limited to 'scipy/base/src')
-rw-r--r-- | scipy/base/src/arrayobject.c | 17 | ||||
-rw-r--r-- | scipy/base/src/multiarraymodule.c | 70 | ||||
-rw-r--r-- | scipy/base/src/scalartypes.inc.src | 6 |
3 files changed, 61 insertions, 32 deletions
diff --git a/scipy/base/src/arrayobject.c b/scipy/base/src/arrayobject.c index bbcd99a6b..4906ac0c7 100644 --- a/scipy/base/src/arrayobject.c +++ b/scipy/base/src/arrayobject.c @@ -51,7 +51,6 @@ PyArray_PyIntAsIntp(PyObject *o) } else if (PyArray_IsScalar(o, Integer)) { arr = PyArray_FromScalar(o, descr); - Py_DECREF(descr); } if (arr != NULL) { ret = *((intp *)PyArray_DATA(arr)); @@ -124,7 +123,6 @@ PyArray_PyIntAsInt(PyObject *o) } if (PyArray_IsScalar(o, Integer)) { arr = PyArray_FromScalar(o, descr); - Py_DECREF(descr); } if (arr != NULL) { ret = *((int *)PyArray_DATA(arr)); @@ -4219,16 +4217,7 @@ array_descr_set(PyArrayObject *self, PyObject *arg) temp->descr = NULL; Py_DECREF(temp); } - - 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); @@ -6597,8 +6586,10 @@ iter_ass_subscript(PyArrayIterObject *self, PyObject *ind, PyObject *val) /* convert to INTP array if Integer array scalar or List */ indtype = PyArray_DescrFromType(PyArray_INTP); - if (PyArray_IsScalar(ind, Integer)) + if (PyArray_IsScalar(ind, Integer)) { + Py_INCREF(indtype); obj = PyArray_FromScalar(ind, indtype); + } else if (PyList_Check(ind)) { Py_INCREF(indtype); obj = PyArray_FromAny(ind, indtype, 0, 0, FORCECAST); diff --git a/scipy/base/src/multiarraymodule.c b/scipy/base/src/multiarraymodule.c index d8fd4bedf..70bc4e3c0 100644 --- a/scipy/base/src/multiarraymodule.c +++ b/scipy/base/src/multiarraymodule.c @@ -2693,39 +2693,80 @@ PyArray_IntpConverter(PyObject *obj, PyArray_Dims *seq) } +/* A tuple type would be either (generic typeobject, typesize) + or (fixed-length data-type, shape) + or (inheriting data-type, new-data-type) + The new data-type must have the same itemsize as the inheriting data-type + unless the latter is 0 in the final case. + + Thus (int32, {'real':(int16,0),'imag',(int16,2)}) - -/* A tuple type would be either (generic typeobject, typesize) - or (fixed-length, data-type, shape) - to indicate an array of a fixed-type. + is one way to specify a descriptor that will give + a['real'] and a['imag'] to an int32 array. */ +/* steal type reference */ +static PyArray_Descr * +_use_inherit(PyArray_Descr *type, PyObject *newobj) +{ + PyArray_Descr *new; + PyArray_Descr *conv; + + if (!PyArray_DescrConverter(newobj, &conv)) { + Py_DECREF(type); + return NULL; + } + new = PyArray_DescrNew(type); + Py_DECREF(type); + if (new == NULL) return NULL; + + if (new->elsize && new->elsize != conv->elsize) { + PyErr_SetString(PyExc_ValueError, + "mismatch in size of old"\ + "and new data-descriptor"); + return NULL; + } + + new->fields = conv->fields; + Py_INCREF(new->fields); + Py_DECREF(conv); + return new; +} + static PyArray_Descr * _convert_from_tuple(PyObject *obj) { PyArray_Descr *type; + PyObject *val; if (PyTuple_GET_SIZE(obj) < 2) return NULL; + if (!PyArray_DescrConverter(PyTuple_GET_ITEM(obj,0), &type)) return NULL; + val = PyTuple_GET_ITEM(obj,1); if (type->elsize == 0) { /* interpret next item as a typesize */ int itemsize; itemsize = PyArray_PyIntAsInt(PyTuple_GET_ITEM(obj,1)); - if (error_converting(itemsize)) goto fail; + if (error_converting(itemsize)) { + PyErr_Clear(); + return _use_inherit(type, val); + } PyArray_DESCR_REPLACE(type); type->elsize = itemsize; } - else { /* interpret next item as shape - and reset the type to PyArray_VOID with - a new fields attribute. + else { + /* interpret next item as shape + and reset the type to PyArray_VOID with + anew fields attribute. */ PyArray_Dims shape; PyArray_Descr *newdescr; - PyObject *val; - val = PyTuple_GET_ITEM(obj,1); if ((PyArray_IntpConverter(val, &shape) < 0) || \ - (shape.len > MAX_DIMS)) goto fail; + (shape.len > MAX_DIMS)) { + PyErr_Clear(); + return _use_inherit(type, val); + } newdescr = PyArray_DescrNew(type); if (newdescr == NULL) {PyDimMem_FREE(shape.ptr); goto fail;} newdescr->elsize *= PyArray_MultiplyList(shape.ptr, @@ -2749,8 +2790,7 @@ _convert_from_tuple(PyObject *obj) /* a dictionary specifying a data-type must have at least two and up to four - keys - These must all be sequences of the same length. + keys These must all be sequences of the same length. "names" --- field names "formats" --- the data-type descriptors for the field. @@ -2764,7 +2804,7 @@ _convert_from_tuple(PyObject *obj) "titles" --- Allows the use of an additional key for the fields dictionary. - + Attribute-lookup-based field names merely has to query the fields dictionary of the data-descriptor. Any result present can be used to return the correct field. @@ -2801,7 +2841,7 @@ _convert_from_dict(PyObject *obj) PyObject *names, *offsets, *descrs, *titles; int n, i; int totalsize; - + fields = PyDict_New(); if (fields == NULL) return (PyArray_Descr *)PyErr_NoMemory(); diff --git a/scipy/base/src/scalartypes.inc.src b/scipy/base/src/scalartypes.inc.src index 2fdec9b84..a437bc486 100644 --- a/scipy/base/src/scalartypes.inc.src +++ b/scipy/base/src/scalartypes.inc.src @@ -110,7 +110,7 @@ PyArray_CastScalarToCtype(PyObject *scalar, void *ctypeptr, /* 0-dim array from array-scalar object */ /* always contains a copy of the data */ -/* does nothing with outcode */ +/* steals reference to outcode */ static PyObject * PyArray_FromScalar(PyObject *scalar, PyArray_Descr *outcode) { @@ -125,7 +125,7 @@ PyArray_FromScalar(PyObject *scalar, PyArray_Descr *outcode) typecode, 0, NULL, NULL, NULL, 0, NULL); - if (r==NULL) return NULL; + if (r==NULL) {Py_XDECREF(outcode); return NULL;} switch(typecode->type_num) { case PyArray_STRING: @@ -159,7 +159,6 @@ PyArray_FromScalar(PyObject *scalar, PyArray_Descr *outcode) } /* cast if necessary to desired output typecode */ - Py_INCREF(outcode); ret = PyArray_CastToType((PyArrayObject *)r, outcode, 0); Py_DECREF(r); return ret; @@ -953,7 +952,6 @@ gentype_getarray(PyObject *scalar, PyObject *args) if (!PyArg_ParseTuple(args, "|O&", &PyArray_DescrConverter, &outcode)) return NULL; ret = PyArray_FromScalar(scalar, outcode); - Py_DECREF(outcode); return ret; } |