Skip to content

ENH: pass copy=True to __array__ #26208

Closed

Description

@ngoldbaum

This is followup for #25941.

As of NumPy 2.0, __array__ implementations will never receive copy=True when NumPy calls the function. As a followup for adding the copy keyword, we need to first prevent numpy from making a copy before calling __array__ and pass copy=True to __array__ implementations. We also need to update the documentation to emphasize that the library is responsible for making a copy, or if making a copy is impossible, raising an error.

Activity

  1. self-assigned this
    on Apr 4, 2024
  2. mtsokol commented on Apr 4, 2024

    @mtsokol
    Member

    Hi @ngoldbaum @seberg,

    I followed np.array implementation and, if I understood it correctly, we need to prevent numpy from making a copy after __array__ is called rather than before.

    def __array__() (with copy argument) is only called deep inside PyArray_DiscoverDTypeAndShape which is meant to discover ndims. I think the result of __array__ is stored in a cache passed to that function (first copy, 1. in the photo), but then this cache is passed in ctors.c::1622:

    arr = (PyArrayObject *)(cache->arr_or_sequence);
    /* we may need to cast or assert flags (e.g. copy) */
    PyObject *res = PyArray_FromArray(arr, dtype, flags);

    where flags still has "copy always" (second copy?, 2. in the photo).

    My question: Would it be sufficient to avoid the second copy by changing "copy always" flag to "copy if needed" in flags, as the cache that was provisioned in Py_Array_Discover... already holds a copy?

  3. seberg commented on Apr 4, 2024

    @seberg
    Member

    Well, there are two things to note I guess:

    • When the discovery finds an array immediately, we may or may not already get a copy if we pass it on with copy=True. But that of course only works for __array__ and none of the others, so would need to add the copy logic also for others or indicate that a copy was made.
    • When the discovery finds a sequence (of arrays), a copy has to be made in any case and it doesn't make sense to keep passing on copy=True to __array__. (also we must fail for copy=False, but I think we do)
  4. mtsokol commented on Apr 4, 2024

    @mtsokol
    Member

    Then I can try with copy was made indicator that is set by Py_Array_Discover..., that would remove that flag for further processing.

  5. changed the title [-]ENH: pass copy=True to __array__[/-] [+]ENH: pass `copy=True` to `__array__`[/+] on Apr 5, 2024
  6. added a commit that references this issue on Apr 15, 2024
  7. added a commit that references this issue on Apr 15, 2024
  8. added a commit that references this issue on May 25, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions