__eq__() inconvenience when subclassing set

Gabriel Genellina gagsl-py2 at yahoo.com.ar
Fri Oct 30 04:41:07 CET 2009

En Wed, 28 Oct 2009 23:12:53 -0300, Jess Austin <jess.austin at gmail.com>  

>>>> class mySet(set):
> ...     def __eq__(self, other):
> ...         print "called mySet.__eq__()!"
> ...         if isinstance(other, (set, frozenset)):
> ...             return True
> ...         return set.__eq__(self, other)
> ...
> Now I want the builtin set and frozenset types to use the new
> __eq__() with mySet symmetrically.
>>>> mySet() == set([1])
> called mySet.__eq__()!
> True
>>>> mySet() == frozenset([1])
> called mySet.__eq__()!
> True
>>>> set([1]) == mySet()
> called mySet.__eq__()!
> True
>>>> frozenset([1]) == mySet()
> False
> frozenset doesn't use mySet.__eq__() because mySet is not a subclass
> of frozenset as it is for set. [...failed attempts to inherit from both  
> set and frozenset...]
> I must redefine __eq__(), and I'd like to be able to compare
> instances of the class to both set and frozenset instances.

We know the last test fails because the == logic fails to recognize mySet  
(on the right side) as a "more specialized" object than frozenset (on the  
left side), because set and frozenset don't have a common base type  
(although they share a lot of implementation)

I think the only way would require modifying tp_richcompare of  
set/frozenset objects, so it is aware of subclasses on the right side.  
Currently, frozenset() == mySet() effectively ignores the fact that mySet  
is a subclass of set.

Gabriel Genellina

More information about the Python-list mailing list