From dc5ec9818e140ed7c432501230c4318a2ffa3fa6 Mon Sep 17 00:00:00 2001 From: Sebastian Berg Date: Fri, 18 Jun 2021 14:01:18 -0500 Subject: [PATCH] BUG: Fix `arr.flat.index` for large or big-endian machines The type read when exposing was previously int, but has to be intp. this would only be visible for >2**31 elements, but is also visible on big-endian machines. Closes gh-19153 --- numpy/core/src/multiarray/iterators.c | 16 ++++++++++------ numpy/core/tests/test_multiarray.py | 11 +++++++++++ 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/numpy/core/src/multiarray/iterators.c b/numpy/core/src/multiarray/iterators.c index 640896f2a937..576ea89b32fc 100644 --- a/numpy/core/src/multiarray/iterators.c +++ b/numpy/core/src/multiarray/iterators.c @@ -1063,13 +1063,15 @@ static PyMemberDef iter_members[] = { T_OBJECT, offsetof(PyArrayIterObject, ao), READONLY, NULL}, - {"index", - T_INT, - offsetof(PyArrayIterObject, index), - READONLY, NULL}, {NULL, 0, 0, 0, NULL}, }; +static PyObject * +iter_index_get(PyArrayIterObject *self) +{ + return PyArray_PyIntFromIntp(self->index); +} + static PyObject * iter_coords_get(PyArrayIterObject *self) { @@ -1096,10 +1098,12 @@ iter_coords_get(PyArrayIterObject *self) } static PyGetSetDef iter_getsets[] = { + {"index", + (getter)iter_index_get, + NULL, NULL, NULL}, {"coords", (getter)iter_coords_get, - NULL, - NULL, NULL}, + NULL, NULL, NULL}, {NULL, NULL, NULL, NULL, NULL}, }; diff --git a/numpy/core/tests/test_multiarray.py b/numpy/core/tests/test_multiarray.py index d567653f5a4a..f807b90a3654 100644 --- a/numpy/core/tests/test_multiarray.py +++ b/numpy/core/tests/test_multiarray.py @@ -5364,6 +5364,17 @@ def test_refcount(self): assert_(abs(sys.getrefcount(ind) - rc_ind) < 50) assert_(abs(sys.getrefcount(indtype) - rc_indtype) < 50) + def test_index_getset(self): + it = np.arange(10).reshape(2, 1, 5).flat + with pytest.raises(AttributeError): + it.index = 10 + + for _ in it: + pass + # Check the value of `.index` is updated correctly (see also gh-19153) + # If the type was incorrect, this would show up on big-endian machines + assert it.index == it.base.size + class TestResize: