summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Doc/reference/datamodel.rst22
-rw-r--r--Lib/test/test_binop.py22
-rw-r--r--Misc/NEWS3
3 files changed, 37 insertions, 10 deletions
diff --git a/Doc/reference/datamodel.rst b/Doc/reference/datamodel.rst
index 2ca1194..e1d71b8 100644
--- a/Doc/reference/datamodel.rst
+++ b/Doc/reference/datamodel.rst
@@ -1276,10 +1276,14 @@ Basic customization
context (e.g., in the condition of an ``if`` statement), Python will call
:func:`bool` on the value to determine if the result is true or false.
- 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 :meth:`__eq__`, one should also define :meth:`__ne__` so that the
- operators will behave as expected. See the paragraph on :meth:`__hash__` for
+ By default, :meth:`__ne__` delegates to :meth:`__eq__` and
+ inverts the result unless it is ``NotImplemented``. There are no other
+ implied relationships among the comparison operators, for example,
+ the truth of ``(x<y or x==y)`` does not imply ``x<=y``.
+ To automatically generate ordering operations from a single root operation,
+ see :func:`functools.total_ordering`.
+
+ See the paragraph on :meth:`__hash__` for
some important notes on creating :term:`hashable` objects which support
custom comparison operations and are usable as dictionary keys.
@@ -1288,11 +1292,11 @@ Basic customization
rather, :meth:`__lt__` and :meth:`__gt__` are each other's reflection,
:meth:`__le__` and :meth:`__ge__` are each other's reflection, and
:meth:`__eq__` and :meth:`__ne__` are their own reflection.
-
- Arguments to rich comparison methods are never coerced.
-
- To automatically generate ordering operations from a single root operation,
- see :func:`functools.total_ordering`.
+ If the operands are of different types, and right operand's type is
+ a direct or indirect subclass of the left operand's type,
+ the reflected method of the right operand has priority, otherwise
+ the left operand's method has priority. Virtual subclassing is
+ not considered.
.. method:: object.__hash__(self)
diff --git a/Lib/test/test_binop.py b/Lib/test/test_binop.py
index 31dc785..823740c 100644
--- a/Lib/test/test_binop.py
+++ b/Lib/test/test_binop.py
@@ -3,6 +3,7 @@
import unittest
from test import support
from operator import eq, ne, lt, gt, le, ge
+from abc import ABCMeta
def gcd(a, b):
"""Greatest common divisor using Euclid's algorithm."""
@@ -332,7 +333,7 @@ class A(OperationLogger):
self.log_operation('A.__ge__')
return NotImplemented
-class B(OperationLogger):
+class B(OperationLogger, metaclass=ABCMeta):
def __eq__(self, other):
self.log_operation('B.__eq__')
return NotImplemented
@@ -354,6 +355,20 @@ class C(B):
self.log_operation('C.__ge__')
return NotImplemented
+class V(OperationLogger):
+ """Virtual subclass of B"""
+ def __eq__(self, other):
+ self.log_operation('V.__eq__')
+ return NotImplemented
+ def __le__(self, other):
+ self.log_operation('V.__le__')
+ return NotImplemented
+ def __ge__(self, other):
+ self.log_operation('V.__ge__')
+ return NotImplemented
+B.register(V)
+
+
class OperationOrderTests(unittest.TestCase):
def test_comparison_orders(self):
self.assertEqual(op_sequence(eq, A, A), ['A.__eq__', 'A.__eq__'])
@@ -369,5 +384,10 @@ class OperationOrderTests(unittest.TestCase):
self.assertEqual(op_sequence(le, B, C), ['C.__ge__', 'B.__le__'])
self.assertEqual(op_sequence(le, C, B), ['C.__le__', 'B.__ge__'])
+ self.assertTrue(issubclass(V, B))
+ self.assertEqual(op_sequence(eq, B, V), ['B.__eq__', 'V.__eq__'])
+ self.assertEqual(op_sequence(le, B, V), ['B.__le__', 'V.__ge__'])
+
+
if __name__ == "__main__":
unittest.main()
diff --git a/Misc/NEWS b/Misc/NEWS
index eada032..5fefcdb 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -13,6 +13,9 @@ Core and Builtins
Library
-------
+- Issue #4395: Better testing and documentation of binary operators.
+ Patch by Martin Panter.
+
- Issue #23973: Update typing.py from GitHub repo.
- Issue #23004: mock_open() now reads binary data correctly when the type of