-
-
Notifications
You must be signed in to change notification settings - Fork 10.8k
No way to mark "NotImplemented" for comparison operations on subclasses #4709
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
Comments
Query: so I get the feeling that you guys are probably pretty convinced at this point that dealing with numpy's subclassing machinery is a huge hassle. And on the numpy side, trying to keep duct-taping these things together so astropy keeps working is becoming quite a challenge (see also the whole mess with The blocker for this is that numpy doesn't yet have sufficiently robust support for parametrized dtypes to make this possible. And it could (again IMO), but no-one currently has time to make it happen. Any chance any of you guys would be interested in helping with that? It would require more effort upfront, but I'd be happy to provide design and review effort on the numpy side, the changes would have a bunch of other beneficial side-effects (e.g. we'd also much better support for missing data and categorical data), and it would solve all these quantity problems once and for all. |
Does just overriding Per Python subclassing rules, shouldn't in |
Ok, I see --- the subclass rule is not enough because Numpy scalars are not array subclasses, but aggressively compare all ndarrays. That can probably be worked around by overriding A better fix in Numpy might be to make Numpy scalar comparisons return NotImplemented with ndarrays, so that the right-hand operation gets a chance to run. |
The subclass rule should be enough here, at least unless other subclasses with higher priority enter the picture. I think we fixed The idea of the change was that showing the error would make more sense then just returning False, so yeah, there is likely no easy way to get around this, though I could imagine some |
It fails for scalars, because scalars call tp_richcompare directly without doing the subclass check, and the ndarray tp_richcompare doesn't second-guess (which is the correct behavior). |
Fix in gh-4711 |
Masked arrays and matrices seem to still be a problem :/ The |
Thanks everyone for looking into this. If there's a low-hanging solution, that would be great. I agree that in the long run, the dtype solution is superior, but ideally (well, selfishly for us), it would be nice to have such a solution in place before these changes are released (and I want a pony, too) 😉. |
I believe python stdlib has a similar issue in the datetime module. If so, I doubt there is a "low-hanging solution" since that bug has not been resolved in 5 years. |
One solution is to just switch from I'm not exactly sure how this situation with two subclasses that don't know about each other is supposed to be handled in Python's binop override mechanism. Clearly some sort of co-operativity is required, but I'm not sure what is the best practice. |
One option to work around this would be to change the ndarray base class binop implementation to the C equivalent of
and be careful to do the same in MaskedArray binop implementations. Not sure if this has unintended consequences, however. |
I think we can close this. Please reopen if there are still open questions around |
In astropy, we have a
Quantity
class which is a subclass ofndarray
for physical quantities. One of its features is that if you compare two of them and the units aren't equivalent, they compare to false.In Numpy master (but not Numpy 1.8.x), as of 9b8f6c7 (@seberg), it seems there might no longer be a way to implement this, since raising an exception in
__array_prepare__
bubbles up throughndarray.richcompare
(it currently emits aDeprecationWarning
, but I understand will eventually pass the original exception through). Since__array_prepare__
is only able to return an instancendarray
(or subclass), there doesn't seem to be a way to flag to the comparison operator that what we really want isNotImplemented
. Overriding the__eq__
operators, etc., doesn't seem to be sufficient, since it can't handle the case where there is a (regular) array on the left hand side.Here's a minimal script to reproduce the issue (the actual code is much more complex, but this boils it down to the essence of the problem):
The output on Numpy 1.8.x is:
The output on Numpy master is:
If you uncomment the
__eq__
function above, the first test passes, but the second still fails.Is there a workaround here, or something I'm missing?
@mhvk, @astrofrog
The text was updated successfully, but these errors were encountered: