1# Python test set -- part 6, built-in types
2
3from test.support import run_with_locale, cpython_only
4import collections.abc
5from collections import namedtuple
6import copy
7import gc
8import inspect
9import pickle
10import locale
11import sys
12import types
13import unittest.mock
14import weakref
15import typing
16
17
18T = typing.TypeVar("T")
19
20class Example:
21    pass
22
23class Forward: ...
24
25def clear_typing_caches():
26    for f in typing._cleanups:
27        f()
28
29
30class TypesTests(unittest.TestCase):
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 C: 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            assert type(i) == int
230            assert 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
640class UnionTests(unittest.TestCase):
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 BadMeta(type):
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 BadMeta(type):
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        assert TV | str == typing.Union[TV, str]
786        assert 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        assert typing.get_args(typing.get_type_hints(forward_after)['x']) == (int, Forward)
891        assert typing.get_args(typing.get_type_hints(forward_before)['x']) == (int, Forward)
892
893    def test_or_type_operator_with_Protocol(self):
894        class Proto(typing.Protocol):
895            def meth(self) -> int:
896                ...
897        assert Proto | str == typing.Union[Proto, str]
898
899    def test_or_type_operator_with_Alias(self):
900        assert list | str == typing.Union[list, str]
901        assert typing.List | str == typing.Union[typing.List, str]
902
903    def test_or_type_operator_with_NamedTuple(self):
904        NT=namedtuple('A', ['B', 'C', 'D'])
905        assert NT | str == typing.Union[NT,str]
906
907    def test_or_type_operator_with_TypedDict(self):
908        class Point2D(typing.TypedDict):
909            x: int
910            y: int
911            label: str
912        assert Point2D | str == typing.Union[Point2D, str]
913
914    def test_or_type_operator_with_NewType(self):
915        UserId = typing.NewType('UserId', int)
916        assert UserId | str == typing.Union[UserId, str]
917
918    def test_or_type_operator_with_IO(self):
919        assert typing.IO | str == typing.Union[typing.IO, str]
920
921    def test_or_type_operator_with_SpecialForm(self):
922        assert typing.Any | str == typing.Union[typing.Any, str]
923        assert typing.NoReturn | str == typing.Union[typing.NoReturn, str]
924        assert typing.Optional[int] | str == typing.Union[typing.Optional[int], str]
925        assert typing.Optional[int] | str == typing.Union[int, str, None]
926        assert typing.Union[int, bool] | str == typing.Union[int, bool, str]
927
928    def test_or_type_operator_with_Literal(self):
929        Literal = typing.Literal
930        self.assertEqual((Literal[1] | Literal[2]).__args__,
931                         (Literal[1], Literal[2]))
932
933        self.assertEqual((Literal[0] | Literal[False]).__args__,
934                         (Literal[0], Literal[False]))
935        self.assertEqual((Literal[1] | Literal[True]).__args__,
936                         (Literal[1], Literal[True]))
937
938        self.assertEqual(Literal[1] | Literal[1], Literal[1])
939        self.assertEqual(Literal['a'] | Literal['a'], Literal['a'])
940
941        import enum
942        class Ints(enum.IntEnum):
943            A = 0
944            B = 1
945
946        self.assertEqual(Literal[Ints.A] | Literal[Ints.A], Literal[Ints.A])
947        self.assertEqual(Literal[Ints.B] | Literal[Ints.B], Literal[Ints.B])
948
949        self.assertEqual((Literal[Ints.B] | Literal[Ints.A]).__args__,
950                         (Literal[Ints.B], Literal[Ints.A]))
951
952        self.assertEqual((Literal[0] | Literal[Ints.A]).__args__,
953                         (Literal[0], Literal[Ints.A]))
954        self.assertEqual((Literal[1] | Literal[Ints.B]).__args__,
955                         (Literal[1], Literal[Ints.B]))
956
957    def test_or_type_repr(self):
958        assert repr(int | str) == "int | str"
959        assert repr((int | str) | list) == "int | str | list"
960        assert repr(int | (str | list)) == "int | str | list"
961        assert repr(int | None) == "int | None"
962        assert repr(int | type(None)) == "int | None"
963        assert repr(int | typing.GenericAlias(list, int)) == "int | list[int]"
964
965    def test_or_type_operator_with_genericalias(self):
966        a = list[int]
967        b = list[str]
968        c = dict[float, str]
969        class SubClass(types.GenericAlias): ...
970        d = SubClass(list, float)
971        # equivalence with typing.Union
972        self.assertEqual(a | b | c | d, typing.Union[a, b, c, d])
973        # de-duplicate
974        self.assertEqual(a | c | b | b | a | c | d | d, a | b | c | d)
975        # order shouldn't matter
976        self.assertEqual(a | b | d, b | a | d)
977        self.assertEqual(repr(a | b | c | d),
978                         "list[int] | list[str] | dict[float, str] | list[float]")
979
980        class BadType(type):
981            def __eq__(self, other):
982                return 1 / 0
983
984        bt = BadType('bt', (), {})
985        # Comparison should fail and errors should propagate out for bad types.
986        with self.assertRaises(ZeroDivisionError):
987            list[int] | list[bt]
988
989        union_ga = (list[str] | int, collections.abc.Callable[..., str] | int,
990                    d | int)
991        # Raise error when isinstance(type, genericalias | type)
992        for type_ in union_ga:
993            with self.subTest(f"check isinstance/issubclass is invalid for {type_}"):
994                with self.assertRaises(TypeError):
995                    isinstance(1, type_)
996                with self.assertRaises(TypeError):
997                    issubclass(int, type_)
998
999    def test_or_type_operator_with_bad_module(self):
1000        class BadMeta(type):
1001            __qualname__ = 'TypeVar'
1002            @property
1003            def __module__(self):
1004                1 / 0
1005        TypeVar = BadMeta('TypeVar', (), {})
1006        _SpecialForm = BadMeta('_SpecialForm', (), {})
1007        # Crashes in Issue44483
1008        with self.assertRaises((TypeError, ZeroDivisionError)):
1009            str | TypeVar()
1010        with self.assertRaises((TypeError, ZeroDivisionError)):
1011            str | _SpecialForm()
1012
1013    @cpython_only
1014    def test_or_type_operator_reference_cycle(self):
1015        if not hasattr(sys, 'gettotalrefcount'):
1016            self.skipTest('Cannot get total reference count.')
1017        gc.collect()
1018        before = sys.gettotalrefcount()
1019        for _ in range(30):
1020            T = typing.TypeVar('T')
1021            U = int | list[T]
1022            T.blah = U
1023            del T
1024            del U
1025        gc.collect()
1026        leeway = 15
1027        self.assertLessEqual(sys.gettotalrefcount() - before, leeway,
1028                             msg='Check for union reference leak.')
1029
1030
1031class MappingProxyTests(unittest.TestCase):
1032    mappingproxy = types.MappingProxyType
1033
1034    def test_constructor(self):
1035        class userdict(dict):
1036            pass
1037
1038        mapping = {'x': 1, 'y': 2}
1039        self.assertEqual(self.mappingproxy(mapping), mapping)
1040        mapping = userdict(x=1, y=2)
1041        self.assertEqual(self.mappingproxy(mapping), mapping)
1042        mapping = collections.ChainMap({'x': 1}, {'y': 2})
1043        self.assertEqual(self.mappingproxy(mapping), mapping)
1044
1045        self.assertRaises(TypeError, self.mappingproxy, 10)
1046        self.assertRaises(TypeError, self.mappingproxy, ("a", "tuple"))
1047        self.assertRaises(TypeError, self.mappingproxy, ["a", "list"])
1048
1049    def test_methods(self):
1050        attrs = set(dir(self.mappingproxy({}))) - set(dir(object()))
1051        self.assertEqual(attrs, {
1052             '__contains__',
1053             '__getitem__',
1054             '__class_getitem__',
1055             '__ior__',
1056             '__iter__',
1057             '__len__',
1058             '__or__',
1059             '__reversed__',
1060             '__ror__',
1061             'copy',
1062             'get',
1063             'items',
1064             'keys',
1065             'values',
1066        })
1067
1068    def test_get(self):
1069        view = self.mappingproxy({'a': 'A', 'b': 'B'})
1070        self.assertEqual(view['a'], 'A')
1071        self.assertEqual(view['b'], 'B')
1072        self.assertRaises(KeyError, view.__getitem__, 'xxx')
1073        self.assertEqual(view.get('a'), 'A')
1074        self.assertIsNone(view.get('xxx'))
1075        self.assertEqual(view.get('xxx', 42), 42)
1076
1077    def test_missing(self):
1078        class dictmissing(dict):
1079            def __missing__(self, key):
1080                return "missing=%s" % key
1081
1082        view = self.mappingproxy(dictmissing(x=1))
1083        self.assertEqual(view['x'], 1)
1084        self.assertEqual(view['y'], 'missing=y')
1085        self.assertEqual(view.get('x'), 1)
1086        self.assertEqual(view.get('y'), None)
1087        self.assertEqual(view.get('y', 42), 42)
1088        self.assertTrue('x' in view)
1089        self.assertFalse('y' in view)
1090
1091    def test_customdict(self):
1092        class customdict(dict):
1093            def __contains__(self, key):
1094                if key == 'magic':
1095                    return True
1096                else:
1097                    return dict.__contains__(self, key)
1098
1099            def __iter__(self):
1100                return iter(('iter',))
1101
1102            def __len__(self):
1103                return 500
1104
1105            def copy(self):
1106                return 'copy'
1107
1108            def keys(self):
1109                return 'keys'
1110
1111            def items(self):
1112                return 'items'
1113
1114            def values(self):
1115                return 'values'
1116
1117            def __getitem__(self, key):
1118                return "getitem=%s" % dict.__getitem__(self, key)
1119
1120            def get(self, key, default=None):
1121                return "get=%s" % dict.get(self, key, 'default=%r' % default)
1122
1123        custom = customdict({'key': 'value'})
1124        view = self.mappingproxy(custom)
1125        self.assertTrue('key' in view)
1126        self.assertTrue('magic' in view)
1127        self.assertFalse('xxx' in view)
1128        self.assertEqual(view['key'], 'getitem=value')
1129        self.assertRaises(KeyError, view.__getitem__, 'xxx')
1130        self.assertEqual(tuple(view), ('iter',))
1131        self.assertEqual(len(view), 500)
1132        self.assertEqual(view.copy(), 'copy')
1133        self.assertEqual(view.get('key'), 'get=value')
1134        self.assertEqual(view.get('xxx'), 'get=default=None')
1135        self.assertEqual(view.items(), 'items')
1136        self.assertEqual(view.keys(), 'keys')
1137        self.assertEqual(view.values(), 'values')
1138
1139    def test_chainmap(self):
1140        d1 = {'x': 1}
1141        d2 = {'y': 2}
1142        mapping = collections.ChainMap(d1, d2)
1143        view = self.mappingproxy(mapping)
1144        self.assertTrue('x' in view)
1145        self.assertTrue('y' in view)
1146        self.assertFalse('z' in view)
1147        self.assertEqual(view['x'], 1)
1148        self.assertEqual(view['y'], 2)
1149        self.assertRaises(KeyError, view.__getitem__, 'z')
1150        self.assertEqual(tuple(sorted(view)), ('x', 'y'))
1151        self.assertEqual(len(view), 2)
1152        copy = view.copy()
1153        self.assertIsNot(copy, mapping)
1154        self.assertIsInstance(copy, collections.ChainMap)
1155        self.assertEqual(copy, mapping)
1156        self.assertEqual(view.get('x'), 1)
1157        self.assertEqual(view.get('y'), 2)
1158        self.assertIsNone(view.get('z'))
1159        self.assertEqual(tuple(sorted(view.items())), (('x', 1), ('y', 2)))
1160        self.assertEqual(tuple(sorted(view.keys())), ('x', 'y'))
1161        self.assertEqual(tuple(sorted(view.values())), (1, 2))
1162
1163    def test_contains(self):
1164        view = self.mappingproxy(dict.fromkeys('abc'))
1165        self.assertTrue('a' in view)
1166        self.assertTrue('b' in view)
1167        self.assertTrue('c' in view)
1168        self.assertFalse('xxx' in view)
1169
1170    def test_views(self):
1171        mapping = {}
1172        view = self.mappingproxy(mapping)
1173        keys = view.keys()
1174        values = view.values()
1175        items = view.items()
1176        self.assertEqual(list(keys), [])
1177        self.assertEqual(list(values), [])
1178        self.assertEqual(list(items), [])
1179        mapping['key'] = 'value'
1180        self.assertEqual(list(keys), ['key'])
1181        self.assertEqual(list(values), ['value'])
1182        self.assertEqual(list(items), [('key', 'value')])
1183
1184    def test_len(self):
1185        for expected in range(6):
1186            data = dict.fromkeys('abcde'[:expected])
1187            self.assertEqual(len(data), expected)
1188            view = self.mappingproxy(data)
1189            self.assertEqual(len(view), expected)
1190
1191    def test_iterators(self):
1192        keys = ('x', 'y')
1193        values = (1, 2)
1194        items = tuple(zip(keys, values))
1195        view = self.mappingproxy(dict(items))
1196        self.assertEqual(set(view), set(keys))
1197        self.assertEqual(set(view.keys()), set(keys))
1198        self.assertEqual(set(view.values()), set(values))
1199        self.assertEqual(set(view.items()), set(items))
1200
1201    def test_reversed(self):
1202        d = {'a': 1, 'b': 2, 'foo': 0, 'c': 3, 'd': 4}
1203        mp = self.mappingproxy(d)
1204        del d['foo']
1205        r = reversed(mp)
1206        self.assertEqual(list(r), list('dcba'))
1207        self.assertRaises(StopIteration, next, r)
1208
1209    def test_copy(self):
1210        original = {'key1': 27, 'key2': 51, 'key3': 93}
1211        view = self.mappingproxy(original)
1212        copy = view.copy()
1213        self.assertEqual(type(copy), dict)
1214        self.assertEqual(copy, original)
1215        original['key1'] = 70
1216        self.assertEqual(view['key1'], 70)
1217        self.assertEqual(copy['key1'], 27)
1218
1219    def test_union(self):
1220        mapping = {'a': 0, 'b': 1, 'c': 2}
1221        view = self.mappingproxy(mapping)
1222        with self.assertRaises(TypeError):
1223            view | [('r', 2), ('d', 2)]
1224        with self.assertRaises(TypeError):
1225            [('r', 2), ('d', 2)] | view
1226        with self.assertRaises(TypeError):
1227            view |= [('r', 2), ('d', 2)]
1228        other = {'c': 3, 'p': 0}
1229        self.assertDictEqual(view | other, {'a': 0, 'b': 1, 'c': 3, 'p': 0})
1230        self.assertDictEqual(other | view, {'c': 2, 'p': 0, 'a': 0, 'b': 1})
1231        self.assertEqual(view, {'a': 0, 'b': 1, 'c': 2})
1232        self.assertDictEqual(mapping, {'a': 0, 'b': 1, 'c': 2})
1233        self.assertDictEqual(other, {'c': 3, 'p': 0})
1234
1235
1236class ClassCreationTests(unittest.TestCase):
1237
1238    class Meta(type):
1239        def __init__(cls, name, bases, ns, **kw):
1240            super().__init__(name, bases, ns)
1241        @staticmethod
1242        def __new__(mcls, name, bases, ns, **kw):
1243            return super().__new__(mcls, name, bases, ns)
1244        @classmethod
1245        def __prepare__(mcls, name, bases, **kw):
1246            ns = super().__prepare__(name, bases)
1247            ns["y"] = 1
1248            ns.update(kw)
1249            return ns
1250
1251    def test_new_class_basics(self):
1252        C = types.new_class("C")
1253        self.assertEqual(C.__name__, "C")
1254        self.assertEqual(C.__bases__, (object,))
1255
1256    def test_new_class_subclass(self):
1257        C = types.new_class("C", (int,))
1258        self.assertTrue(issubclass(C, int))
1259
1260    def test_new_class_meta(self):
1261        Meta = self.Meta
1262        settings = {"metaclass": Meta, "z": 2}
1263        # We do this twice to make sure the passed in dict isn't mutated
1264        for i in range(2):
1265            C = types.new_class("C" + str(i), (), settings)
1266            self.assertIsInstance(C, Meta)
1267            self.assertEqual(C.y, 1)
1268            self.assertEqual(C.z, 2)
1269
1270    def test_new_class_exec_body(self):
1271        Meta = self.Meta
1272        def func(ns):
1273            ns["x"] = 0
1274        C = types.new_class("C", (), {"metaclass": Meta, "z": 2}, func)
1275        self.assertIsInstance(C, Meta)
1276        self.assertEqual(C.x, 0)
1277        self.assertEqual(C.y, 1)
1278        self.assertEqual(C.z, 2)
1279
1280    def test_new_class_metaclass_keywords(self):
1281        #Test that keywords are passed to the metaclass:
1282        def meta_func(name, bases, ns, **kw):
1283            return name, bases, ns, kw
1284        res = types.new_class("X",
1285                              (int, object),
1286                              dict(metaclass=meta_func, x=0))
1287        self.assertEqual(res, ("X", (int, object), {}, {"x": 0}))
1288
1289    def test_new_class_defaults(self):
1290        # Test defaults/keywords:
1291        C = types.new_class("C", (), {}, None)
1292        self.assertEqual(C.__name__, "C")
1293        self.assertEqual(C.__bases__, (object,))
1294
1295    def test_new_class_meta_with_base(self):
1296        Meta = self.Meta
1297        def func(ns):
1298            ns["x"] = 0
1299        C = types.new_class(name="C",
1300                            bases=(int,),
1301                            kwds=dict(metaclass=Meta, z=2),
1302                            exec_body=func)
1303        self.assertTrue(issubclass(C, int))
1304        self.assertIsInstance(C, Meta)
1305        self.assertEqual(C.x, 0)
1306        self.assertEqual(C.y, 1)
1307        self.assertEqual(C.z, 2)
1308
1309    def test_new_class_with_mro_entry(self):
1310        class A: pass
1311        class C:
1312            def __mro_entries__(self, bases):
1313                return (A,)
1314        c = C()
1315        D = types.new_class('D', (c,), {})
1316        self.assertEqual(D.__bases__, (A,))
1317        self.assertEqual(D.__orig_bases__, (c,))
1318        self.assertEqual(D.__mro__, (D, A, object))
1319
1320    def test_new_class_with_mro_entry_genericalias(self):
1321        L1 = types.new_class('L1', (typing.List[int],), {})
1322        self.assertEqual(L1.__bases__, (list, typing.Generic))
1323        self.assertEqual(L1.__orig_bases__, (typing.List[int],))
1324        self.assertEqual(L1.__mro__, (L1, list, typing.Generic, object))
1325
1326        L2 = types.new_class('L2', (list[int],), {})
1327        self.assertEqual(L2.__bases__, (list,))
1328        self.assertEqual(L2.__orig_bases__, (list[int],))
1329        self.assertEqual(L2.__mro__, (L2, list, object))
1330
1331    def test_new_class_with_mro_entry_none(self):
1332        class A: pass
1333        class B: pass
1334        class C:
1335            def __mro_entries__(self, bases):
1336                return ()
1337        c = C()
1338        D = types.new_class('D', (A, c, B), {})
1339        self.assertEqual(D.__bases__, (A, B))
1340        self.assertEqual(D.__orig_bases__, (A, c, B))
1341        self.assertEqual(D.__mro__, (D, A, B, object))
1342
1343    def test_new_class_with_mro_entry_error(self):
1344        class A: pass
1345        class C:
1346            def __mro_entries__(self, bases):
1347                return A
1348        c = C()
1349        with self.assertRaises(TypeError):
1350            types.new_class('D', (c,), {})
1351
1352    def test_new_class_with_mro_entry_multiple(self):
1353        class A1: pass
1354        class A2: pass
1355        class B1: pass
1356        class B2: pass
1357        class A:
1358            def __mro_entries__(self, bases):
1359                return (A1, A2)
1360        class B:
1361            def __mro_entries__(self, bases):
1362                return (B1, B2)
1363        D = types.new_class('D', (A(), B()), {})
1364        self.assertEqual(D.__bases__, (A1, A2, B1, B2))
1365
1366    def test_new_class_with_mro_entry_multiple_2(self):
1367        class A1: pass
1368        class A2: pass
1369        class A3: pass
1370        class B1: pass
1371        class B2: pass
1372        class A:
1373            def __mro_entries__(self, bases):
1374                return (A1, A2, A3)
1375        class B:
1376            def __mro_entries__(self, bases):
1377                return (B1, B2)
1378        class C: pass
1379        D = types.new_class('D', (A(), C, B()), {})
1380        self.assertEqual(D.__bases__, (A1, A2, A3, C, B1, B2))
1381
1382    # Many of the following tests are derived from test_descr.py
1383    def test_prepare_class(self):
1384        # Basic test of metaclass derivation
1385        expected_ns = {}
1386        class A(type):
1387            def __new__(*args, **kwargs):
1388                return type.__new__(*args, **kwargs)
1389
1390            def __prepare__(*args):
1391                return expected_ns
1392
1393        B = types.new_class("B", (object,))
1394        C = types.new_class("C", (object,), {"metaclass": A})
1395
1396        # The most derived metaclass of D is A rather than type.
1397        meta, ns, kwds = types.prepare_class("D", (B, C), {"metaclass": type})
1398        self.assertIs(meta, A)
1399        self.assertIs(ns, expected_ns)
1400        self.assertEqual(len(kwds), 0)
1401
1402    def test_bad___prepare__(self):
1403        # __prepare__() must return a mapping.
1404        class BadMeta(type):
1405            @classmethod
1406            def __prepare__(*args):
1407                return None
1408        with self.assertRaisesRegex(TypeError,
1409                                    r'^BadMeta\.__prepare__\(\) must '
1410                                    r'return a mapping, not NoneType$'):
1411            class Foo(metaclass=BadMeta):
1412                pass
1413        # Also test the case in which the metaclass is not a type.
1414        class BadMeta:
1415            @classmethod
1416            def __prepare__(*args):
1417                return None
1418        with self.assertRaisesRegex(TypeError,
1419                                    r'^<metaclass>\.__prepare__\(\) must '
1420                                    r'return a mapping, not NoneType$'):
1421            class Bar(metaclass=BadMeta()):
1422                pass
1423
1424    def test_resolve_bases(self):
1425        class A: pass
1426        class B: pass
1427        class C:
1428            def __mro_entries__(self, bases):
1429                if A in bases:
1430                    return ()
1431                return (A,)
1432        c = C()
1433        self.assertEqual(types.resolve_bases(()), ())
1434        self.assertEqual(types.resolve_bases((c,)), (A,))
1435        self.assertEqual(types.resolve_bases((C,)), (C,))
1436        self.assertEqual(types.resolve_bases((A, C)), (A, C))
1437        self.assertEqual(types.resolve_bases((c, A)), (A,))
1438        self.assertEqual(types.resolve_bases((A, c)), (A,))
1439        x = (A,)
1440        y = (C,)
1441        z = (A, C)
1442        t = (A, C, B)
1443        for bases in [x, y, z, t]:
1444            self.assertIs(types.resolve_bases(bases), bases)
1445
1446    def test_resolve_bases_with_mro_entry(self):
1447        self.assertEqual(types.resolve_bases((typing.List[int],)),
1448                         (list, typing.Generic))
1449        self.assertEqual(types.resolve_bases((list[int],)), (list,))
1450
1451    def test_metaclass_derivation(self):
1452        # issue1294232: correct metaclass calculation
1453        new_calls = []  # to check the order of __new__ calls
1454        class AMeta(type):
1455            def __new__(mcls, name, bases, ns):
1456                new_calls.append('AMeta')
1457                return super().__new__(mcls, name, bases, ns)
1458            @classmethod
1459            def __prepare__(mcls, name, bases):
1460                return {}
1461
1462        class BMeta(AMeta):
1463            def __new__(mcls, name, bases, ns):
1464                new_calls.append('BMeta')
1465                return super().__new__(mcls, name, bases, ns)
1466            @classmethod
1467            def __prepare__(mcls, name, bases):
1468                ns = super().__prepare__(name, bases)
1469                ns['BMeta_was_here'] = True
1470                return ns
1471
1472        A = types.new_class("A", (), {"metaclass": AMeta})
1473        self.assertEqual(new_calls, ['AMeta'])
1474        new_calls.clear()
1475
1476        B = types.new_class("B", (), {"metaclass": BMeta})
1477        # BMeta.__new__ calls AMeta.__new__ with super:
1478        self.assertEqual(new_calls, ['BMeta', 'AMeta'])
1479        new_calls.clear()
1480
1481        C = types.new_class("C", (A, B))
1482        # The most derived metaclass is BMeta:
1483        self.assertEqual(new_calls, ['BMeta', 'AMeta'])
1484        new_calls.clear()
1485        # BMeta.__prepare__ should've been called:
1486        self.assertIn('BMeta_was_here', C.__dict__)
1487
1488        # The order of the bases shouldn't matter:
1489        C2 = types.new_class("C2", (B, A))
1490        self.assertEqual(new_calls, ['BMeta', 'AMeta'])
1491        new_calls.clear()
1492        self.assertIn('BMeta_was_here', C2.__dict__)
1493
1494        # Check correct metaclass calculation when a metaclass is declared:
1495        D = types.new_class("D", (C,), {"metaclass": type})
1496        self.assertEqual(new_calls, ['BMeta', 'AMeta'])
1497        new_calls.clear()
1498        self.assertIn('BMeta_was_here', D.__dict__)
1499
1500        E = types.new_class("E", (C,), {"metaclass": AMeta})
1501        self.assertEqual(new_calls, ['BMeta', 'AMeta'])
1502        new_calls.clear()
1503        self.assertIn('BMeta_was_here', E.__dict__)
1504
1505    def test_metaclass_override_function(self):
1506        # Special case: the given metaclass isn't a class,
1507        # so there is no metaclass calculation.
1508        class A(metaclass=self.Meta):
1509            pass
1510
1511        marker = object()
1512        def func(*args, **kwargs):
1513            return marker
1514
1515        X = types.new_class("X", (), {"metaclass": func})
1516        Y = types.new_class("Y", (object,), {"metaclass": func})
1517        Z = types.new_class("Z", (A,), {"metaclass": func})
1518        self.assertIs(marker, X)
1519        self.assertIs(marker, Y)
1520        self.assertIs(marker, Z)
1521
1522    def test_metaclass_override_callable(self):
1523        # The given metaclass is a class,
1524        # but not a descendant of type.
1525        new_calls = []  # to check the order of __new__ calls
1526        prepare_calls = []  # to track __prepare__ calls
1527        class ANotMeta:
1528            def __new__(mcls, *args, **kwargs):
1529                new_calls.append('ANotMeta')
1530                return super().__new__(mcls)
1531            @classmethod
1532            def __prepare__(mcls, name, bases):
1533                prepare_calls.append('ANotMeta')
1534                return {}
1535
1536        class BNotMeta(ANotMeta):
1537            def __new__(mcls, *args, **kwargs):
1538                new_calls.append('BNotMeta')
1539                return super().__new__(mcls)
1540            @classmethod
1541            def __prepare__(mcls, name, bases):
1542                prepare_calls.append('BNotMeta')
1543                return super().__prepare__(name, bases)
1544
1545        A = types.new_class("A", (), {"metaclass": ANotMeta})
1546        self.assertIs(ANotMeta, type(A))
1547        self.assertEqual(prepare_calls, ['ANotMeta'])
1548        prepare_calls.clear()
1549        self.assertEqual(new_calls, ['ANotMeta'])
1550        new_calls.clear()
1551
1552        B = types.new_class("B", (), {"metaclass": BNotMeta})
1553        self.assertIs(BNotMeta, type(B))
1554        self.assertEqual(prepare_calls, ['BNotMeta', 'ANotMeta'])
1555        prepare_calls.clear()
1556        self.assertEqual(new_calls, ['BNotMeta', 'ANotMeta'])
1557        new_calls.clear()
1558
1559        C = types.new_class("C", (A, B))
1560        self.assertIs(BNotMeta, type(C))
1561        self.assertEqual(prepare_calls, ['BNotMeta', 'ANotMeta'])
1562        prepare_calls.clear()
1563        self.assertEqual(new_calls, ['BNotMeta', 'ANotMeta'])
1564        new_calls.clear()
1565
1566        C2 = types.new_class("C2", (B, A))
1567        self.assertIs(BNotMeta, type(C2))
1568        self.assertEqual(prepare_calls, ['BNotMeta', 'ANotMeta'])
1569        prepare_calls.clear()
1570        self.assertEqual(new_calls, ['BNotMeta', 'ANotMeta'])
1571        new_calls.clear()
1572
1573        # This is a TypeError, because of a metaclass conflict:
1574        # BNotMeta is neither a subclass, nor a superclass of type
1575        with self.assertRaises(TypeError):
1576            D = types.new_class("D", (C,), {"metaclass": type})
1577
1578        E = types.new_class("E", (C,), {"metaclass": ANotMeta})
1579        self.assertIs(BNotMeta, type(E))
1580        self.assertEqual(prepare_calls, ['BNotMeta', 'ANotMeta'])
1581        prepare_calls.clear()
1582        self.assertEqual(new_calls, ['BNotMeta', 'ANotMeta'])
1583        new_calls.clear()
1584
1585        F = types.new_class("F", (object(), C))
1586        self.assertIs(BNotMeta, type(F))
1587        self.assertEqual(prepare_calls, ['BNotMeta', 'ANotMeta'])
1588        prepare_calls.clear()
1589        self.assertEqual(new_calls, ['BNotMeta', 'ANotMeta'])
1590        new_calls.clear()
1591
1592        F2 = types.new_class("F2", (C, object()))
1593        self.assertIs(BNotMeta, type(F2))
1594        self.assertEqual(prepare_calls, ['BNotMeta', 'ANotMeta'])
1595        prepare_calls.clear()
1596        self.assertEqual(new_calls, ['BNotMeta', 'ANotMeta'])
1597        new_calls.clear()
1598
1599        # TypeError: BNotMeta is neither a
1600        # subclass, nor a superclass of int
1601        with self.assertRaises(TypeError):
1602            X = types.new_class("X", (C, int()))
1603        with self.assertRaises(TypeError):
1604            X = types.new_class("X", (int(), C))
1605
1606    def test_one_argument_type(self):
1607        expected_message = 'type.__new__() takes exactly 3 arguments (1 given)'
1608
1609        # Only type itself can use the one-argument form (#27157)
1610        self.assertIs(type(5), int)
1611
1612        class M(type):
1613            pass
1614        with self.assertRaises(TypeError) as cm:
1615            M(5)
1616        self.assertEqual(str(cm.exception), expected_message)
1617
1618        class N(type, metaclass=M):
1619            pass
1620        with self.assertRaises(TypeError) as cm:
1621            N(5)
1622        self.assertEqual(str(cm.exception), expected_message)
1623
1624    def test_metaclass_new_error(self):
1625        # bpo-44232: The C function type_new() must properly report the
1626        # exception when a metaclass constructor raises an exception and the
1627        # winner class is not the metaclass.
1628        class ModelBase(type):
1629            def __new__(cls, name, bases, attrs):
1630                super_new = super().__new__
1631                new_class = super_new(cls, name, bases, {})
1632                if name != "Model":
1633                    raise RuntimeWarning(f"{name=}")
1634                return new_class
1635
1636        class Model(metaclass=ModelBase):
1637            pass
1638
1639        with self.assertRaises(RuntimeWarning):
1640            type("SouthPonies", (Model,), {})
1641
1642
1643class SimpleNamespaceTests(unittest.TestCase):
1644
1645    def test_constructor(self):
1646        ns1 = types.SimpleNamespace()
1647        ns2 = types.SimpleNamespace(x=1, y=2)
1648        ns3 = types.SimpleNamespace(**dict(x=1, y=2))
1649
1650        with self.assertRaises(TypeError):
1651            types.SimpleNamespace(1, 2, 3)
1652        with self.assertRaises(TypeError):
1653            types.SimpleNamespace(**{1: 2})
1654
1655        self.assertEqual(len(ns1.__dict__), 0)
1656        self.assertEqual(vars(ns1), {})
1657        self.assertEqual(len(ns2.__dict__), 2)
1658        self.assertEqual(vars(ns2), {'y': 2, 'x': 1})
1659        self.assertEqual(len(ns3.__dict__), 2)
1660        self.assertEqual(vars(ns3), {'y': 2, 'x': 1})
1661
1662    def test_unbound(self):
1663        ns1 = vars(types.SimpleNamespace())
1664        ns2 = vars(types.SimpleNamespace(x=1, y=2))
1665
1666        self.assertEqual(ns1, {})
1667        self.assertEqual(ns2, {'y': 2, 'x': 1})
1668
1669    def test_underlying_dict(self):
1670        ns1 = types.SimpleNamespace()
1671        ns2 = types.SimpleNamespace(x=1, y=2)
1672        ns3 = types.SimpleNamespace(a=True, b=False)
1673        mapping = ns3.__dict__
1674        del ns3
1675
1676        self.assertEqual(ns1.__dict__, {})
1677        self.assertEqual(ns2.__dict__, {'y': 2, 'x': 1})
1678        self.assertEqual(mapping, dict(a=True, b=False))
1679
1680    def test_attrget(self):
1681        ns = types.SimpleNamespace(x=1, y=2, w=3)
1682
1683        self.assertEqual(ns.x, 1)
1684        self.assertEqual(ns.y, 2)
1685        self.assertEqual(ns.w, 3)
1686        with self.assertRaises(AttributeError):
1687            ns.z
1688
1689    def test_attrset(self):
1690        ns1 = types.SimpleNamespace()
1691        ns2 = types.SimpleNamespace(x=1, y=2, w=3)
1692        ns1.a = 'spam'
1693        ns1.b = 'ham'
1694        ns2.z = 4
1695        ns2.theta = None
1696
1697        self.assertEqual(ns1.__dict__, dict(a='spam', b='ham'))
1698        self.assertEqual(ns2.__dict__, dict(x=1, y=2, w=3, z=4, theta=None))
1699
1700    def test_attrdel(self):
1701        ns1 = types.SimpleNamespace()
1702        ns2 = types.SimpleNamespace(x=1, y=2, w=3)
1703
1704        with self.assertRaises(AttributeError):
1705            del ns1.spam
1706        with self.assertRaises(AttributeError):
1707            del ns2.spam
1708
1709        del ns2.y
1710        self.assertEqual(vars(ns2), dict(w=3, x=1))
1711        ns2.y = 'spam'
1712        self.assertEqual(vars(ns2), dict(w=3, x=1, y='spam'))
1713        del ns2.y
1714        self.assertEqual(vars(ns2), dict(w=3, x=1))
1715
1716        ns1.spam = 5
1717        self.assertEqual(vars(ns1), dict(spam=5))
1718        del ns1.spam
1719        self.assertEqual(vars(ns1), {})
1720
1721    def test_repr(self):
1722        ns1 = types.SimpleNamespace(x=1, y=2, w=3)
1723        ns2 = types.SimpleNamespace()
1724        ns2.x = "spam"
1725        ns2._y = 5
1726        name = "namespace"
1727
1728        self.assertEqual(repr(ns1), "{name}(x=1, y=2, w=3)".format(name=name))
1729        self.assertEqual(repr(ns2), "{name}(x='spam', _y=5)".format(name=name))
1730
1731    def test_equal(self):
1732        ns1 = types.SimpleNamespace(x=1)
1733        ns2 = types.SimpleNamespace()
1734        ns2.x = 1
1735
1736        self.assertEqual(types.SimpleNamespace(), types.SimpleNamespace())
1737        self.assertEqual(ns1, ns2)
1738        self.assertNotEqual(ns2, types.SimpleNamespace())
1739
1740    def test_nested(self):
1741        ns1 = types.SimpleNamespace(a=1, b=2)
1742        ns2 = types.SimpleNamespace()
1743        ns3 = types.SimpleNamespace(x=ns1)
1744        ns2.spam = ns1
1745        ns2.ham = '?'
1746        ns2.spam = ns3
1747
1748        self.assertEqual(vars(ns1), dict(a=1, b=2))
1749        self.assertEqual(vars(ns2), dict(spam=ns3, ham='?'))
1750        self.assertEqual(ns2.spam, ns3)
1751        self.assertEqual(vars(ns3), dict(x=ns1))
1752        self.assertEqual(ns3.x.a, 1)
1753
1754    def test_recursive(self):
1755        ns1 = types.SimpleNamespace(c='cookie')
1756        ns2 = types.SimpleNamespace()
1757        ns3 = types.SimpleNamespace(x=1)
1758        ns1.spam = ns1
1759        ns2.spam = ns3
1760        ns3.spam = ns2
1761
1762        self.assertEqual(ns1.spam, ns1)
1763        self.assertEqual(ns1.spam.spam, ns1)
1764        self.assertEqual(ns1.spam.spam, ns1.spam)
1765        self.assertEqual(ns2.spam, ns3)
1766        self.assertEqual(ns3.spam, ns2)
1767        self.assertEqual(ns2.spam.spam, ns2)
1768
1769    def test_recursive_repr(self):
1770        ns1 = types.SimpleNamespace(c='cookie')
1771        ns2 = types.SimpleNamespace()
1772        ns3 = types.SimpleNamespace(x=1)
1773        ns1.spam = ns1
1774        ns2.spam = ns3
1775        ns3.spam = ns2
1776        name = "namespace"
1777        repr1 = "{name}(c='cookie', spam={name}(...))".format(name=name)
1778        repr2 = "{name}(spam={name}(x=1, spam={name}(...)))".format(name=name)
1779
1780        self.assertEqual(repr(ns1), repr1)
1781        self.assertEqual(repr(ns2), repr2)
1782
1783    def test_as_dict(self):
1784        ns = types.SimpleNamespace(spam='spamspamspam')
1785
1786        with self.assertRaises(TypeError):
1787            len(ns)
1788        with self.assertRaises(TypeError):
1789            iter(ns)
1790        with self.assertRaises(TypeError):
1791            'spam' in ns
1792        with self.assertRaises(TypeError):
1793            ns['spam']
1794
1795    def test_subclass(self):
1796        class Spam(types.SimpleNamespace):
1797            pass
1798
1799        spam = Spam(ham=8, eggs=9)
1800
1801        self.assertIs(type(spam), Spam)
1802        self.assertEqual(vars(spam), {'ham': 8, 'eggs': 9})
1803
1804    def test_pickle(self):
1805        ns = types.SimpleNamespace(breakfast="spam", lunch="spam")
1806
1807        for protocol in range(pickle.HIGHEST_PROTOCOL + 1):
1808            pname = "protocol {}".format(protocol)
1809            try:
1810                ns_pickled = pickle.dumps(ns, protocol)
1811            except TypeError as e:
1812                raise TypeError(pname) from e
1813            ns_roundtrip = pickle.loads(ns_pickled)
1814
1815            self.assertEqual(ns, ns_roundtrip, pname)
1816
1817    def test_fake_namespace_compare(self):
1818        # Issue #24257: Incorrect use of PyObject_IsInstance() caused
1819        # SystemError.
1820        class FakeSimpleNamespace(str):
1821            __class__ = types.SimpleNamespace
1822        self.assertFalse(types.SimpleNamespace() == FakeSimpleNamespace())
1823        self.assertTrue(types.SimpleNamespace() != FakeSimpleNamespace())
1824        with self.assertRaises(TypeError):
1825            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
1833
1834class CoroutineTests(unittest.TestCase):
1835    def test_wrong_args(self):
1836        samples = [None, 1, object()]
1837        for sample in samples:
1838            with self.assertRaisesRegex(TypeError,
1839                                        'types.coroutine.*expects a callable'):
1840                types.coroutine(sample)
1841
1842    def test_non_gen_values(self):
1843        @types.coroutine
1844        def foo():
1845            return 'spam'
1846        self.assertEqual(foo(), 'spam')
1847
1848        class Awaitable:
1849            def __await__(self):
1850                return ()
1851        aw = Awaitable()
1852        @types.coroutine
1853        def foo():
1854            return aw
1855        self.assertIs(aw, foo())
1856
1857        # decorate foo second time
1858        foo = types.coroutine(foo)
1859        self.assertIs(aw, foo())
1860
1861    def test_async_def(self):
1862        # Test that types.coroutine passes 'async def' coroutines
1863        # without modification
1864
1865        async def foo(): pass
1866        foo_code = foo.__code__
1867        foo_flags = foo.__code__.co_flags
1868        decorated_foo = types.coroutine(foo)
1869        self.assertIs(foo, decorated_foo)
1870        self.assertEqual(foo.__code__.co_flags, foo_flags)
1871        self.assertIs(decorated_foo.__code__, foo_code)
1872
1873        foo_coro = foo()
1874        def bar(): return foo_coro
1875        for _ in range(2):
1876            bar = types.coroutine(bar)
1877            coro = bar()
1878            self.assertIs(foo_coro, coro)
1879            self.assertEqual(coro.cr_code.co_flags, foo_flags)
1880            coro.close()
1881
1882    def test_duck_coro(self):
1883        class CoroLike:
1884            def send(self): pass
1885            def throw(self): pass
1886            def close(self): pass
1887            def __await__(self): return self
1888
1889        coro = CoroLike()
1890        @types.coroutine
1891        def foo():
1892            return coro
1893        self.assertIs(foo(), coro)
1894        self.assertIs(foo().__await__(), coro)
1895
1896    def test_duck_corogen(self):
1897        class CoroGenLike:
1898            def send(self): pass
1899            def throw(self): pass
1900            def close(self): pass
1901            def __await__(self): return self
1902            def __iter__(self): return self
1903            def __next__(self): pass
1904
1905        coro = CoroGenLike()
1906        @types.coroutine
1907        def foo():
1908            return coro
1909        self.assertIs(foo(), coro)
1910        self.assertIs(foo().__await__(), coro)
1911
1912    def test_duck_gen(self):
1913        class GenLike:
1914            def send(self): pass
1915            def throw(self): pass
1916            def close(self): pass
1917            def __iter__(self): pass
1918            def __next__(self): pass
1919
1920        # Setup generator mock object
1921        gen = unittest.mock.MagicMock(GenLike)
1922        gen.__iter__ = lambda gen: gen
1923        gen.__name__ = 'gen'
1924        gen.__qualname__ = 'test.gen'
1925        self.assertIsInstance(gen, collections.abc.Generator)
1926        self.assertIs(gen, iter(gen))
1927
1928        @types.coroutine
1929        def foo(): return gen
1930
1931        wrapper = foo()
1932        self.assertIsInstance(wrapper, types._GeneratorWrapper)
1933        self.assertIs(wrapper.__await__(), wrapper)
1934        # Wrapper proxies duck generators completely:
1935        self.assertIs(iter(wrapper), wrapper)
1936
1937        self.assertIsInstance(wrapper, collections.abc.Coroutine)
1938        self.assertIsInstance(wrapper, collections.abc.Awaitable)
1939
1940        self.assertIs(wrapper.__qualname__, gen.__qualname__)
1941        self.assertIs(wrapper.__name__, gen.__name__)
1942
1943        # Test AttributeErrors
1944        for name in {'gi_running', 'gi_frame', 'gi_code', 'gi_yieldfrom',
1945                     'cr_running', 'cr_frame', 'cr_code', 'cr_await'}:
1946            with self.assertRaises(AttributeError):
1947                getattr(wrapper, name)
1948
1949        # Test attributes pass-through
1950        gen.gi_running = object()
1951        gen.gi_frame = object()
1952        gen.gi_code = object()
1953        gen.gi_yieldfrom = object()
1954        self.assertIs(wrapper.gi_running, gen.gi_running)
1955        self.assertIs(wrapper.gi_frame, gen.gi_frame)
1956        self.assertIs(wrapper.gi_code, gen.gi_code)
1957        self.assertIs(wrapper.gi_yieldfrom, gen.gi_yieldfrom)
1958        self.assertIs(wrapper.cr_running, gen.gi_running)
1959        self.assertIs(wrapper.cr_frame, gen.gi_frame)
1960        self.assertIs(wrapper.cr_code, gen.gi_code)
1961        self.assertIs(wrapper.cr_await, gen.gi_yieldfrom)
1962
1963        wrapper.close()
1964        gen.close.assert_called_once_with()
1965
1966        wrapper.send(1)
1967        gen.send.assert_called_once_with(1)
1968        gen.reset_mock()
1969
1970        next(wrapper)
1971        gen.__next__.assert_called_once_with()
1972        gen.reset_mock()
1973
1974        wrapper.throw(1, 2, 3)
1975        gen.throw.assert_called_once_with(1, 2, 3)
1976        gen.reset_mock()
1977
1978        wrapper.throw(1, 2)
1979        gen.throw.assert_called_once_with(1, 2)
1980        gen.reset_mock()
1981
1982        wrapper.throw(1)
1983        gen.throw.assert_called_once_with(1)
1984        gen.reset_mock()
1985
1986        # Test exceptions propagation
1987        error = Exception()
1988        gen.throw.side_effect = error
1989        try:
1990            wrapper.throw(1)
1991        except Exception as ex:
1992            self.assertIs(ex, error)
1993        else:
1994            self.fail('wrapper did not propagate an exception')
1995
1996        # Test invalid args
1997        gen.reset_mock()
1998        with self.assertRaises(TypeError):
1999            wrapper.throw()
2000        self.assertFalse(gen.throw.called)
2001        with self.assertRaises(TypeError):
2002            wrapper.close(1)
2003        self.assertFalse(gen.close.called)
2004        with self.assertRaises(TypeError):
2005            wrapper.send()
2006        self.assertFalse(gen.send.called)
2007
2008        # Test that we do not double wrap
2009        @types.coroutine
2010        def bar(): return wrapper
2011        self.assertIs(wrapper, bar())
2012
2013        # Test weakrefs support
2014        ref = weakref.ref(wrapper)
2015        self.assertIs(ref(), wrapper)
2016
2017    def test_duck_functional_gen(self):
2018        class Generator:
2019            """Emulates the following generator (very clumsy):
2020
2021              def gen(fut):
2022                  result = yield fut
2023                  return result * 2
2024            """
2025            def __init__(self, fut):
2026                self._i = 0
2027                self._fut = fut
2028            def __iter__(self):
2029                return self
2030            def __next__(self):
2031                return self.send(None)
2032            def send(self, v):
2033                try:
2034                    if self._i == 0:
2035                        assert v is None
2036                        return self._fut
2037                    if self._i == 1:
2038                        raise StopIteration(v * 2)
2039                    if self._i > 1:
2040                        raise StopIteration
2041                finally:
2042                    self._i += 1
2043            def throw(self, tp, *exc):
2044                self._i = 100
2045                if tp is not GeneratorExit:
2046                    raise tp
2047            def close(self):
2048                self.throw(GeneratorExit)
2049
2050        @types.coroutine
2051        def foo(): return Generator('spam')
2052
2053        wrapper = foo()
2054        self.assertIsInstance(wrapper, types._GeneratorWrapper)
2055
2056        async def corofunc():
2057            return await foo() + 100
2058        coro = corofunc()
2059
2060        self.assertEqual(coro.send(None), 'spam')
2061        try:
2062            coro.send(20)
2063        except StopIteration as ex:
2064            self.assertEqual(ex.args[0], 140)
2065        else:
2066            self.fail('StopIteration was expected')
2067
2068    def test_gen(self):
2069        def gen_func():
2070            yield 1
2071            return (yield 2)
2072        gen = gen_func()
2073        @types.coroutine
2074        def foo(): return gen
2075        wrapper = foo()
2076        self.assertIsInstance(wrapper, types._GeneratorWrapper)
2077        self.assertIs(wrapper.__await__(), gen)
2078
2079        for name in ('__name__', '__qualname__', 'gi_code',
2080                     'gi_running', 'gi_frame'):
2081            self.assertIs(getattr(foo(), name),
2082                          getattr(gen, name))
2083        self.assertIs(foo().cr_code, gen.gi_code)
2084
2085        self.assertEqual(next(wrapper), 1)
2086        self.assertEqual(wrapper.send(None), 2)
2087        with self.assertRaisesRegex(StopIteration, 'spam'):
2088            wrapper.send('spam')
2089
2090        gen = gen_func()
2091        wrapper = foo()
2092        wrapper.send(None)
2093        with self.assertRaisesRegex(Exception, 'ham'):
2094            wrapper.throw(Exception, Exception('ham'))
2095
2096        # decorate foo second time
2097        foo = types.coroutine(foo)
2098        self.assertIs(foo().__await__(), gen)
2099
2100    def test_returning_itercoro(self):
2101        @types.coroutine
2102        def gen():
2103            yield
2104
2105        gencoro = gen()
2106
2107        @types.coroutine
2108        def foo():
2109            return gencoro
2110
2111        self.assertIs(foo(), gencoro)
2112
2113        # decorate foo second time
2114        foo = types.coroutine(foo)
2115        self.assertIs(foo(), gencoro)
2116
2117    def test_genfunc(self):
2118        def gen(): yield
2119        self.assertIs(types.coroutine(gen), gen)
2120        self.assertIs(types.coroutine(types.coroutine(gen)), gen)
2121
2122        self.assertTrue(gen.__code__.co_flags & inspect.CO_ITERABLE_COROUTINE)
2123        self.assertFalse(gen.__code__.co_flags & inspect.CO_COROUTINE)
2124
2125        g = gen()
2126        self.assertTrue(g.gi_code.co_flags & inspect.CO_ITERABLE_COROUTINE)
2127        self.assertFalse(g.gi_code.co_flags & inspect.CO_COROUTINE)
2128
2129        self.assertIs(types.coroutine(gen), gen)
2130
2131    def test_wrapper_object(self):
2132        def gen():
2133            yield
2134        @types.coroutine
2135        def coro():
2136            return gen()
2137
2138        wrapper = coro()
2139        self.assertIn('GeneratorWrapper', repr(wrapper))
2140        self.assertEqual(repr(wrapper), str(wrapper))
2141        self.assertTrue(set(dir(wrapper)).issuperset({
2142            '__await__', '__iter__', '__next__', 'cr_code', 'cr_running',
2143            'cr_frame', 'gi_code', 'gi_frame', 'gi_running', 'send',
2144            'close', 'throw'}))
2145
2146
2147if __name__ == '__main__':
2148    unittest.main()
2149