Description
The following code does not output "sub_class radd" as expected since NumPy ignores __array_priority__
when the right-hand-side operand is a subclass of ndarray.
import numpy as np
class sub_class(np.ndarray):
__array_priority__ = 1000
def __add__(self, rhs):
print "sub_class add"
def __radd__(self, lhs):
print "sub_class radd"
sub = sub_class((2,2))
np.float32(42.0) + sub
The problem is line 282 in number.c where a branch uses PyArray_Check()
to check the right-hand-side operand m2
. If PyArray_Check(m2)
returns True
, which is the case when m2
is a subclass of ndarray, __array_priority__
is ignored.
Now, this is not a problem when the left-hand-side operand is an ndarray since in CPython a subclass always takes precedence over its superclass. However, a NumPy scalar is not a sub-/super-class of ndarray as the example code above illustrates.
There is a very simple fix: change PyArray_Check(m2)
to PyArray_CheckExact(m2)
. However, this fix has the side-effect that the operation will fail with NotImplementedError if the subclass doesn’t implement the operator, which is a change to the current behavior.