diff options
| author | Sebastian Berg <sebastianb@nvidia.com> | 2022-10-20 09:34:32 +0200 |
|---|---|---|
| committer | Sebastian Berg <sebastianb@nvidia.com> | 2022-10-20 09:53:48 +0200 |
| commit | 9a5c2f5c56c75f823f96615786819d6d52500899 (patch) | |
| tree | 5d0002389a910a85ef8b42ae9ab7fdd629b31959 /numpy | |
| parent | aed648cceed90b4ae8850ca8d17202578eac654c (diff) | |
| download | numpy-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.c | 16 | ||||
| -rw-r--r-- | numpy/core/tests/test_nditer.py | 16 |
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) |
