__eq__() inconvenience when subclassing set

Jess Austin jess.austin at gmail.com
Mon Nov 2 20:05:42 EST 2009


On Nov 1, 1:13 am, "Gabriel Genellina" <gagsl-... at yahoo.com.ar> wrote:
> Looks like in 3.1 this can be done with bytes+str and viceversa, even if  
> bytes and str don't have a common ancestor (other than object; basestring  
> doesn't exist in 3.x):
>
> p3> Base = bytes
> p3> Other = str
> p3>
> p3> class Derived(Base):
> ...   def __eq__(self, other):
> ...     print('Derived.__eq__')
> ...     return True
> ...
> p3> Derived()==Base()
> Derived.__eq__
> True
> p3> Base()==Derived()
> Derived.__eq__
> True
> p3> Derived()==Other()
> Derived.__eq__
> True
> p3> Other()==Derived()
> Derived.__eq__            # !!!
> True
> p3> Base.mro()
> [<class 'bytes'>, <class 'object'>]
> p3> Other.mro()
> [<class 'str'>, <class 'object'>]
>
> The same example with set+frozenset (the one you're actually interested  
> in) doesn't work, unfortunately.
> After further analysis, this works for bytes and str because both types  
> refuse to guess and compare to each other; they return NotImplemented when  
> the right-side operand is not of the same type. And this gives that other  
> operand the chance of being called.
>
> set and frozenset, on the other hand, are promiscuous: their  
> tp_richcompare slot happily accepts any set of any kind, derived or not,  
> and compares their contents. I think it should be a bit more strict: if  
> the right hand side is not of the same type, and its tp_richcompare slot  
> is not the default one, it should return NotImplemented. This way the  
> other type has a chance to be called.

Thanks for this, Gabriel!  There seems to be a difference between the
two cases, however:

>>> str() == bytes()
False
>>> set() == frozenset()
True

I doubt that either of these invariants is amenable to modification,
even for purposes of "consistency".  I'm not sure how to resolve this,
but you've definitely helped me here.  Perhaps the test in
set_richcompare can return NotImplemented in particular cases but not
in others?  I'll think about this; let me know if you come up with
anything more.

thanks,
Jess



More information about the Python-list mailing list