Skip to content

BUG: __array__ method return object itself when returning an array with single item #29161

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
Daraan opened this issue Jun 10, 2025 · 1 comment
Labels

Comments

@Daraan
Copy link

Daraan commented Jun 10, 2025

Describe the issue:

I became aware of this from this recent SO question.

The expectation when returning np.array(self.data, dtype=object) inside __array__ would be to return the wrapped dict itself. However it returns the instance of the object itself.
I realized that when using ndmin=1 or [self.data] it returns the correct result, however this creates an unexpected additional dimension.

My further research showed that this happens always when returning single item array:

Reproduce the code example:

import numpy as np

class MyUserDict:
    def __array__(self, dtype=None, copy=None):
        return np.array(None, dtype=object)

arr = np.array([MyUserDict()])
print(arr)
print(type(arr[0]))

Output:

[<__main__.MyUserDict object at 0x7624203b1dd0>]
<class '__main__.MyUserDict'>

Expected:
[None]
NoneType

Python and NumPy Versions:

Tested with Python 3.10 & 3.11.
Numpy: 1.24.x & 2.2.4

Runtime Environment:

No response

Context for the issue:

No response

@Daraan Daraan changed the title BUG: __array__ method on UserDict returns object itself when returning an array with single item BUG: __array__ method return object itself when returning an array with single item Jun 10, 2025
@seberg
Copy link
Member

seberg commented Jun 10, 2025

There is nothing special about your UserDict here, the same happens for just NumPy arrays:

a = np.array(3, dtype=object)

np.asarray(a)    # just returns a
np.asarray([a])  # returns a list containing a

Unless you want to distinguish np.asarray(a, dtype=object) here, I am not sure there is much to be done about it. The trust is that NumPy has to effectively guess if you want to put in the array as an element, or assign the contents of that same array.

In the first case:

  • np.asarray(array) needs to return input arrays unchanged, we can't avoid that really.
  • np.asarray([a], dtype=object) often can't avoid packing the whole array, so unpacking it is also awkward... Thus the behavior.

I suppose you could invent a rule that may be slightly more spot-on (with some extra complexity in the code), such as "if all entries are arrays and 0-D, unpack them".
In particular np.asarray([None, a]) is an example where I think it would be arguably wrong to default to unpacking a, since you don't unpack the None (as you can't).

There may be some old discussions about this. I was once convinced that this is as good as it gets, but probably with the constraint "I don't want to change more than necessary".

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants