diff options
author | Travis Oliphant <oliphant@enthought.com> | 2005-11-30 09:30:51 +0000 |
---|---|---|
committer | Travis Oliphant <oliphant@enthought.com> | 2005-11-30 09:30:51 +0000 |
commit | 8dfbf5d48d60c741a066c2e86ee9b4aed5d370a1 (patch) | |
tree | d87b93b538b149f8c390fb4695495de9db7e283d | |
parent | 0376164cffd1b64f276f2a04c922e1c1727f57d4 (diff) | |
download | numpy-8dfbf5d48d60c741a066c2e86ee9b4aed5d370a1.tar.gz |
Fixed up ndchararray a bit. Fixed up use of registered data types.
-rw-r--r-- | scipy/base/chararray.py | 289 | ||||
-rw-r--r-- | scipy/base/matrix.py | 3 | ||||
-rw-r--r-- | scipy/base/numeric.py | 4 | ||||
-rw-r--r-- | scipy/base/records.py | 12 | ||||
-rw-r--r-- | scipy/base/src/arrayobject.c | 59 | ||||
-rw-r--r-- | scipy/base/src/multiarraymodule.c | 11 | ||||
-rw-r--r-- | scipy/base/src/scalartypes.inc.src | 35 | ||||
-rw-r--r-- | scipy/base/src/ufuncobject.c | 13 |
8 files changed, 241 insertions, 185 deletions
diff --git a/scipy/base/chararray.py b/scipy/base/chararray.py index d81c2fffd..510d4bf8c 100644 --- a/scipy/base/chararray.py +++ b/scipy/base/chararray.py @@ -1,240 +1,277 @@ from numerictypes import character, string, unicode_, obj2dtype, integer -from numeric import ndarray, multiter, empty +from numeric import ndarray, broadcast, empty +import sys # special sub-class for character arrays (string and unicode_) # This adds equality testing and methods of str and unicode types # which operate on an element-by-element basis + class ndchararray(ndarray): def __new__(subtype, shape, itemlen=1, unicode=False, buffer=None, offset=0, strides=None, swap=0, fortran=0): if unicode: - dtype = 'U%d' % itemlen + dtype = unicode_ else: - dtype = 'U%d' % itemlen + dtype = string swap = 0 - if buffer is None: - self = ndarray.__new__(subtype, shape, dtype, fortran=fortran) + self = ndarray.__new__(subtype, shape, dtype, itemlen, fortran=fortran) else: - self = ndarray.__new__(subtype, shape, dtype, buffer=buffer, + self = ndarray.__new__(subtype, shape, dtype, itemlen, buffer=buffer, offset=offset, strides=strides, swap=swap, fortran=fortran) return self - def __reduce__(self): pass - # these should be moved to C - def __eq__(self, other): - b = multiter(self, other) + def _richcmpfunc(self, other, op): + b = broadcast(self, other) result = empty(b.shape, dtype=bool) res = result.flat for k, val in enumerate(b): - res[k] = (val[0] == val[1]) + r1 = val[0].strip('\x00') + r2 = val[1] + res[k] = eval("r1 %s r2" % op, {'r1':r1,'r2':r2}) return result + + # these should probably be moved to C + def __eq__(self, other): + return self._richcmpfunc(other, '==') def __ne__(self, other): - b = multiter(self, other) - result = empty(b.shape, dtype=bool) - res = result.flat - for k, val in enumerate(b): - res[k] = (val[0] != val[1]) - return result + return self._richcmpfunc(other, '!=') def __ge__(self, other): - b = multiter(self, other) - result = empty(b.shape, dtype=bool) - res = result.flat - for k, val in enumerate(b): - res[k] = (val[0] >= val[1]) - return result - + return self._richcmpfunc(other, '>=') + def __le__(self, other): - b = multiter(self, other) - result = empty(b.shape, dtype=bool) - res = result.flat - for k, val in enumerate(b): - res[k] = (val[0] <= val[1]) - return result + return self._richcmpfunc(other, '<=') def __gt__(self, other): - b = multiter(self, other) - result = empty(b.shape, dtype=bool) - res = result.flat - for k, val in enumerate(b): - res[k] = (val[0] > val[1]) - return result + return self._richcmpfunc(other, '>') def __lt__(self, other): - b = multiter(self, other) - result = empty(b.shape, dtype=bool) - res = result.flat - for k, val in enumerate(b): - res[k] = (val[0] < val[1]) - return result + return self._richcmpfunc(other, '<') def __add__(self, other): - b = multiter(self, other) + b = broadcast(self, other) arr = b.iters[1].base outitem = self.itemsize + arr.itemsize - dtype = self.dtypestr[1:2] + str(outitem) - result = empty(b.shape, dtype=dtype) + result = ndchararray(b.shape, outitem, self.dtype is unicode_) res = result.flat for k, val in enumerate(b): res[k] = (val[0] + val[1]) return result def __radd__(self, other): - b = multiter(other, self) + b = broadcast(other, self) outitem = b.iters[0].base.itemsize + \ b.iters[1].base.itemsize - dtype = self.dtypestr[1:2] + str(outitem) - result = empty(b.shape, dtype=dtype) + result = ndchararray(b.shape, outitem, self.dtype is unicode_) res = result.flat for k, val in enumerate(b): res[k] = (val[0] + val[1]) return result def __mul__(self, other): - b = multiter(self, other) + b = broadcast(self, other) arr = b.iters[1].base if not issubclass(arr.dtype, integer): raise ValueError, "Can only multiply by integers" outitem = b.iters[0].base.itemsize * arr.max() - dtype = self.dtypestr[1:2] + str(outitem) - result = empty(b.shape, dtype=dtype) + result = ndchararray(b.shape, outitem, self.dtype is unicode_) res = result.flat for k, val in enumerate(b): res[k] = val[0]*val[1] return result def __rmul__(self, other): - b = multiter(self, other) + b = broadcast(self, other) arr = b.iters[1].base if not issubclass(arr.dtype, integer): raise ValueError, "Can only multiply by integers" outitem = b.iters[0].base.itemsize * arr.max() - dtype = self.dtypestr[1:2] + str(outitem) - result = empty(b.shape, dtype=dtype) + result = ndchararray(b.shape, outitem, self.dtype is unicode_) res = result.flat for k, val in enumerate(b): res[k] = val[0]*val[1] return result def __mod__(self, other): - return NotImplemented - + b = broadcast(self, other) + res = [None]*b.size + maxsize = -1 + for k,val in enumerate(b): + newval = val[0] % val[1] + maxsize = max(len(newval), maxsize) + res[k] = newval + newarr = ndchararray(b.shape, maxsize, self.dtype is unicode_) + nearr[:] = res + return newarr + def __rmod__(self, other): return NotImplemented - def capitalize(self): - pass - - def center(self): - pass - - def count(self): - pass - - def decode(self): - pass - - def encode(self): - pass + def _generalmethod(self, name, myiter): + res = [None]*myiter.size + maxsize = -1 + for k, val in enumerate(myiter): + newval = [] + for chk in val[1:]: + if chk is None: + break + newval.append(chk) + newitem = getattr(val[0],name)(*newval) + maxsize = max(len(newitem), maxsize) + res[k] = newval + newarr = ndchararray(myiter.shape, maxsize, self.dtype is unicode_) + newarr[:] = res + return newarr + + def _typedmethod(self, name, myiter, dtype): + result = empty(myiter.shape, dtype=dtype) + res = result.flat + for k, val in enumerate(myiter): + newval = [] + for chk in val[1:]: + if chk is None: + break + newval.append(chk) + newitem = getattr(val[0],name)(*newval) + res[k] = newval + return res + + def _samemethod(self, name): + result = self.copy() + res = result.flat + for k, val in enumerate(self.flat): + res[k] = getattr(val, name)() + return result - def endswith(self): - pass + def capitalize(self): + return self._samemethod('capitalize') + + if sys.version[:3] >= '2.4': + def center(self, width, fillchar=' '): + return self._generalmethod('center', broadcast(self, width, fillchar)) + def ljust(self, width, fillchar=' '): + return self._generalmethod('ljust', broadcast(self, width, fillchar)) + def rjust(self, width, fillchar=' '): + return self._generalmethod('rjust', broadcast(self, width, fillchar)) + def rsplit(self, sep=None, maxsplit=None): + return self._generalmethod2('rsplit', broadcast(self, sep, maxsplit)) + else: + def ljust(self, width): + return self._generalmethod('ljust', broadcast(self, width)) + def rjust(self, width): + return self._generalmethod('rjust', broadcast(self, width)) + def center(self, width): + return self._generalmethod('center', broadcast(self, width)) + + def count(self, sub, start=None, end=None): + return self._typedmethod('count', broadcast(self, sub, start, end), int) + + def decode(self,encoding=None,errors=None): + return self._generalmethod('decode', broadcast(self, encoding, errors)) + + def encode(self,encoding=None,errors=None): + return self._generalmethod('encode', broadcast(self, encoding, errors)) + + def endswith(self, suffix, start=None, end=None): + return self._typedmethod('endswith', broadcast(self, suffix, start, end), bool) + + def expandtabs(self, tabsize=None): + return self._generalmethod('endswith', broadcast(self, tabsize)) - def expandtabs(self): - pass + def find(self, sub, start=None, end=None): + return self._typedmethod('find', broadcast(self, sub, start, end), int) - def find(self): - pass + def index(self, sub, start=None, end=None): + return self._typedmethod('index', broadcast(self, sub, start, end), int) - def index(self): - pass + def _ismethod(self, name): + result = empty(self.shape, dtype=bool) + res = result.flat + for k, val in enumerate(self.flat): + res[k] = getattr(val, name)() + return result def isalnum(self): - pass + return self._ismethod('isalnum') def isalpha(self): - pass + return self._ismethod('isalpha') def isdigit(self): - pass + return self._ismethod('isdigit') def islower(self): - pass - + return self._ismethod('islower') + def isspace(self): - pass + return self._ismethod('isspace') def istitle(self): - pass + return self._ismethod('istitle') def isupper(self): - pass - - def join(self): - pass - - def ljust(self): - pass + return self._ismethod('isupper') + def join(self, seq): + return self._generalmethod('join', broadcast(self, seq)) + def lower(self): - pass + return self._samemethod('lower') - def lstrip(self): - pass + def lstrip(self, chars): + return self._generalmethod('lstrip', broadcast(self, chars)) - def replace(self): - pass - - def rfind(self): - pass + def replace(self, old, new, count=None): + return self._generalmethod('replace', broadcast(self, old, new, count)) - def rindex(self): - pass + def rfind(self, sub, start=None, end=None): + return self._typedmethod('rfind', broadcast(self, sub, start, end), int) - def rjust(self): - pass + def rindex(self, sub, start=None, end=None): + return self._typedmethod('rindex', broadcast(self, sub, start, end), int) - def rsplit(self): - pass + def rstrip(self, chars=None): + return self._generalmethod('rstrip', broadcast(self, chars)) - def rstrip(self): - pass - - def split(self): - pass - - def splitlines(self): - pass + def split(self, sep=None, maxsplit=None): + return self._typedmethod('split', broadcast(self, sep, maxsplit), object) - def startswith(self): - pass + def splitlines(self, keepends=None): + return self._typedmethod('splitlines', broadcast(self, keepends), object) + + def startswith(self, prefix, start=None, end=None): + return self._typedmethod('startswith', broadcast(self, prefix, start, end), bool) - def strip(self): - pass + def strip(self, chars=None): + return self._generalmethod('strip', broadcast(self, chars)) def swapcase(self): - pass + return self._samemethod('swapcase') def title(self): - pass - - def translate(self): - pass + return self._samemethod('title') + #deletechars not accepted for unicode objects + def translate(self, table, deletechars=None): + if self.dtype is unicode_: + return self._generalmethod('translate', broadcast(self, table)) + else: + return self._generalmethod('translate', broadcast(self, table, deletechars)) + def upper(self): - pass + return self._samemethod('upper') - def zfill(self): - pass + def zfill(self, width): + return self._generalmethod('zfill', broadcast(self, width)) def chararray(obj, itemlen=7, copy=True, unicode=False, fortran=False): diff --git a/scipy/base/matrix.py b/scipy/base/matrix.py index eaebafeec..63743be9b 100644 --- a/scipy/base/matrix.py +++ b/scipy/base/matrix.py @@ -88,7 +88,8 @@ class matrix(N.ndarray): if not (fortran or arr.flags.contiguous): arr = arr.copy() - ret = N.ndarray.__new__(subtype, shape, arr.dtype, buffer=arr, + ret = N.ndarray.__new__(subtype, shape, arr.dtype, arr.itemsize, + buffer=arr, fortran=fortran, swap=arr.flags.swapped) return ret diff --git a/scipy/base/numeric.py b/scipy/base/numeric.py index ce3c7a758..f3837f201 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', 'multiter', + 'arange', 'array', 'zeros', 'empty', 'broadcast', 'fromstring', 'fromfile', 'frombuffer','newbuffer','getbuffer', 'where', 'concatenate', 'fastCopyAndTranspose', 'register_dtype', 'set_numeric_ops', 'can_cast', @@ -47,7 +47,7 @@ newaxis = None ndarray = multiarray.ndarray bigndarray = multiarray.bigndarray flatiter = multiarray.flatiter -multiter = multiarray.multiter +broadcast = multiarray.broadcast ufunc = type(sin) arange = multiarray.arange diff --git a/scipy/base/records.py b/scipy/base/records.py index 34c255a56..c80e76676 100644 --- a/scipy/base/records.py +++ b/scipy/base/records.py @@ -1,4 +1,5 @@ import numeric as sb +import numerictypes as nt import sys import types import re @@ -139,10 +140,12 @@ class format_parser: # This pads record so next record is aligned if self._rec_align is true. # Otherwise next the record starts right after the end of the last one. self._total_itemsize = (self._stops[-1]/maxalign + 1) * maxalign - -class RecArray(sb.ndarray): +class record(nt.void): + pass + +class ndrecarray(sb.ndarray): def __new__(self, *args, **kwds): buf = args[0] formats = args[1] @@ -159,15 +162,14 @@ class RecArray(sb.ndarray): else: raise NameError, "Illegal shape %s" % `shape` - typecode = 'V%d' % itemsize if buf is None: - this = sb.ndarray.__new__(RecArray, shape, typecode) + this = sb.ndarray.__new__(self, shape, record, itemsize) else: byteorder = kwds.get('byteorder', sys.byteorder) swapped = 0 if (byteorder != sys.byteorder): swapped = 1 - this = sb.ndarray.__new__(RecArray, shape, typecode, buffer=buf, + this = sb.ndarray.__new__(self, shape, record, itemsize, buffer=buf, swapped=swapped) this.parsed = parsed return this diff --git a/scipy/base/src/arrayobject.c b/scipy/base/src/arrayobject.c index f8833c9e6..ac6814ac3 100644 --- a/scipy/base/src/arrayobject.c +++ b/scipy/base/src/arrayobject.c @@ -804,7 +804,7 @@ PyArray_Scalar(void *data, int type_num, int itemsize, int swap) else obj = type->tp_alloc(type, 0); if (obj == NULL) return NULL; - if PyTypeNum_ISFLEXIBLE(type_num) { + if PyTypeNum_ISEXTENDED(type_num) { if (type_num == PyArray_STRING) { destptr = PyString_AS_STRING(obj); ((PyStringObject *)obj)->ob_shash = -1; @@ -895,6 +895,7 @@ static int PyArray_RegisterDataType(PyTypeObject *type) { PyArray_Descr *descr; + PyObject *obj; int typenum; int i; @@ -915,7 +916,14 @@ PyArray_RegisterDataType(PyTypeObject *type) sizeof(PyArray_Descr)); typenum = PyArray_USERDEF + PyArray_NUMUSERTYPES; descr->type_num = typenum; - descr->typeobj = type; + descr->typeobj = type; + obj = PyObject_GetAttrString((PyObject *)type,"itemsize"); + if (obj) { + i = PyInt_AsLong(obj); + if ((i < 0) && (PyErr_Occurred())) PyErr_Clear(); + else descr->elsize = i; + } + Py_INCREF(type); userdescrs = realloc(userdescrs, (PyArray_NUMUSERTYPES+1)*sizeof(void *)); if (userdescrs == NULL) { @@ -2763,7 +2771,7 @@ array_repr_builtin(PyArrayObject *self) free(string); return NULL; } - if (PyArray_ISFLEXIBLE(self)) { + if (PyArray_ISEXTENDED(self)) { char buf[100]; snprintf(buf, sizeof(buf), "%d", self->itemsize); sprintf(string+n, ", '%c%s')", self->descr->type, buf); @@ -3242,23 +3250,18 @@ PyArray_New(PyTypeObject *subtype, int nd, intp *dims, int type_num, } } else self->flags = (flags & ~UPDATEIFCOPY); - - if (PyTypeNum_ISFLEXIBLE(type_num)) { + + self->itemsize = descr->elsize; + if (self->itemsize == 0) { if (itemsize < 1) { PyErr_SetString(PyExc_ValueError, - "type must provide an itemsize"); + "data type must provide an itemsize"); self->ob_type->tp_free((PyObject *)self); return NULL; } self->itemsize = itemsize; - /* Guarantee that these kind of arrays are never byteswapped - unknowingly. - */ - if (type_num != PyArray_UNICODE) - self->flags |= NOTSWAPPED; } - else self->itemsize = descr->elsize; - + sd = self->itemsize; if (nd > 0) { @@ -3532,9 +3535,9 @@ PyArray_FillWithScalar(PyArrayObject *arr, PyObject *obj) static PyObject * array_new(PyTypeObject *subtype, PyObject *args, PyObject *kwds) { - static char *kwlist[] = {"shape", "dtype", "buffer", "offset", + static char *kwlist[] = {"shape", "dtype", "itemlen", "buffer", "offset", "strides", "swap", "fortran", NULL}; - int itemsize = 0; + int itemsize = -1; PyArray_Typecode typecode = {PyArray_NOTYPE, 0, 0}; int type_num = PyArray_NOTYPE; PyArray_Dims dims = {NULL, 0}; @@ -3554,11 +3557,12 @@ array_new(PyTypeObject *subtype, PyObject *args, PyObject *kwds) array of a specific type and shape. */ - if (!PyArg_ParseTupleAndKeywords(args, kwds, "O&|O&O&LO&ii", + if (!PyArg_ParseTupleAndKeywords(args, kwds, "O&|O&iO&LO&ii", kwlist, PyArray_IntpConverter, &dims, PyArray_TypecodeConverter, &typecode, + &itemsize, PyArray_BufferConverter, &buffer, &offset, @@ -3571,6 +3575,13 @@ array_new(PyTypeObject *subtype, PyObject *args, PyObject *kwds) typecode.type_num = PyArray_DOUBLE; typecode.itemsize = sizeof(double); } + /* An itemlen is used only if the typecode.itemsize is 0 */ + if ((itemsize != -1) && typecode.itemsize==0) { + if (typecode.type_num == PyArray_UNICODE) { + itemsize *= sizeof(Py_UNICODE); + } + typecode.itemsize = itemsize; + } type_num = typecode.type_num; itemsize = typecode.itemsize; @@ -3977,7 +3988,7 @@ array_nbytes_get(PyArrayObject *self) static PyObject * array_typechar_get(PyArrayObject *self) { - if PyArray_ISFLEXIBLE(self) + if PyArray_ISEXTENDED(self) return PyString_FromFormat("%c%d", (self->descr->type), self->itemsize); else @@ -4637,8 +4648,8 @@ _array_small_type(int chktype, int mintype, int chksize, int minsize, PyArray_Typecode *outtype) { outtype->type_num = MAX(chktype, mintype); - if (PyTypeNum_ISFLEXIBLE(outtype->type_num) && \ - (PyTypeNum_ISFLEXIBLE(mintype) || mintype==0)) { + if (PyTypeNum_ISEXTENDED(outtype->type_num) && \ + (PyTypeNum_ISEXTENDED(mintype) || mintype==0)) { /* Handle string->unicode case separately because string itemsize is twice as large */ if (outtype->type_num == PyArray_UNICODE && @@ -4858,7 +4869,7 @@ Array_FromScalar(PyObject *op, PyArray_Typecode *typecode) itemsize = typecode->itemsize; type = typecode->type_num; - if (itemsize == 0 && PyTypeNum_ISFLEXIBLE(type)) { + if (itemsize == 0 && PyTypeNum_ISEXTENDED(type)) { itemsize = PyObject_Length(op); } @@ -4912,7 +4923,7 @@ Array_FromSequence(PyObject *s, PyArray_Typecode *typecode, int min_depth, if(discover_dimensions(s,nd,d, !stop_at_string) == -1) { return NULL; } - if (itemsize == 0 && PyTypeNum_ISFLEXIBLE(type)) { + if (itemsize == 0 && PyTypeNum_ISEXTENDED(type)) { if (discover_itemsize(s, nd, &itemsize) == -1) { return NULL; } @@ -5598,7 +5609,7 @@ array_fromattr(PyObject *op, PyArray_Typecode *typecode, int flags) PyObject *obj; descr = PyArray_DescrFromType(typecode->type_num); - if (PyTypeNum_ISFLEXIBLE(typecode->type_num)) { + if (PyTypeNum_ISEXTENDED(typecode->type_num)) { obj = PyString_FromFormat("%c%d", descr->type, typecode->itemsize); } @@ -7340,7 +7351,7 @@ PyArray_MultiIterNew(int n, ...) "array objects (inclusive).", MAX_DIMS); } - fprintf(stderr, "multi new..."); + /* fprintf(stderr, "multi new...");*/ multi = PyObject_New(PyArrayMultiIterObject, &PyArrayMultiIter_Type); if (multi == NULL) return NULL; @@ -7548,7 +7559,7 @@ static PyMethodDef arraymultiter_methods[] = { static PyTypeObject PyArrayMultiIter_Type = { PyObject_HEAD_INIT(NULL) 0, /* ob_size */ - "scipy.multiter", /* tp_name */ + "scipy.broadcast", /* tp_name */ sizeof(PyArrayMultiIterObject), /* tp_basicsize */ 0, /* tp_itemsize */ /* methods */ diff --git a/scipy/base/src/multiarraymodule.c b/scipy/base/src/multiarraymodule.c index fd8cf4339..fdefb54e4 100644 --- a/scipy/base/src/multiarraymodule.c +++ b/scipy/base/src/multiarraymodule.c @@ -124,7 +124,7 @@ PyArray_View(PyArrayObject *self, PyArray_Typecode *type) PyArray_BASE(new) = (PyObject *)self; if ((type_num != PyArray_NOTYPE) && \ (type_num != self->descr->type_num)) { - if (!PyTypeNum_ISFLEXIBLE(type_num)) { + if (!PyTypeNum_ISEXTENDED(type_num)) { v = PyArray_TypeObjectFromType(type_num); } else { @@ -460,11 +460,13 @@ PyArray_Std(PyArrayObject *self, int axis, int rtype, int variance) if (n<=0) n=1; obj2 = PyFloat_FromDouble(1.0/((double )n)); if (obj2 == NULL) {Py_DECREF(obj1); return NULL;} - ret = PyArray_EnsureArray(PyNumber_Multiply(obj1, obj2)); + ret = PyNumber_Multiply(obj1, obj2); Py_DECREF(obj1); Py_DECREF(obj2); - if (variance) return PyArray_Return(ret); + if (variance) return ret; + + ret = PyArray_EnsureArray(ret); /* sqrt() */ obj1 = PyArray_GenericUnaryFunction((PyAO *)ret, n_ops.sqrt); @@ -2087,6 +2089,7 @@ PyArray_Correlate(PyObject *op1, PyObject *op2, int mode) return NULL; } + static PyObject * PyArray_ArgMin(PyArrayObject *ap, int axis) { @@ -4210,7 +4213,7 @@ DL_EXPORT(void) initmultiarray(void) { Py_INCREF(&PyArrayIter_Type); PyDict_SetItemString(d, "flatiter", (PyObject *)&PyArrayIter_Type); Py_INCREF(&PyArrayMultiIter_Type); - PyDict_SetItemString(d, "multiter", (PyObject *)&PyArrayMultiIter_Type); + PyDict_SetItemString(d, "broadcast", (PyObject *)&PyArrayMultiIter_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 884d87aab..4945f130a 100644 --- a/scipy/base/src/scalartypes.inc.src +++ b/scipy/base/src/scalartypes.inc.src @@ -50,14 +50,14 @@ PyArray_ScalarAsCtype(PyObject *scalar, void *ctypeptr) PyArray_Typecode typecode; PyArray_TypecodeFromScalar(scalar, &typecode); - if (PyTypeNum_ISFLEXIBLE(typecode.type_num)) { + if (PyTypeNum_ISEXTENDED(typecode.type_num)) { void **newptr = (void **)ctypeptr; switch(typecode.type_num) { case PyArray_STRING: *newptr = (void *)PyString_AS_STRING(scalar); case PyArray_UNICODE: *newptr = (void *)PyUnicode_AS_DATA(scalar); - case PyArray_VOID: + default: *newptr = ((PyVoidScalarObject *)scalar)->obval; } return; @@ -81,8 +81,8 @@ PyArray_CastScalarToCtype(PyObject *scalar, void *ctypeptr, PyArray_TypecodeFromScalar(scalar, &incode); descr = PyArray_DescrFromType(incode.type_num); - if (PyTypeNum_ISFLEXIBLE(incode.type_num) || - PyTypeNum_ISFLEXIBLE(outcode->type_num)) { + if (PyTypeNum_ISEXTENDED(incode.type_num) || + PyTypeNum_ISEXTENDED(outcode->type_num)) { PyArrayObject *ain, *aout; ain = (PyArrayObject *)PyArray_FromScalar(scalar, NULL); @@ -129,11 +129,13 @@ PyArray_FromScalar(PyObject *scalar, PyArray_Typecode *outcode) case PyArray_UNICODE: memptr = (char *)PyUnicode_AS_DATA(scalar); break; - case PyArray_VOID: - memptr = (((PyVoidScalarObject *)scalar)->obval); - break; default: - memptr = _SOFFSET_(scalar, typecode.type_num); + if (PyTypeNum_ISEXTENDED(typecode.type_num)) { + memptr = (((PyVoidScalarObject *)scalar)->obval); + } + else { + memptr = _SOFFSET_(scalar, typecode.type_num); + } break; } @@ -147,7 +149,7 @@ PyArray_FromScalar(PyObject *scalar, PyArray_Typecode *outcode) return r; if (outcode->type_num == typecode.type_num) { - if (!PyTypeNum_ISFLEXIBLE(typecode.type_num)) + if (!PyTypeNum_ISEXTENDED(typecode.type_num)) return r; if (outcode->itemsize == typecode.itemsize) return r; @@ -1672,11 +1674,11 @@ PyArray_TypenumFromTypeObject(PyObject *type) i++; } - /* Seacrh any registered types */ + /* Search any registered types */ i = 0; while (i < PyArray_NUMUSERTYPES) { if (type == (PyObject *)(userdescrs[i]->typeobj)) { - typenum = i; + typenum = i + PyArray_USERDEF; break; } i++; @@ -1699,7 +1701,7 @@ PyArray_TypenumFromTypeObject(PyObject *type) return PyArray_ULONG; else if (type == (PyObject *) &PyCharacterArrType_Type) return PyArray_STRING; - else if (type == (PyObject *) &PyFlexibleArrType_Type) + else if (PyType_IsSubtype((PyTypeObject *)type, &PyFlexibleArrType_Type)) return PyArray_VOID; else if (type == (PyObject *)&PyBool_Type) typenum = PyArray_BOOL; @@ -1728,10 +1730,7 @@ PyArray_TypecodeFromTypeObject(PyObject *type, PyArray_Typecode *typecode) { type_num = PyArray_TypenumFromTypeObject(type); typecode->type_num = type_num; - if (PyTypeNum_ISFLEXIBLE(type_num)) { - itemsize = 0; - } - else { + if (!PyTypeNum_ISFLEXIBLE(type_num)) { PyArray_Descr *descr; descr = PyArray_DescrFromType(type_num); if (descr != NULL) @@ -1754,8 +1753,8 @@ PyArray_TypecodeFromScalar(PyObject *sc, PyArray_Typecode *typecode) typecode->itemsize = PyString_GET_SIZE(sc); else if (type_num == PyArray_UNICODE) typecode->itemsize = PyUnicode_GET_DATA_SIZE(sc); - else if (type_num == PyArray_VOID) { - typecode->itemsize = \ + else { + typecode->itemsize = \ ((PyVoidScalarObject *)sc)->ob_size; } } diff --git a/scipy/base/src/ufuncobject.c b/scipy/base/src/ufuncobject.c index ea3cf266c..ea1ec3bd4 100644 --- a/scipy/base/src/ufuncobject.c +++ b/scipy/base/src/ufuncobject.c @@ -602,11 +602,14 @@ select_types(PyUFuncObject *self, int *arg_types, for (i=self->nin; i<self->nargs; i++) { arg_types[i] = arg_types[0]; } - - key = PyInt_FromLong((long) arg_types[0]); - if (key == NULL) return -1; - obj = PyDict_GetItem(self->userloops, key); - Py_DECREF(key); + + obj = NULL; + if (self->userloops) { + key = PyInt_FromLong((long) arg_types[0]); + if (key == NULL) return -1; + obj = PyDict_GetItem(self->userloops, key); + Py_DECREF(key); + } if (obj == NULL) { PyErr_SetString(PyExc_TypeError, "no registered loop for this " \ |