-
-
Notifications
You must be signed in to change notification settings - Fork 12k
Description
As noted in #9147, ndarray.__eq__ special-cases void arrays, which means that array-likes cannot use __array_ufunc__ or to override it:__array_priority__
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.