You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
In-place operators typically behave the same as their out-of-place equivalents (excluding what happens with views). For example, if x and y are float64 arrays, then x += y and x = x + y are equivalent statements. However, something unexpected may happen when the right-hand operand has a dtype that would normally cause upcasting when combined with the left-hand operand according to NumPy's casting rules. In such cases, the in-place version doesn't upcast the left-hand operand, but downcasts the right-hand operand. To illustrate the difference:
>>># The in-place version:>>>a=np.array(1, dtype=np.int8)
>>>a+=np.array(2**12, dtype=np.int16)
>>>aarray(1, dtype=int8)
>>># The out-of-place version:>>>a+np.array(2**12, dtype=np.int16)
4097>>> (a+np.array(2**12, dtype=np.int16)).dtypedtype('int16')
This yields silently incorrect results, and seems undesirable.
It is already forbidden to do this with dtypes that aren't the same kind:
It seems like it would be safer if the behavior would only allow 'safe' rather than 'same_kind' casting. Making that change would avoid the silently incorrect results, and recover the property that in-place and out-of-place statements act the same.
This came up in the review of NEP 56 (gh-25542). We decided to punt on it there, since it's a little unclear how impactful deprecating unsafe casts are, and there is no hurry in making this change. It does seem desirable though.
The right course of action here is probably to implement this change in a branch, and then seeing what fails in test suites of downstream projects to assess the impact.
The text was updated successfully, but these errors were encountered:
Note the related report about the performance impact of no longer automatically casting scalars in #26183. While that is not going to change, perhaps worth mentioning here was the suggestion for in-place operations to use the dtype of the in-place array by default (instead of erroring with casting='safe'), i.e., assume that for an in-place operation one effectively has the equivalent of np.ufunc(in, other, out=in, dtype=in.dtype) - this could be just the implementation for the __i*__ operators, not a default that happens automatically for doing np.ufunc(in, other, out=in).
In-place operators typically behave the same as their out-of-place equivalents (excluding what happens with views). For example, if
x
andy
arefloat64
arrays, thenx += y
andx = x + y
are equivalent statements. However, something unexpected may happen when the right-hand operand has a dtype that would normally cause upcasting when combined with the left-hand operand according to NumPy's casting rules. In such cases, the in-place version doesn't upcast the left-hand operand, but downcasts the right-hand operand. To illustrate the difference:This yields silently incorrect results, and seems undesirable.
It is already forbidden to do this with dtypes that aren't the same kind:
It seems like it would be safer if the behavior would only allow
'safe'
rather than'same_kind'
casting. Making that change would avoid the silently incorrect results, and recover the property that in-place and out-of-place statements act the same.This came up in the review of NEP 56 (gh-25542). We decided to punt on it there, since it's a little unclear how impactful deprecating unsafe casts are, and there is no hurry in making this change. It does seem desirable though.
The right course of action here is probably to implement this change in a branch, and then seeing what fails in test suites of downstream projects to assess the impact.
The text was updated successfully, but these errors were encountered: