diff options
author | Sebastian Berg <sebastian@sipsolutions.net> | 2021-10-29 13:42:09 -0500 |
---|---|---|
committer | Muhammad Motawe <muhammad.a.motawe@gmail.com> | 2021-10-30 17:10:01 +0000 |
commit | 7c512e05192376ae118f9c2a05faf0fe50673aa4 (patch) | |
tree | 196058cdbd1f568337e64cc9e94608743bad8bde | |
parent | a37a51c8faca87c0cf20a2765939c824a9b0fd37 (diff) | |
download | numpy-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.src | 4 | ||||
-rw-r--r-- | numpy/core/tests/test_numeric.py | 12 |
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 |