Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(11)

Delta Between Two Patch Sets: Lib/test/test_binop.py

Issue 25958: Implicit ABCs have no means of "anti-registration"
Left Patch Set: Created 4 years, 1 month ago
Right Patch Set: Created 3 years, 6 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
« no previous file with change/comment | « Lib/test/test_augassign.py ('k') | Lib/test/test_bool.py » ('j') | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
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
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
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):
storchaka 2016/01/06 21:55:31 (object) is not needed in Python 3.
abarnert 2016/01/06 23:04:32 Of course, but it's used in all of the other test
Martin Panter 2016/01/09 02:34:56 IMO it is better to be locally consistent (see cla
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):
storchaka 2016/01/06 21:55:31 (object) is not needed in Python 3.
404 """Independent class that should fail""" 404 """Independent class that should fail"""
405 __eq__ = None 405 __eq__ = None
406 406
407 class SN(E): 407 class SN(SupEq):
408 """Subclass of E that can test equality, but not non-equality""" 408 """Subclass of SupEq that can test equality, but not non-equality"""
409 __ne__ = None 409 __ne__ = None
410 410
411 class XN: 411 class XN:
412 """Independent class that can test equality, but not non-equality""" 412 """Independent class that can test equality, but not non-equality"""
413 def __eq__(self, other): 413 def __eq__(self, other):
414 return True 414 return True
415 __ne__ = None 415 __ne__ = None
416 416
417 class FallbackBlockingTests(unittest.TestCase): 417 class FallbackBlockingTests(unittest.TestCase):
418 """Unit tests for None method blocking"""
419
418 def test_fallback_rmethod_blocking(self): 420 def test_fallback_rmethod_blocking(self):
419 e, f, s, x = E(), F(), S(), X() 421 e, f, s, x = SupEq(), F(), S(), X()
storchaka 2016/01/06 21:55:31 Since there are 4 classes, shouldn't you test all
abarnert 2016/01/06 23:04:32 There's no need for the full cartesian product of
Martin Panter 2016/01/09 02:34:56 I tend to agree, unless there is any particular co
420 self.assertEqual(e, e) 422 self.assertEqual(e, e)
storchaka 2016/01/06 21:55:31 Perhaps it would be better to write explicitly as
abarnert 2016/01/06 23:04:32 Maybe? But the other tests for __eq__ use assertEq
Martin Panter 2016/01/09 02:34:56 Your tests for __ne__ use “!=”. It is more explici
421 self.assertEqual(e, f) 423 self.assertEqual(e, f)
422 self.assertEqual(f, e) 424 self.assertEqual(f, e)
423 # left operand is checked first 425 # left operand is checked first
424 self.assertEqual(e, x) 426 self.assertEqual(e, x)
425 self.assertRaises(TypeError, eq, x, e) 427 self.assertRaises(TypeError, eq, x, e)
426 # S is a subclass, so it's always checked first 428 # S is a subclass, so it's always checked first
427 self.assertRaises(TypeError, eq, e, s) 429 self.assertRaises(TypeError, eq, e, s)
428 self.assertRaises(TypeError, eq, s, e) 430 self.assertRaises(TypeError, eq, s, e)
431
429 def test_fallback_ne_blocking(self): 432 def test_fallback_ne_blocking(self):
storchaka 2016/01/06 21:55:31 Needed an empty line between methods.
abarnert 2016/01/06 23:04:32 Oops; thanks, I'll fix that.
430 e, sn, xn = E(), SN(), XN() 433 e, sn, xn = SupEq(), SN(), XN()
431 self.assertFalse(e != e) 434 self.assertFalse(e != e)
432 self.assertRaises(TypeError, ne, e, sn) 435 self.assertRaises(TypeError, ne, e, sn)
433 self.assertRaises(TypeError, ne, sn, e) 436 self.assertRaises(TypeError, ne, sn, e)
434 self.assertFalse(e != xn) 437 self.assertFalse(e != xn)
435 self.assertRaises(TypeError, ne, xn, e) 438 self.assertRaises(TypeError, ne, xn, e)
436 439
storchaka 2016/01/06 21:55:31 Default __ne__ falls back to __eq__. It is worth t
abarnert 2016/01/06 23:04:32 I don't think so. What could an implementation do
Martin Panter 2016/01/09 02:34:56 The key question is: given a.__eq__ has priority b
437 if __name__ == "__main__": 440 if __name__ == "__main__":
438 unittest.main() 441 unittest.main()
LEFTRIGHT

RSS Feeds Recent Issues | This issue
This is Rietveld 894c83f36cb7+