diff options
author | Mark Wiebe <mwwiebe@gmail.com> | 2011-01-21 14:03:38 -0800 |
---|---|---|
committer | Mark Wiebe <mwwiebe@gmail.com> | 2011-01-21 14:03:38 -0800 |
commit | a8ceecad783492f6546e06812ac6b93d84ea25a1 (patch) | |
tree | e19fbdf6737bfd2b22c2a4b8cfde9fc6fd0f3924 /numpy/core | |
parent | 9317b745856b4bb956426b199d3422a6ef71e269 (diff) | |
download | numpy-a8ceecad783492f6546e06812ac6b93d84ea25a1.tar.gz |
BUG: core: Fix issue converting nested list with a number to a string type
Diffstat (limited to 'numpy/core')
-rw-r--r-- | numpy/core/src/multiarray/ctors.c | 67 | ||||
-rw-r--r-- | numpy/core/tests/test_regression.py | 18 |
2 files changed, 44 insertions, 41 deletions
diff --git a/numpy/core/src/multiarray/ctors.c b/numpy/core/src/multiarray/ctors.c index 9acfd15b3..fa5932f9b 100644 --- a/numpy/core/src/multiarray/ctors.c +++ b/numpy/core/src/multiarray/ctors.c @@ -816,14 +816,12 @@ static int discover_itemsize(PyObject *s, int nd, int *itemsize) { int n, r, i; - PyObject *e; if (PyArray_Check(s)) { *itemsize = MAX(*itemsize, PyArray_ITEMSIZE(s)); return 0; } - n = PyObject_Length(s); if ((nd == 0) || PyString_Check(s) || #if defined(NPY_PY3K) PyMemoryView_Check(s) || @@ -832,19 +830,32 @@ discover_itemsize(PyObject *s, int nd, int *itemsize) #endif PyUnicode_Check(s)) { - *itemsize = MAX(*itemsize, n); + /* If an object has no length, leave it be */ + n = PyObject_Length(s); + if (n == -1) { + PyErr_Clear(); + } + else { + *itemsize = MAX(*itemsize, n); + } return 0; } + + n = PySequence_Length(s); for (i = 0; i < n; i++) { - if ((e = PySequence_GetItem(s,i))==NULL) { + PyObject *e = PySequence_GetItem(s,i); + + if (e == NULL) { return -1; } + r = discover_itemsize(e,nd-1,itemsize); Py_DECREF(e); if (r == -1) { return -1; } } + return 0; } @@ -968,6 +979,7 @@ Array_FromSequence(PyObject *s, PyArray_Descr *typecode, int fortran, itemsize *= 4; } } + if (itemsize != typecode->elsize) { PyArray_DESCR_REPLACE(typecode); typecode->elsize = itemsize; @@ -2343,31 +2355,6 @@ PyArray_CopyInto(PyArrayObject *dst, PyArrayObject *src) return -1; } - if (PyArray_SIZE(src) == 0) { - /* If src and dst have the same shapes, copying zero-sized is ok */ - if (PyArray_NDIM(src) == PyArray_NDIM(dst) && - PyArray_CompareLists(PyArray_DIMS(src), PyArray_DIMS(dst), - PyArray_NDIM(src))) { - return 0; - } - else { - PyErr_SetString(PyExc_ValueError, - "cannot copy from zero-sized array"); - return -1; - } - } - if (PyArray_SIZE(dst) == 0) { - /* Allow a scalar to be assigned to anything, even an empty array */ - if (PyArray_NDIM(src) == 0) { - return 0; - } - else { - PyErr_SetString(PyExc_ValueError, - "cannot copy to zero-sized array"); - return -1; - } - } - if (PyArray_NDIM(dst) >= PyArray_NDIM(src) && PyArray_TRIVIALLY_ITERABLE_PAIR(dst, src)) { char *dst_data, *src_data; @@ -2437,7 +2424,8 @@ PyArray_CopyInto(PyArrayObject *dst, PyArrayObject *src) iter = NpyIter_MultiNew(2, op, NPY_ITER_NO_INNER_ITERATION| - NPY_ITER_REFS_OK, + NPY_ITER_REFS_OK| + NPY_ITER_ZEROSIZE_OK, NPY_KEEPORDER, NPY_NO_CASTING, op_flags, @@ -2476,21 +2464,20 @@ PyArray_CopyInto(PyArrayObject *dst, PyArrayObject *src) } - if (needs_api) { - do { - stransfer(dataptr[0], stride[0], - dataptr[1], stride[1], - *countptr, src_itemsize, transferdata); - } while(iternext(iter)); - } - else { - NPY_BEGIN_THREADS; + if (NpyIter_GetIterSize(iter) != 0) { + if (!needs_api) { + NPY_BEGIN_THREADS; + } + do { stransfer(dataptr[0], stride[0], dataptr[1], stride[1], *countptr, src_itemsize, transferdata); } while(iternext(iter)); - NPY_END_THREADS; + + if (!needs_api) { + NPY_END_THREADS; + } } PyArray_FreeStridedTransferData(transferdata); diff --git a/numpy/core/tests/test_regression.py b/numpy/core/tests/test_regression.py index 04fd9210e..01e15c981 100644 --- a/numpy/core/tests/test_regression.py +++ b/numpy/core/tests/test_regression.py @@ -608,6 +608,9 @@ class TestRegression(TestCase): assert_equal(np.dot(x,z),np.dot(x,y2)) def test_object_casting(self, level=rlevel): + # This currently triggers the object-type version of + # the bitwise_or operation, because float64 -> object + # casting succeeds def rs(): x = np.ones([484,286]) y = np.zeros([484,286]) @@ -1140,7 +1143,8 @@ class TestRegression(TestCase): def test_array_from_sequence_scalar_array2(self): """Ticket #1081: weird array with strange input...""" t = np.array([np.array([]), np.array(0, object)]) - assert_raises(ValueError, lambda: np.array(t)) + assert_equal(t.shape, (2,)) + assert_equal(t.dtype, np.dtype(object)) def test_array_too_big(self): """Ticket #1080.""" @@ -1446,5 +1450,17 @@ class TestRegression(TestCase): a[1:1] *= 2 assert_equal(a, [1.]) + def test_array_side_effect(self): + assert_equal(np.dtype('S10').itemsize, 10) + + A = np.array([['abc', 2], ['long ', '0123456789']], dtype=np.string_) + + # This was throwing an exception because in ctors.c, + # discover_itemsize was calling PyObject_Length without checking + # the return code. This failed to get the length of the number 2, + # and the exception hung around until something checked + # PyErr_Occurred() and returned an error. + assert_equal(np.dtype('S10').itemsize, 10) + if __name__ == "__main__": run_module_suite() |