8000 Deprecating in-place operations where the out-of-place equivalent would upcast? · Issue #25621 · numpy/numpy · GitHub
[go: up one dir, main page]

Skip to content
Deprecating in-place operations where the out-of-place equivalent would upcast? #25621
Open
@rgommers

Description

@rgommers

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)
>>> a
array(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)).dtype
dtype('int16')

This yields silently incorrect results, and seems undesirable.

It is already forbidden to do this with dtypes that aren't the same kind:

>>> a += np.array(2**12, dtype=np.float16)
...
UFuncTypeError: Cannot cast ufunc 'add' output from dtype('float16') to dtype('int8') with casting rule '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.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      0