diff options
-rw-r--r-- | numpy/core/src/multiarray/methods.c | 63 | ||||
-rw-r--r-- | numpy/core/tests/test_regression.py | 18 |
2 files changed, 66 insertions, 15 deletions
diff --git a/numpy/core/src/multiarray/methods.c b/numpy/core/src/multiarray/methods.c index 5165a074b..72f5922e4 100644 --- a/numpy/core/src/multiarray/methods.c +++ b/numpy/core/src/multiarray/methods.c @@ -1407,44 +1407,79 @@ _deepcopy_call(char *iptr, char *optr, PyArray_Descr *dtype, static PyObject * array_deepcopy(PyArrayObject *self, PyObject *args) { + PyArrayObject* copied_array; PyObject* visit; - char *optr; - PyArrayIterObject *it; + + NpyIter* iter; + NpyIter_IterNextFunc* iternext; + + char* data; + char** dataptr; + npy_intp* strideptr,* innersizeptr; + npy_intp stride, count; + PyObject *copy, *deepcopy; - PyArrayObject *ret; if (!PyArg_ParseTuple(args, "O", &visit)) { return NULL; } - ret = (PyArrayObject *)PyArray_NewCopy(self, NPY_KEEPORDER); - if (ret == NULL) { + copied_array = (PyArrayObject*) PyArray_NewCopy(self, NPY_KEEPORDER); + if (copied_array == NULL) { return NULL; } if (PyDataType_REFCHK(PyArray_DESCR(self))) { copy = PyImport_ImportModule("copy"); if (copy == NULL) { + Py_DECREF(copied_array); + Py_DECREF(copy); return NULL; } deepcopy = PyObject_GetAttrString(copy, "deepcopy"); Py_DECREF(copy); if (deepcopy == NULL) { + Py_DECREF(copied_array); return NULL; } - it = (PyArrayIterObject *)PyArray_IterNew((PyObject *)self); - if (it == NULL) { + iter = (NpyIter *)NpyIter_New(copied_array, + (NPY_ITER_READWRITE | + NPY_ITER_EXTERNAL_LOOP | + NPY_ITER_REFS_OK), + NPY_KEEPORDER, + NPY_NO_CASTING, + NULL); + if (iter == NULL) { Py_DECREF(deepcopy); + Py_DECREF(copied_array); return NULL; } - optr = PyArray_DATA(ret); - while(it->index < it->size) { - _deepcopy_call(it->dataptr, optr, PyArray_DESCR(self), deepcopy, visit); - optr += PyArray_DESCR(self)->elsize; - PyArray_ITER_NEXT(it); + iternext = NpyIter_GetIterNext(iter, NULL); + if (iternext == NULL) { + NpyIter_Deallocate(iter); + Py_DECREF(deepcopy); + Py_DECREF(copied_array); + return NULL; } + + dataptr = NpyIter_GetDataPtrArray(iter); + strideptr = NpyIter_GetInnerStrideArray(iter); + innersizeptr = NpyIter_GetInnerLoopSizePtr(iter); + + do { + data = *dataptr; + stride = *strideptr; + count = *innersizeptr; + + while (count--) { + _deepcopy_call(data, data, PyArray_DESCR(copied_array), + deepcopy, visit); + data += stride; + } + } while (iternext(iter)); + + NpyIter_Deallocate(iter); Py_DECREF(deepcopy); - Py_DECREF(it); } - return (PyObject*)ret; + return (PyObject*) copied_array; } /* Convert Array to flat list (using getitem) */ diff --git a/numpy/core/tests/test_regression.py b/numpy/core/tests/test_regression.py index 40b456f35..3b167b5e2 100644 --- a/numpy/core/tests/test_regression.py +++ b/numpy/core/tests/test_regression.py @@ -457,7 +457,7 @@ class TestRegression(TestCase): def test_object_array_from_list(self, level=rlevel): # Ticket #270 - np.array([1, 'A', None]) # Should succeed + self.assertEqual(np.array([1, 'A', None]).shape, (3,)) def test_multiple_assign(self, level=rlevel): # Ticket #273 @@ -2091,6 +2091,22 @@ class TestRegression(TestCase): self.assertTrue(arr is not arr_cp) self.assertTrue(isinstance(arr_cp, type(arr))) + def test_deepcopy_F_order_object_array(self): + # Ticket #6456. + a = {'a': 1} + b = {'b': 2} + arr = np.array([[a, b], [a, b]], order='F') + arr_cp = copy.deepcopy(arr) + + assert_equal(arr, arr_cp) + self.assertTrue(arr is not arr_cp) + # Ensure that we have actually copied the item. + self.assertTrue(arr[0, 1] is not arr_cp[1, 1]) + # Ensure we are allowed to have references to the same object. + self.assertTrue(arr[0, 1] is arr[1, 1]) + # Check the references hold for the copied objects. + self.assertTrue(arr_cp[0, 1] is arr_cp[1, 1]) + def test_bool_subscript_crash(self): # gh-4494 c = np.rec.array([(1, 2, 3), (4, 5, 6)]) |