summaryrefslogtreecommitdiff
path: root/numpy
diff options
context:
space:
mode:
authorSebastian Berg <sebastian@sipsolutions.net>2021-08-10 14:10:40 -0500
committerSebastian Berg <sebastian@sipsolutions.net>2021-10-11 19:32:35 -0500
commit2aeaa44c454d90e6efa140f539bcfbe5a9ca0a77 (patch)
tree1dd1a5c047c1664bef7a2138f8af198400a603ca /numpy
parentb5a76ef437b672535f0ab10fbb8342655a33ebe6 (diff)
downloadnumpy-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.c8
-rw-r--r--numpy/core/tests/test_ufunc.py16
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])