• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Test properties of bool promised by PEP 285
2
3import unittest
4from test.support import os_helper
5
6import os
7
8class BoolTest(unittest.TestCase):
9
10    def test_subclass(self):
11        try:
12            class C(bool):
13                pass
14        except TypeError:
15            pass
16        else:
17            self.fail("bool should not be subclassable")
18
19        self.assertRaises(TypeError, int.__new__, bool, 0)
20
21    def test_repr(self):
22        self.assertEqual(repr(False), 'False')
23        self.assertEqual(repr(True), 'True')
24        self.assertIs(eval(repr(False)), False)
25        self.assertIs(eval(repr(True)), True)
26
27    def test_str(self):
28        self.assertEqual(str(False), 'False')
29        self.assertEqual(str(True), 'True')
30
31    def test_int(self):
32        self.assertEqual(int(False), 0)
33        self.assertIsNot(int(False), False)
34        self.assertEqual(int(True), 1)
35        self.assertIsNot(int(True), True)
36
37    def test_float(self):
38        self.assertEqual(float(False), 0.0)
39        self.assertIsNot(float(False), False)
40        self.assertEqual(float(True), 1.0)
41        self.assertIsNot(float(True), True)
42
43    def test_math(self):
44        self.assertEqual(+False, 0)
45        self.assertIsNot(+False, False)
46        self.assertEqual(-False, 0)
47        self.assertIsNot(-False, False)
48        self.assertEqual(abs(False), 0)
49        self.assertIsNot(abs(False), False)
50        self.assertEqual(+True, 1)
51        self.assertIsNot(+True, True)
52        self.assertEqual(-True, -1)
53        self.assertEqual(abs(True), 1)
54        self.assertIsNot(abs(True), True)
55        self.assertEqual(~False, -1)
56        self.assertEqual(~True, -2)
57
58        self.assertEqual(False+2, 2)
59        self.assertEqual(True+2, 3)
60        self.assertEqual(2+False, 2)
61        self.assertEqual(2+True, 3)
62
63        self.assertEqual(False+False, 0)
64        self.assertIsNot(False+False, False)
65        self.assertEqual(False+True, 1)
66        self.assertIsNot(False+True, True)
67        self.assertEqual(True+False, 1)
68        self.assertIsNot(True+False, True)
69        self.assertEqual(True+True, 2)
70
71        self.assertEqual(True-True, 0)
72        self.assertIsNot(True-True, False)
73        self.assertEqual(False-False, 0)
74        self.assertIsNot(False-False, False)
75        self.assertEqual(True-False, 1)
76        self.assertIsNot(True-False, True)
77        self.assertEqual(False-True, -1)
78
79        self.assertEqual(True*1, 1)
80        self.assertEqual(False*1, 0)
81        self.assertIsNot(False*1, False)
82
83        self.assertEqual(True/1, 1)
84        self.assertIsNot(True/1, True)
85        self.assertEqual(False/1, 0)
86        self.assertIsNot(False/1, False)
87
88        self.assertEqual(True%1, 0)
89        self.assertIsNot(True%1, False)
90        self.assertEqual(True%2, 1)
91        self.assertIsNot(True%2, True)
92        self.assertEqual(False%1, 0)
93        self.assertIsNot(False%1, False)
94
95        for b in False, True:
96            for i in 0, 1, 2:
97                self.assertEqual(b**i, int(b)**i)
98                self.assertIsNot(b**i, bool(int(b)**i))
99
100        for a in False, True:
101            for b in False, True:
102                self.assertIs(a&b, bool(int(a)&int(b)))
103                self.assertIs(a|b, bool(int(a)|int(b)))
104                self.assertIs(a^b, bool(int(a)^int(b)))
105                self.assertEqual(a&int(b), int(a)&int(b))
106                self.assertIsNot(a&int(b), bool(int(a)&int(b)))
107                self.assertEqual(a|int(b), int(a)|int(b))
108                self.assertIsNot(a|int(b), bool(int(a)|int(b)))
109                self.assertEqual(a^int(b), int(a)^int(b))
110                self.assertIsNot(a^int(b), bool(int(a)^int(b)))
111                self.assertEqual(int(a)&b, int(a)&int(b))
112                self.assertIsNot(int(a)&b, bool(int(a)&int(b)))
113                self.assertEqual(int(a)|b, int(a)|int(b))
114                self.assertIsNot(int(a)|b, bool(int(a)|int(b)))
115                self.assertEqual(int(a)^b, int(a)^int(b))
116                self.assertIsNot(int(a)^b, bool(int(a)^int(b)))
117
118        self.assertIs(1==1, True)
119        self.assertIs(1==0, False)
120        self.assertIs(0<1, True)
121        self.assertIs(1<0, False)
122        self.assertIs(0<=0, True)
123        self.assertIs(1<=0, False)
124        self.assertIs(1>0, True)
125        self.assertIs(1>1, False)
126        self.assertIs(1>=1, True)
127        self.assertIs(0>=1, False)
128        self.assertIs(0!=1, True)
129        self.assertIs(0!=0, False)
130
131        x = [1]
132        self.assertIs(x is x, True)
133        self.assertIs(x is not x, False)
134
135        self.assertIs(1 in x, True)
136        self.assertIs(0 in x, False)
137        self.assertIs(1 not in x, False)
138        self.assertIs(0 not in x, True)
139
140        x = {1: 2}
141        self.assertIs(x is x, True)
142        self.assertIs(x is not x, False)
143
144        self.assertIs(1 in x, True)
145        self.assertIs(0 in x, False)
146        self.assertIs(1 not in x, False)
147        self.assertIs(0 not in x, True)
148
149        self.assertIs(not True, False)
150        self.assertIs(not False, True)
151
152    def test_convert(self):
153        self.assertRaises(TypeError, bool, 42, 42)
154        self.assertIs(bool(10), True)
155        self.assertIs(bool(1), True)
156        self.assertIs(bool(-1), True)
157        self.assertIs(bool(0), False)
158        self.assertIs(bool("hello"), True)
159        self.assertIs(bool(""), False)
160        self.assertIs(bool(), False)
161
162    def test_keyword_args(self):
163        with self.assertRaisesRegex(TypeError, 'keyword argument'):
164            bool(x=10)
165
166    def test_format(self):
167        self.assertEqual("%d" % False, "0")
168        self.assertEqual("%d" % True, "1")
169        self.assertEqual("%x" % False, "0")
170        self.assertEqual("%x" % True, "1")
171
172    def test_hasattr(self):
173        self.assertIs(hasattr([], "append"), True)
174        self.assertIs(hasattr([], "wobble"), False)
175
176    def test_callable(self):
177        self.assertIs(callable(len), True)
178        self.assertIs(callable(1), False)
179
180    def test_isinstance(self):
181        self.assertIs(isinstance(True, bool), True)
182        self.assertIs(isinstance(False, bool), True)
183        self.assertIs(isinstance(True, int), True)
184        self.assertIs(isinstance(False, int), True)
185        self.assertIs(isinstance(1, bool), False)
186        self.assertIs(isinstance(0, bool), False)
187
188    def test_issubclass(self):
189        self.assertIs(issubclass(bool, int), True)
190        self.assertIs(issubclass(int, bool), False)
191
192    def test_contains(self):
193        self.assertIs(1 in {}, False)
194        self.assertIs(1 in {1:1}, True)
195
196    def test_string(self):
197        self.assertIs("xyz".endswith("z"), True)
198        self.assertIs("xyz".endswith("x"), False)
199        self.assertIs("xyz0123".isalnum(), True)
200        self.assertIs("@#$%".isalnum(), False)
201        self.assertIs("xyz".isalpha(), True)
202        self.assertIs("@#$%".isalpha(), False)
203        self.assertIs("0123".isdigit(), True)
204        self.assertIs("xyz".isdigit(), False)
205        self.assertIs("xyz".islower(), True)
206        self.assertIs("XYZ".islower(), False)
207        self.assertIs("0123".isdecimal(), True)
208        self.assertIs("xyz".isdecimal(), False)
209        self.assertIs("0123".isnumeric(), True)
210        self.assertIs("xyz".isnumeric(), False)
211        self.assertIs(" ".isspace(), True)
212        self.assertIs("\xa0".isspace(), True)
213        self.assertIs("\u3000".isspace(), True)
214        self.assertIs("XYZ".isspace(), False)
215        self.assertIs("X".istitle(), True)
216        self.assertIs("x".istitle(), False)
217        self.assertIs("XYZ".isupper(), True)
218        self.assertIs("xyz".isupper(), False)
219        self.assertIs("xyz".startswith("x"), True)
220        self.assertIs("xyz".startswith("z"), False)
221
222    def test_boolean(self):
223        self.assertEqual(True & 1, 1)
224        self.assertNotIsInstance(True & 1, bool)
225        self.assertIs(True & True, True)
226
227        self.assertEqual(True | 1, 1)
228        self.assertNotIsInstance(True | 1, bool)
229        self.assertIs(True | True, True)
230
231        self.assertEqual(True ^ 1, 0)
232        self.assertNotIsInstance(True ^ 1, bool)
233        self.assertIs(True ^ True, False)
234
235    def test_fileclosed(self):
236        try:
237            with open(os_helper.TESTFN, "w", encoding="utf-8") as f:
238                self.assertIs(f.closed, False)
239            self.assertIs(f.closed, True)
240        finally:
241            os.remove(os_helper.TESTFN)
242
243    def test_types(self):
244        # types are always true.
245        for t in [bool, complex, dict, float, int, list, object,
246                  set, str, tuple, type]:
247            self.assertIs(bool(t), True)
248
249    def test_operator(self):
250        import operator
251        self.assertIs(operator.truth(0), False)
252        self.assertIs(operator.truth(1), True)
253        self.assertIs(operator.not_(1), False)
254        self.assertIs(operator.not_(0), True)
255        self.assertIs(operator.contains([], 1), False)
256        self.assertIs(operator.contains([1], 1), True)
257        self.assertIs(operator.lt(0, 0), False)
258        self.assertIs(operator.lt(0, 1), True)
259        self.assertIs(operator.is_(True, True), True)
260        self.assertIs(operator.is_(True, False), False)
261        self.assertIs(operator.is_not(True, True), False)
262        self.assertIs(operator.is_not(True, False), True)
263
264    def test_marshal(self):
265        import marshal
266        self.assertIs(marshal.loads(marshal.dumps(True)), True)
267        self.assertIs(marshal.loads(marshal.dumps(False)), False)
268
269    def test_pickle(self):
270        import pickle
271        for proto in range(pickle.HIGHEST_PROTOCOL + 1):
272            self.assertIs(pickle.loads(pickle.dumps(True, proto)), True)
273            self.assertIs(pickle.loads(pickle.dumps(False, proto)), False)
274
275    def test_picklevalues(self):
276        # Test for specific backwards-compatible pickle values
277        import pickle
278        self.assertEqual(pickle.dumps(True, protocol=0), b"I01\n.")
279        self.assertEqual(pickle.dumps(False, protocol=0), b"I00\n.")
280        self.assertEqual(pickle.dumps(True, protocol=1), b"I01\n.")
281        self.assertEqual(pickle.dumps(False, protocol=1), b"I00\n.")
282        self.assertEqual(pickle.dumps(True, protocol=2), b'\x80\x02\x88.')
283        self.assertEqual(pickle.dumps(False, protocol=2), b'\x80\x02\x89.')
284
285    def test_convert_to_bool(self):
286        # Verify that TypeError occurs when bad things are returned
287        # from __bool__().  This isn't really a bool test, but
288        # it's related.
289        check = lambda o: self.assertRaises(TypeError, bool, o)
290        class Foo(object):
291            def __bool__(self):
292                return self
293        check(Foo())
294
295        class Bar(object):
296            def __bool__(self):
297                return "Yes"
298        check(Bar())
299
300        class Baz(int):
301            def __bool__(self):
302                return self
303        check(Baz())
304
305        # __bool__() must return a bool not an int
306        class Spam(int):
307            def __bool__(self):
308                return 1
309        check(Spam())
310
311        class Eggs:
312            def __len__(self):
313                return -1
314        self.assertRaises(ValueError, bool, Eggs())
315
316    def test_from_bytes(self):
317        self.assertIs(bool.from_bytes(b'\x00'*8, 'big'), False)
318        self.assertIs(bool.from_bytes(b'abcd', 'little'), True)
319
320    def test_sane_len(self):
321        # this test just tests our assumptions about __len__
322        # this will start failing if __len__ changes assertions
323        for badval in ['illegal', -1, 1 << 32]:
324            class A:
325                def __len__(self):
326                    return badval
327            try:
328                bool(A())
329            except (Exception) as e_bool:
330                try:
331                    len(A())
332                except (Exception) as e_len:
333                    self.assertEqual(str(e_bool), str(e_len))
334
335    def test_blocked(self):
336        class A:
337            __bool__ = None
338        self.assertRaises(TypeError, bool, A())
339
340        class B:
341            def __len__(self):
342                return 10
343            __bool__ = None
344        self.assertRaises(TypeError, bool, B())
345
346    def test_real_and_imag(self):
347        self.assertEqual(True.real, 1)
348        self.assertEqual(True.imag, 0)
349        self.assertIs(type(True.real), int)
350        self.assertIs(type(True.imag), int)
351        self.assertEqual(False.real, 0)
352        self.assertEqual(False.imag, 0)
353        self.assertIs(type(False.real), int)
354        self.assertIs(type(False.imag), int)
355
356    def test_bool_called_at_least_once(self):
357        class X:
358            def __init__(self):
359                self.count = 0
360            def __bool__(self):
361                self.count += 1
362                return True
363
364        def f(x):
365            if x or True:
366                pass
367
368        x = X()
369        f(x)
370        self.assertGreaterEqual(x.count, 1)
371
372
373if __name__ == "__main__":
374    unittest.main()
375