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