Skip to content

BUG: NEP 50 inconsistency in copyto #26381

@seberg

Description

@seberg

As @ev-br noticed: Copyto is currently inconsistent in NEP 50, which will be noticed relatively rarely, because the default is same-kind casting, where it just doesn't matter.

It turns out, copyto is the only (meaningful) user of PyArray_AssignRawScalar when the input is 0-D, and that function is the only direct user of the old scalar logic.

Now, copyto runs into the same difficulty as ufuncs (even more niche), about how you define "safe" casting for Python int/float/complex. In principle, we could:

  1. Just designate that the src is an array, and ignore any subtleties (right now it uses old logic, which also kicks in for 0-d arrays).
    • Means that np.copyto(uint8_arr, 1000) wraps the integer (which is what happens right now anyway).
  2. Make a decision on how to define "safe" for Python scalars:
    • For integers, safe could be "fits the result" (based on the value).
    • For floats, safe is tricky, they always lose precision.

I don't care too much which way we go here, but I think we should punt this to NumPy 2.1 and then need to make a decision though. We were bound to have such issues, that it is actually using old logic is annoying, but not much worse than similar ones we must still have in Python.

The advantage of defining things as 2. is that it can make copyto behave like a ufunc: np.positive(src, out=dst, casting=...) (positive is just effectively an identity ufunc).
That part has the subtlety about mixing casting= with Python scalars (but not the issue about 0-D arrays).


I would be much obliged for input, there is a reason this is still there: Deciding what to do with scalars and cast-safety is not trivial and probably more of an "expectation" decision than trying to reason what is "right".

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions