summaryrefslogtreecommitdiffstats
path: root/Lib/test/test_binop.py
diff options
context:
space:
mode:
authorMark Dickinson <dickinsm@gmail.com>2009-11-15 13:58:49 (GMT)
committerMark Dickinson <dickinsm@gmail.com>2009-11-15 13:58:49 (GMT)
commit6f1d04945b98cd66b95131833942526c85bbb867 (patch)
tree7c6bdef12d242b18389d4c46e6c984aadadf3b98 /Lib/test/test_binop.py
parentf4243f6d1f1a7512751d26235a492c24a9a4c76c (diff)
downloadcpython-6f1d04945b98cd66b95131833942526c85bbb867.zip
cpython-6f1d04945b98cd66b95131833942526c85bbb867.tar.gz
cpython-6f1d04945b98cd66b95131833942526c85bbb867.tar.bz2
Issue #6970: Remove redundant calls made when comparing objects.
Diffstat (limited to 'Lib/test/test_binop.py')
-rw-r--r--Lib/test/test_binop.py74
1 files changed, 72 insertions, 2 deletions
diff --git a/Lib/test/test_binop.py b/Lib/test/test_binop.py
index 5d77f23..c7987b2 100644
--- a/Lib/test/test_binop.py
+++ b/Lib/test/test_binop.py
@@ -2,6 +2,7 @@
import unittest
from test import support
+from operator import eq, ne, lt, gt, le, ge
def gcd(a, b):
"""Greatest common divisor using Euclid's algorithm."""
@@ -305,9 +306,78 @@ class RatTestCase(unittest.TestCase):
# XXX Ran out of steam; TO DO: divmod, div, future division
-def test_main():
- support.run_unittest(RatTestCase)
+class OperationLogger:
+ """Base class for classes with operation logging."""
+ def __init__(self, logger):
+ self.logger = logger
+ def log_operation(self, *args):
+ self.logger(*args)
+
+def op_sequence(op, *classes):
+ """Return the sequence of operations that results from applying
+ the operation `op` to instances of the given classes."""
+ log = []
+ instances = []
+ for c in classes:
+ instances.append(c(log.append))
+
+ try:
+ op(*instances)
+ except TypeError:
+ pass
+ return log
+
+class A(OperationLogger):
+ def __eq__(self, other):
+ self.log_operation('A.__eq__')
+ return NotImplemented
+ def __le__(self, other):
+ self.log_operation('A.__le__')
+ return NotImplemented
+ def __ge__(self, other):
+ self.log_operation('A.__ge__')
+ return NotImplemented
+
+class B(OperationLogger):
+ def __eq__(self, other):
+ self.log_operation('B.__eq__')
+ return NotImplemented
+ def __le__(self, other):
+ self.log_operation('B.__le__')
+ return NotImplemented
+ def __ge__(self, other):
+ self.log_operation('B.__ge__')
+ return NotImplemented
+
+class C(B):
+ def __eq__(self, other):
+ self.log_operation('C.__eq__')
+ return NotImplemented
+ def __le__(self, other):
+ self.log_operation('C.__le__')
+ return NotImplemented
+ def __ge__(self, other):
+ self.log_operation('C.__ge__')
+ return NotImplemented
+
+class OperationOrderTests(unittest.TestCase):
+ def test_comparison_orders(self):
+ self.assertEqual(op_sequence(eq, A, A), ['A.__eq__', 'A.__eq__'])
+ self.assertEqual(op_sequence(eq, A, B), ['A.__eq__', 'B.__eq__'])
+ self.assertEqual(op_sequence(eq, B, A), ['B.__eq__', 'A.__eq__'])
+ # C is a subclass of B, so C.__eq__ is called first
+ self.assertEqual(op_sequence(eq, B, C), ['C.__eq__', 'B.__eq__'])
+ self.assertEqual(op_sequence(eq, C, B), ['C.__eq__', 'B.__eq__'])
+
+ self.assertEqual(op_sequence(le, A, A), ['A.__le__', 'A.__ge__'])
+ self.assertEqual(op_sequence(le, A, B), ['A.__le__', 'B.__ge__'])
+ self.assertEqual(op_sequence(le, B, A), ['B.__le__', 'A.__ge__'])
+ self.assertEqual(op_sequence(le, B, C), ['C.__ge__', 'B.__le__'])
+ self.assertEqual(op_sequence(le, C, B), ['C.__le__', 'B.__ge__'])
+
+def test_main():
+ support.run_unittest(RatTestCase, OperationOrderTests)
if __name__ == "__main__":
test_main()