From b884d998f468f89704dae39ef4d1e0b2bc71a9f3 Mon Sep 17 00:00:00 2001 From: Travis Oliphant Date: Wed, 19 Jul 2006 07:08:41 +0000 Subject: Improve creation of object arrays when dtype=object is specified. --- numpy/core/src/arrayobject.c | 93 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 87 insertions(+), 6 deletions(-) (limited to 'numpy/core/src/arrayobject.c') diff --git a/numpy/core/src/arrayobject.c b/numpy/core/src/arrayobject.c index 8a80e2e68..c20bc4fa4 100644 --- a/numpy/core/src/arrayobject.c +++ b/numpy/core/src/arrayobject.c @@ -6859,7 +6859,7 @@ Assign_Array(PyArrayObject *self, PyObject *v) /* "Array Scalars don't call this code" */ /* steals reference to typecode -- no NULL*/ static PyObject * -Array_FromScalar(PyObject *op, PyArray_Descr *typecode) +Array_FromPyScalar(PyObject *op, PyArray_Descr *typecode) { PyArrayObject *ret; int itemsize; @@ -6900,10 +6900,83 @@ Array_FromScalar(PyObject *op, PyArray_Descr *typecode) } +/* If s is not a list, return 0 + Otherwise: + + run object_depth_and_dimension on all the elements + and make sure the returned shape and size + is the same for each element + +*/ +static int +object_depth_and_dimension(PyObject *s, int max, intp *dims) +{ + intp *newdims, *test_dims; + int nd, test_nd; + int i; + intp size; + + if (!PyList_Check(s) || ((size=PyList_GET_SIZE(s)) == 0)) + return 0; + if (max < 2) { + if (max < 1) return 0; + dims[0] = size; + return 1; + } + newdims = PyDimMem_NEW(2*(max-1)); + test_dims = newdims + (max-1); + nd = object_depth_and_dimension(PyList_GET_ITEM(s, 0), + max-1, newdims); + for (i=1; itype_num; int itemsize = typecode->elsize; + if (isobject) + return ObjectArray_FromNestedList(s, typecode, fortran); + stop_at_string = ((type == PyArray_OBJECT) || \ (type == PyArray_STRING && \ typecode->type == PyArray_STRINGLTR) || \ @@ -6926,7 +7002,7 @@ Array_FromSequence(PyObject *s, PyArray_Descr *typecode, int fortran, if (!((nd=discover_depth(s, MAX_DIMS+1, stop_at_string, stop_at_tuple)) > 0)) { if (nd==0) - return Array_FromScalar(s, typecode); + return Array_FromPyScalar(s, typecode); PyErr_SetString(PyExc_ValueError, "invalid input sequence"); goto fail; @@ -7944,7 +8020,7 @@ PyArray_FromAny(PyObject *op, PyArray_Descr *newtype, int min_depth, } else if (newtype == NULL && (newtype = _array_find_python_scalar_type(op))) { if (flags & UPDATEIFCOPY) goto err; - r = Array_FromScalar(op, newtype); + r = Array_FromPyScalar(op, newtype); } else if (((r = PyArray_FromStructInterface(op))!=Py_NotImplemented)|| \ ((r = PyArray_FromInterface(op)) != Py_NotImplemented) || \ @@ -7960,17 +8036,22 @@ PyArray_FromAny(PyObject *op, PyArray_Descr *newtype, int min_depth, } } else { + int isobject; if (flags & UPDATEIFCOPY) goto err; + isobject = 0; if (newtype == NULL) { newtype = _array_find_type(op, NULL, MAX_DIMS); } + else if (newtype->type_num == PyArray_OBJECT) { + isobject = 1; + } if (PySequence_Check(op)) { PyObject *thiserr; /* necessary but not sufficient */ Py_INCREF(newtype); r = Array_FromSequence(op, newtype, flags & FORTRAN, - min_depth, max_depth); + min_depth, max_depth, isobject); if (r == NULL && \ ((thiserr = PyErr_Occurred()) && \ !PyErr_GivenExceptionMatches(thiserr, @@ -7985,7 +8066,7 @@ PyArray_FromAny(PyObject *op, PyArray_Descr *newtype, int min_depth, } } if (!seq) - r = Array_FromScalar(op, newtype); + r = Array_FromPyScalar(op, newtype); } /* If we didn't succeed return NULL */ -- cgit v1.2.1