1 # Python test set -- part 6, built-in types
2
3 from test.support import run_with_locale, cpython_only
4 import collections.abc
5 from collections import namedtuple
6 import copy
7 import gc
8 import inspect
9 import pickle
10 import locale
11 import sys
12 import types
13 import unittest.mock
14 import weakref
15 import typing
16
17
18 T = typing.TypeVar("T")
19
20 class ESC[4;38;5;81mExample:
21 pass
22
23 class ESC[4;38;5;81mForward: ...
24
25 def clear_typing_caches():
26 for f in typing._cleanups:
27 f()
28
29
30 class ESC[4;38;5;81mTypesTests(ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
31
32 def test_truth_values(self):
33 if None: self.fail('None is true instead of false')
34 if 0: self.fail('0 is true instead of false')
35 if 0.0: self.fail('0.0 is true instead of false')
36 if '': self.fail('\'\' is true instead of false')
37 if not 1: self.fail('1 is false instead of true')
38 if not 1.0: self.fail('1.0 is false instead of true')
39 if not 'x': self.fail('\'x\' is false instead of true')
40 if not {'x': 1}: self.fail('{\'x\': 1} is false instead of true')
41 def f(): pass
42 class ESC[4;38;5;81mC: pass
43 x = C()
44 if not f: self.fail('f is false instead of true')
45 if not C: self.fail('C is false instead of true')
46 if not sys: self.fail('sys is false instead of true')
47 if not x: self.fail('x is false instead of true')
48
49 def test_boolean_ops(self):
50 if 0 or 0: self.fail('0 or 0 is true instead of false')
51 if 1 and 1: pass
52 else: self.fail('1 and 1 is false instead of true')
53 if not 1: self.fail('not 1 is true instead of false')
54
55 def test_comparisons(self):
56 if 0 < 1 <= 1 == 1 >= 1 > 0 != 1: pass
57 else: self.fail('int comparisons failed')
58 if 0.0 < 1.0 <= 1.0 == 1.0 >= 1.0 > 0.0 != 1.0: pass
59 else: self.fail('float comparisons failed')
60 if '' < 'a' <= 'a' == 'a' < 'abc' < 'abd' < 'b': pass
61 else: self.fail('string comparisons failed')
62 if None is None: pass
63 else: self.fail('identity test failed')
64
65 def test_float_constructor(self):
66 self.assertRaises(ValueError, float, '')
67 self.assertRaises(ValueError, float, '5\0')
68 self.assertRaises(ValueError, float, '5_5\0')
69
70 def test_zero_division(self):
71 try: 5.0 / 0.0
72 except ZeroDivisionError: pass
73 else: self.fail("5.0 / 0.0 didn't raise ZeroDivisionError")
74
75 try: 5.0 // 0.0
76 except ZeroDivisionError: pass
77 else: self.fail("5.0 // 0.0 didn't raise ZeroDivisionError")
78
79 try: 5.0 % 0.0
80 except ZeroDivisionError: pass
81 else: self.fail("5.0 % 0.0 didn't raise ZeroDivisionError")
82
83 try: 5 / 0
84 except ZeroDivisionError: pass
85 else: self.fail("5 / 0 didn't raise ZeroDivisionError")
86
87 try: 5 // 0
88 except ZeroDivisionError: pass
89 else: self.fail("5 // 0 didn't raise ZeroDivisionError")
90
91 try: 5 % 0
92 except ZeroDivisionError: pass
93 else: self.fail("5 % 0 didn't raise ZeroDivisionError")
94
95 def test_numeric_types(self):
96 if 0 != 0.0 or 1 != 1.0 or -1 != -1.0:
97 self.fail('int/float value not equal')
98 # calling built-in types without argument must return 0
99 if int() != 0: self.fail('int() does not return 0')
100 if float() != 0.0: self.fail('float() does not return 0.0')
101 if int(1.9) == 1 == int(1.1) and int(-1.1) == -1 == int(-1.9): pass
102 else: self.fail('int() does not round properly')
103 if float(1) == 1.0 and float(-1) == -1.0 and float(0) == 0.0: pass
104 else: self.fail('float() does not work properly')
105
106 def test_float_to_string(self):
107 def test(f, result):
108 self.assertEqual(f.__format__('e'), result)
109 self.assertEqual('%e' % f, result)
110
111 # test all 2 digit exponents, both with __format__ and with
112 # '%' formatting
113 for i in range(-99, 100):
114 test(float('1.5e'+str(i)), '1.500000e{0:+03d}'.format(i))
115
116 # test some 3 digit exponents
117 self.assertEqual(1.5e100.__format__('e'), '1.500000e+100')
118 self.assertEqual('%e' % 1.5e100, '1.500000e+100')
119
120 self.assertEqual(1.5e101.__format__('e'), '1.500000e+101')
121 self.assertEqual('%e' % 1.5e101, '1.500000e+101')
122
123 self.assertEqual(1.5e-100.__format__('e'), '1.500000e-100')
124 self.assertEqual('%e' % 1.5e-100, '1.500000e-100')
125
126 self.assertEqual(1.5e-101.__format__('e'), '1.500000e-101')
127 self.assertEqual('%e' % 1.5e-101, '1.500000e-101')
128
129 self.assertEqual('%g' % 1.0, '1')
130 self.assertEqual('%#g' % 1.0, '1.00000')
131
132 def test_normal_integers(self):
133 # Ensure the first 256 integers are shared
134 a = 256
135 b = 128*2
136 if a is not b: self.fail('256 is not shared')
137 if 12 + 24 != 36: self.fail('int op')
138 if 12 + (-24) != -12: self.fail('int op')
139 if (-12) + 24 != 12: self.fail('int op')
140 if (-12) + (-24) != -36: self.fail('int op')
141 if not 12 < 24: self.fail('int op')
142 if not -24 < -12: self.fail('int op')
143 # Test for a particular bug in integer multiply
144 xsize, ysize, zsize = 238, 356, 4
145 if not (xsize*ysize*zsize == zsize*xsize*ysize == 338912):
146 self.fail('int mul commutativity')
147 # And another.
148 m = -sys.maxsize - 1
149 for divisor in 1, 2, 4, 8, 16, 32:
150 j = m // divisor
151 prod = divisor * j
152 if prod != m:
153 self.fail("%r * %r == %r != %r" % (divisor, j, prod, m))
154 if type(prod) is not int:
155 self.fail("expected type(prod) to be int, not %r" %
156 type(prod))
157 # Check for unified integral type
158 for divisor in 1, 2, 4, 8, 16, 32:
159 j = m // divisor - 1
160 prod = divisor * j
161 if type(prod) is not int:
162 self.fail("expected type(%r) to be int, not %r" %
163 (prod, type(prod)))
164 # Check for unified integral type
165 m = sys.maxsize
166 for divisor in 1, 2, 4, 8, 16, 32:
167 j = m // divisor + 1
168 prod = divisor * j
169 if type(prod) is not int:
170 self.fail("expected type(%r) to be int, not %r" %
171 (prod, type(prod)))
172
173 x = sys.maxsize
174 self.assertIsInstance(x + 1, int,
175 "(sys.maxsize + 1) should have returned int")
176 self.assertIsInstance(-x - 1, int,
177 "(-sys.maxsize - 1) should have returned int")
178 self.assertIsInstance(-x - 2, int,
179 "(-sys.maxsize - 2) should have returned int")
180
181 try: 5 << -5
182 except ValueError: pass
183 else: self.fail('int negative shift <<')
184
185 try: 5 >> -5
186 except ValueError: pass
187 else: self.fail('int negative shift >>')
188
189 def test_floats(self):
190 if 12.0 + 24.0 != 36.0: self.fail('float op')
191 if 12.0 + (-24.0) != -12.0: self.fail('float op')
192 if (-12.0) + 24.0 != 12.0: self.fail('float op')
193 if (-12.0) + (-24.0) != -36.0: self.fail('float op')
194 if not 12.0 < 24.0: self.fail('float op')
195 if not -24.0 < -12.0: self.fail('float op')
196
197 def test_strings(self):
198 if len('') != 0: self.fail('len(\'\')')
199 if len('a') != 1: self.fail('len(\'a\')')
200 if len('abcdef') != 6: self.fail('len(\'abcdef\')')
201 if 'xyz' + 'abcde' != 'xyzabcde': self.fail('string concatenation')
202 if 'xyz'*3 != 'xyzxyzxyz': self.fail('string repetition *3')
203 if 0*'abcde' != '': self.fail('string repetition 0*')
204 if min('abc') != 'a' or max('abc') != 'c': self.fail('min/max string')
205 if 'a' in 'abc' and 'b' in 'abc' and 'c' in 'abc' and 'd' not in 'abc': pass
206 else: self.fail('in/not in string')
207 x = 'x'*103
208 if '%s!'%x != x+'!': self.fail('nasty string formatting bug')
209
210 #extended slices for strings
211 a = '0123456789'
212 self.assertEqual(a[::], a)
213 self.assertEqual(a[::2], '02468')
214 self.assertEqual(a[1::2], '13579')
215 self.assertEqual(a[::-1],'9876543210')
216 self.assertEqual(a[::-2], '97531')
217 self.assertEqual(a[3::-2], '31')
218 self.assertEqual(a[-100:100:], a)
219 self.assertEqual(a[100:-100:-1], a[::-1])
220 self.assertEqual(a[-100:100:2], '02468')
221
222 def test_type_function(self):
223 self.assertRaises(TypeError, type, 1, 2)
224 self.assertRaises(TypeError, type, 1, 2, 3, 4)
225
226 def test_int__format__(self):
227 def test(i, format_spec, result):
228 # just make sure we have the unified type for integers
229 self.assertIs(type(i), int)
230 self.assertIs(type(format_spec), str)
231 self.assertEqual(i.__format__(format_spec), result)
232
233 test(123456789, 'd', '123456789')
234 test(123456789, 'd', '123456789')
235
236 test(1, 'c', '\01')
237
238 # sign and aligning are interdependent
239 test(1, "-", '1')
240 test(-1, "-", '-1')
241 test(1, "-3", ' 1')
242 test(-1, "-3", ' -1')
243 test(1, "+3", ' +1')
244 test(-1, "+3", ' -1')
245 test(1, " 3", ' 1')
246 test(-1, " 3", ' -1')
247 test(1, " ", ' 1')
248 test(-1, " ", '-1')
249
250 # hex
251 test(3, "x", "3")
252 test(3, "X", "3")
253 test(1234, "x", "4d2")
254 test(-1234, "x", "-4d2")
255 test(1234, "8x", " 4d2")
256 test(-1234, "8x", " -4d2")
257 test(1234, "x", "4d2")
258 test(-1234, "x", "-4d2")
259 test(-3, "x", "-3")
260 test(-3, "X", "-3")
261 test(int('be', 16), "x", "be")
262 test(int('be', 16), "X", "BE")
263 test(-int('be', 16), "x", "-be")
264 test(-int('be', 16), "X", "-BE")
265
266 # octal
267 test(3, "o", "3")
268 test(-3, "o", "-3")
269 test(65, "o", "101")
270 test(-65, "o", "-101")
271 test(1234, "o", "2322")
272 test(-1234, "o", "-2322")
273 test(1234, "-o", "2322")
274 test(-1234, "-o", "-2322")
275 test(1234, " o", " 2322")
276 test(-1234, " o", "-2322")
277 test(1234, "+o", "+2322")
278 test(-1234, "+o", "-2322")
279
280 # binary
281 test(3, "b", "11")
282 test(-3, "b", "-11")
283 test(1234, "b", "10011010010")
284 test(-1234, "b", "-10011010010")
285 test(1234, "-b", "10011010010")
286 test(-1234, "-b", "-10011010010")
287 test(1234, " b", " 10011010010")
288 test(-1234, " b", "-10011010010")
289 test(1234, "+b", "+10011010010")
290 test(-1234, "+b", "-10011010010")
291
292 # alternate (#) formatting
293 test(0, "#b", '0b0')
294 test(0, "-#b", '0b0')
295 test(1, "-#b", '0b1')
296 test(-1, "-#b", '-0b1')
297 test(-1, "-#5b", ' -0b1')
298 test(1, "+#5b", ' +0b1')
299 test(100, "+#b", '+0b1100100')
300 test(100, "#012b", '0b0001100100')
301 test(-100, "#012b", '-0b001100100')
302
303 test(0, "#o", '0o0')
304 test(0, "-#o", '0o0')
305 test(1, "-#o", '0o1')
306 test(-1, "-#o", '-0o1')
307 test(-1, "-#5o", ' -0o1')
308 test(1, "+#5o", ' +0o1')
309 test(100, "+#o", '+0o144')
310 test(100, "#012o", '0o0000000144')
311 test(-100, "#012o", '-0o000000144')
312
313 test(0, "#x", '0x0')
314 test(0, "-#x", '0x0')
315 test(1, "-#x", '0x1')
316 test(-1, "-#x", '-0x1')
317 test(-1, "-#5x", ' -0x1')
318 test(1, "+#5x", ' +0x1')
319 test(100, "+#x", '+0x64')
320 test(100, "#012x", '0x0000000064')
321 test(-100, "#012x", '-0x000000064')
322 test(123456, "#012x", '0x000001e240')
323 test(-123456, "#012x", '-0x00001e240')
324
325 test(0, "#X", '0X0')
326 test(0, "-#X", '0X0')
327 test(1, "-#X", '0X1')
328 test(-1, "-#X", '-0X1')
329 test(-1, "-#5X", ' -0X1')
330 test(1, "+#5X", ' +0X1')
331 test(100, "+#X", '+0X64')
332 test(100, "#012X", '0X0000000064')
333 test(-100, "#012X", '-0X000000064')
334 test(123456, "#012X", '0X000001E240')
335 test(-123456, "#012X", '-0X00001E240')
336
337 test(123, ',', '123')
338 test(-123, ',', '-123')
339 test(1234, ',', '1,234')
340 test(-1234, ',', '-1,234')
341 test(123456, ',', '123,456')
342 test(-123456, ',', '-123,456')
343 test(1234567, ',', '1,234,567')
344 test(-1234567, ',', '-1,234,567')
345
346 # issue 5782, commas with no specifier type
347 test(1234, '010,', '00,001,234')
348
349 # Unified type for integers
350 test(10**100, 'd', '1' + '0' * 100)
351 test(10**100+100, 'd', '1' + '0' * 97 + '100')
352
353 # make sure these are errors
354
355 # precision disallowed
356 self.assertRaises(ValueError, 3 .__format__, "1.3")
357 # sign not allowed with 'c'
358 self.assertRaises(ValueError, 3 .__format__, "+c")
359 # format spec must be string
360 self.assertRaises(TypeError, 3 .__format__, None)
361 self.assertRaises(TypeError, 3 .__format__, 0)
362 # can't have ',' with 'n'
363 self.assertRaises(ValueError, 3 .__format__, ",n")
364 # can't have ',' with 'c'
365 self.assertRaises(ValueError, 3 .__format__, ",c")
366 # can't have '#' with 'c'
367 self.assertRaises(ValueError, 3 .__format__, "#c")
368
369 # ensure that only int and float type specifiers work
370 for format_spec in ([chr(x) for x in range(ord('a'), ord('z')+1)] +
371 [chr(x) for x in range(ord('A'), ord('Z')+1)]):
372 if not format_spec in 'bcdoxXeEfFgGn%':
373 self.assertRaises(ValueError, 0 .__format__, format_spec)
374 self.assertRaises(ValueError, 1 .__format__, format_spec)
375 self.assertRaises(ValueError, (-1) .__format__, format_spec)
376
377 # ensure that float type specifiers work; format converts
378 # the int to a float
379 for format_spec in 'eEfFgG%':
380 for value in [0, 1, -1, 100, -100, 1234567890, -1234567890]:
381 self.assertEqual(value.__format__(format_spec),
382 float(value).__format__(format_spec))
383
384 # Issue 6902
385 test(123456, "0<20", '12345600000000000000')
386 test(123456, "1<20", '12345611111111111111')
387 test(123456, "*<20", '123456**************')
388 test(123456, "0>20", '00000000000000123456')
389 test(123456, "1>20", '11111111111111123456')
390 test(123456, "*>20", '**************123456')
391 test(123456, "0=20", '00000000000000123456')
392 test(123456, "1=20", '11111111111111123456')
393 test(123456, "*=20", '**************123456')
394
395 @run_with_locale('LC_NUMERIC', 'en_US.UTF8')
396 def test_float__format__locale(self):
397 # test locale support for __format__ code 'n'
398
399 for i in range(-10, 10):
400 x = 1234567890.0 * (10.0 ** i)
401 self.assertEqual(locale.format_string('%g', x, grouping=True), format(x, 'n'))
402 self.assertEqual(locale.format_string('%.10g', x, grouping=True), format(x, '.10n'))
403
404 @run_with_locale('LC_NUMERIC', 'en_US.UTF8')
405 def test_int__format__locale(self):
406 # test locale support for __format__ code 'n' for integers
407
408 x = 123456789012345678901234567890
409 for i in range(0, 30):
410 self.assertEqual(locale.format_string('%d', x, grouping=True), format(x, 'n'))
411
412 # move to the next integer to test
413 x = x // 10
414
415 rfmt = ">20n"
416 lfmt = "<20n"
417 cfmt = "^20n"
418 for x in (1234, 12345, 123456, 1234567, 12345678, 123456789, 1234567890, 12345678900):
419 self.assertEqual(len(format(0, rfmt)), len(format(x, rfmt)))
420 self.assertEqual(len(format(0, lfmt)), len(format(x, lfmt)))
421 self.assertEqual(len(format(0, cfmt)), len(format(x, cfmt)))
422
423 def test_float__format__(self):
424 def test(f, format_spec, result):
425 self.assertEqual(f.__format__(format_spec), result)
426 self.assertEqual(format(f, format_spec), result)
427
428 test(0.0, 'f', '0.000000')
429
430 # the default is 'g', except for empty format spec
431 test(0.0, '', '0.0')
432 test(0.01, '', '0.01')
433 test(0.01, 'g', '0.01')
434
435 # test for issue 3411
436 test(1.23, '1', '1.23')
437 test(-1.23, '1', '-1.23')
438 test(1.23, '1g', '1.23')
439 test(-1.23, '1g', '-1.23')
440
441 test( 1.0, ' g', ' 1')
442 test(-1.0, ' g', '-1')
443 test( 1.0, '+g', '+1')
444 test(-1.0, '+g', '-1')
445 test(1.1234e200, 'g', '1.1234e+200')
446 test(1.1234e200, 'G', '1.1234E+200')
447
448
449 test(1.0, 'f', '1.000000')
450
451 test(-1.0, 'f', '-1.000000')
452
453 test( 1.0, ' f', ' 1.000000')
454 test(-1.0, ' f', '-1.000000')
455 test( 1.0, '+f', '+1.000000')
456 test(-1.0, '+f', '-1.000000')
457
458 # Python versions <= 3.0 switched from 'f' to 'g' formatting for
459 # values larger than 1e50. No longer.
460 f = 1.1234e90
461 for fmt in 'f', 'F':
462 # don't do a direct equality check, since on some
463 # platforms only the first few digits of dtoa
464 # will be reliable
465 result = f.__format__(fmt)
466 self.assertEqual(len(result), 98)
467 self.assertEqual(result[-7], '.')
468 self.assertIn(result[:12], ('112340000000', '112339999999'))
469 f = 1.1234e200
470 for fmt in 'f', 'F':
471 result = f.__format__(fmt)
472 self.assertEqual(len(result), 208)
473 self.assertEqual(result[-7], '.')
474 self.assertIn(result[:12], ('112340000000', '112339999999'))
475
476
477 test( 1.0, 'e', '1.000000e+00')
478 test(-1.0, 'e', '-1.000000e+00')
479 test( 1.0, 'E', '1.000000E+00')
480 test(-1.0, 'E', '-1.000000E+00')
481 test(1.1234e20, 'e', '1.123400e+20')
482 test(1.1234e20, 'E', '1.123400E+20')
483
484 # No format code means use g, but must have a decimal
485 # and a number after the decimal. This is tricky, because
486 # a totally empty format specifier means something else.
487 # So, just use a sign flag
488 test(1e200, '+g', '+1e+200')
489 test(1e200, '+', '+1e+200')
490
491 test(1.1e200, '+g', '+1.1e+200')
492 test(1.1e200, '+', '+1.1e+200')
493
494 # 0 padding
495 test(1234., '010f', '1234.000000')
496 test(1234., '011f', '1234.000000')
497 test(1234., '012f', '01234.000000')
498 test(-1234., '011f', '-1234.000000')
499 test(-1234., '012f', '-1234.000000')
500 test(-1234., '013f', '-01234.000000')
501 test(-1234.12341234, '013f', '-01234.123412')
502 test(-123456.12341234, '011.2f', '-0123456.12')
503
504 # issue 5782, commas with no specifier type
505 test(1.2, '010,.2', '0,000,001.2')
506
507 # 0 padding with commas
508 test(1234., '011,f', '1,234.000000')
509 test(1234., '012,f', '1,234.000000')
510 test(1234., '013,f', '01,234.000000')
511 test(-1234., '012,f', '-1,234.000000')
512 test(-1234., '013,f', '-1,234.000000')
513 test(-1234., '014,f', '-01,234.000000')
514 test(-12345., '015,f', '-012,345.000000')
515 test(-123456., '016,f', '-0,123,456.000000')
516 test(-123456., '017,f', '-0,123,456.000000')
517 test(-123456.12341234, '017,f', '-0,123,456.123412')
518 test(-123456.12341234, '013,.2f', '-0,123,456.12')
519
520 # % formatting
521 test(-1.0, '%', '-100.000000%')
522
523 # format spec must be string
524 self.assertRaises(TypeError, 3.0.__format__, None)
525 self.assertRaises(TypeError, 3.0.__format__, 0)
526
527 # confirm format options expected to fail on floats, such as integer
528 # presentation types
529 for format_spec in 'sbcdoxX':
530 self.assertRaises(ValueError, format, 0.0, format_spec)
531 self.assertRaises(ValueError, format, 1.0, format_spec)
532 self.assertRaises(ValueError, format, -1.0, format_spec)
533 self.assertRaises(ValueError, format, 1e100, format_spec)
534 self.assertRaises(ValueError, format, -1e100, format_spec)
535 self.assertRaises(ValueError, format, 1e-100, format_spec)
536 self.assertRaises(ValueError, format, -1e-100, format_spec)
537
538 # Alternate float formatting
539 test(1.0, '.0e', '1e+00')
540 test(1.0, '#.0e', '1.e+00')
541 test(1.0, '.0f', '1')
542 test(1.0, '#.0f', '1.')
543 test(1.1, 'g', '1.1')
544 test(1.1, '#g', '1.10000')
545 test(1.0, '.0%', '100%')
546 test(1.0, '#.0%', '100.%')
547
548 # Issue 7094: Alternate formatting (specified by #)
549 test(1.0, '0e', '1.000000e+00')
550 test(1.0, '#0e', '1.000000e+00')
551 test(1.0, '0f', '1.000000' )
552 test(1.0, '#0f', '1.000000')
553 test(1.0, '.1e', '1.0e+00')
554 test(1.0, '#.1e', '1.0e+00')
555 test(1.0, '.1f', '1.0')
556 test(1.0, '#.1f', '1.0')
557 test(1.0, '.1%', '100.0%')
558 test(1.0, '#.1%', '100.0%')
559
560 # Issue 6902
561 test(12345.6, "0<20", '12345.60000000000000')
562 test(12345.6, "1<20", '12345.61111111111111')
563 test(12345.6, "*<20", '12345.6*************')
564 test(12345.6, "0>20", '000000000000012345.6')
565 test(12345.6, "1>20", '111111111111112345.6')
566 test(12345.6, "*>20", '*************12345.6')
567 test(12345.6, "0=20", '000000000000012345.6')
568 test(12345.6, "1=20", '111111111111112345.6')
569 test(12345.6, "*=20", '*************12345.6')
570
571 def test_format_spec_errors(self):
572 # int, float, and string all share the same format spec
573 # mini-language parser.
574
575 # Check that we can't ask for too many digits. This is
576 # probably a CPython specific test. It tries to put the width
577 # into a C long.
578 self.assertRaises(ValueError, format, 0, '1'*10000 + 'd')
579
580 # Similar with the precision.
581 self.assertRaises(ValueError, format, 0, '.' + '1'*10000 + 'd')
582
583 # And may as well test both.
584 self.assertRaises(ValueError, format, 0, '1'*1000 + '.' + '1'*10000 + 'd')
585
586 # Make sure commas aren't allowed with various type codes
587 for code in 'xXobns':
588 self.assertRaises(ValueError, format, 0, ',' + code)
589
590 def test_internal_sizes(self):
591 self.assertGreater(object.__basicsize__, 0)
592 self.assertGreater(tuple.__itemsize__, 0)
593
594 def test_slot_wrapper_types(self):
595 self.assertIsInstance(object.__init__, types.WrapperDescriptorType)
596 self.assertIsInstance(object.__str__, types.WrapperDescriptorType)
597 self.assertIsInstance(object.__lt__, types.WrapperDescriptorType)
598 self.assertIsInstance(int.__lt__, types.WrapperDescriptorType)
599
600 def test_dunder_get_signature(self):
601 sig = inspect.signature(object.__init__.__get__)
602 self.assertEqual(list(sig.parameters), ["instance", "owner"])
603 # gh-93021: Second parameter is optional
604 self.assertIs(sig.parameters["owner"].default, None)
605
606 def test_method_wrapper_types(self):
607 self.assertIsInstance(object().__init__, types.MethodWrapperType)
608 self.assertIsInstance(object().__str__, types.MethodWrapperType)
609 self.assertIsInstance(object().__lt__, types.MethodWrapperType)
610 self.assertIsInstance((42).__lt__, types.MethodWrapperType)
611
612 def test_method_descriptor_types(self):
613 self.assertIsInstance(str.join, types.MethodDescriptorType)
614 self.assertIsInstance(list.append, types.MethodDescriptorType)
615 self.assertIsInstance(''.join, types.BuiltinMethodType)
616 self.assertIsInstance([].append, types.BuiltinMethodType)
617
618 self.assertIsInstance(int.__dict__['from_bytes'], types.ClassMethodDescriptorType)
619 self.assertIsInstance(int.from_bytes, types.BuiltinMethodType)
620 self.assertIsInstance(int.__new__, types.BuiltinMethodType)
621
622 def test_ellipsis_type(self):
623 self.assertIsInstance(Ellipsis, types.EllipsisType)
624
625 def test_notimplemented_type(self):
626 self.assertIsInstance(NotImplemented, types.NotImplementedType)
627
628 def test_none_type(self):
629 self.assertIsInstance(None, types.NoneType)
630
631 def test_traceback_and_frame_types(self):
632 try:
633 raise OSError
634 except OSError as e:
635 exc = e
636 self.assertIsInstance(exc.__traceback__, types.TracebackType)
637 self.assertIsInstance(exc.__traceback__.tb_frame, types.FrameType)
638
639
640 class ESC[4;38;5;81mUnionTests(ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
641
642 def test_or_types_operator(self):
643 self.assertEqual(int | str, typing.Union[int, str])
644 self.assertNotEqual(int | list, typing.Union[int, str])
645 self.assertEqual(str | int, typing.Union[int, str])
646 self.assertEqual(int | None, typing.Union[int, None])
647 self.assertEqual(None | int, typing.Union[int, None])
648 self.assertEqual(int | type(None), int | None)
649 self.assertEqual(type(None) | int, None | int)
650 self.assertEqual(int | str | list, typing.Union[int, str, list])
651 self.assertEqual(int | (str | list), typing.Union[int, str, list])
652 self.assertEqual(str | (int | list), typing.Union[int, str, list])
653 self.assertEqual(typing.List | typing.Tuple, typing.Union[typing.List, typing.Tuple])
654 self.assertEqual(typing.List[int] | typing.Tuple[int], typing.Union[typing.List[int], typing.Tuple[int]])
655 self.assertEqual(typing.List[int] | None, typing.Union[typing.List[int], None])
656 self.assertEqual(None | typing.List[int], typing.Union[None, typing.List[int]])
657 self.assertEqual(str | float | int | complex | int, (int | str) | (float | complex))
658 self.assertEqual(typing.Union[str, int, typing.List[int]], str | int | typing.List[int])
659 self.assertIs(int | int, int)
660 self.assertEqual(
661 BaseException |
662 bool |
663 bytes |
664 complex |
665 float |
666 int |
667 list |
668 map |
669 set,
670 typing.Union[
671 BaseException,
672 bool,
673 bytes,
674 complex,
675 float,
676 int,
677 list,
678 map,
679 set,
680 ])
681 with self.assertRaises(TypeError):
682 int | 3
683 with self.assertRaises(TypeError):
684 3 | int
685 with self.assertRaises(TypeError):
686 Example() | int
687 x = int | str
688 self.assertEqual(x, int | str)
689 self.assertEqual(x, str | int)
690 self.assertNotEqual(x, {}) # should not raise exception
691 with self.assertRaises(TypeError):
692 x < x
693 with self.assertRaises(TypeError):
694 x <= x
695 y = typing.Union[str, int]
696 with self.assertRaises(TypeError):
697 x < y
698 y = int | bool
699 with self.assertRaises(TypeError):
700 x < y
701 # Check that we don't crash if typing.Union does not have a tuple in __args__
702 y = typing.Union[str, int]
703 y.__args__ = [str, int]
704 self.assertEqual(x, y)
705
706 def test_hash(self):
707 self.assertEqual(hash(int | str), hash(str | int))
708 self.assertEqual(hash(int | str), hash(typing.Union[int, str]))
709
710 def test_instancecheck_and_subclasscheck(self):
711 for x in (int | str, typing.Union[int, str]):
712 with self.subTest(x=x):
713 self.assertIsInstance(1, x)
714 self.assertIsInstance(True, x)
715 self.assertIsInstance('a', x)
716 self.assertNotIsInstance(None, x)
717 self.assertTrue(issubclass(int, x))
718 self.assertTrue(issubclass(bool, x))
719 self.assertTrue(issubclass(str, x))
720 self.assertFalse(issubclass(type(None), x))
721
722 for x in (int | None, typing.Union[int, None]):
723 with self.subTest(x=x):
724 self.assertIsInstance(None, x)
725 self.assertTrue(issubclass(type(None), x))
726
727 for x in (
728 int | collections.abc.Mapping,
729 typing.Union[int, collections.abc.Mapping],
730 ):
731 with self.subTest(x=x):
732 self.assertIsInstance({}, x)
733 self.assertNotIsInstance((), x)
734 self.assertTrue(issubclass(dict, x))
735 self.assertFalse(issubclass(list, x))
736
737 def test_instancecheck_and_subclasscheck_order(self):
738 T = typing.TypeVar('T')
739
740 will_resolve = (
741 int | T,
742 typing.Union[int, T],
743 )
744 for x in will_resolve:
745 with self.subTest(x=x):
746 self.assertIsInstance(1, x)
747 self.assertTrue(issubclass(int, x))
748
749 wont_resolve = (
750 T | int,
751 typing.Union[T, int],
752 )
753 for x in wont_resolve:
754 with self.subTest(x=x):
755 with self.assertRaises(TypeError):
756 issubclass(int, x)
757 with self.assertRaises(TypeError):
758 isinstance(1, x)
759
760 for x in (*will_resolve, *wont_resolve):
761 with self.subTest(x=x):
762 with self.assertRaises(TypeError):
763 issubclass(object, x)
764 with self.assertRaises(TypeError):
765 isinstance(object(), x)
766
767 def test_bad_instancecheck(self):
768 class ESC[4;38;5;81mBadMeta(ESC[4;38;5;149mtype):
769 def __instancecheck__(cls, inst):
770 1/0
771 x = int | BadMeta('A', (), {})
772 self.assertTrue(isinstance(1, x))
773 self.assertRaises(ZeroDivisionError, isinstance, [], x)
774
775 def test_bad_subclasscheck(self):
776 class ESC[4;38;5;81mBadMeta(ESC[4;38;5;149mtype):
777 def __subclasscheck__(cls, sub):
778 1/0
779 x = int | BadMeta('A', (), {})
780 self.assertTrue(issubclass(int, x))
781 self.assertRaises(ZeroDivisionError, issubclass, list, x)
782
783 def test_or_type_operator_with_TypeVar(self):
784 TV = typing.TypeVar('T')
785 self.assertEqual(TV | str, typing.Union[TV, str])
786 self.assertEqual(str | TV, typing.Union[str, TV])
787 self.assertIs((int | TV)[int], int)
788 self.assertIs((TV | int)[int], int)
789
790 def test_union_args(self):
791 def check(arg, expected):
792 clear_typing_caches()
793 self.assertEqual(arg.__args__, expected)
794
795 check(int | str, (int, str))
796 check((int | str) | list, (int, str, list))
797 check(int | (str | list), (int, str, list))
798 check((int | str) | int, (int, str))
799 check(int | (str | int), (int, str))
800 check((int | str) | (str | int), (int, str))
801 check(typing.Union[int, str] | list, (int, str, list))
802 check(int | typing.Union[str, list], (int, str, list))
803 check((int | str) | (list | int), (int, str, list))
804 check((int | str) | typing.Union[list, int], (int, str, list))
805 check(typing.Union[int, str] | (list | int), (int, str, list))
806 check((str | int) | (int | list), (str, int, list))
807 check((str | int) | typing.Union[int, list], (str, int, list))
808 check(typing.Union[str, int] | (int | list), (str, int, list))
809 check(int | type(None), (int, type(None)))
810 check(type(None) | int, (type(None), int))
811
812 args = (int, list[int], typing.List[int],
813 typing.Tuple[int, int], typing.Callable[[int], int],
814 typing.Hashable, typing.TypeVar('T'))
815 for x in args:
816 with self.subTest(x):
817 check(x | None, (x, type(None)))
818 check(None | x, (type(None), x))
819
820 def test_union_parameter_chaining(self):
821 T = typing.TypeVar("T")
822 S = typing.TypeVar("S")
823
824 self.assertEqual((float | list[T])[int], float | list[int])
825 self.assertEqual(list[int | list[T]].__parameters__, (T,))
826 self.assertEqual(list[int | list[T]][str], list[int | list[str]])
827 self.assertEqual((list[T] | list[S]).__parameters__, (T, S))
828 self.assertEqual((list[T] | list[S])[int, T], list[int] | list[T])
829 self.assertEqual((list[T] | list[S])[int, int], list[int])
830
831 def test_union_parameter_substitution(self):
832 def eq(actual, expected, typed=True):
833 self.assertEqual(actual, expected)
834 if typed:
835 self.assertIs(type(actual), type(expected))
836
837 T = typing.TypeVar('T')
838 S = typing.TypeVar('S')
839 NT = typing.NewType('NT', str)
840 x = int | T | bytes
841
842 eq(x[str], int | str | bytes, typed=False)
843 eq(x[list[int]], int | list[int] | bytes, typed=False)
844 eq(x[typing.List], int | typing.List | bytes)
845 eq(x[typing.List[int]], int | typing.List[int] | bytes)
846 eq(x[typing.Hashable], int | typing.Hashable | bytes)
847 eq(x[collections.abc.Hashable],
848 int | collections.abc.Hashable | bytes, typed=False)
849 eq(x[typing.Callable[[int], str]],
850 int | typing.Callable[[int], str] | bytes)
851 eq(x[collections.abc.Callable[[int], str]],
852 int | collections.abc.Callable[[int], str] | bytes, typed=False)
853 eq(x[typing.Tuple[int, str]], int | typing.Tuple[int, str] | bytes)
854 eq(x[typing.Literal['none']], int | typing.Literal['none'] | bytes)
855 eq(x[str | list], int | str | list | bytes, typed=False)
856 eq(x[typing.Union[str, list]], typing.Union[int, str, list, bytes])
857 eq(x[str | int], int | str | bytes, typed=False)
858 eq(x[typing.Union[str, int]], typing.Union[int, str, bytes])
859 eq(x[NT], int | NT | bytes)
860 eq(x[S], int | S | bytes)
861
862 def test_union_pickle(self):
863 orig = list[T] | int
864 for proto in range(pickle.HIGHEST_PROTOCOL + 1):
865 s = pickle.dumps(orig, proto)
866 loaded = pickle.loads(s)
867 self.assertEqual(loaded, orig)
868 self.assertEqual(loaded.__args__, orig.__args__)
869 self.assertEqual(loaded.__parameters__, orig.__parameters__)
870
871 def test_union_copy(self):
872 orig = list[T] | int
873 for copied in (copy.copy(orig), copy.deepcopy(orig)):
874 self.assertEqual(copied, orig)
875 self.assertEqual(copied.__args__, orig.__args__)
876 self.assertEqual(copied.__parameters__, orig.__parameters__)
877
878 def test_union_parameter_substitution_errors(self):
879 T = typing.TypeVar("T")
880 x = int | T
881 with self.assertRaises(TypeError):
882 x[int, str]
883
884 def test_or_type_operator_with_forward(self):
885 T = typing.TypeVar('T')
886 ForwardAfter = T | 'Forward'
887 ForwardBefore = 'Forward' | T
888 def forward_after(x: ForwardAfter[int]) -> None: ...
889 def forward_before(x: ForwardBefore[int]) -> None: ...
890 self.assertEqual(typing.get_args(typing.get_type_hints(forward_after)['x']),
891 (int, Forward))
892 self.assertEqual(typing.get_args(typing.get_type_hints(forward_before)['x']),
893 (int, Forward))
894
895 def test_or_type_operator_with_Protocol(self):
896 class ESC[4;38;5;81mProto(ESC[4;38;5;149mtypingESC[4;38;5;149m.ESC[4;38;5;149mProtocol):
897 def meth(self) -> int:
898 ...
899 self.assertEqual(Proto | str, typing.Union[Proto, str])
900
901 def test_or_type_operator_with_Alias(self):
902 self.assertEqual(list | str, typing.Union[list, str])
903 self.assertEqual(typing.List | str, typing.Union[typing.List, str])
904
905 def test_or_type_operator_with_NamedTuple(self):
906 NT = namedtuple('A', ['B', 'C', 'D'])
907 self.assertEqual(NT | str, typing.Union[NT, str])
908
909 def test_or_type_operator_with_TypedDict(self):
910 class ESC[4;38;5;81mPoint2D(ESC[4;38;5;149mtypingESC[4;38;5;149m.ESC[4;38;5;149mTypedDict):
911 x: int
912 y: int
913 label: str
914 self.assertEqual(Point2D | str, typing.Union[Point2D, str])
915
916 def test_or_type_operator_with_NewType(self):
917 UserId = typing.NewType('UserId', int)
918 self.assertEqual(UserId | str, typing.Union[UserId, str])
919
920 def test_or_type_operator_with_IO(self):
921 self.assertEqual(typing.IO | str, typing.Union[typing.IO, str])
922
923 def test_or_type_operator_with_SpecialForm(self):
924 self.assertEqual(typing.Any | str, typing.Union[typing.Any, str])
925 self.assertEqual(typing.NoReturn | str, typing.Union[typing.NoReturn, str])
926 self.assertEqual(typing.Optional[int] | str, typing.Union[typing.Optional[int], str])
927 self.assertEqual(typing.Optional[int] | str, typing.Union[int, str, None])
928 self.assertEqual(typing.Union[int, bool] | str, typing.Union[int, bool, str])
929
930 def test_or_type_operator_with_Literal(self):
931 Literal = typing.Literal
932 self.assertEqual((Literal[1] | Literal[2]).__args__,
933 (Literal[1], Literal[2]))
934
935 self.assertEqual((Literal[0] | Literal[False]).__args__,
936 (Literal[0], Literal[False]))
937 self.assertEqual((Literal[1] | Literal[True]).__args__,
938 (Literal[1], Literal[True]))
939
940 self.assertEqual(Literal[1] | Literal[1], Literal[1])
941 self.assertEqual(Literal['a'] | Literal['a'], Literal['a'])
942
943 import enum
944 class ESC[4;38;5;81mInts(ESC[4;38;5;149menumESC[4;38;5;149m.ESC[4;38;5;149mIntEnum):
945 A = 0
946 B = 1
947
948 self.assertEqual(Literal[Ints.A] | Literal[Ints.A], Literal[Ints.A])
949 self.assertEqual(Literal[Ints.B] | Literal[Ints.B], Literal[Ints.B])
950
951 self.assertEqual((Literal[Ints.B] | Literal[Ints.A]).__args__,
952 (Literal[Ints.B], Literal[Ints.A]))
953
954 self.assertEqual((Literal[0] | Literal[Ints.A]).__args__,
955 (Literal[0], Literal[Ints.A]))
956 self.assertEqual((Literal[1] | Literal[Ints.B]).__args__,
957 (Literal[1], Literal[Ints.B]))
958
959 def test_or_type_repr(self):
960 self.assertEqual(repr(int | str), "int | str")
961 self.assertEqual(repr((int | str) | list), "int | str | list")
962 self.assertEqual(repr(int | (str | list)), "int | str | list")
963 self.assertEqual(repr(int | None), "int | None")
964 self.assertEqual(repr(int | type(None)), "int | None")
965 self.assertEqual(repr(int | typing.GenericAlias(list, int)), "int | list[int]")
966
967 def test_or_type_operator_with_genericalias(self):
968 a = list[int]
969 b = list[str]
970 c = dict[float, str]
971 class ESC[4;38;5;81mSubClass(ESC[4;38;5;149mtypesESC[4;38;5;149m.ESC[4;38;5;149mGenericAlias): ...
972 d = SubClass(list, float)
973 # equivalence with typing.Union
974 self.assertEqual(a | b | c | d, typing.Union[a, b, c, d])
975 # de-duplicate
976 self.assertEqual(a | c | b | b | a | c | d | d, a | b | c | d)
977 # order shouldn't matter
978 self.assertEqual(a | b | d, b | a | d)
979 self.assertEqual(repr(a | b | c | d),
980 "list[int] | list[str] | dict[float, str] | list[float]")
981
982 class ESC[4;38;5;81mBadType(ESC[4;38;5;149mtype):
983 def __eq__(self, other):
984 return 1 / 0
985
986 bt = BadType('bt', (), {})
987 # Comparison should fail and errors should propagate out for bad types.
988 with self.assertRaises(ZeroDivisionError):
989 list[int] | list[bt]
990
991 union_ga = (list[str] | int, collections.abc.Callable[..., str] | int,
992 d | int)
993 # Raise error when isinstance(type, genericalias | type)
994 for type_ in union_ga:
995 with self.subTest(f"check isinstance/issubclass is invalid for {type_}"):
996 with self.assertRaises(TypeError):
997 isinstance(1, type_)
998 with self.assertRaises(TypeError):
999 issubclass(int, type_)
1000
1001 def test_or_type_operator_with_bad_module(self):
1002 class ESC[4;38;5;81mBadMeta(ESC[4;38;5;149mtype):
1003 __qualname__ = 'TypeVar'
1004 @property
1005 def __module__(self):
1006 1 / 0
1007 TypeVar = BadMeta('TypeVar', (), {})
1008 _SpecialForm = BadMeta('_SpecialForm', (), {})
1009 # Crashes in Issue44483
1010 with self.assertRaises((TypeError, ZeroDivisionError)):
1011 str | TypeVar()
1012 with self.assertRaises((TypeError, ZeroDivisionError)):
1013 str | _SpecialForm()
1014
1015 @cpython_only
1016 def test_or_type_operator_reference_cycle(self):
1017 if not hasattr(sys, 'gettotalrefcount'):
1018 self.skipTest('Cannot get total reference count.')
1019 gc.collect()
1020 before = sys.gettotalrefcount()
1021 for _ in range(30):
1022 T = typing.TypeVar('T')
1023 U = int | list[T]
1024 T.blah = U
1025 del T
1026 del U
1027 gc.collect()
1028 leeway = 15
1029 self.assertLessEqual(sys.gettotalrefcount() - before, leeway,
1030 msg='Check for union reference leak.')
1031
1032
1033 class ESC[4;38;5;81mMappingProxyTests(ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
1034 mappingproxy = types.MappingProxyType
1035
1036 def test_constructor(self):
1037 class ESC[4;38;5;81muserdict(ESC[4;38;5;149mdict):
1038 pass
1039
1040 mapping = {'x': 1, 'y': 2}
1041 self.assertEqual(self.mappingproxy(mapping), mapping)
1042 mapping = userdict(x=1, y=2)
1043 self.assertEqual(self.mappingproxy(mapping), mapping)
1044 mapping = collections.ChainMap({'x': 1}, {'y': 2})
1045 self.assertEqual(self.mappingproxy(mapping), mapping)
1046
1047 self.assertRaises(TypeError, self.mappingproxy, 10)
1048 self.assertRaises(TypeError, self.mappingproxy, ("a", "tuple"))
1049 self.assertRaises(TypeError, self.mappingproxy, ["a", "list"])
1050
1051 def test_methods(self):
1052 attrs = set(dir(self.mappingproxy({}))) - set(dir(object()))
1053 self.assertEqual(attrs, {
1054 '__contains__',
1055 '__getitem__',
1056 '__class_getitem__',
1057 '__ior__',
1058 '__iter__',
1059 '__len__',
1060 '__or__',
1061 '__reversed__',
1062 '__ror__',
1063 'copy',
1064 'get',
1065 'items',
1066 'keys',
1067 'values',
1068 })
1069
1070 def test_get(self):
1071 view = self.mappingproxy({'a': 'A', 'b': 'B'})
1072 self.assertEqual(view['a'], 'A')
1073 self.assertEqual(view['b'], 'B')
1074 self.assertRaises(KeyError, view.__getitem__, 'xxx')
1075 self.assertEqual(view.get('a'), 'A')
1076 self.assertIsNone(view.get('xxx'))
1077 self.assertEqual(view.get('xxx', 42), 42)
1078
1079 def test_missing(self):
1080 class ESC[4;38;5;81mdictmissing(ESC[4;38;5;149mdict):
1081 def __missing__(self, key):
1082 return "missing=%s" % key
1083
1084 view = self.mappingproxy(dictmissing(x=1))
1085 self.assertEqual(view['x'], 1)
1086 self.assertEqual(view['y'], 'missing=y')
1087 self.assertEqual(view.get('x'), 1)
1088 self.assertEqual(view.get('y'), None)
1089 self.assertEqual(view.get('y', 42), 42)
1090 self.assertTrue('x' in view)
1091 self.assertFalse('y' in view)
1092
1093 def test_customdict(self):
1094 class ESC[4;38;5;81mcustomdict(ESC[4;38;5;149mdict):
1095 def __contains__(self, key):
1096 if key == 'magic':
1097 return True
1098 else:
1099 return dict.__contains__(self, key)
1100
1101 def __iter__(self):
1102 return iter(('iter',))
1103
1104 def __len__(self):
1105 return 500
1106
1107 def copy(self):
1108 return 'copy'
1109
1110 def keys(self):
1111 return 'keys'
1112
1113 def items(self):
1114 return 'items'
1115
1116 def values(self):
1117 return 'values'
1118
1119 def __getitem__(self, key):
1120 return "getitem=%s" % dict.__getitem__(self, key)
1121
1122 def get(self, key, default=None):
1123 return "get=%s" % dict.get(self, key, 'default=%r' % default)
1124
1125 custom = customdict({'key': 'value'})
1126 view = self.mappingproxy(custom)
1127 self.assertTrue('key' in view)
1128 self.assertTrue('magic' in view)
1129 self.assertFalse('xxx' in view)
1130 self.assertEqual(view['key'], 'getitem=value')
1131 self.assertRaises(KeyError, view.__getitem__, 'xxx')
1132 self.assertEqual(tuple(view), ('iter',))
1133 self.assertEqual(len(view), 500)
1134 self.assertEqual(view.copy(), 'copy')
1135 self.assertEqual(view.get('key'), 'get=value')
1136 self.assertEqual(view.get('xxx'), 'get=default=None')
1137 self.assertEqual(view.items(), 'items')
1138 self.assertEqual(view.keys(), 'keys')
1139 self.assertEqual(view.values(), 'values')
1140
1141 def test_chainmap(self):
1142 d1 = {'x': 1}
1143 d2 = {'y': 2}
1144 mapping = collections.ChainMap(d1, d2)
1145 view = self.mappingproxy(mapping)
1146 self.assertTrue('x' in view)
1147 self.assertTrue('y' in view)
1148 self.assertFalse('z' in view)
1149 self.assertEqual(view['x'], 1)
1150 self.assertEqual(view['y'], 2)
1151 self.assertRaises(KeyError, view.__getitem__, 'z')
1152 self.assertEqual(tuple(sorted(view)), ('x', 'y'))
1153 self.assertEqual(len(view), 2)
1154 copy = view.copy()
1155 self.assertIsNot(copy, mapping)
1156 self.assertIsInstance(copy, collections.ChainMap)
1157 self.assertEqual(copy, mapping)
1158 self.assertEqual(view.get('x'), 1)
1159 self.assertEqual(view.get('y'), 2)
1160 self.assertIsNone(view.get('z'))
1161 self.assertEqual(tuple(sorted(view.items())), (('x', 1), ('y', 2)))
1162 self.assertEqual(tuple(sorted(view.keys())), ('x', 'y'))
1163 self.assertEqual(tuple(sorted(view.values())), (1, 2))
1164
1165 def test_contains(self):
1166 view = self.mappingproxy(dict.fromkeys('abc'))
1167 self.assertTrue('a' in view)
1168 self.assertTrue('b' in view)
1169 self.assertTrue('c' in view)
1170 self.assertFalse('xxx' in view)
1171
1172 def test_views(self):
1173 mapping = {}
1174 view = self.mappingproxy(mapping)
1175 keys = view.keys()
1176 values = view.values()
1177 items = view.items()
1178 self.assertEqual(list(keys), [])
1179 self.assertEqual(list(values), [])
1180 self.assertEqual(list(items), [])
1181 mapping['key'] = 'value'
1182 self.assertEqual(list(keys), ['key'])
1183 self.assertEqual(list(values), ['value'])
1184 self.assertEqual(list(items), [('key', 'value')])
1185
1186 def test_len(self):
1187 for expected in range(6):
1188 data = dict.fromkeys('abcde'[:expected])
1189 self.assertEqual(len(data), expected)
1190 view = self.mappingproxy(data)
1191 self.assertEqual(len(view), expected)
1192
1193 def test_iterators(self):
1194 keys = ('x', 'y')
1195 values = (1, 2)
1196 items = tuple(zip(keys, values))
1197 view = self.mappingproxy(dict(items))
1198 self.assertEqual(set(view), set(keys))
1199 self.assertEqual(set(view.keys()), set(keys))
1200 self.assertEqual(set(view.values()), set(values))
1201 self.assertEqual(set(view.items()), set(items))
1202
1203 def test_reversed(self):
1204 d = {'a': 1, 'b': 2, 'foo': 0, 'c': 3, 'd': 4}
1205 mp = self.mappingproxy(d)
1206 del d['foo']
1207 r = reversed(mp)
1208 self.assertEqual(list(r), list('dcba'))
1209 self.assertRaises(StopIteration, next, r)
1210
1211 def test_copy(self):
1212 original = {'key1': 27, 'key2': 51, 'key3': 93}
1213 view = self.mappingproxy(original)
1214 copy = view.copy()
1215 self.assertEqual(type(copy), dict)
1216 self.assertEqual(copy, original)
1217 original['key1'] = 70
1218 self.assertEqual(view['key1'], 70)
1219 self.assertEqual(copy['key1'], 27)
1220
1221 def test_union(self):
1222 mapping = {'a': 0, 'b': 1, 'c': 2}
1223 view = self.mappingproxy(mapping)
1224 with self.assertRaises(TypeError):
1225 view | [('r', 2), ('d', 2)]
1226 with self.assertRaises(TypeError):
1227 [('r', 2), ('d', 2)] | view
1228 with self.assertRaises(TypeError):
1229 view |= [('r', 2), ('d', 2)]
1230 other = {'c': 3, 'p': 0}
1231 self.assertDictEqual(view | other, {'a': 0, 'b': 1, 'c': 3, 'p': 0})
1232 self.assertDictEqual(other | view, {'c': 2, 'p': 0, 'a': 0, 'b': 1})
1233 self.assertEqual(view, {'a': 0, 'b': 1, 'c': 2})
1234 self.assertDictEqual(mapping, {'a': 0, 'b': 1, 'c': 2})
1235 self.assertDictEqual(other, {'c': 3, 'p': 0})
1236
1237
1238 class ESC[4;38;5;81mClassCreationTests(ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
1239
1240 class ESC[4;38;5;81mMeta(ESC[4;38;5;149mtype):
1241 def __init__(cls, name, bases, ns, **kw):
1242 super().__init__(name, bases, ns)
1243 @staticmethod
1244 def __new__(mcls, name, bases, ns, **kw):
1245 return super().__new__(mcls, name, bases, ns)
1246 @classmethod
1247 def __prepare__(mcls, name, bases, **kw):
1248 ns = super().__prepare__(name, bases)
1249 ns["y"] = 1
1250 ns.update(kw)
1251 return ns
1252
1253 def test_new_class_basics(self):
1254 C = types.new_class("C")
1255 self.assertEqual(C.__name__, "C")
1256 self.assertEqual(C.__bases__, (object,))
1257
1258 def test_new_class_subclass(self):
1259 C = types.new_class("C", (int,))
1260 self.assertTrue(issubclass(C, int))
1261
1262 def test_new_class_meta(self):
1263 Meta = self.Meta
1264 settings = {"metaclass": Meta, "z": 2}
1265 # We do this twice to make sure the passed in dict isn't mutated
1266 for i in range(2):
1267 C = types.new_class("C" + str(i), (), settings)
1268 self.assertIsInstance(C, Meta)
1269 self.assertEqual(C.y, 1)
1270 self.assertEqual(C.z, 2)
1271
1272 def test_new_class_exec_body(self):
1273 Meta = self.Meta
1274 def func(ns):
1275 ns["x"] = 0
1276 C = types.new_class("C", (), {"metaclass": Meta, "z": 2}, func)
1277 self.assertIsInstance(C, Meta)
1278 self.assertEqual(C.x, 0)
1279 self.assertEqual(C.y, 1)
1280 self.assertEqual(C.z, 2)
1281
1282 def test_new_class_metaclass_keywords(self):
1283 #Test that keywords are passed to the metaclass:
1284 def meta_func(name, bases, ns, **kw):
1285 return name, bases, ns, kw
1286 res = types.new_class("X",
1287 (int, object),
1288 dict(metaclass=meta_func, x=0))
1289 self.assertEqual(res, ("X", (int, object), {}, {"x": 0}))
1290
1291 def test_new_class_defaults(self):
1292 # Test defaults/keywords:
1293 C = types.new_class("C", (), {}, None)
1294 self.assertEqual(C.__name__, "C")
1295 self.assertEqual(C.__bases__, (object,))
1296
1297 def test_new_class_meta_with_base(self):
1298 Meta = self.Meta
1299 def func(ns):
1300 ns["x"] = 0
1301 C = types.new_class(name="C",
1302 bases=(int,),
1303 kwds=dict(metaclass=Meta, z=2),
1304 exec_body=func)
1305 self.assertTrue(issubclass(C, int))
1306 self.assertIsInstance(C, Meta)
1307 self.assertEqual(C.x, 0)
1308 self.assertEqual(C.y, 1)
1309 self.assertEqual(C.z, 2)
1310
1311 def test_new_class_with_mro_entry(self):
1312 class ESC[4;38;5;81mA: pass
1313 class ESC[4;38;5;81mC:
1314 def __mro_entries__(self, bases):
1315 return (A,)
1316 c = C()
1317 D = types.new_class('D', (c,), {})
1318 self.assertEqual(D.__bases__, (A,))
1319 self.assertEqual(D.__orig_bases__, (c,))
1320 self.assertEqual(D.__mro__, (D, A, object))
1321
1322 def test_new_class_with_mro_entry_genericalias(self):
1323 L1 = types.new_class('L1', (typing.List[int],), {})
1324 self.assertEqual(L1.__bases__, (list, typing.Generic))
1325 self.assertEqual(L1.__orig_bases__, (typing.List[int],))
1326 self.assertEqual(L1.__mro__, (L1, list, typing.Generic, object))
1327
1328 L2 = types.new_class('L2', (list[int],), {})
1329 self.assertEqual(L2.__bases__, (list,))
1330 self.assertEqual(L2.__orig_bases__, (list[int],))
1331 self.assertEqual(L2.__mro__, (L2, list, object))
1332
1333 def test_new_class_with_mro_entry_none(self):
1334 class ESC[4;38;5;81mA: pass
1335 class ESC[4;38;5;81mB: pass
1336 class ESC[4;38;5;81mC:
1337 def __mro_entries__(self, bases):
1338 return ()
1339 c = C()
1340 D = types.new_class('D', (A, c, B), {})
1341 self.assertEqual(D.__bases__, (A, B))
1342 self.assertEqual(D.__orig_bases__, (A, c, B))
1343 self.assertEqual(D.__mro__, (D, A, B, object))
1344
1345 def test_new_class_with_mro_entry_error(self):
1346 class ESC[4;38;5;81mA: pass
1347 class ESC[4;38;5;81mC:
1348 def __mro_entries__(self, bases):
1349 return A
1350 c = C()
1351 with self.assertRaises(TypeError):
1352 types.new_class('D', (c,), {})
1353
1354 def test_new_class_with_mro_entry_multiple(self):
1355 class ESC[4;38;5;81mA1: pass
1356 class ESC[4;38;5;81mA2: pass
1357 class ESC[4;38;5;81mB1: pass
1358 class ESC[4;38;5;81mB2: pass
1359 class ESC[4;38;5;81mA:
1360 def __mro_entries__(self, bases):
1361 return (A1, A2)
1362 class ESC[4;38;5;81mB:
1363 def __mro_entries__(self, bases):
1364 return (B1, B2)
1365 D = types.new_class('D', (A(), B()), {})
1366 self.assertEqual(D.__bases__, (A1, A2, B1, B2))
1367
1368 def test_new_class_with_mro_entry_multiple_2(self):
1369 class ESC[4;38;5;81mA1: pass
1370 class ESC[4;38;5;81mA2: pass
1371 class ESC[4;38;5;81mA3: pass
1372 class ESC[4;38;5;81mB1: pass
1373 class ESC[4;38;5;81mB2: pass
1374 class ESC[4;38;5;81mA:
1375 def __mro_entries__(self, bases):
1376 return (A1, A2, A3)
1377 class ESC[4;38;5;81mB:
1378 def __mro_entries__(self, bases):
1379 return (B1, B2)
1380 class ESC[4;38;5;81mC: pass
1381 D = types.new_class('D', (A(), C, B()), {})
1382 self.assertEqual(D.__bases__, (A1, A2, A3, C, B1, B2))
1383
1384 # Many of the following tests are derived from test_descr.py
1385 def test_prepare_class(self):
1386 # Basic test of metaclass derivation
1387 expected_ns = {}
1388 class ESC[4;38;5;81mA(ESC[4;38;5;149mtype):
1389 def __new__(*args, **kwargs):
1390 return type.__new__(*args, **kwargs)
1391
1392 def __prepare__(*args):
1393 return expected_ns
1394
1395 B = types.new_class("B", (object,))
1396 C = types.new_class("C", (object,), {"metaclass": A})
1397
1398 # The most derived metaclass of D is A rather than type.
1399 meta, ns, kwds = types.prepare_class("D", (B, C), {"metaclass": type})
1400 self.assertIs(meta, A)
1401 self.assertIs(ns, expected_ns)
1402 self.assertEqual(len(kwds), 0)
1403
1404 def test_bad___prepare__(self):
1405 # __prepare__() must return a mapping.
1406 class ESC[4;38;5;81mBadMeta(ESC[4;38;5;149mtype):
1407 @classmethod
1408 def __prepare__(*args):
1409 return None
1410 with self.assertRaisesRegex(TypeError,
1411 r'^BadMeta\.__prepare__\(\) must '
1412 r'return a mapping, not NoneType$'):
1413 class ESC[4;38;5;81mFoo(metaclass=ESC[4;38;5;149mBadMeta):
1414 pass
1415 # Also test the case in which the metaclass is not a type.
1416 class ESC[4;38;5;81mBadMeta:
1417 @classmethod
1418 def __prepare__(*args):
1419 return None
1420 with self.assertRaisesRegex(TypeError,
1421 r'^<metaclass>\.__prepare__\(\) must '
1422 r'return a mapping, not NoneType$'):
1423 class ESC[4;38;5;81mBar(metaclass=ESC[4;38;5;149mBadMeta()):
1424 pass
1425
1426 def test_resolve_bases(self):
1427 class ESC[4;38;5;81mA: pass
1428 class ESC[4;38;5;81mB: pass
1429 class ESC[4;38;5;81mC:
1430 def __mro_entries__(self, bases):
1431 if A in bases:
1432 return ()
1433 return (A,)
1434 c = C()
1435 self.assertEqual(types.resolve_bases(()), ())
1436 self.assertEqual(types.resolve_bases((c,)), (A,))
1437 self.assertEqual(types.resolve_bases((C,)), (C,))
1438 self.assertEqual(types.resolve_bases((A, C)), (A, C))
1439 self.assertEqual(types.resolve_bases((c, A)), (A,))
1440 self.assertEqual(types.resolve_bases((A, c)), (A,))
1441 x = (A,)
1442 y = (C,)
1443 z = (A, C)
1444 t = (A, C, B)
1445 for bases in [x, y, z, t]:
1446 self.assertIs(types.resolve_bases(bases), bases)
1447
1448 def test_resolve_bases_with_mro_entry(self):
1449 self.assertEqual(types.resolve_bases((typing.List[int],)),
1450 (list, typing.Generic))
1451 self.assertEqual(types.resolve_bases((list[int],)), (list,))
1452
1453 def test_metaclass_derivation(self):
1454 # issue1294232: correct metaclass calculation
1455 new_calls = [] # to check the order of __new__ calls
1456 class ESC[4;38;5;81mAMeta(ESC[4;38;5;149mtype):
1457 def __new__(mcls, name, bases, ns):
1458 new_calls.append('AMeta')
1459 return super().__new__(mcls, name, bases, ns)
1460 @classmethod
1461 def __prepare__(mcls, name, bases):
1462 return {}
1463
1464 class ESC[4;38;5;81mBMeta(ESC[4;38;5;149mAMeta):
1465 def __new__(mcls, name, bases, ns):
1466 new_calls.append('BMeta')
1467 return super().__new__(mcls, name, bases, ns)
1468 @classmethod
1469 def __prepare__(mcls, name, bases):
1470 ns = super().__prepare__(name, bases)
1471 ns['BMeta_was_here'] = True
1472 return ns
1473
1474 A = types.new_class("A", (), {"metaclass": AMeta})
1475 self.assertEqual(new_calls, ['AMeta'])
1476 new_calls.clear()
1477
1478 B = types.new_class("B", (), {"metaclass": BMeta})
1479 # BMeta.__new__ calls AMeta.__new__ with super:
1480 self.assertEqual(new_calls, ['BMeta', 'AMeta'])
1481 new_calls.clear()
1482
1483 C = types.new_class("C", (A, B))
1484 # The most derived metaclass is BMeta:
1485 self.assertEqual(new_calls, ['BMeta', 'AMeta'])
1486 new_calls.clear()
1487 # BMeta.__prepare__ should've been called:
1488 self.assertIn('BMeta_was_here', C.__dict__)
1489
1490 # The order of the bases shouldn't matter:
1491 C2 = types.new_class("C2", (B, A))
1492 self.assertEqual(new_calls, ['BMeta', 'AMeta'])
1493 new_calls.clear()
1494 self.assertIn('BMeta_was_here', C2.__dict__)
1495
1496 # Check correct metaclass calculation when a metaclass is declared:
1497 D = types.new_class("D", (C,), {"metaclass": type})
1498 self.assertEqual(new_calls, ['BMeta', 'AMeta'])
1499 new_calls.clear()
1500 self.assertIn('BMeta_was_here', D.__dict__)
1501
1502 E = types.new_class("E", (C,), {"metaclass": AMeta})
1503 self.assertEqual(new_calls, ['BMeta', 'AMeta'])
1504 new_calls.clear()
1505 self.assertIn('BMeta_was_here', E.__dict__)
1506
1507 def test_metaclass_override_function(self):
1508 # Special case: the given metaclass isn't a class,
1509 # so there is no metaclass calculation.
1510 class ESC[4;38;5;81mA(metaclass=ESC[4;38;5;149mselfESC[4;38;5;149m.ESC[4;38;5;149mMeta):
1511 pass
1512
1513 marker = object()
1514 def func(*args, **kwargs):
1515 return marker
1516
1517 X = types.new_class("X", (), {"metaclass": func})
1518 Y = types.new_class("Y", (object,), {"metaclass": func})
1519 Z = types.new_class("Z", (A,), {"metaclass": func})
1520 self.assertIs(marker, X)
1521 self.assertIs(marker, Y)
1522 self.assertIs(marker, Z)
1523
1524 def test_metaclass_override_callable(self):
1525 # The given metaclass is a class,
1526 # but not a descendant of type.
1527 new_calls = [] # to check the order of __new__ calls
1528 prepare_calls = [] # to track __prepare__ calls
1529 class ESC[4;38;5;81mANotMeta:
1530 def __new__(mcls, *args, **kwargs):
1531 new_calls.append('ANotMeta')
1532 return super().__new__(mcls)
1533 @classmethod
1534 def __prepare__(mcls, name, bases):
1535 prepare_calls.append('ANotMeta')
1536 return {}
1537
1538 class ESC[4;38;5;81mBNotMeta(ESC[4;38;5;149mANotMeta):
1539 def __new__(mcls, *args, **kwargs):
1540 new_calls.append('BNotMeta')
1541 return super().__new__(mcls)
1542 @classmethod
1543 def __prepare__(mcls, name, bases):
1544 prepare_calls.append('BNotMeta')
1545 return super().__prepare__(name, bases)
1546
1547 A = types.new_class("A", (), {"metaclass": ANotMeta})
1548 self.assertIs(ANotMeta, type(A))
1549 self.assertEqual(prepare_calls, ['ANotMeta'])
1550 prepare_calls.clear()
1551 self.assertEqual(new_calls, ['ANotMeta'])
1552 new_calls.clear()
1553
1554 B = types.new_class("B", (), {"metaclass": BNotMeta})
1555 self.assertIs(BNotMeta, type(B))
1556 self.assertEqual(prepare_calls, ['BNotMeta', 'ANotMeta'])
1557 prepare_calls.clear()
1558 self.assertEqual(new_calls, ['BNotMeta', 'ANotMeta'])
1559 new_calls.clear()
1560
1561 C = types.new_class("C", (A, B))
1562 self.assertIs(BNotMeta, type(C))
1563 self.assertEqual(prepare_calls, ['BNotMeta', 'ANotMeta'])
1564 prepare_calls.clear()
1565 self.assertEqual(new_calls, ['BNotMeta', 'ANotMeta'])
1566 new_calls.clear()
1567
1568 C2 = types.new_class("C2", (B, A))
1569 self.assertIs(BNotMeta, type(C2))
1570 self.assertEqual(prepare_calls, ['BNotMeta', 'ANotMeta'])
1571 prepare_calls.clear()
1572 self.assertEqual(new_calls, ['BNotMeta', 'ANotMeta'])
1573 new_calls.clear()
1574
1575 # This is a TypeError, because of a metaclass conflict:
1576 # BNotMeta is neither a subclass, nor a superclass of type
1577 with self.assertRaises(TypeError):
1578 D = types.new_class("D", (C,), {"metaclass": type})
1579
1580 E = types.new_class("E", (C,), {"metaclass": ANotMeta})
1581 self.assertIs(BNotMeta, type(E))
1582 self.assertEqual(prepare_calls, ['BNotMeta', 'ANotMeta'])
1583 prepare_calls.clear()
1584 self.assertEqual(new_calls, ['BNotMeta', 'ANotMeta'])
1585 new_calls.clear()
1586
1587 F = types.new_class("F", (object(), C))
1588 self.assertIs(BNotMeta, type(F))
1589 self.assertEqual(prepare_calls, ['BNotMeta', 'ANotMeta'])
1590 prepare_calls.clear()
1591 self.assertEqual(new_calls, ['BNotMeta', 'ANotMeta'])
1592 new_calls.clear()
1593
1594 F2 = types.new_class("F2", (C, object()))
1595 self.assertIs(BNotMeta, type(F2))
1596 self.assertEqual(prepare_calls, ['BNotMeta', 'ANotMeta'])
1597 prepare_calls.clear()
1598 self.assertEqual(new_calls, ['BNotMeta', 'ANotMeta'])
1599 new_calls.clear()
1600
1601 # TypeError: BNotMeta is neither a
1602 # subclass, nor a superclass of int
1603 with self.assertRaises(TypeError):
1604 X = types.new_class("X", (C, int()))
1605 with self.assertRaises(TypeError):
1606 X = types.new_class("X", (int(), C))
1607
1608 def test_one_argument_type(self):
1609 expected_message = 'type.__new__() takes exactly 3 arguments (1 given)'
1610
1611 # Only type itself can use the one-argument form (#27157)
1612 self.assertIs(type(5), int)
1613
1614 class ESC[4;38;5;81mM(ESC[4;38;5;149mtype):
1615 pass
1616 with self.assertRaises(TypeError) as cm:
1617 M(5)
1618 self.assertEqual(str(cm.exception), expected_message)
1619
1620 class ESC[4;38;5;81mN(ESC[4;38;5;149mtype, metaclass=ESC[4;38;5;149mM):
1621 pass
1622 with self.assertRaises(TypeError) as cm:
1623 N(5)
1624 self.assertEqual(str(cm.exception), expected_message)
1625
1626 def test_metaclass_new_error(self):
1627 # bpo-44232: The C function type_new() must properly report the
1628 # exception when a metaclass constructor raises an exception and the
1629 # winner class is not the metaclass.
1630 class ESC[4;38;5;81mModelBase(ESC[4;38;5;149mtype):
1631 def __new__(cls, name, bases, attrs):
1632 super_new = super().__new__
1633 new_class = super_new(cls, name, bases, {})
1634 if name != "Model":
1635 raise RuntimeWarning(f"{name=}")
1636 return new_class
1637
1638 class ESC[4;38;5;81mModel(metaclass=ESC[4;38;5;149mModelBase):
1639 pass
1640
1641 with self.assertRaises(RuntimeWarning):
1642 type("SouthPonies", (Model,), {})
1643
1644
1645 class ESC[4;38;5;81mSimpleNamespaceTests(ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
1646
1647 def test_constructor(self):
1648 ns1 = types.SimpleNamespace()
1649 ns2 = types.SimpleNamespace(x=1, y=2)
1650 ns3 = types.SimpleNamespace(**dict(x=1, y=2))
1651
1652 with self.assertRaises(TypeError):
1653 types.SimpleNamespace(1, 2, 3)
1654 with self.assertRaises(TypeError):
1655 types.SimpleNamespace(**{1: 2})
1656
1657 self.assertEqual(len(ns1.__dict__), 0)
1658 self.assertEqual(vars(ns1), {})
1659 self.assertEqual(len(ns2.__dict__), 2)
1660 self.assertEqual(vars(ns2), {'y': 2, 'x': 1})
1661 self.assertEqual(len(ns3.__dict__), 2)
1662 self.assertEqual(vars(ns3), {'y': 2, 'x': 1})
1663
1664 def test_unbound(self):
1665 ns1 = vars(types.SimpleNamespace())
1666 ns2 = vars(types.SimpleNamespace(x=1, y=2))
1667
1668 self.assertEqual(ns1, {})
1669 self.assertEqual(ns2, {'y': 2, 'x': 1})
1670
1671 def test_underlying_dict(self):
1672 ns1 = types.SimpleNamespace()
1673 ns2 = types.SimpleNamespace(x=1, y=2)
1674 ns3 = types.SimpleNamespace(a=True, b=False)
1675 mapping = ns3.__dict__
1676 del ns3
1677
1678 self.assertEqual(ns1.__dict__, {})
1679 self.assertEqual(ns2.__dict__, {'y': 2, 'x': 1})
1680 self.assertEqual(mapping, dict(a=True, b=False))
1681
1682 def test_attrget(self):
1683 ns = types.SimpleNamespace(x=1, y=2, w=3)
1684
1685 self.assertEqual(ns.x, 1)
1686 self.assertEqual(ns.y, 2)
1687 self.assertEqual(ns.w, 3)
1688 with self.assertRaises(AttributeError):
1689 ns.z
1690
1691 def test_attrset(self):
1692 ns1 = types.SimpleNamespace()
1693 ns2 = types.SimpleNamespace(x=1, y=2, w=3)
1694 ns1.a = 'spam'
1695 ns1.b = 'ham'
1696 ns2.z = 4
1697 ns2.theta = None
1698
1699 self.assertEqual(ns1.__dict__, dict(a='spam', b='ham'))
1700 self.assertEqual(ns2.__dict__, dict(x=1, y=2, w=3, z=4, theta=None))
1701
1702 def test_attrdel(self):
1703 ns1 = types.SimpleNamespace()
1704 ns2 = types.SimpleNamespace(x=1, y=2, w=3)
1705
1706 with self.assertRaises(AttributeError):
1707 del ns1.spam
1708 with self.assertRaises(AttributeError):
1709 del ns2.spam
1710
1711 del ns2.y
1712 self.assertEqual(vars(ns2), dict(w=3, x=1))
1713 ns2.y = 'spam'
1714 self.assertEqual(vars(ns2), dict(w=3, x=1, y='spam'))
1715 del ns2.y
1716 self.assertEqual(vars(ns2), dict(w=3, x=1))
1717
1718 ns1.spam = 5
1719 self.assertEqual(vars(ns1), dict(spam=5))
1720 del ns1.spam
1721 self.assertEqual(vars(ns1), {})
1722
1723 def test_repr(self):
1724 ns1 = types.SimpleNamespace(x=1, y=2, w=3)
1725 ns2 = types.SimpleNamespace()
1726 ns2.x = "spam"
1727 ns2._y = 5
1728 name = "namespace"
1729
1730 self.assertEqual(repr(ns1), "{name}(x=1, y=2, w=3)".format(name=name))
1731 self.assertEqual(repr(ns2), "{name}(x='spam', _y=5)".format(name=name))
1732
1733 def test_equal(self):
1734 ns1 = types.SimpleNamespace(x=1)
1735 ns2 = types.SimpleNamespace()
1736 ns2.x = 1
1737
1738 self.assertEqual(types.SimpleNamespace(), types.SimpleNamespace())
1739 self.assertEqual(ns1, ns2)
1740 self.assertNotEqual(ns2, types.SimpleNamespace())
1741
1742 def test_nested(self):
1743 ns1 = types.SimpleNamespace(a=1, b=2)
1744 ns2 = types.SimpleNamespace()
1745 ns3 = types.SimpleNamespace(x=ns1)
1746 ns2.spam = ns1
1747 ns2.ham = '?'
1748 ns2.spam = ns3
1749
1750 self.assertEqual(vars(ns1), dict(a=1, b=2))
1751 self.assertEqual(vars(ns2), dict(spam=ns3, ham='?'))
1752 self.assertEqual(ns2.spam, ns3)
1753 self.assertEqual(vars(ns3), dict(x=ns1))
1754 self.assertEqual(ns3.x.a, 1)
1755
1756 def test_recursive(self):
1757 ns1 = types.SimpleNamespace(c='cookie')
1758 ns2 = types.SimpleNamespace()
1759 ns3 = types.SimpleNamespace(x=1)
1760 ns1.spam = ns1
1761 ns2.spam = ns3
1762 ns3.spam = ns2
1763
1764 self.assertEqual(ns1.spam, ns1)
1765 self.assertEqual(ns1.spam.spam, ns1)
1766 self.assertEqual(ns1.spam.spam, ns1.spam)
1767 self.assertEqual(ns2.spam, ns3)
1768 self.assertEqual(ns3.spam, ns2)
1769 self.assertEqual(ns2.spam.spam, ns2)
1770
1771 def test_recursive_repr(self):
1772 ns1 = types.SimpleNamespace(c='cookie')
1773 ns2 = types.SimpleNamespace()
1774 ns3 = types.SimpleNamespace(x=1)
1775 ns1.spam = ns1
1776 ns2.spam = ns3
1777 ns3.spam = ns2
1778 name = "namespace"
1779 repr1 = "{name}(c='cookie', spam={name}(...))".format(name=name)
1780 repr2 = "{name}(spam={name}(x=1, spam={name}(...)))".format(name=name)
1781
1782 self.assertEqual(repr(ns1), repr1)
1783 self.assertEqual(repr(ns2), repr2)
1784
1785 def test_as_dict(self):
1786 ns = types.SimpleNamespace(spam='spamspamspam')
1787
1788 with self.assertRaises(TypeError):
1789 len(ns)
1790 with self.assertRaises(TypeError):
1791 iter(ns)
1792 with self.assertRaises(TypeError):
1793 'spam' in ns
1794 with self.assertRaises(TypeError):
1795 ns['spam']
1796
1797 def test_subclass(self):
1798 class ESC[4;38;5;81mSpam(ESC[4;38;5;149mtypesESC[4;38;5;149m.ESC[4;38;5;149mSimpleNamespace):
1799 pass
1800
1801 spam = Spam(ham=8, eggs=9)
1802
1803 self.assertIs(type(spam), Spam)
1804 self.assertEqual(vars(spam), {'ham': 8, 'eggs': 9})
1805
1806 def test_pickle(self):
1807 ns = types.SimpleNamespace(breakfast="spam", lunch="spam")
1808
1809 for protocol in range(pickle.HIGHEST_PROTOCOL + 1):
1810 pname = "protocol {}".format(protocol)
1811 try:
1812 ns_pickled = pickle.dumps(ns, protocol)
1813 except TypeError as e:
1814 raise TypeError(pname) from e
1815 ns_roundtrip = pickle.loads(ns_pickled)
1816
1817 self.assertEqual(ns, ns_roundtrip, pname)
1818
1819 def test_fake_namespace_compare(self):
1820 # Issue #24257: Incorrect use of PyObject_IsInstance() caused
1821 # SystemError.
1822 class ESC[4;38;5;81mFakeSimpleNamespace(ESC[4;38;5;149mstr):
1823 __class__ = types.SimpleNamespace
1824 self.assertFalse(types.SimpleNamespace() == FakeSimpleNamespace())
1825 self.assertTrue(types.SimpleNamespace() != FakeSimpleNamespace())
1826 with self.assertRaises(TypeError):
1827 types.SimpleNamespace() < FakeSimpleNamespace()
1828 with self.assertRaises(TypeError):
1829 types.SimpleNamespace() <= FakeSimpleNamespace()
1830 with self.assertRaises(TypeError):
1831 types.SimpleNamespace() > FakeSimpleNamespace()
1832 with self.assertRaises(TypeError):
1833 types.SimpleNamespace() >= FakeSimpleNamespace()
1834
1835
1836 class ESC[4;38;5;81mCoroutineTests(ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
1837 def test_wrong_args(self):
1838 samples = [None, 1, object()]
1839 for sample in samples:
1840 with self.assertRaisesRegex(TypeError,
1841 'types.coroutine.*expects a callable'):
1842 types.coroutine(sample)
1843
1844 def test_non_gen_values(self):
1845 @types.coroutine
1846 def foo():
1847 return 'spam'
1848 self.assertEqual(foo(), 'spam')
1849
1850 class ESC[4;38;5;81mAwaitable:
1851 def __await__(self):
1852 return ()
1853 aw = Awaitable()
1854 @types.coroutine
1855 def foo():
1856 return aw
1857 self.assertIs(aw, foo())
1858
1859 # decorate foo second time
1860 foo = types.coroutine(foo)
1861 self.assertIs(aw, foo())
1862
1863 def test_async_def(self):
1864 # Test that types.coroutine passes 'async def' coroutines
1865 # without modification
1866
1867 async def foo(): pass
1868 foo_code = foo.__code__
1869 foo_flags = foo.__code__.co_flags
1870 decorated_foo = types.coroutine(foo)
1871 self.assertIs(foo, decorated_foo)
1872 self.assertEqual(foo.__code__.co_flags, foo_flags)
1873 self.assertIs(decorated_foo.__code__, foo_code)
1874
1875 foo_coro = foo()
1876 def bar(): return foo_coro
1877 for _ in range(2):
1878 bar = types.coroutine(bar)
1879 coro = bar()
1880 self.assertIs(foo_coro, coro)
1881 self.assertEqual(coro.cr_code.co_flags, foo_flags)
1882 coro.close()
1883
1884 def test_duck_coro(self):
1885 class ESC[4;38;5;81mCoroLike:
1886 def send(self): pass
1887 def throw(self): pass
1888 def close(self): pass
1889 def __await__(self): return self
1890
1891 coro = CoroLike()
1892 @types.coroutine
1893 def foo():
1894 return coro
1895 self.assertIs(foo(), coro)
1896 self.assertIs(foo().__await__(), coro)
1897
1898 def test_duck_corogen(self):
1899 class ESC[4;38;5;81mCoroGenLike:
1900 def send(self): pass
1901 def throw(self): pass
1902 def close(self): pass
1903 def __await__(self): return self
1904 def __iter__(self): return self
1905 def __next__(self): pass
1906
1907 coro = CoroGenLike()
1908 @types.coroutine
1909 def foo():
1910 return coro
1911 self.assertIs(foo(), coro)
1912 self.assertIs(foo().__await__(), coro)
1913
1914 def test_duck_gen(self):
1915 class ESC[4;38;5;81mGenLike:
1916 def send(self): pass
1917 def throw(self): pass
1918 def close(self): pass
1919 def __iter__(self): pass
1920 def __next__(self): pass
1921
1922 # Setup generator mock object
1923 gen = unittest.mock.MagicMock(GenLike)
1924 gen.__iter__ = lambda gen: gen
1925 gen.__name__ = 'gen'
1926 gen.__qualname__ = 'test.gen'
1927 self.assertIsInstance(gen, collections.abc.Generator)
1928 self.assertIs(gen, iter(gen))
1929
1930 @types.coroutine
1931 def foo(): return gen
1932
1933 wrapper = foo()
1934 self.assertIsInstance(wrapper, types._GeneratorWrapper)
1935 self.assertIs(wrapper.__await__(), wrapper)
1936 # Wrapper proxies duck generators completely:
1937 self.assertIs(iter(wrapper), wrapper)
1938
1939 self.assertIsInstance(wrapper, collections.abc.Coroutine)
1940 self.assertIsInstance(wrapper, collections.abc.Awaitable)
1941
1942 self.assertIs(wrapper.__qualname__, gen.__qualname__)
1943 self.assertIs(wrapper.__name__, gen.__name__)
1944
1945 # Test AttributeErrors
1946 for name in {'gi_running', 'gi_frame', 'gi_code', 'gi_yieldfrom',
1947 'cr_running', 'cr_frame', 'cr_code', 'cr_await'}:
1948 with self.assertRaises(AttributeError):
1949 getattr(wrapper, name)
1950
1951 # Test attributes pass-through
1952 gen.gi_running = object()
1953 gen.gi_frame = object()
1954 gen.gi_code = object()
1955 gen.gi_yieldfrom = object()
1956 self.assertIs(wrapper.gi_running, gen.gi_running)
1957 self.assertIs(wrapper.gi_frame, gen.gi_frame)
1958 self.assertIs(wrapper.gi_code, gen.gi_code)
1959 self.assertIs(wrapper.gi_yieldfrom, gen.gi_yieldfrom)
1960 self.assertIs(wrapper.cr_running, gen.gi_running)
1961 self.assertIs(wrapper.cr_frame, gen.gi_frame)
1962 self.assertIs(wrapper.cr_code, gen.gi_code)
1963 self.assertIs(wrapper.cr_await, gen.gi_yieldfrom)
1964
1965 wrapper.close()
1966 gen.close.assert_called_once_with()
1967
1968 wrapper.send(1)
1969 gen.send.assert_called_once_with(1)
1970 gen.reset_mock()
1971
1972 next(wrapper)
1973 gen.__next__.assert_called_once_with()
1974 gen.reset_mock()
1975
1976 wrapper.throw(1, 2, 3)
1977 gen.throw.assert_called_once_with(1, 2, 3)
1978 gen.reset_mock()
1979
1980 wrapper.throw(1, 2)
1981 gen.throw.assert_called_once_with(1, 2)
1982 gen.reset_mock()
1983
1984 wrapper.throw(1)
1985 gen.throw.assert_called_once_with(1)
1986 gen.reset_mock()
1987
1988 # Test exceptions propagation
1989 error = Exception()
1990 gen.throw.side_effect = error
1991 try:
1992 wrapper.throw(1)
1993 except Exception as ex:
1994 self.assertIs(ex, error)
1995 else:
1996 self.fail('wrapper did not propagate an exception')
1997
1998 # Test invalid args
1999 gen.reset_mock()
2000 with self.assertRaises(TypeError):
2001 wrapper.throw()
2002 self.assertFalse(gen.throw.called)
2003 with self.assertRaises(TypeError):
2004 wrapper.close(1)
2005 self.assertFalse(gen.close.called)
2006 with self.assertRaises(TypeError):
2007 wrapper.send()
2008 self.assertFalse(gen.send.called)
2009
2010 # Test that we do not double wrap
2011 @types.coroutine
2012 def bar(): return wrapper
2013 self.assertIs(wrapper, bar())
2014
2015 # Test weakrefs support
2016 ref = weakref.ref(wrapper)
2017 self.assertIs(ref(), wrapper)
2018
2019 def test_duck_functional_gen(self):
2020 class ESC[4;38;5;81mGenerator:
2021 """Emulates the following generator (very clumsy):
2022
2023 def gen(fut):
2024 result = yield fut
2025 return result * 2
2026 """
2027 def __init__(self, fut):
2028 self._i = 0
2029 self._fut = fut
2030 def __iter__(self):
2031 return self
2032 def __next__(self):
2033 return self.send(None)
2034 def send(self, v):
2035 try:
2036 if self._i == 0:
2037 assert v is None
2038 return self._fut
2039 if self._i == 1:
2040 raise StopIteration(v * 2)
2041 if self._i > 1:
2042 raise StopIteration
2043 finally:
2044 self._i += 1
2045 def throw(self, tp, *exc):
2046 self._i = 100
2047 if tp is not GeneratorExit:
2048 raise tp
2049 def close(self):
2050 self.throw(GeneratorExit)
2051
2052 @types.coroutine
2053 def foo(): return Generator('spam')
2054
2055 wrapper = foo()
2056 self.assertIsInstance(wrapper, types._GeneratorWrapper)
2057
2058 async def corofunc():
2059 return await foo() + 100
2060 coro = corofunc()
2061
2062 self.assertEqual(coro.send(None), 'spam')
2063 try:
2064 coro.send(20)
2065 except StopIteration as ex:
2066 self.assertEqual(ex.args[0], 140)
2067 else:
2068 self.fail('StopIteration was expected')
2069
2070 def test_gen(self):
2071 def gen_func():
2072 yield 1
2073 return (yield 2)
2074 gen = gen_func()
2075 @types.coroutine
2076 def foo(): return gen
2077 wrapper = foo()
2078 self.assertIsInstance(wrapper, types._GeneratorWrapper)
2079 self.assertIs(wrapper.__await__(), gen)
2080
2081 for name in ('__name__', '__qualname__', 'gi_code',
2082 'gi_running', 'gi_frame'):
2083 self.assertIs(getattr(foo(), name),
2084 getattr(gen, name))
2085 self.assertIs(foo().cr_code, gen.gi_code)
2086
2087 self.assertEqual(next(wrapper), 1)
2088 self.assertEqual(wrapper.send(None), 2)
2089 with self.assertRaisesRegex(StopIteration, 'spam'):
2090 wrapper.send('spam')
2091
2092 gen = gen_func()
2093 wrapper = foo()
2094 wrapper.send(None)
2095 with self.assertRaisesRegex(Exception, 'ham'):
2096 wrapper.throw(Exception, Exception('ham'))
2097
2098 # decorate foo second time
2099 foo = types.coroutine(foo)
2100 self.assertIs(foo().__await__(), gen)
2101
2102 def test_returning_itercoro(self):
2103 @types.coroutine
2104 def gen():
2105 yield
2106
2107 gencoro = gen()
2108
2109 @types.coroutine
2110 def foo():
2111 return gencoro
2112
2113 self.assertIs(foo(), gencoro)
2114
2115 # decorate foo second time
2116 foo = types.coroutine(foo)
2117 self.assertIs(foo(), gencoro)
2118
2119 def test_genfunc(self):
2120 def gen(): yield
2121 self.assertIs(types.coroutine(gen), gen)
2122 self.assertIs(types.coroutine(types.coroutine(gen)), gen)
2123
2124 self.assertTrue(gen.__code__.co_flags & inspect.CO_ITERABLE_COROUTINE)
2125 self.assertFalse(gen.__code__.co_flags & inspect.CO_COROUTINE)
2126
2127 g = gen()
2128 self.assertTrue(g.gi_code.co_flags & inspect.CO_ITERABLE_COROUTINE)
2129 self.assertFalse(g.gi_code.co_flags & inspect.CO_COROUTINE)
2130
2131 self.assertIs(types.coroutine(gen), gen)
2132
2133 def test_wrapper_object(self):
2134 def gen():
2135 yield
2136 @types.coroutine
2137 def coro():
2138 return gen()
2139
2140 wrapper = coro()
2141 self.assertIn('GeneratorWrapper', repr(wrapper))
2142 self.assertEqual(repr(wrapper), str(wrapper))
2143 self.assertTrue(set(dir(wrapper)).issuperset({
2144 '__await__', '__iter__', '__next__', 'cr_code', 'cr_running',
2145 'cr_frame', 'gi_code', 'gi_frame', 'gi_running', 'send',
2146 'close', 'throw'}))
2147
2148
2149 if __name__ == '__main__':
2150 unittest.main()