summaryrefslogtreecommitdiff
path: root/numpy
diff options
context:
space:
mode:
authorSebastian Berg <sebastianb@nvidia.com>2022-10-20 09:34:32 +0200
committerSebastian Berg <sebastianb@nvidia.com>2022-10-20 09:53:48 +0200
commit9a5c2f5c56c75f823f96615786819d6d52500899 (patch)
tree5d0002389a910a85ef8b42ae9ab7fdd629b31959 /numpy
parentaed648cceed90b4ae8850ca8d17202578eac654c (diff)
downloadnumpy-9a5c2f5c56c75f823f96615786819d6d52500899.tar.gz
ENH: Allow all allocated operands in nditer/NpyIter
This allows all operands to be allocated, it is necessary to provide the dtype in this case, if missing the error changes from ``ValueError`` to ``TypeError`` Closes gh-13934, gh-15140
Diffstat (limited to 'numpy')
-rw-r--r--numpy/core/src/multiarray/nditer_constr.c16
-rw-r--r--numpy/core/tests/test_nditer.py16
2 files changed, 13 insertions, 19 deletions
diff --git a/numpy/core/src/multiarray/nditer_constr.c b/numpy/core/src/multiarray/nditer_constr.c
index b6acce570..9134e9f04 100644
--- a/numpy/core/src/multiarray/nditer_constr.c
+++ b/numpy/core/src/multiarray/nditer_constr.c
@@ -1225,22 +1225,6 @@ npyiter_prepare_operands(int nop, PyArrayObject **op_in,
}
}
- /* If all the operands were NULL, it's an error */
- if (op[0] == NULL) {
- int all_null = 1;
- for (iop = 1; iop < nop; ++iop) {
- if (op[iop] != NULL) {
- all_null = 0;
- break;
- }
- }
- if (all_null) {
- PyErr_SetString(PyExc_ValueError,
- "At least one iterator operand must be non-NULL");
- goto fail_nop;
- }
- }
-
if (any_writemasked_ops && maskop < 0) {
PyErr_SetString(PyExc_ValueError,
"An iterator operand was flagged as WRITEMASKED, "
diff --git a/numpy/core/tests/test_nditer.py b/numpy/core/tests/test_nditer.py
index b43bc50e9..473ea9754 100644
--- a/numpy/core/tests/test_nditer.py
+++ b/numpy/core/tests/test_nditer.py
@@ -1594,11 +1594,12 @@ def test_iter_allocate_output_errors():
# Allocated output can't have buffering without delayed bufalloc
assert_raises(ValueError, nditer, [a, None], ['buffered'],
['allocate', 'readwrite'])
- # Must specify at least one input
- assert_raises(ValueError, nditer, [None, None], [],
+ # Must specify dtype if there are no inputs (cannot promote existing ones;
+ # maybe this should use the 'f4' here, but it does not historically.)
+ assert_raises(TypeError, nditer, [None, None], [],
[['writeonly', 'allocate'],
['writeonly', 'allocate']],
- op_dtypes=[np.dtype('f4'), np.dtype('f4')])
+ op_dtypes=[None, np.dtype('f4')])
# If using op_axes, must specify all the axes
a = arange(24, dtype='i4').reshape(2, 3, 4)
assert_raises(ValueError, nditer, [a, None], [],
@@ -1623,6 +1624,15 @@ def test_iter_allocate_output_errors():
op_dtypes=[None, np.dtype('f4')],
op_axes=[None, [0, np.newaxis, 2]])
+def test_all_allocated():
+ # When no output and no shape is given, `()` is used as shape.
+ i = np.nditer([None], op_dtypes=["int64"])
+ assert i.operands[0].shape == ()
+ assert i.dtypes == (np.dtype("int64"),)
+
+ i = np.nditer([None], op_dtypes=["int64"], itershape=(2, 3, 4))
+ assert i.operands[0].shape == (2, 3, 4)
+
def test_iter_remove_axis():
a = arange(24).reshape(2, 3, 4)