LEFT | RIGHT |
1 """Tests for binary operators on subtypes of built-in types.""" | 1 """Tests for binary operators on subtypes of built-in types.""" |
2 | 2 |
3 import unittest | 3 import unittest |
4 from test import support | 4 from test import support |
5 from operator import eq, ne, lt, gt, le, ge | 5 from operator import eq, le, ne |
6 from abc import ABCMeta | 6 from abc import ABCMeta |
7 | 7 |
8 def gcd(a, b): | 8 def gcd(a, b): |
9 """Greatest common divisor using Euclid's algorithm.""" | 9 """Greatest common divisor using Euclid's algorithm.""" |
10 while a: | 10 while a: |
11 a, b = b%a, a | 11 a, b = b%a, a |
12 return b | 12 return b |
13 | 13 |
14 def isint(x): | 14 def isint(x): |
15 """Test whether an object is an instance of int.""" | 15 """Test whether an object is an instance of int.""" |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
51 """Accessor function for read-only 'num' attribute of Rat.""" | 51 """Accessor function for read-only 'num' attribute of Rat.""" |
52 return self.__num | 52 return self.__num |
53 num = property(_get_num, None) | 53 num = property(_get_num, None) |
54 | 54 |
55 def _get_den(self): | 55 def _get_den(self): |
56 """Accessor function for read-only 'den' attribute of Rat.""" | 56 """Accessor function for read-only 'den' attribute of Rat.""" |
57 return self.__den | 57 return self.__den |
58 den = property(_get_den, None) | 58 den = property(_get_den, None) |
59 | 59 |
60 def __repr__(self): | 60 def __repr__(self): |
61 """Convert a Rat to an string resembling a Rat constructor call.""" | 61 """Convert a Rat to a string resembling a Rat constructor call.""" |
62 return "Rat(%d, %d)" % (self.__num, self.__den) | 62 return "Rat(%d, %d)" % (self.__num, self.__den) |
63 | 63 |
64 def __str__(self): | 64 def __str__(self): |
65 """Convert a Rat to a string resembling a decimal numeric value.""" | 65 """Convert a Rat to a string resembling a decimal numeric value.""" |
66 return str(float(self)) | 66 return str(float(self)) |
67 | 67 |
68 def __float__(self): | 68 def __float__(self): |
69 """Convert a Rat to a float.""" | 69 """Convert a Rat to a float.""" |
70 return self.__num*1.0/self.__den | 70 return self.__num*1.0/self.__den |
71 | 71 |
(...skipping 309 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
381 self.assertEqual(op_sequence(le, A, A), ['A.__le__', 'A.__ge__']) | 381 self.assertEqual(op_sequence(le, A, A), ['A.__le__', 'A.__ge__']) |
382 self.assertEqual(op_sequence(le, A, B), ['A.__le__', 'B.__ge__']) | 382 self.assertEqual(op_sequence(le, A, B), ['A.__le__', 'B.__ge__']) |
383 self.assertEqual(op_sequence(le, B, A), ['B.__le__', 'A.__ge__']) | 383 self.assertEqual(op_sequence(le, B, A), ['B.__le__', 'A.__ge__']) |
384 self.assertEqual(op_sequence(le, B, C), ['C.__ge__', 'B.__le__']) | 384 self.assertEqual(op_sequence(le, B, C), ['C.__ge__', 'B.__le__']) |
385 self.assertEqual(op_sequence(le, C, B), ['C.__le__', 'B.__ge__']) | 385 self.assertEqual(op_sequence(le, C, B), ['C.__le__', 'B.__ge__']) |
386 | 386 |
387 self.assertTrue(issubclass(V, B)) | 387 self.assertTrue(issubclass(V, B)) |
388 self.assertEqual(op_sequence(eq, B, V), ['B.__eq__', 'V.__eq__']) | 388 self.assertEqual(op_sequence(eq, B, V), ['B.__eq__', 'V.__eq__']) |
389 self.assertEqual(op_sequence(le, B, V), ['B.__le__', 'V.__ge__']) | 389 self.assertEqual(op_sequence(le, B, V), ['B.__le__', 'V.__ge__']) |
390 | 390 |
391 class E(object): | 391 class SupEq(object): |
392 """Class that can test equality""" | 392 """Class that can test equality""" |
393 def __eq__(self, other): | 393 def __eq__(self, other): |
394 return True | 394 return True |
395 | 395 |
396 class S(E): | 396 class S(SupEq): |
397 """Subclass of E that should fail""" | 397 """Subclass of SupEq that should fail""" |
398 __eq__ = None | 398 __eq__ = None |
399 | 399 |
400 class F(object): | 400 class F(object): |
401 """Independent class that should fall back""" | 401 """Independent class that should fall back""" |
402 | 402 |
403 class X(object): | 403 class X(object): |
404 """Independent class that should fail""" | 404 """Independent class that should fail""" |
405 __eq__ = None | 405 __eq__ = None |
406 | 406 |
| 407 class SN(SupEq): |
| 408 """Subclass of SupEq that can test equality, but not non-equality""" |
| 409 __ne__ = None |
| 410 |
| 411 class XN: |
| 412 """Independent class that can test equality, but not non-equality""" |
| 413 def __eq__(self, other): |
| 414 return True |
| 415 __ne__ = None |
| 416 |
407 class FallbackBlockingTests(unittest.TestCase): | 417 class FallbackBlockingTests(unittest.TestCase): |
408 def test_fallback_blocking(self): | 418 """Unit tests for None method blocking""" |
409 e, f, s, x = E(), F(), S(), X() | 419 |
| 420 def test_fallback_rmethod_blocking(self): |
| 421 e, f, s, x = SupEq(), F(), S(), X() |
410 self.assertEqual(e, e) | 422 self.assertEqual(e, e) |
411 self.assertEqual(e, f) | 423 self.assertEqual(e, f) |
412 self.assertEqual(f, e) | 424 self.assertEqual(f, e) |
413 # left operand is checked first | 425 # left operand is checked first |
414 self.assertEqual(e, x) | 426 self.assertEqual(e, x) |
415 self.assertRaises(TypeError, eq, x, e) | 427 self.assertRaises(TypeError, eq, x, e) |
416 # S is a subclass, so it's always checked first | 428 # S is a subclass, so it's always checked first |
417 self.assertRaises(TypeError, eq, e, s) | 429 self.assertRaises(TypeError, eq, e, s) |
418 self.assertRaises(TypeError, eq, s, e) | 430 self.assertRaises(TypeError, eq, s, e) |
419 | 431 |
| 432 def test_fallback_ne_blocking(self): |
| 433 e, sn, xn = SupEq(), SN(), XN() |
| 434 self.assertFalse(e != e) |
| 435 self.assertRaises(TypeError, ne, e, sn) |
| 436 self.assertRaises(TypeError, ne, sn, e) |
| 437 self.assertFalse(e != xn) |
| 438 self.assertRaises(TypeError, ne, xn, e) |
| 439 |
420 if __name__ == "__main__": | 440 if __name__ == "__main__": |
421 unittest.main() | 441 unittest.main() |
LEFT | RIGHT |