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