test_contains.py 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. from collections import deque
  2. import unittest
  3. from test.support import NEVER_EQ
  4. class base_set:
  5. def __init__(self, el):
  6. self.el = el
  7. class myset(base_set):
  8. def __contains__(self, el):
  9. return self.el == el
  10. class seq(base_set):
  11. def __getitem__(self, n):
  12. return [self.el][n]
  13. class TestContains(unittest.TestCase):
  14. def test_common_tests(self):
  15. a = base_set(1)
  16. b = myset(1)
  17. c = seq(1)
  18. self.assertIn(1, b)
  19. self.assertNotIn(0, b)
  20. self.assertIn(1, c)
  21. self.assertNotIn(0, c)
  22. self.assertRaises(TypeError, lambda: 1 in a)
  23. self.assertRaises(TypeError, lambda: 1 not in a)
  24. # test char in string
  25. self.assertIn('c', 'abc')
  26. self.assertNotIn('d', 'abc')
  27. self.assertIn('', '')
  28. self.assertIn('', 'abc')
  29. self.assertRaises(TypeError, lambda: None in 'abc')
  30. def test_builtin_sequence_types(self):
  31. # a collection of tests on builtin sequence types
  32. a = range(10)
  33. for i in a:
  34. self.assertIn(i, a)
  35. self.assertNotIn(16, a)
  36. self.assertNotIn(a, a)
  37. a = tuple(a)
  38. for i in a:
  39. self.assertIn(i, a)
  40. self.assertNotIn(16, a)
  41. self.assertNotIn(a, a)
  42. class Deviant1:
  43. """Behaves strangely when compared
  44. This class is designed to make sure that the contains code
  45. works when the list is modified during the check.
  46. """
  47. aList = list(range(15))
  48. def __eq__(self, other):
  49. if other == 12:
  50. self.aList.remove(12)
  51. self.aList.remove(13)
  52. self.aList.remove(14)
  53. return 0
  54. self.assertNotIn(Deviant1(), Deviant1.aList)
  55. def test_nonreflexive(self):
  56. # containment and equality tests involving elements that are
  57. # not necessarily equal to themselves
  58. values = float('nan'), 1, None, 'abc', NEVER_EQ
  59. constructors = list, tuple, dict.fromkeys, set, frozenset, deque
  60. for constructor in constructors:
  61. container = constructor(values)
  62. for elem in container:
  63. self.assertIn(elem, container)
  64. self.assertTrue(container == constructor(values))
  65. self.assertTrue(container == container)
  66. def test_block_fallback(self):
  67. # blocking fallback with __contains__ = None
  68. class ByContains(object):
  69. def __contains__(self, other):
  70. return False
  71. c = ByContains()
  72. class BlockContains(ByContains):
  73. """Is not a container
  74. This class is a perfectly good iterable (as tested by
  75. list(bc)), as well as inheriting from a perfectly good
  76. container, but __contains__ = None prevents the usual
  77. fallback to iteration in the container protocol. That
  78. is, normally, 0 in bc would fall back to the equivalent
  79. of any(x==0 for x in bc), but here it's blocked from
  80. doing so.
  81. """
  82. def __iter__(self):
  83. while False:
  84. yield None
  85. __contains__ = None
  86. bc = BlockContains()
  87. self.assertFalse(0 in c)
  88. self.assertFalse(0 in list(bc))
  89. self.assertRaises(TypeError, lambda: 0 in bc)
  90. if __name__ == '__main__':
  91. unittest.main()