Skip to content

Regression: Change in behaviour for np.array() on class that defines __array__ #13958

Closed
@mhvk

Description

@mhvk

An issue has been raised for numpy 1.17rc in astropy (astropy/astropy#8976), which after a bit of digging boils down to the change below in bahaviour for classes that define __array__ as well as a __len__ and __getitem__. I must admit I think the behaviour in both cases is strange, as it doesn't simply use __array__ but rather seems to iterate, but the behaviour in 1.17 definitely makes (even) less sense than that in 1.16.

import numpy as np
class A:
    """A recarray mimic in which one indexes items by order not name"""
    def __init__(self, item):
        self.item = item
    def __array__(self, dtype=None):
        return self.item
    def __len__(self):
        return len(self.item.dtype.names)
    def __getitem__(self, item):
        return self.item[self.item.dtype.names[item]]

dtype = np.dtype([('a', 'f'), ('b', 'i')])
rec1 = A(np.array((1., 1), dtype=dtype))
rec2 = A(np.array((2., 2), dtype=dtype))
np.array([rec1, rec2], dtype=object)
# numpy 1.16
# array([[array(1., dtype=float32), array(1, dtype=int32)],
#        [array(2., dtype=float32), array(2, dtype=int32)]], dtype=object)
# numpy 1.17rc
# array([[(1.0, 1), (1.0, 1)],
#        [(2.0, 2), (2.0, 2)]], dtype=object)

Note that the following do not depend on version:

len(rec1)
# 2
rec1[0]
# array(1., dtype=float32)
np.array(rec1)
# array((1., 1), dtype=[('a', '<f4'), ('b', '<i4')])

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions