summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarten van Kerkwijk <mhvk@astro.utoronto.ca>2018-09-19 09:45:43 -0400
committerMarten van Kerkwijk <mhvk@astro.utoronto.ca>2018-09-19 09:51:05 -0400
commitde46fecdecf6a5ed40991ffc82d4bfc36d74c10d (patch)
treefd3c31a8bf3b358c3122f7fa564f1022f17b81d9
parent9741ce23eeeb972d5097cd8d5a835c67fb40ff26 (diff)
downloadnumpy-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.c2
-rw-r--r--numpy/core/tests/test_indexing.py30
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.