Skip to content

BUG: np.ndarray.__array_function__ cannot be handle NEP 35 creation functions #27500

Closed

Description

@mhvk

Describe the issue:

NEP 35 introduced the ability to pass in an instance via like= for array creation functions such as zeros and arange, which are passed through __array_function__. But ndarray subclasses cannot use super().__array_function__: one gets

a = np.array([])
a.__array_function__(np.asarray, (np.ndarray,), [1., 2., 3.], {})

AttributeError: 'builtin_function_or_method' object has no attribute '_implementation'

Reproduce the code example:

import numpy as np
a = np.arange(3)
# Passing through reshape works fine
a.__array_function__(np.reshape, (np.ndarray,), (a, (3,1)), {})
# array([[0],
#        [1],
#        [2]])
# But not asarray
a.__array_function__(np.asarray, (np.ndarray,), [1., 2., 3.], {})
# AttributeError: 'builtin_function_or_method' object has no attribute '_implementation'

Error message:

No response

Python and NumPy Versions:

2.1.1
3.11.2 (main, Aug 26 2024, 07:20:54) [GCC 12.2.0]

Runtime Environment:

No response

Context for the issue:

Found while trying to add support for NEP 35 functions for astropy's Quantity.

Related: #27451, about these creation functions not being present in the output of np.testing.overrides.get_overridable_numpy_array_functions

Activity

  1. seberg commented on Oct 4, 2024

    @seberg
    Member

    Hmmm, yeah. Not that I am sure super() is very useful... Should we have an _implementation that just ignores the like=!? Or uses it for .view() on the result?
    (Just thinking that might be easier for symmetry then some dropping of like= itself.)

  2. mhvk commented on Oct 4, 2024

    @mhvk
    ContributorAuthor

    It is definitely not super useful, but I liked how for a subclass one does not have to know about _implementation generally, but can just call super(). Currently, the implementation of ndarray.__array_function__ explicitly looks for _implementation:

    PyObject *implementation = PyObject_GetAttr(func, npy_interned_str.implementation);
    if (implementation == NULL) {
    return NULL;

    Ideally, it would just call functions that do not have this directly. Note that __array_function__ is not passed the like argument, though it does have its type, so I guess in principle one could do a view. I don't know that that is really necessary, just not failing would be good enough!

    Note that I'm happy to make the change, just not quite sure what it should be: just call the function directly if there is no _implementation? That should be OK in principle...

  3. mhvk commented on Oct 4, 2024

    @mhvk
    ContributorAuthor

    p.s. Looking more at the code, I see that if a subclass does not define __array_function__ one is just passed on to the regular implementation, so it seems reasonable to do the same for a super() call.

  4. mhvk commented on Oct 4, 2024

    @mhvk
    ContributorAuthor

    @seberg - see #27504 for a possible fix (built on #27503, since I found I could cause segfaults with bad calls to ndarray.__array_function__...)

  5. seberg commented on Oct 4, 2024

    @seberg
    Member

    Thanks, I have to think about it abit and look at all of the open PRs on this in the next day or two!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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