[Python-Dev] Dict suppressing exceptions

"Martin v. Löwis" martin at v.loewis.de
Sat Aug 12 07:57:00 CEST 2006


Guido van Rossum schrieb:

>> >    __eq__ methods should always return True or False. They should
>> >    only raise an exception if there is some internal error within
>> >    one of the objects being compared -- they should never raise
>> >    an exception because the other object is of an unexpected type.
>>
>> That policy is currently difficult to implement, but reasonable
>> (difficult because it is quite some code to write).
> 
> Why? Are you thinking of the standard library, or of an end user's
> __eq__ method? Returning False from your __eq__ if other's type is
> unexpected doesn't seem a lot of code. Or am I misunderstanding
> something?

It seemed like a lot of code to me: In the specific enum example,
I first wrote

  def __eq__(self, other):
    return self.EnumType is other.EnumType \
       and self.__value==other.__value

So this was wrong, as it did not take into account 'other' being
something completely different, and I wrote

  def __eq__(self, other):
    return type(self) is type(other) \
       and self.EnumType is other.EnumType \
       and self.__value==other.__value

Having two additional continuation lines seems quite difficult to
me, yet a version that breaks the expression into multiple statements
is even longer

  def __eq__(self, other):
    if type(self) is not type(other):
      return False
    if self.EnumType is not other.EnumType:
      return False
    return self.__value==other.__value

Compare this to the current two-line __cmp__ implementation:

  def __cmp__(self, other):
    assert self.Enumtype is other.EnumType
    return cmp(self.__value, other.__value)

This covers all comparisons just fine in two lines of method
body; to implement the __eq__ policy, you need another 6
lines. For consistency, you should also implement __ne__,
probably as

  def __ne__(self, other):
    return not self.__eq__(other)

I expect many people get this wrong, for example

http://pyref.infogami.com/__eq__
UserList.py

Also, there is confusion as to whether NotImplemented
should ever be returned in these. decimal.py believes
it does (for different types), sets.py believes it
doesn't.

Regards,
Martin


More information about the Python-Dev mailing list