Reputation: 18720
In Python 3, if you provide an __eq__
method, a sensible __ne__
is also typically provided which makes use of your __eq__
. However, I have (in Python 3):
class SomeOtherClassWhichInheritsFromList(list):
def __init__(self):
super().__init__()
self.parval = 44
def __eq__(self, other):
print ("IN SomeOtherClassWhichInheritsFromList EQ")
if isinstance(other, SomeOtherClassWhichInheritsFromList):
return super().__eq__(other) and self.parval == other.parval
return NotImplemented
class SomeClass(SomeOtherClassWhichInheritsFromList):
def __init__(self, val):
super().__init__()
self.val = val
def __eq__(self, other):
print ("IN SomeClass EQ")
if isinstance(other, SomeClass):
return super().__eq__(other) and self.val == other.val
return NotImplemented
And if I do:
sc = SomeClass(99)
sc2 = SomeClass(104)
print (sc != sc2)
I would expect to see:
IN SomeClass EQ
IN SomeOtherClassWhichInheritsFromList EQ
True
But I instead see:
False
Indicating that my __eq__
isn't being called by the default provided __ne__
. If I change SomeOtherClassWhichInheritsFromList to inherit from object instead of list, it works as expected.
Is this because list does not seem to have an __mro__
attribute, and thus all the super()
stuff in my __eq__
methods fails to get triggered?
Note: I know I could add my own __ne__
method that calls my __eq__
(which I'll have to do since I do want to inherit from list), but what I'm looking for here is an explanation of why I have to do so.
Upvotes: 2
Views: 307
Reputation: 110536
If you define __eq__
you have to define __ne__
as well, always.
From the "Data Model" documentation for Python 3.2:
"""There are no implied relationships among the comparison operators. The truth of x==y does not imply that x!=y is false. Accordingly, when defining eq(), one should also define ne() so that the operators will behave as expected. """
What probably happen that you suppose that "In Python 3, if you provide an __eq__
method, a sensible __ne__
is also typically provided which makes use of your __eq__
. " - is that object
's __ne__
method does that. There is no reference to the behavior you state on the Data Model doc - although classes with no explicit superclass (therfore inheriting from object
) behave as you describe.
Upvotes: 4