Skip to content

RFC: define behavior for __setitem__ when the assigned value promotes to the array's dtype #916

Open
@crusaderky

Description

@crusaderky

__setitem__ states:
https://data-apis.org/array-api/2024.12/API_specification/generated/array_api.array.__setitem__.html#array_api.array.__setitem__

Setting array values must not affect the data type of self.

When value is a Python scalar (i.e., int, float, complex, bool), behavior must follow specification guidance on mixing arrays with Python scalars (see Type Promotion Rules).

When value is an array of a different data type than self, how values are cast to the data type of self is implementation defined.

The last line is majorly problematic in my opinion and should be revised.
These use cases are left to the library's discretion:

  • setting a float array value into an integer array, e.g.
>>> a = xp.asarray([1], dtype=xp.int64)
>>> a[0] = xp.asarray(1.0)
  • setting a signed array value into an unsigned array, e.g.
>>> a = xp.asarray([1], dtype=xp.unt64)
>>> a[0] = xp.asarray(-2, dtype=xp.int8)
  • setting an array value with a larger dtype into a smaller dtype of the same kind, e.g.
>>> a = xp.asarray([1], dtype=xp.int8)
>>> a[0] = xp.asarray(2, dtype=xp.int64)

All these use cases are quietly allowed by numpy.
Sanity would dictate for them to be all disallowed, exactly like in binops.

If the last use case is allowed, it also opens the issue of in-place binops (__iadd__) etc.
Whereas out-of-place binops unambiguously must cast the smaller dtype to the larger one and then perform the operation, what is the correct process for in-place ones, when lhs has smaller dtype than rhs?

lhs[idx] = op(lhs[idx], xp.astype(rhs[idx], lhs.dtype))

or

lhs[idx] = xp.astype(op(lhs[idx], rhs[idx]), lhs.dtype)

which is the same as saying

t = xp.result_type(lhs, rhs)
lhs[idx] = xp.astype(op(xp.astype(lhs[idx], t), xp.astype(rhs[idx], t)), lhs.dtype)

? the output will subtly differ.

Metadata

Metadata

Assignees

No one assigned

    Labels

    RFCRequest for comments. Feature requests and proposed changes.

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions