summaryrefslogtreecommitdiff
path: root/numpy/core
diff options
context:
space:
mode:
authorJulian Taylor <jtaylor.debian@googlemail.com>2014-07-18 21:31:44 +0200
committerJulian Taylor <jtaylor.debian@googlemail.com>2014-07-18 21:48:14 +0200
commitc09d0ce0e11c94a83413c1bc6c9b2f5f40008a5a (patch)
tree465ee903d43308c02e8968fa1bcb19a1c4e8faec /numpy/core
parent88cf0e4f6d722b12f2d57e3acb6452d6a015cc93 (diff)
downloadnumpy-c09d0ce0e11c94a83413c1bc6c9b2f5f40008a5a.tar.gz
BUG: initialize object array of array on resize and zeros
np.zeros(2, dtype=[('k', object, 2)]) did only initialize the first element to zero while the rest stayed None. In [1]: numpy.zeros(2, dtype=[('k', object, 2)]) Out[1]: array([([0, None],), ([0, None],)], dtype=[('k', 'O', (2,))]) This is a surprising and likely not intended behavior which is fixed here. The changed function PyArray_FillObjectArray is only used with None or zero inputs from numpy, though as its part of the API it could affect third parties but this is not very likely. Additionally the memory after the first element was not initialized when the object was resized. Closes gh-4857
Diffstat (limited to 'numpy/core')
-rw-r--r--numpy/core/src/multiarray/refcount.c8
-rw-r--r--numpy/core/src/multiarray/shape.c8
-rw-r--r--numpy/core/tests/test_multiarray.py12
3 files changed, 24 insertions, 4 deletions
diff --git a/numpy/core/src/multiarray/refcount.c b/numpy/core/src/multiarray/refcount.c
index eab11e933..88f660118 100644
--- a/numpy/core/src/multiarray/refcount.c
+++ b/numpy/core/src/multiarray/refcount.c
@@ -275,8 +275,12 @@ _fillobject(char *optr, PyObject *obj, PyArray_Descr *dtype)
}
}
else {
- Py_XINCREF(obj);
- NPY_COPY_PYOBJECT_PTR(optr, &obj);
+ npy_intp i;
+ for (i = 0; i < dtype->elsize / sizeof(obj); i++) {
+ Py_XINCREF(obj);
+ NPY_COPY_PYOBJECT_PTR(optr, &obj);
+ optr += sizeof(obj);
+ }
return;
}
}
diff --git a/numpy/core/src/multiarray/shape.c b/numpy/core/src/multiarray/shape.c
index d5fde5b97..2278b5d5b 100644
--- a/numpy/core/src/multiarray/shape.c
+++ b/numpy/core/src/multiarray/shape.c
@@ -326,8 +326,12 @@ _putzero(char *optr, PyObject *zero, PyArray_Descr *dtype)
}
}
else {
- Py_INCREF(zero);
- NPY_COPY_PYOBJECT_PTR(optr, &zero);
+ npy_intp i;
+ for (i = 0; i < dtype->elsize / sizeof(zero); i++) {
+ Py_INCREF(zero);
+ NPY_COPY_PYOBJECT_PTR(optr, &zero);
+ optr += sizeof(zero);
+ }
}
return;
}
diff --git a/numpy/core/tests/test_multiarray.py b/numpy/core/tests/test_multiarray.py
index 2e40a2b7c..9c51895fa 100644
--- a/numpy/core/tests/test_multiarray.py
+++ b/numpy/core/tests/test_multiarray.py
@@ -511,6 +511,10 @@ class TestCreation(TestCase):
assert_array_equal(d, [0] * 13)
assert_equal(np.count_nonzero(d), 0)
+ def test_zeros_obj_obj(self):
+ d = zeros(10, dtype=[('k', object, 2)])
+ assert_array_equal(d['k'], 0)
+
def test_sequence_non_homogenous(self):
assert_equal(np.array([4, 2**80]).dtype, np.object)
assert_equal(np.array([4, 2**80, 4]).dtype, np.object)
@@ -2784,6 +2788,14 @@ class TestResize(TestCase):
assert_array_equal(x[0], np.eye(3))
assert_array_equal(x[1], np.zeros((3, 3)))
+ def test_obj_obj(self):
+ # check memory is initialized on resize, gh-4857
+ a = ones(10, dtype=[('k', object, 2)])
+ a.resize(15,)
+ assert_equal(a.shape, (15,))
+ assert_array_equal(a['k'][-5:], 0)
+ assert_array_equal(a['k'][:-5], 1)
+
class TestRecord(TestCase):
def test_field_rename(self):