[Python-Dev] operator precedence of eq, ne, etc, if both object have implementations (original) (raw)

Mark Dickinson dickinsm at gmail.com
Wed Sep 23 13:05:31 CEST 2009


On Wed, Sep 23, 2009 at 9:12 AM, Chris Withers <chris at simplistix.co.uk> wrote:

Mark Dickinson wrote:

I (still :-) think this is covered, for Python 2.x at least, by: http://docs.python.org/reference/datamodel.html#coercion-rules But this isn't coercion! :-)

Agreed. FWIW this behaviour for arithmetic operations is also mentioned in

http://docs.python.org/reference/datamodel.html#emulating-numeric-types

but then again that section doesn't include the comparison operators.

- For objects x and y, first x.op(y) is tried. If this is not implemented or returns NotImplemented, y.rop(x) is tried. Also, the above is not so: Python 2.5.1

class X: ...   def eq(self,other): ...     print "X eq" class Z: pass ... Z()==X() X eq No req in sight...

Okay, so combine this with the sentence under:

http://docs.python.org/reference/datamodel.html#object._eq_

that says:

"There are no swapped-argument versions of these methods (to be used when the left argument does not support the operation but the right argument does); rather, lt() and gt() are each other’s reflection, le() and ge() are each other’s reflection, and eq() and ne() are their own reflection."

So in the earlier doc snippets, if op is eq, then rop should also be interpreted as eq; similarly if op is lt then rop is gt.

I'm not saying that the documentation here couldn't be improved; just that IMO the docs do (with a little bit of extrapolation) describe what should happen, giving the 'official' specification that you were after.

I don't know where/whether the behaviour for classes that define both cmp and eq are documented, though, and I'm far from sure what the rules are in that case.

One minor oddity is that for arithmetic operations like add(self, other), if type(self) == type(other) then radd isn't checked, on the basis that if add fails then the operation is presumably not supported. This makes sense, but I wonder why this doesn't apply equally well to eq: that is, in doing A() == A() for a class A, why do we try the eq method of both instances?

Mark



More information about the Python-Dev mailing list