Skip to content

BUG: ndarray.__eq__ does not respect overrides for void #9153

@mhvk

Description

@mhvk

As noted in #9147, ndarray.__eq__ special-cases void arrays, which means that array-likes cannot use __array_ufunc__ or __array_priority__ to override it:

class B(object):
    def __array_ufunc__(self, ufunc, method, *inputs, **kwargs):
        return 'B!'
    def __eq__(self, other):
        return 'B==B'

b = B()
x = np.array([(0, 1, 0)] * 10, dtype=[('f0', '<i4'), ('f1', '<i4'), ('f2', '<i4')])
b == x
# 'B==B'
x == b
# FutureWarning: elementwise == comparison failed and returning scalar instead;...
# False

Likely, all that is needed is to move the RICHCMP_GIVE_UP_IF_NEEDED line up to before the check on void types (see https://github.com/numpy/numpy/blob/master/numpy/core/src/multiarray/arrayobject.c#L1395)

EDIT: the above also means array-like's cannot override via __array_priority__ either.

EDIT 2: For subclasses, the situation is better. If they override __eq__, that will just get called by python. If they do not, things still work more or less, since the code gets elements from the arrays, and compares those using np.equal and combines the results using np.logical_and, both of which do get overridden with __array_ufunc__.

EDIT 3: Crossed out text above reflects #9167, which moves RICHCMP_GIVE_UP_IF_NEEDED and thus solves __array_priority__ and __array_ufunc__ = None, but not a properly defined __array_ufunc__ like the example above.

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