Hello, Are they bugs in the Python docs or just some CPython implementation details that are purposely not documented? (but then, again, some of the docs seem to be at least not precise...):
In https://docs.python.org/3.4/reference/datamodel.html#object.__eq__ there is the statement: > 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. On the other hand, in https://docs.python.org/3.4/library/stdtypes.html#comparisons we read: > (in general, __lt__() and __eq__() are sufficient, if you want the > conventional meanings of the comparison operators) And, when I try the __eq__() stuff in CPython it seems that, indeed, the language provides a proper __ne__() implementation for me automatically (without need to implement __ne__() explicitly by myself): Python 3.4.0 (default, Mar 20 2014, 01:28:00) [...] >>> class A: ... def __eq__(self, other): ... if hasattr(self, 'x') and hasattr(other, 'x'): ... return self.x == other.x ... return NotImplemented ... >>> A() == A() False >>> A() != A() True >>> a = A() >>> a.x = 1 >>> a1 = A() >>> a1.x = 1 >>> a2 = A() >>> a2.x = 2 >>> a == a1 True >>> a != a1 False >>> a1 == a1 True >>> a1 != a1 False >>> a1 == a2 False >>> a1 != a2 True Is it a language guarantee (then, I believe, it should be documented) or just an implementation accident? (then, I believe, it still could be documented as a CPython implementation detail). See also the Python equivalent of the SimpleNamespace class (without __ne__() implemented explicitly): https://docs.python.org/3/library/types.html#types.SimpleNamespace On the other hand, the "__lt__() and __eq__() are sufficient" statement seems not to be true: >>> a < a1 False >>> a <= a1 Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: unorderable types: A() <= A() >>> a > a1 False >>> a >= a1 Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: unorderable types: A() >= A() >>> a1 < a2 True >>> a1 <= a2 Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: unorderable types: A() <= A() >>> a1 > a2 False >>> a1 >= a2 Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: unorderable types: A() >= A() On yet another hand, adding __le__() to that class seems to be perfectly sufficient (without adding __gt__() and __ge__()): >>> def le(self, other): ... if hasattr(self, 'x') and hasattr(other, 'x'): ... return self.x <= other.x ... return NotImplemented ... >>> A.__le__ = le >>> a < a1 False >>> a <= a1 True >>> a > a1 False >>> a >= a1 True >>> a1 < a2 True >>> a1 <= a2 True >>> a1 > a2 False >>> a1 >= a2 False What of all this stuff is a language guarantee and what is just an implementation accident? Shouldn't it be documented more accurately? Cheers. *j _______________________________________________ Python-Dev mailing list Python-Dev@python.org https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com