summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--numpy/core/src/multiarray/methods.c63
-rw-r--r--numpy/core/tests/test_regression.py18
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)])