Description
NumPy allows this behavior in setitem
>>> import numpy as np
>>> x = np.empty((2, 3, 4))
>>> a = np.empty((1, 3, 4))
>>> x[1, ...].shape
(3, 4)
>>> x[1, ...] = a
This is sort of a "reverse broadcasting". The rhs can't be broadcast to the shape of the lhs, but it can be made into that shape by adding a size 1 dimension.
We should more explicitly disallow this in the spec. Right now the spec just says:
As implied by the broadcasting algorithm, in-place element-wise operations must not change the shape of the in-place array as a result of broadcasting.
I think it should also say something like "the shape of the right-hand side of an operation must be broadcastable into the shape of the left-hand side, after applying any indices". It's also not completely clear that this statement applies to plain __setitem__
as an "in-place operation".
Note that the NumPy developers have expressed interest in deprecating this behavior in NumPy numpy/numpy#10615 (comment) (@seberg). It's also worth noting that NumPy's documentation says
You may use slicing to set values in the array, but (unlike lists) you can never grow the array. The size of the value to be set in x[obj] = value must be (broadcastable) to the same shape as x[obj]."
which itself doesn't quite capture this "reverse broadcasting" semantics.
Currently the numpy.array_api implementation allows the above to work. I haven't checked any other array libraries.