diff options
| author | Sebastian Berg <sebastian@sipsolutions.net> | 2021-08-10 14:10:40 -0500 |
|---|---|---|
| committer | Sebastian Berg <sebastian@sipsolutions.net> | 2021-10-11 19:32:35 -0500 |
| commit | 2aeaa44c454d90e6efa140f539bcfbe5a9ca0a77 (patch) | |
| tree | 1dd1a5c047c1664bef7a2138f8af198400a603ca /numpy | |
| parent | b5a76ef437b672535f0ab10fbb8342655a33ebe6 (diff) | |
| download | numpy-2aeaa44c454d90e6efa140f539bcfbe5a9ca0a77.tar.gz | |
TST: Add test for reduceat/accumulate output shape mismatch
At least the reduceat path seems to have been untested before.
The slight change in code layout (added assert) is just to make
the code slightly easier to read. Since otherwise it looks like
there is an additional `else` branch when `out` is given.
Diffstat (limited to 'numpy')
| -rw-r--r-- | numpy/core/src/umath/ufunc_object.c | 8 | ||||
| -rw-r--r-- | numpy/core/tests/test_ufunc.py | 16 |
2 files changed, 22 insertions, 2 deletions
diff --git a/numpy/core/src/umath/ufunc_object.c b/numpy/core/src/umath/ufunc_object.c index 1bdac0933..0a919e6f4 100644 --- a/numpy/core/src/umath/ufunc_object.c +++ b/numpy/core/src/umath/ufunc_object.c @@ -3524,8 +3524,12 @@ PyUFunc_Reduceat(PyUFuncObject *ufunc, PyArrayObject *arr, PyArrayObject *ind, Py_INCREF(out); } } - /* Allocate the output for when there's no outer iterator */ - else if (out == NULL) { + else { + /* + * Allocate the output for when there's no outer iterator, we always + * use the outer_iteration path when `out` is passed. + */ + assert(out == NULL); Py_INCREF(descrs[0]); op[0] = out = (PyArrayObject *)PyArray_NewFromDescr( &PyArray_Type, descrs[0], diff --git a/numpy/core/tests/test_ufunc.py b/numpy/core/tests/test_ufunc.py index fe0b07c6b..78833a33c 100644 --- a/numpy/core/tests/test_ufunc.py +++ b/numpy/core/tests/test_ufunc.py @@ -2155,6 +2155,22 @@ class TestUfunc: assert_equal(y_base[1,:], y_base_copy[1,:]) assert_equal(y_base[3,:], y_base_copy[3,:]) + @pytest.mark.parametrize("with_cast", [True, False]) + def test_reduceat_and_accumulate_out_shape_mismatch(self, with_cast): + # Should raise an error mentioning "shape" or "size" + arr = np.arange(5) + out = np.arange(3) # definitely wrong shape + if with_cast: + # If a cast is necessary on the output, we can be sure to use + # the generic NpyIter (non-fast) path. + out = out.astype(np.float64) + + with pytest.raises(ValueError, match="(shape|size)"): + np.add.reduceat(arr, [0, 3], out=out) + + with pytest.raises(ValueError, match="(shape|size)"): + np.add.accumulate(arr, out=out) + @pytest.mark.parametrize('out_shape', [(), (1,), (3,), (1, 1), (1, 3), (4, 3)]) @pytest.mark.parametrize('keepdims', [True, False]) |
