__eq__ and sets

Tim Peters tim.one at comcast.net
Tue Feb 25 16:20:58 EST 2003


[Chris Reedy]
> I recently encountered the following:
>
>  >>> from sets import Set
>  >>> x = Set([1])
>  >>> x == 2
> TypeError: Binary operation only permitted between sets
>
> The TypeError is raised by Set.__eq__ (actually BaseSet.__eq__) upon
> recognizing that 2 is not a set.
>
> My question: Is this the expected and/or appropriate behavior?

It's the implemented behavior <wink>.

> In the case in question, I was expecting false to be returned. Changing
> the __eq__ and __ne__ operators in sets.py to return NotImplemented
> instead or raising an exception would result in the behavior I was
> expecting.

No, it wouldn't.  If, when you compare x to y, both objects return
NotImplemented, Python automatically falls back to comparing x and y by
their memory addresses (cmp(id(x), id(y))).  The Set class definitely didn't
want you to get a nonsense result from "x == 2", and, in the absence of a
meaningful result, the only way to stop the comparison machinery from
falling back to address comparison is to raise an exception.

The objects in the new (for 2.3) datetime module used to raise an exception
on mixed-type comparisons too.  Between 2.3a1 and 2.3a2, I changed them so
that mixed-type __eq__ comparison returns False, and mixed-type __ne__
comparison returns True.  This is discussed in the 2.3a2 NEWS file, and I
think that may be a useful strategy for other types of objects that don't
want to fall back to address comparison.  It allows things like "x in
sequence" to work without raising pointless TypeErrors.






More information about the Python-list mailing list