diff options
author | Marten van Kerkwijk <mhvk@astro.utoronto.ca> | 2018-09-19 09:45:43 -0400 |
---|---|---|
committer | Marten van Kerkwijk <mhvk@astro.utoronto.ca> | 2018-09-19 09:51:05 -0400 |
commit | de46fecdecf6a5ed40991ffc82d4bfc36d74c10d (patch) | |
tree | fd3c31a8bf3b358c3122f7fa564f1022f17b81d9 | |
parent | 9741ce23eeeb972d5097cd8d5a835c67fb40ff26 (diff) | |
download | numpy-de46fecdecf6a5ed40991ffc82d4bfc36d74c10d.tar.gz |
BUG: Ensure boolean indexing of subclasses sets base correctly.
Corrects a mistake in gh-11246, where the base for this case was
set to the indexed subclass instance (like for a view). Since a
copy is made in this case, the base should be the new ndarray that
holds the indexed values.
Thanks to @yymao for noticing and reporting the bug in astropy.
-rw-r--r-- | numpy/core/src/multiarray/mapping.c | 2 | ||||
-rw-r--r-- | numpy/core/tests/test_indexing.py | 30 |
2 files changed, 25 insertions, 7 deletions
diff --git a/numpy/core/src/multiarray/mapping.c b/numpy/core/src/multiarray/mapping.c index 2fdb3ebf6..b50866b4d 100644 --- a/numpy/core/src/multiarray/mapping.c +++ b/numpy/core/src/multiarray/mapping.c @@ -1125,7 +1125,7 @@ array_boolean_subscript(PyArrayObject *self, ret = (PyArrayObject *)PyArray_NewFromDescrAndBase( Py_TYPE(self), dtype, 1, &size, PyArray_STRIDES(ret), PyArray_BYTES(ret), - PyArray_FLAGS(self), (PyObject *)self, (PyObject *)self); + PyArray_FLAGS(self), (PyObject *)self, (PyObject *)tmp); if (ret == NULL) { Py_DECREF(tmp); diff --git a/numpy/core/tests/test_indexing.py b/numpy/core/tests/test_indexing.py index 1934d542a..99792cee7 100644 --- a/numpy/core/tests/test_indexing.py +++ b/numpy/core/tests/test_indexing.py @@ -580,15 +580,33 @@ class TestBroadcastedAssignments(object): class TestSubclasses(object): def test_basic(self): + # Test that indexing in various ways produces SubClass instances, + # and that the base is set up correctly: the original subclass + # instance for views, and a new ndarray for advanced/boolean indexing + # where a copy was made (latter a regression test for gh-11983). class SubClass(np.ndarray): pass - s = np.arange(5).view(SubClass) - assert_(isinstance(s[:3], SubClass)) - assert_(s[:3].base is s) - - assert_(isinstance(s[[0, 1, 2]], SubClass)) - assert_(isinstance(s[s > 0], SubClass)) + a = np.arange(5) + s = a.view(SubClass) + s_slice = s[:3] + assert_(type(s_slice) is SubClass) + assert_(s_slice.base is s) + assert_array_equal(s_slice, a[:3]) + + s_fancy = s[[0, 1, 2]] + assert_(type(s_fancy) is SubClass) + assert_(s_fancy.base is not s) + assert_(type(s_fancy.base) is np.ndarray) + assert_array_equal(s_fancy, a[[0, 1, 2]]) + assert_array_equal(s_fancy.base, a[[0, 1, 2]]) + + s_bool = s[s > 0] + assert_(type(s_bool) is SubClass) + assert_(s_bool.base is not s) + assert_(type(s_bool.base) is np.ndarray) + assert_array_equal(s_bool, a[a > 0]) + assert_array_equal(s_bool.base, a[a > 0]) def test_finalize_gets_full_info(self): # Array finalize should be called on the filled array. |