summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian Berg <sebastian@sipsolutions.net>2021-10-29 13:42:09 -0500
committerMuhammad Motawe <muhammad.a.motawe@gmail.com>2021-10-30 17:10:01 +0000
commit7c512e05192376ae118f9c2a05faf0fe50673aa4 (patch)
tree196058cdbd1f568337e64cc9e94608743bad8bde
parenta37a51c8faca87c0cf20a2765939c824a9b0fd37 (diff)
downloadnumpy-7c512e05192376ae118f9c2a05faf0fe50673aa4.tar.gz
BUG: `VOID_nonzero` could sometimes mutate alignment flag
This fixes that invocations of `VOID_nonzero` could flip the alignment flag on the original array even though the original array is not modified.
-rw-r--r--numpy/core/src/multiarray/arraytypes.c.src4
-rw-r--r--numpy/core/tests/test_numeric.py12
2 files changed, 14 insertions, 2 deletions
diff --git a/numpy/core/src/multiarray/arraytypes.c.src b/numpy/core/src/multiarray/arraytypes.c.src
index 9fe76845a..71808cc48 100644
--- a/numpy/core/src/multiarray/arraytypes.c.src
+++ b/numpy/core/src/multiarray/arraytypes.c.src
@@ -2759,10 +2759,10 @@ VOID_nonzero (char *ip, PyArrayObject *ap)
dummy_fields.descr = new;
if ((new->alignment > 1) && !__ALIGNED(ip + offset,
new->alignment)) {
- PyArray_CLEARFLAGS(ap, NPY_ARRAY_ALIGNED);
+ PyArray_CLEARFLAGS(dummy_arr, NPY_ARRAY_ALIGNED);
}
else {
- PyArray_ENABLEFLAGS(ap, NPY_ARRAY_ALIGNED);
+ PyArray_ENABLEFLAGS(dummy_arr, NPY_ARRAY_ALIGNED);
}
if (new->f->nonzero(ip+offset, dummy_arr)) {
nonz = NPY_TRUE;
diff --git a/numpy/core/tests/test_numeric.py b/numpy/core/tests/test_numeric.py
index 96173a482..ad9437911 100644
--- a/numpy/core/tests/test_numeric.py
+++ b/numpy/core/tests/test_numeric.py
@@ -1484,6 +1484,18 @@ class TestNonzero:
a = np.array([[False], [TrueThenFalse()]])
assert_raises(RuntimeError, np.nonzero, a)
+ def test_nonzero_sideffects_structured_void(self):
+ # Checks that structured void does not mutate alignment flag of
+ # original array.
+ arr = np.zeros(5, dtype="i1,i8,i8") # `ones` may short-circuit
+ assert arr.flags.aligned # structs are considered "aligned"
+ assert not arr["f2"].flags.aligned
+ # make sure that nonzero/count_nonzero do not flip the flag:
+ np.nonzero(arr)
+ assert arr.flags.aligned
+ np.count_nonzero(arr)
+ assert arr.flags.aligned
+
def test_nonzero_exception_safe(self):
# gh-13930