[Python-Dev] Exceptions in comparison operators

Mark Shannon mark at hotpy.org
Mon Mar 5 13:41:58 CET 2012


Comparing two objects (of the same type for simplicity)
involves a three stage lookup:
The class has the operator C.__eq__
It can be applied to operator (descriptor protocol): C().__eq__
and it produces a result: C().__eq__(C())

Exceptions can be raised in all 3 phases,
but an exception in the first phase is not really an error,
its just says the operation is not supported.
E.g.

class C: pass

C() == C() is False, rather than raising an Exception.

If an exception is raised in the 3rd stage, then it is propogated,
as follows:

class C:
    def __eq__(self, other):
        raise Exception("I'm incomparable")

C() == C()  raises an exception

However, if an exception is raised in the second phase (descriptor)
then it is silenced:

def no_eq(self):
     raise Exception("I'm incomparable")

class C:
    __eq__ = property(no_eq)

C() == C() is False.

But should it raise an exception?

The behaviour for arithmetic is different.

def no_add(self):
     raise Exception("I don't add up")

class C:
    __add__ = property(no_add)

C() + C() raises an exception.

So what is the "correct" behaviour?
It is my opinion that comparisons should behave like arithmetic
and raise an exception.

Cheers,
Mark


More information about the Python-Dev mailing list