• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Python test set -- part 6, built-in types
2
3from test.support import run_with_locale
4import collections.abc
5import inspect
6import pickle
7import locale
8import sys
9import types
10import unittest.mock
11import weakref
12
13class TypesTests(unittest.TestCase):
14
15    def test_truth_values(self):
16        if None: self.fail('None is true instead of false')
17        if 0: self.fail('0 is true instead of false')
18        if 0.0: self.fail('0.0 is true instead of false')
19        if '': self.fail('\'\' is true instead of false')
20        if not 1: self.fail('1 is false instead of true')
21        if not 1.0: self.fail('1.0 is false instead of true')
22        if not 'x': self.fail('\'x\' is false instead of true')
23        if not {'x': 1}: self.fail('{\'x\': 1} is false instead of true')
24        def f(): pass
25        class C: pass
26        x = C()
27        if not f: self.fail('f is false instead of true')
28        if not C: self.fail('C is false instead of true')
29        if not sys: self.fail('sys is false instead of true')
30        if not x: self.fail('x is false instead of true')
31
32    def test_boolean_ops(self):
33        if 0 or 0: self.fail('0 or 0 is true instead of false')
34        if 1 and 1: pass
35        else: self.fail('1 and 1 is false instead of true')
36        if not 1: self.fail('not 1 is true instead of false')
37
38    def test_comparisons(self):
39        if 0 < 1 <= 1 == 1 >= 1 > 0 != 1: pass
40        else: self.fail('int comparisons failed')
41        if 0.0 < 1.0 <= 1.0 == 1.0 >= 1.0 > 0.0 != 1.0: pass
42        else: self.fail('float comparisons failed')
43        if '' < 'a' <= 'a' == 'a' < 'abc' < 'abd' < 'b': pass
44        else: self.fail('string comparisons failed')
45        if None is None: pass
46        else: self.fail('identity test failed')
47
48    def test_float_constructor(self):
49        self.assertRaises(ValueError, float, '')
50        self.assertRaises(ValueError, float, '5\0')
51        self.assertRaises(ValueError, float, '5_5\0')
52
53    def test_zero_division(self):
54        try: 5.0 / 0.0
55        except ZeroDivisionError: pass
56        else: self.fail("5.0 / 0.0 didn't raise ZeroDivisionError")
57
58        try: 5.0 // 0.0
59        except ZeroDivisionError: pass
60        else: self.fail("5.0 // 0.0 didn't raise ZeroDivisionError")
61
62        try: 5.0 % 0.0
63        except ZeroDivisionError: pass
64        else: self.fail("5.0 % 0.0 didn't raise ZeroDivisionError")
65
66        try: 5 / 0
67        except ZeroDivisionError: pass
68        else: self.fail("5 / 0 didn't raise ZeroDivisionError")
69
70        try: 5 // 0
71        except ZeroDivisionError: pass
72        else: self.fail("5 // 0 didn't raise ZeroDivisionError")
73
74        try: 5 % 0
75        except ZeroDivisionError: pass
76        else: self.fail("5 % 0 didn't raise ZeroDivisionError")
77
78    def test_numeric_types(self):
79        if 0 != 0.0 or 1 != 1.0 or -1 != -1.0:
80            self.fail('int/float value not equal')
81        # calling built-in types without argument must return 0
82        if int() != 0: self.fail('int() does not return 0')
83        if float() != 0.0: self.fail('float() does not return 0.0')
84        if int(1.9) == 1 == int(1.1) and int(-1.1) == -1 == int(-1.9): pass
85        else: self.fail('int() does not round properly')
86        if float(1) == 1.0 and float(-1) == -1.0 and float(0) == 0.0: pass
87        else: self.fail('float() does not work properly')
88
89    def test_float_to_string(self):
90        def test(f, result):
91            self.assertEqual(f.__format__('e'), result)
92            self.assertEqual('%e' % f, result)
93
94        # test all 2 digit exponents, both with __format__ and with
95        #  '%' formatting
96        for i in range(-99, 100):
97            test(float('1.5e'+str(i)), '1.500000e{0:+03d}'.format(i))
98
99        # test some 3 digit exponents
100        self.assertEqual(1.5e100.__format__('e'), '1.500000e+100')
101        self.assertEqual('%e' % 1.5e100, '1.500000e+100')
102
103        self.assertEqual(1.5e101.__format__('e'), '1.500000e+101')
104        self.assertEqual('%e' % 1.5e101, '1.500000e+101')
105
106        self.assertEqual(1.5e-100.__format__('e'), '1.500000e-100')
107        self.assertEqual('%e' % 1.5e-100, '1.500000e-100')
108
109        self.assertEqual(1.5e-101.__format__('e'), '1.500000e-101')
110        self.assertEqual('%e' % 1.5e-101, '1.500000e-101')
111
112        self.assertEqual('%g' % 1.0, '1')
113        self.assertEqual('%#g' % 1.0, '1.00000')
114
115    def test_normal_integers(self):
116        # Ensure the first 256 integers are shared
117        a = 256
118        b = 128*2
119        if a is not b: self.fail('256 is not shared')
120        if 12 + 24 != 36: self.fail('int op')
121        if 12 + (-24) != -12: self.fail('int op')
122        if (-12) + 24 != 12: self.fail('int op')
123        if (-12) + (-24) != -36: self.fail('int op')
124        if not 12 < 24: self.fail('int op')
125        if not -24 < -12: self.fail('int op')
126        # Test for a particular bug in integer multiply
127        xsize, ysize, zsize = 238, 356, 4
128        if not (xsize*ysize*zsize == zsize*xsize*ysize == 338912):
129            self.fail('int mul commutativity')
130        # And another.
131        m = -sys.maxsize - 1
132        for divisor in 1, 2, 4, 8, 16, 32:
133            j = m // divisor
134            prod = divisor * j
135            if prod != m:
136                self.fail("%r * %r == %r != %r" % (divisor, j, prod, m))
137            if type(prod) is not int:
138                self.fail("expected type(prod) to be int, not %r" %
139                                   type(prod))
140        # Check for unified integral type
141        for divisor in 1, 2, 4, 8, 16, 32:
142            j = m // divisor - 1
143            prod = divisor * j
144            if type(prod) is not int:
145                self.fail("expected type(%r) to be int, not %r" %
146                                   (prod, type(prod)))
147        # Check for unified integral type
148        m = sys.maxsize
149        for divisor in 1, 2, 4, 8, 16, 32:
150            j = m // divisor + 1
151            prod = divisor * j
152            if type(prod) is not int:
153                self.fail("expected type(%r) to be int, not %r" %
154                                   (prod, type(prod)))
155
156        x = sys.maxsize
157        self.assertIsInstance(x + 1, int,
158                              "(sys.maxsize + 1) should have returned int")
159        self.assertIsInstance(-x - 1, int,
160                              "(-sys.maxsize - 1) should have returned int")
161        self.assertIsInstance(-x - 2, int,
162                              "(-sys.maxsize - 2) should have returned int")
163
164        try: 5 << -5
165        except ValueError: pass
166        else: self.fail('int negative shift <<')
167
168        try: 5 >> -5
169        except ValueError: pass
170        else: self.fail('int negative shift >>')
171
172    def test_floats(self):
173        if 12.0 + 24.0 != 36.0: self.fail('float op')
174        if 12.0 + (-24.0) != -12.0: self.fail('float op')
175        if (-12.0) + 24.0 != 12.0: self.fail('float op')
176        if (-12.0) + (-24.0) != -36.0: self.fail('float op')
177        if not 12.0 < 24.0: self.fail('float op')
178        if not -24.0 < -12.0: self.fail('float op')
179
180    def test_strings(self):
181        if len('') != 0: self.fail('len(\'\')')
182        if len('a') != 1: self.fail('len(\'a\')')
183        if len('abcdef') != 6: self.fail('len(\'abcdef\')')
184        if 'xyz' + 'abcde' != 'xyzabcde': self.fail('string concatenation')
185        if 'xyz'*3 != 'xyzxyzxyz': self.fail('string repetition *3')
186        if 0*'abcde' != '': self.fail('string repetition 0*')
187        if min('abc') != 'a' or max('abc') != 'c': self.fail('min/max string')
188        if 'a' in 'abc' and 'b' in 'abc' and 'c' in 'abc' and 'd' not in 'abc': pass
189        else: self.fail('in/not in string')
190        x = 'x'*103
191        if '%s!'%x != x+'!': self.fail('nasty string formatting bug')
192
193        #extended slices for strings
194        a = '0123456789'
195        self.assertEqual(a[::], a)
196        self.assertEqual(a[::2], '02468')
197        self.assertEqual(a[1::2], '13579')
198        self.assertEqual(a[::-1],'9876543210')
199        self.assertEqual(a[::-2], '97531')
200        self.assertEqual(a[3::-2], '31')
201        self.assertEqual(a[-100:100:], a)
202        self.assertEqual(a[100:-100:-1], a[::-1])
203        self.assertEqual(a[-100:100:2], '02468')
204
205    def test_type_function(self):
206        self.assertRaises(TypeError, type, 1, 2)
207        self.assertRaises(TypeError, type, 1, 2, 3, 4)
208
209    def test_int__format__(self):
210        def test(i, format_spec, result):
211            # just make sure we have the unified type for integers
212            assert type(i) == int
213            assert type(format_spec) == str
214            self.assertEqual(i.__format__(format_spec), result)
215
216        test(123456789, 'd', '123456789')
217        test(123456789, 'd', '123456789')
218
219        test(1, 'c', '\01')
220
221        # sign and aligning are interdependent
222        test(1, "-", '1')
223        test(-1, "-", '-1')
224        test(1, "-3", '  1')
225        test(-1, "-3", ' -1')
226        test(1, "+3", ' +1')
227        test(-1, "+3", ' -1')
228        test(1, " 3", '  1')
229        test(-1, " 3", ' -1')
230        test(1, " ", ' 1')
231        test(-1, " ", '-1')
232
233        # hex
234        test(3, "x", "3")
235        test(3, "X", "3")
236        test(1234, "x", "4d2")
237        test(-1234, "x", "-4d2")
238        test(1234, "8x", "     4d2")
239        test(-1234, "8x", "    -4d2")
240        test(1234, "x", "4d2")
241        test(-1234, "x", "-4d2")
242        test(-3, "x", "-3")
243        test(-3, "X", "-3")
244        test(int('be', 16), "x", "be")
245        test(int('be', 16), "X", "BE")
246        test(-int('be', 16), "x", "-be")
247        test(-int('be', 16), "X", "-BE")
248
249        # octal
250        test(3, "o", "3")
251        test(-3, "o", "-3")
252        test(65, "o", "101")
253        test(-65, "o", "-101")
254        test(1234, "o", "2322")
255        test(-1234, "o", "-2322")
256        test(1234, "-o", "2322")
257        test(-1234, "-o", "-2322")
258        test(1234, " o", " 2322")
259        test(-1234, " o", "-2322")
260        test(1234, "+o", "+2322")
261        test(-1234, "+o", "-2322")
262
263        # binary
264        test(3, "b", "11")
265        test(-3, "b", "-11")
266        test(1234, "b", "10011010010")
267        test(-1234, "b", "-10011010010")
268        test(1234, "-b", "10011010010")
269        test(-1234, "-b", "-10011010010")
270        test(1234, " b", " 10011010010")
271        test(-1234, " b", "-10011010010")
272        test(1234, "+b", "+10011010010")
273        test(-1234, "+b", "-10011010010")
274
275        # alternate (#) formatting
276        test(0, "#b", '0b0')
277        test(0, "-#b", '0b0')
278        test(1, "-#b", '0b1')
279        test(-1, "-#b", '-0b1')
280        test(-1, "-#5b", ' -0b1')
281        test(1, "+#5b", ' +0b1')
282        test(100, "+#b", '+0b1100100')
283        test(100, "#012b", '0b0001100100')
284        test(-100, "#012b", '-0b001100100')
285
286        test(0, "#o", '0o0')
287        test(0, "-#o", '0o0')
288        test(1, "-#o", '0o1')
289        test(-1, "-#o", '-0o1')
290        test(-1, "-#5o", ' -0o1')
291        test(1, "+#5o", ' +0o1')
292        test(100, "+#o", '+0o144')
293        test(100, "#012o", '0o0000000144')
294        test(-100, "#012o", '-0o000000144')
295
296        test(0, "#x", '0x0')
297        test(0, "-#x", '0x0')
298        test(1, "-#x", '0x1')
299        test(-1, "-#x", '-0x1')
300        test(-1, "-#5x", ' -0x1')
301        test(1, "+#5x", ' +0x1')
302        test(100, "+#x", '+0x64')
303        test(100, "#012x", '0x0000000064')
304        test(-100, "#012x", '-0x000000064')
305        test(123456, "#012x", '0x000001e240')
306        test(-123456, "#012x", '-0x00001e240')
307
308        test(0, "#X", '0X0')
309        test(0, "-#X", '0X0')
310        test(1, "-#X", '0X1')
311        test(-1, "-#X", '-0X1')
312        test(-1, "-#5X", ' -0X1')
313        test(1, "+#5X", ' +0X1')
314        test(100, "+#X", '+0X64')
315        test(100, "#012X", '0X0000000064')
316        test(-100, "#012X", '-0X000000064')
317        test(123456, "#012X", '0X000001E240')
318        test(-123456, "#012X", '-0X00001E240')
319
320        test(123, ',', '123')
321        test(-123, ',', '-123')
322        test(1234, ',', '1,234')
323        test(-1234, ',', '-1,234')
324        test(123456, ',', '123,456')
325        test(-123456, ',', '-123,456')
326        test(1234567, ',', '1,234,567')
327        test(-1234567, ',', '-1,234,567')
328
329        # issue 5782, commas with no specifier type
330        test(1234, '010,', '00,001,234')
331
332        # Unified type for integers
333        test(10**100, 'd', '1' + '0' * 100)
334        test(10**100+100, 'd', '1' + '0' * 97 + '100')
335
336        # make sure these are errors
337
338        # precision disallowed
339        self.assertRaises(ValueError, 3 .__format__, "1.3")
340        # sign not allowed with 'c'
341        self.assertRaises(ValueError, 3 .__format__, "+c")
342        # format spec must be string
343        self.assertRaises(TypeError, 3 .__format__, None)
344        self.assertRaises(TypeError, 3 .__format__, 0)
345        # can't have ',' with 'n'
346        self.assertRaises(ValueError, 3 .__format__, ",n")
347        # can't have ',' with 'c'
348        self.assertRaises(ValueError, 3 .__format__, ",c")
349        # can't have '#' with 'c'
350        self.assertRaises(ValueError, 3 .__format__, "#c")
351
352        # ensure that only int and float type specifiers work
353        for format_spec in ([chr(x) for x in range(ord('a'), ord('z')+1)] +
354                            [chr(x) for x in range(ord('A'), ord('Z')+1)]):
355            if not format_spec in 'bcdoxXeEfFgGn%':
356                self.assertRaises(ValueError, 0 .__format__, format_spec)
357                self.assertRaises(ValueError, 1 .__format__, format_spec)
358                self.assertRaises(ValueError, (-1) .__format__, format_spec)
359
360        # ensure that float type specifiers work; format converts
361        #  the int to a float
362        for format_spec in 'eEfFgG%':
363            for value in [0, 1, -1, 100, -100, 1234567890, -1234567890]:
364                self.assertEqual(value.__format__(format_spec),
365                                 float(value).__format__(format_spec))
366
367        # Issue 6902
368        test(123456, "0<20", '12345600000000000000')
369        test(123456, "1<20", '12345611111111111111')
370        test(123456, "*<20", '123456**************')
371        test(123456, "0>20", '00000000000000123456')
372        test(123456, "1>20", '11111111111111123456')
373        test(123456, "*>20", '**************123456')
374        test(123456, "0=20", '00000000000000123456')
375        test(123456, "1=20", '11111111111111123456')
376        test(123456, "*=20", '**************123456')
377
378    @run_with_locale('LC_NUMERIC', 'en_US.UTF8')
379    def test_float__format__locale(self):
380        # test locale support for __format__ code 'n'
381
382        for i in range(-10, 10):
383            x = 1234567890.0 * (10.0 ** i)
384            self.assertEqual(locale.format_string('%g', x, grouping=True), format(x, 'n'))
385            self.assertEqual(locale.format_string('%.10g', x, grouping=True), format(x, '.10n'))
386
387    @run_with_locale('LC_NUMERIC', 'en_US.UTF8')
388    def test_int__format__locale(self):
389        # test locale support for __format__ code 'n' for integers
390
391        x = 123456789012345678901234567890
392        for i in range(0, 30):
393            self.assertEqual(locale.format_string('%d', x, grouping=True), format(x, 'n'))
394
395            # move to the next integer to test
396            x = x // 10
397
398        rfmt = ">20n"
399        lfmt = "<20n"
400        cfmt = "^20n"
401        for x in (1234, 12345, 123456, 1234567, 12345678, 123456789, 1234567890, 12345678900):
402            self.assertEqual(len(format(0, rfmt)), len(format(x, rfmt)))
403            self.assertEqual(len(format(0, lfmt)), len(format(x, lfmt)))
404            self.assertEqual(len(format(0, cfmt)), len(format(x, cfmt)))
405
406    def test_float__format__(self):
407        def test(f, format_spec, result):
408            self.assertEqual(f.__format__(format_spec), result)
409            self.assertEqual(format(f, format_spec), result)
410
411        test(0.0, 'f', '0.000000')
412
413        # the default is 'g', except for empty format spec
414        test(0.0, '', '0.0')
415        test(0.01, '', '0.01')
416        test(0.01, 'g', '0.01')
417
418        # test for issue 3411
419        test(1.23, '1', '1.23')
420        test(-1.23, '1', '-1.23')
421        test(1.23, '1g', '1.23')
422        test(-1.23, '1g', '-1.23')
423
424        test( 1.0, ' g', ' 1')
425        test(-1.0, ' g', '-1')
426        test( 1.0, '+g', '+1')
427        test(-1.0, '+g', '-1')
428        test(1.1234e200, 'g', '1.1234e+200')
429        test(1.1234e200, 'G', '1.1234E+200')
430
431
432        test(1.0, 'f', '1.000000')
433
434        test(-1.0, 'f', '-1.000000')
435
436        test( 1.0, ' f', ' 1.000000')
437        test(-1.0, ' f', '-1.000000')
438        test( 1.0, '+f', '+1.000000')
439        test(-1.0, '+f', '-1.000000')
440
441        # Python versions <= 3.0 switched from 'f' to 'g' formatting for
442        # values larger than 1e50.  No longer.
443        f = 1.1234e90
444        for fmt in 'f', 'F':
445            # don't do a direct equality check, since on some
446            # platforms only the first few digits of dtoa
447            # will be reliable
448            result = f.__format__(fmt)
449            self.assertEqual(len(result), 98)
450            self.assertEqual(result[-7], '.')
451            self.assertIn(result[:12], ('112340000000', '112339999999'))
452        f = 1.1234e200
453        for fmt in 'f', 'F':
454            result = f.__format__(fmt)
455            self.assertEqual(len(result), 208)
456            self.assertEqual(result[-7], '.')
457            self.assertIn(result[:12], ('112340000000', '112339999999'))
458
459
460        test( 1.0, 'e', '1.000000e+00')
461        test(-1.0, 'e', '-1.000000e+00')
462        test( 1.0, 'E', '1.000000E+00')
463        test(-1.0, 'E', '-1.000000E+00')
464        test(1.1234e20, 'e', '1.123400e+20')
465        test(1.1234e20, 'E', '1.123400E+20')
466
467        # No format code means use g, but must have a decimal
468        # and a number after the decimal.  This is tricky, because
469        # a totally empty format specifier means something else.
470        # So, just use a sign flag
471        test(1e200, '+g', '+1e+200')
472        test(1e200, '+', '+1e+200')
473
474        test(1.1e200, '+g', '+1.1e+200')
475        test(1.1e200, '+', '+1.1e+200')
476
477        # 0 padding
478        test(1234., '010f', '1234.000000')
479        test(1234., '011f', '1234.000000')
480        test(1234., '012f', '01234.000000')
481        test(-1234., '011f', '-1234.000000')
482        test(-1234., '012f', '-1234.000000')
483        test(-1234., '013f', '-01234.000000')
484        test(-1234.12341234, '013f', '-01234.123412')
485        test(-123456.12341234, '011.2f', '-0123456.12')
486
487        # issue 5782, commas with no specifier type
488        test(1.2, '010,.2', '0,000,001.2')
489
490        # 0 padding with commas
491        test(1234., '011,f', '1,234.000000')
492        test(1234., '012,f', '1,234.000000')
493        test(1234., '013,f', '01,234.000000')
494        test(-1234., '012,f', '-1,234.000000')
495        test(-1234., '013,f', '-1,234.000000')
496        test(-1234., '014,f', '-01,234.000000')
497        test(-12345., '015,f', '-012,345.000000')
498        test(-123456., '016,f', '-0,123,456.000000')
499        test(-123456., '017,f', '-0,123,456.000000')
500        test(-123456.12341234, '017,f', '-0,123,456.123412')
501        test(-123456.12341234, '013,.2f', '-0,123,456.12')
502
503        # % formatting
504        test(-1.0, '%', '-100.000000%')
505
506        # format spec must be string
507        self.assertRaises(TypeError, 3.0.__format__, None)
508        self.assertRaises(TypeError, 3.0.__format__, 0)
509
510        # other format specifiers shouldn't work on floats,
511        #  in particular int specifiers
512        for format_spec in ([chr(x) for x in range(ord('a'), ord('z')+1)] +
513                            [chr(x) for x in range(ord('A'), ord('Z')+1)]):
514            if not format_spec in 'eEfFgGn%':
515                self.assertRaises(ValueError, format, 0.0, format_spec)
516                self.assertRaises(ValueError, format, 1.0, format_spec)
517                self.assertRaises(ValueError, format, -1.0, format_spec)
518                self.assertRaises(ValueError, format, 1e100, format_spec)
519                self.assertRaises(ValueError, format, -1e100, format_spec)
520                self.assertRaises(ValueError, format, 1e-100, format_spec)
521                self.assertRaises(ValueError, format, -1e-100, format_spec)
522
523        # Alternate float formatting
524        test(1.0, '.0e', '1e+00')
525        test(1.0, '#.0e', '1.e+00')
526        test(1.0, '.0f', '1')
527        test(1.0, '#.0f', '1.')
528        test(1.1, 'g', '1.1')
529        test(1.1, '#g', '1.10000')
530        test(1.0, '.0%', '100%')
531        test(1.0, '#.0%', '100.%')
532
533        # Issue 7094: Alternate formatting (specified by #)
534        test(1.0, '0e',  '1.000000e+00')
535        test(1.0, '#0e', '1.000000e+00')
536        test(1.0, '0f',  '1.000000' )
537        test(1.0, '#0f', '1.000000')
538        test(1.0, '.1e',  '1.0e+00')
539        test(1.0, '#.1e', '1.0e+00')
540        test(1.0, '.1f',  '1.0')
541        test(1.0, '#.1f', '1.0')
542        test(1.0, '.1%',  '100.0%')
543        test(1.0, '#.1%', '100.0%')
544
545        # Issue 6902
546        test(12345.6, "0<20", '12345.60000000000000')
547        test(12345.6, "1<20", '12345.61111111111111')
548        test(12345.6, "*<20", '12345.6*************')
549        test(12345.6, "0>20", '000000000000012345.6')
550        test(12345.6, "1>20", '111111111111112345.6')
551        test(12345.6, "*>20", '*************12345.6')
552        test(12345.6, "0=20", '000000000000012345.6')
553        test(12345.6, "1=20", '111111111111112345.6')
554        test(12345.6, "*=20", '*************12345.6')
555
556    def test_format_spec_errors(self):
557        # int, float, and string all share the same format spec
558        # mini-language parser.
559
560        # Check that we can't ask for too many digits. This is
561        # probably a CPython specific test. It tries to put the width
562        # into a C long.
563        self.assertRaises(ValueError, format, 0, '1'*10000 + 'd')
564
565        # Similar with the precision.
566        self.assertRaises(ValueError, format, 0, '.' + '1'*10000 + 'd')
567
568        # And may as well test both.
569        self.assertRaises(ValueError, format, 0, '1'*1000 + '.' + '1'*10000 + 'd')
570
571        # Make sure commas aren't allowed with various type codes
572        for code in 'xXobns':
573            self.assertRaises(ValueError, format, 0, ',' + code)
574
575    def test_internal_sizes(self):
576        self.assertGreater(object.__basicsize__, 0)
577        self.assertGreater(tuple.__itemsize__, 0)
578
579    def test_slot_wrapper_types(self):
580        self.assertIsInstance(object.__init__, types.WrapperDescriptorType)
581        self.assertIsInstance(object.__str__, types.WrapperDescriptorType)
582        self.assertIsInstance(object.__lt__, types.WrapperDescriptorType)
583        self.assertIsInstance(int.__lt__, types.WrapperDescriptorType)
584
585    def test_method_wrapper_types(self):
586        self.assertIsInstance(object().__init__, types.MethodWrapperType)
587        self.assertIsInstance(object().__str__, types.MethodWrapperType)
588        self.assertIsInstance(object().__lt__, types.MethodWrapperType)
589        self.assertIsInstance((42).__lt__, types.MethodWrapperType)
590
591    def test_method_descriptor_types(self):
592        self.assertIsInstance(str.join, types.MethodDescriptorType)
593        self.assertIsInstance(list.append, types.MethodDescriptorType)
594        self.assertIsInstance(''.join, types.BuiltinMethodType)
595        self.assertIsInstance([].append, types.BuiltinMethodType)
596
597        self.assertIsInstance(int.__dict__['from_bytes'], types.ClassMethodDescriptorType)
598        self.assertIsInstance(int.from_bytes, types.BuiltinMethodType)
599        self.assertIsInstance(int.__new__, types.BuiltinMethodType)
600
601
602class MappingProxyTests(unittest.TestCase):
603    mappingproxy = types.MappingProxyType
604
605    def test_constructor(self):
606        class userdict(dict):
607            pass
608
609        mapping = {'x': 1, 'y': 2}
610        self.assertEqual(self.mappingproxy(mapping), mapping)
611        mapping = userdict(x=1, y=2)
612        self.assertEqual(self.mappingproxy(mapping), mapping)
613        mapping = collections.ChainMap({'x': 1}, {'y': 2})
614        self.assertEqual(self.mappingproxy(mapping), mapping)
615
616        self.assertRaises(TypeError, self.mappingproxy, 10)
617        self.assertRaises(TypeError, self.mappingproxy, ("a", "tuple"))
618        self.assertRaises(TypeError, self.mappingproxy, ["a", "list"])
619
620    def test_methods(self):
621        attrs = set(dir(self.mappingproxy({}))) - set(dir(object()))
622        self.assertEqual(attrs, {
623             '__contains__',
624             '__getitem__',
625             '__class_getitem__',
626             '__ior__',
627             '__iter__',
628             '__len__',
629             '__or__',
630             '__reversed__',
631             '__ror__',
632             'copy',
633             'get',
634             'items',
635             'keys',
636             'values',
637        })
638
639    def test_get(self):
640        view = self.mappingproxy({'a': 'A', 'b': 'B'})
641        self.assertEqual(view['a'], 'A')
642        self.assertEqual(view['b'], 'B')
643        self.assertRaises(KeyError, view.__getitem__, 'xxx')
644        self.assertEqual(view.get('a'), 'A')
645        self.assertIsNone(view.get('xxx'))
646        self.assertEqual(view.get('xxx', 42), 42)
647
648    def test_missing(self):
649        class dictmissing(dict):
650            def __missing__(self, key):
651                return "missing=%s" % key
652
653        view = self.mappingproxy(dictmissing(x=1))
654        self.assertEqual(view['x'], 1)
655        self.assertEqual(view['y'], 'missing=y')
656        self.assertEqual(view.get('x'), 1)
657        self.assertEqual(view.get('y'), None)
658        self.assertEqual(view.get('y', 42), 42)
659        self.assertTrue('x' in view)
660        self.assertFalse('y' in view)
661
662    def test_customdict(self):
663        class customdict(dict):
664            def __contains__(self, key):
665                if key == 'magic':
666                    return True
667                else:
668                    return dict.__contains__(self, key)
669
670            def __iter__(self):
671                return iter(('iter',))
672
673            def __len__(self):
674                return 500
675
676            def copy(self):
677                return 'copy'
678
679            def keys(self):
680                return 'keys'
681
682            def items(self):
683                return 'items'
684
685            def values(self):
686                return 'values'
687
688            def __getitem__(self, key):
689                return "getitem=%s" % dict.__getitem__(self, key)
690
691            def get(self, key, default=None):
692                return "get=%s" % dict.get(self, key, 'default=%r' % default)
693
694        custom = customdict({'key': 'value'})
695        view = self.mappingproxy(custom)
696        self.assertTrue('key' in view)
697        self.assertTrue('magic' in view)
698        self.assertFalse('xxx' in view)
699        self.assertEqual(view['key'], 'getitem=value')
700        self.assertRaises(KeyError, view.__getitem__, 'xxx')
701        self.assertEqual(tuple(view), ('iter',))
702        self.assertEqual(len(view), 500)
703        self.assertEqual(view.copy(), 'copy')
704        self.assertEqual(view.get('key'), 'get=value')
705        self.assertEqual(view.get('xxx'), 'get=default=None')
706        self.assertEqual(view.items(), 'items')
707        self.assertEqual(view.keys(), 'keys')
708        self.assertEqual(view.values(), 'values')
709
710    def test_chainmap(self):
711        d1 = {'x': 1}
712        d2 = {'y': 2}
713        mapping = collections.ChainMap(d1, d2)
714        view = self.mappingproxy(mapping)
715        self.assertTrue('x' in view)
716        self.assertTrue('y' in view)
717        self.assertFalse('z' in view)
718        self.assertEqual(view['x'], 1)
719        self.assertEqual(view['y'], 2)
720        self.assertRaises(KeyError, view.__getitem__, 'z')
721        self.assertEqual(tuple(sorted(view)), ('x', 'y'))
722        self.assertEqual(len(view), 2)
723        copy = view.copy()
724        self.assertIsNot(copy, mapping)
725        self.assertIsInstance(copy, collections.ChainMap)
726        self.assertEqual(copy, mapping)
727        self.assertEqual(view.get('x'), 1)
728        self.assertEqual(view.get('y'), 2)
729        self.assertIsNone(view.get('z'))
730        self.assertEqual(tuple(sorted(view.items())), (('x', 1), ('y', 2)))
731        self.assertEqual(tuple(sorted(view.keys())), ('x', 'y'))
732        self.assertEqual(tuple(sorted(view.values())), (1, 2))
733
734    def test_contains(self):
735        view = self.mappingproxy(dict.fromkeys('abc'))
736        self.assertTrue('a' in view)
737        self.assertTrue('b' in view)
738        self.assertTrue('c' in view)
739        self.assertFalse('xxx' in view)
740
741    def test_views(self):
742        mapping = {}
743        view = self.mappingproxy(mapping)
744        keys = view.keys()
745        values = view.values()
746        items = view.items()
747        self.assertEqual(list(keys), [])
748        self.assertEqual(list(values), [])
749        self.assertEqual(list(items), [])
750        mapping['key'] = 'value'
751        self.assertEqual(list(keys), ['key'])
752        self.assertEqual(list(values), ['value'])
753        self.assertEqual(list(items), [('key', 'value')])
754
755    def test_len(self):
756        for expected in range(6):
757            data = dict.fromkeys('abcde'[:expected])
758            self.assertEqual(len(data), expected)
759            view = self.mappingproxy(data)
760            self.assertEqual(len(view), expected)
761
762    def test_iterators(self):
763        keys = ('x', 'y')
764        values = (1, 2)
765        items = tuple(zip(keys, values))
766        view = self.mappingproxy(dict(items))
767        self.assertEqual(set(view), set(keys))
768        self.assertEqual(set(view.keys()), set(keys))
769        self.assertEqual(set(view.values()), set(values))
770        self.assertEqual(set(view.items()), set(items))
771
772    def test_reversed(self):
773        d = {'a': 1, 'b': 2, 'foo': 0, 'c': 3, 'd': 4}
774        mp = self.mappingproxy(d)
775        del d['foo']
776        r = reversed(mp)
777        self.assertEqual(list(r), list('dcba'))
778        self.assertRaises(StopIteration, next, r)
779
780    def test_copy(self):
781        original = {'key1': 27, 'key2': 51, 'key3': 93}
782        view = self.mappingproxy(original)
783        copy = view.copy()
784        self.assertEqual(type(copy), dict)
785        self.assertEqual(copy, original)
786        original['key1'] = 70
787        self.assertEqual(view['key1'], 70)
788        self.assertEqual(copy['key1'], 27)
789
790    def test_union(self):
791        mapping = {'a': 0, 'b': 1, 'c': 2}
792        view = self.mappingproxy(mapping)
793        with self.assertRaises(TypeError):
794            view | [('r', 2), ('d', 2)]
795        with self.assertRaises(TypeError):
796            [('r', 2), ('d', 2)] | view
797        with self.assertRaises(TypeError):
798            view |= [('r', 2), ('d', 2)]
799        other = {'c': 3, 'p': 0}
800        self.assertDictEqual(view | other, {'a': 0, 'b': 1, 'c': 3, 'p': 0})
801        self.assertDictEqual(other | view, {'c': 2, 'p': 0, 'a': 0, 'b': 1})
802        self.assertEqual(view, {'a': 0, 'b': 1, 'c': 2})
803        self.assertDictEqual(mapping, {'a': 0, 'b': 1, 'c': 2})
804        self.assertDictEqual(other, {'c': 3, 'p': 0})
805
806
807class ClassCreationTests(unittest.TestCase):
808
809    class Meta(type):
810        def __init__(cls, name, bases, ns, **kw):
811            super().__init__(name, bases, ns)
812        @staticmethod
813        def __new__(mcls, name, bases, ns, **kw):
814            return super().__new__(mcls, name, bases, ns)
815        @classmethod
816        def __prepare__(mcls, name, bases, **kw):
817            ns = super().__prepare__(name, bases)
818            ns["y"] = 1
819            ns.update(kw)
820            return ns
821
822    def test_new_class_basics(self):
823        C = types.new_class("C")
824        self.assertEqual(C.__name__, "C")
825        self.assertEqual(C.__bases__, (object,))
826
827    def test_new_class_subclass(self):
828        C = types.new_class("C", (int,))
829        self.assertTrue(issubclass(C, int))
830
831    def test_new_class_meta(self):
832        Meta = self.Meta
833        settings = {"metaclass": Meta, "z": 2}
834        # We do this twice to make sure the passed in dict isn't mutated
835        for i in range(2):
836            C = types.new_class("C" + str(i), (), settings)
837            self.assertIsInstance(C, Meta)
838            self.assertEqual(C.y, 1)
839            self.assertEqual(C.z, 2)
840
841    def test_new_class_exec_body(self):
842        Meta = self.Meta
843        def func(ns):
844            ns["x"] = 0
845        C = types.new_class("C", (), {"metaclass": Meta, "z": 2}, func)
846        self.assertIsInstance(C, Meta)
847        self.assertEqual(C.x, 0)
848        self.assertEqual(C.y, 1)
849        self.assertEqual(C.z, 2)
850
851    def test_new_class_metaclass_keywords(self):
852        #Test that keywords are passed to the metaclass:
853        def meta_func(name, bases, ns, **kw):
854            return name, bases, ns, kw
855        res = types.new_class("X",
856                              (int, object),
857                              dict(metaclass=meta_func, x=0))
858        self.assertEqual(res, ("X", (int, object), {}, {"x": 0}))
859
860    def test_new_class_defaults(self):
861        # Test defaults/keywords:
862        C = types.new_class("C", (), {}, None)
863        self.assertEqual(C.__name__, "C")
864        self.assertEqual(C.__bases__, (object,))
865
866    def test_new_class_meta_with_base(self):
867        Meta = self.Meta
868        def func(ns):
869            ns["x"] = 0
870        C = types.new_class(name="C",
871                            bases=(int,),
872                            kwds=dict(metaclass=Meta, z=2),
873                            exec_body=func)
874        self.assertTrue(issubclass(C, int))
875        self.assertIsInstance(C, Meta)
876        self.assertEqual(C.x, 0)
877        self.assertEqual(C.y, 1)
878        self.assertEqual(C.z, 2)
879
880    def test_new_class_with_mro_entry(self):
881        class A: pass
882        class C:
883            def __mro_entries__(self, bases):
884                return (A,)
885        c = C()
886        D = types.new_class('D', (c,), {})
887        self.assertEqual(D.__bases__, (A,))
888        self.assertEqual(D.__orig_bases__, (c,))
889        self.assertEqual(D.__mro__, (D, A, object))
890
891    def test_new_class_with_mro_entry_none(self):
892        class A: pass
893        class B: pass
894        class C:
895            def __mro_entries__(self, bases):
896                return ()
897        c = C()
898        D = types.new_class('D', (A, c, B), {})
899        self.assertEqual(D.__bases__, (A, B))
900        self.assertEqual(D.__orig_bases__, (A, c, B))
901        self.assertEqual(D.__mro__, (D, A, B, object))
902
903    def test_new_class_with_mro_entry_error(self):
904        class A: pass
905        class C:
906            def __mro_entries__(self, bases):
907                return A
908        c = C()
909        with self.assertRaises(TypeError):
910            types.new_class('D', (c,), {})
911
912    def test_new_class_with_mro_entry_multiple(self):
913        class A1: pass
914        class A2: pass
915        class B1: pass
916        class B2: pass
917        class A:
918            def __mro_entries__(self, bases):
919                return (A1, A2)
920        class B:
921            def __mro_entries__(self, bases):
922                return (B1, B2)
923        D = types.new_class('D', (A(), B()), {})
924        self.assertEqual(D.__bases__, (A1, A2, B1, B2))
925
926    def test_new_class_with_mro_entry_multiple_2(self):
927        class A1: pass
928        class A2: pass
929        class A3: pass
930        class B1: pass
931        class B2: pass
932        class A:
933            def __mro_entries__(self, bases):
934                return (A1, A2, A3)
935        class B:
936            def __mro_entries__(self, bases):
937                return (B1, B2)
938        class C: pass
939        D = types.new_class('D', (A(), C, B()), {})
940        self.assertEqual(D.__bases__, (A1, A2, A3, C, B1, B2))
941
942    # Many of the following tests are derived from test_descr.py
943    def test_prepare_class(self):
944        # Basic test of metaclass derivation
945        expected_ns = {}
946        class A(type):
947            def __new__(*args, **kwargs):
948                return type.__new__(*args, **kwargs)
949
950            def __prepare__(*args):
951                return expected_ns
952
953        B = types.new_class("B", (object,))
954        C = types.new_class("C", (object,), {"metaclass": A})
955
956        # The most derived metaclass of D is A rather than type.
957        meta, ns, kwds = types.prepare_class("D", (B, C), {"metaclass": type})
958        self.assertIs(meta, A)
959        self.assertIs(ns, expected_ns)
960        self.assertEqual(len(kwds), 0)
961
962    def test_bad___prepare__(self):
963        # __prepare__() must return a mapping.
964        class BadMeta(type):
965            @classmethod
966            def __prepare__(*args):
967                return None
968        with self.assertRaisesRegex(TypeError,
969                                    r'^BadMeta\.__prepare__\(\) must '
970                                    r'return a mapping, not NoneType$'):
971            class Foo(metaclass=BadMeta):
972                pass
973        # Also test the case in which the metaclass is not a type.
974        class BadMeta:
975            @classmethod
976            def __prepare__(*args):
977                return None
978        with self.assertRaisesRegex(TypeError,
979                                    r'^<metaclass>\.__prepare__\(\) must '
980                                    r'return a mapping, not NoneType$'):
981            class Bar(metaclass=BadMeta()):
982                pass
983
984    def test_resolve_bases(self):
985        class A: pass
986        class B: pass
987        class C:
988            def __mro_entries__(self, bases):
989                if A in bases:
990                    return ()
991                return (A,)
992        c = C()
993        self.assertEqual(types.resolve_bases(()), ())
994        self.assertEqual(types.resolve_bases((c,)), (A,))
995        self.assertEqual(types.resolve_bases((C,)), (C,))
996        self.assertEqual(types.resolve_bases((A, C)), (A, C))
997        self.assertEqual(types.resolve_bases((c, A)), (A,))
998        self.assertEqual(types.resolve_bases((A, c)), (A,))
999        x = (A,)
1000        y = (C,)
1001        z = (A, C)
1002        t = (A, C, B)
1003        for bases in [x, y, z, t]:
1004            self.assertIs(types.resolve_bases(bases), bases)
1005
1006    def test_metaclass_derivation(self):
1007        # issue1294232: correct metaclass calculation
1008        new_calls = []  # to check the order of __new__ calls
1009        class AMeta(type):
1010            def __new__(mcls, name, bases, ns):
1011                new_calls.append('AMeta')
1012                return super().__new__(mcls, name, bases, ns)
1013            @classmethod
1014            def __prepare__(mcls, name, bases):
1015                return {}
1016
1017        class BMeta(AMeta):
1018            def __new__(mcls, name, bases, ns):
1019                new_calls.append('BMeta')
1020                return super().__new__(mcls, name, bases, ns)
1021            @classmethod
1022            def __prepare__(mcls, name, bases):
1023                ns = super().__prepare__(name, bases)
1024                ns['BMeta_was_here'] = True
1025                return ns
1026
1027        A = types.new_class("A", (), {"metaclass": AMeta})
1028        self.assertEqual(new_calls, ['AMeta'])
1029        new_calls.clear()
1030
1031        B = types.new_class("B", (), {"metaclass": BMeta})
1032        # BMeta.__new__ calls AMeta.__new__ with super:
1033        self.assertEqual(new_calls, ['BMeta', 'AMeta'])
1034        new_calls.clear()
1035
1036        C = types.new_class("C", (A, B))
1037        # The most derived metaclass is BMeta:
1038        self.assertEqual(new_calls, ['BMeta', 'AMeta'])
1039        new_calls.clear()
1040        # BMeta.__prepare__ should've been called:
1041        self.assertIn('BMeta_was_here', C.__dict__)
1042
1043        # The order of the bases shouldn't matter:
1044        C2 = types.new_class("C2", (B, A))
1045        self.assertEqual(new_calls, ['BMeta', 'AMeta'])
1046        new_calls.clear()
1047        self.assertIn('BMeta_was_here', C2.__dict__)
1048
1049        # Check correct metaclass calculation when a metaclass is declared:
1050        D = types.new_class("D", (C,), {"metaclass": type})
1051        self.assertEqual(new_calls, ['BMeta', 'AMeta'])
1052        new_calls.clear()
1053        self.assertIn('BMeta_was_here', D.__dict__)
1054
1055        E = types.new_class("E", (C,), {"metaclass": AMeta})
1056        self.assertEqual(new_calls, ['BMeta', 'AMeta'])
1057        new_calls.clear()
1058        self.assertIn('BMeta_was_here', E.__dict__)
1059
1060    def test_metaclass_override_function(self):
1061        # Special case: the given metaclass isn't a class,
1062        # so there is no metaclass calculation.
1063        class A(metaclass=self.Meta):
1064            pass
1065
1066        marker = object()
1067        def func(*args, **kwargs):
1068            return marker
1069
1070        X = types.new_class("X", (), {"metaclass": func})
1071        Y = types.new_class("Y", (object,), {"metaclass": func})
1072        Z = types.new_class("Z", (A,), {"metaclass": func})
1073        self.assertIs(marker, X)
1074        self.assertIs(marker, Y)
1075        self.assertIs(marker, Z)
1076
1077    def test_metaclass_override_callable(self):
1078        # The given metaclass is a class,
1079        # but not a descendant of type.
1080        new_calls = []  # to check the order of __new__ calls
1081        prepare_calls = []  # to track __prepare__ calls
1082        class ANotMeta:
1083            def __new__(mcls, *args, **kwargs):
1084                new_calls.append('ANotMeta')
1085                return super().__new__(mcls)
1086            @classmethod
1087            def __prepare__(mcls, name, bases):
1088                prepare_calls.append('ANotMeta')
1089                return {}
1090
1091        class BNotMeta(ANotMeta):
1092            def __new__(mcls, *args, **kwargs):
1093                new_calls.append('BNotMeta')
1094                return super().__new__(mcls)
1095            @classmethod
1096            def __prepare__(mcls, name, bases):
1097                prepare_calls.append('BNotMeta')
1098                return super().__prepare__(name, bases)
1099
1100        A = types.new_class("A", (), {"metaclass": ANotMeta})
1101        self.assertIs(ANotMeta, type(A))
1102        self.assertEqual(prepare_calls, ['ANotMeta'])
1103        prepare_calls.clear()
1104        self.assertEqual(new_calls, ['ANotMeta'])
1105        new_calls.clear()
1106
1107        B = types.new_class("B", (), {"metaclass": BNotMeta})
1108        self.assertIs(BNotMeta, type(B))
1109        self.assertEqual(prepare_calls, ['BNotMeta', 'ANotMeta'])
1110        prepare_calls.clear()
1111        self.assertEqual(new_calls, ['BNotMeta', 'ANotMeta'])
1112        new_calls.clear()
1113
1114        C = types.new_class("C", (A, B))
1115        self.assertIs(BNotMeta, type(C))
1116        self.assertEqual(prepare_calls, ['BNotMeta', 'ANotMeta'])
1117        prepare_calls.clear()
1118        self.assertEqual(new_calls, ['BNotMeta', 'ANotMeta'])
1119        new_calls.clear()
1120
1121        C2 = types.new_class("C2", (B, A))
1122        self.assertIs(BNotMeta, type(C2))
1123        self.assertEqual(prepare_calls, ['BNotMeta', 'ANotMeta'])
1124        prepare_calls.clear()
1125        self.assertEqual(new_calls, ['BNotMeta', 'ANotMeta'])
1126        new_calls.clear()
1127
1128        # This is a TypeError, because of a metaclass conflict:
1129        # BNotMeta is neither a subclass, nor a superclass of type
1130        with self.assertRaises(TypeError):
1131            D = types.new_class("D", (C,), {"metaclass": type})
1132
1133        E = types.new_class("E", (C,), {"metaclass": ANotMeta})
1134        self.assertIs(BNotMeta, type(E))
1135        self.assertEqual(prepare_calls, ['BNotMeta', 'ANotMeta'])
1136        prepare_calls.clear()
1137        self.assertEqual(new_calls, ['BNotMeta', 'ANotMeta'])
1138        new_calls.clear()
1139
1140        F = types.new_class("F", (object(), C))
1141        self.assertIs(BNotMeta, type(F))
1142        self.assertEqual(prepare_calls, ['BNotMeta', 'ANotMeta'])
1143        prepare_calls.clear()
1144        self.assertEqual(new_calls, ['BNotMeta', 'ANotMeta'])
1145        new_calls.clear()
1146
1147        F2 = types.new_class("F2", (C, object()))
1148        self.assertIs(BNotMeta, type(F2))
1149        self.assertEqual(prepare_calls, ['BNotMeta', 'ANotMeta'])
1150        prepare_calls.clear()
1151        self.assertEqual(new_calls, ['BNotMeta', 'ANotMeta'])
1152        new_calls.clear()
1153
1154        # TypeError: BNotMeta is neither a
1155        # subclass, nor a superclass of int
1156        with self.assertRaises(TypeError):
1157            X = types.new_class("X", (C, int()))
1158        with self.assertRaises(TypeError):
1159            X = types.new_class("X", (int(), C))
1160
1161    def test_one_argument_type(self):
1162        expected_message = 'type.__new__() takes exactly 3 arguments (1 given)'
1163
1164        # Only type itself can use the one-argument form (#27157)
1165        self.assertIs(type(5), int)
1166
1167        class M(type):
1168            pass
1169        with self.assertRaises(TypeError) as cm:
1170            M(5)
1171        self.assertEqual(str(cm.exception), expected_message)
1172
1173        class N(type, metaclass=M):
1174            pass
1175        with self.assertRaises(TypeError) as cm:
1176            N(5)
1177        self.assertEqual(str(cm.exception), expected_message)
1178
1179
1180class SimpleNamespaceTests(unittest.TestCase):
1181
1182    def test_constructor(self):
1183        ns1 = types.SimpleNamespace()
1184        ns2 = types.SimpleNamespace(x=1, y=2)
1185        ns3 = types.SimpleNamespace(**dict(x=1, y=2))
1186
1187        with self.assertRaises(TypeError):
1188            types.SimpleNamespace(1, 2, 3)
1189        with self.assertRaises(TypeError):
1190            types.SimpleNamespace(**{1: 2})
1191
1192        self.assertEqual(len(ns1.__dict__), 0)
1193        self.assertEqual(vars(ns1), {})
1194        self.assertEqual(len(ns2.__dict__), 2)
1195        self.assertEqual(vars(ns2), {'y': 2, 'x': 1})
1196        self.assertEqual(len(ns3.__dict__), 2)
1197        self.assertEqual(vars(ns3), {'y': 2, 'x': 1})
1198
1199    def test_unbound(self):
1200        ns1 = vars(types.SimpleNamespace())
1201        ns2 = vars(types.SimpleNamespace(x=1, y=2))
1202
1203        self.assertEqual(ns1, {})
1204        self.assertEqual(ns2, {'y': 2, 'x': 1})
1205
1206    def test_underlying_dict(self):
1207        ns1 = types.SimpleNamespace()
1208        ns2 = types.SimpleNamespace(x=1, y=2)
1209        ns3 = types.SimpleNamespace(a=True, b=False)
1210        mapping = ns3.__dict__
1211        del ns3
1212
1213        self.assertEqual(ns1.__dict__, {})
1214        self.assertEqual(ns2.__dict__, {'y': 2, 'x': 1})
1215        self.assertEqual(mapping, dict(a=True, b=False))
1216
1217    def test_attrget(self):
1218        ns = types.SimpleNamespace(x=1, y=2, w=3)
1219
1220        self.assertEqual(ns.x, 1)
1221        self.assertEqual(ns.y, 2)
1222        self.assertEqual(ns.w, 3)
1223        with self.assertRaises(AttributeError):
1224            ns.z
1225
1226    def test_attrset(self):
1227        ns1 = types.SimpleNamespace()
1228        ns2 = types.SimpleNamespace(x=1, y=2, w=3)
1229        ns1.a = 'spam'
1230        ns1.b = 'ham'
1231        ns2.z = 4
1232        ns2.theta = None
1233
1234        self.assertEqual(ns1.__dict__, dict(a='spam', b='ham'))
1235        self.assertEqual(ns2.__dict__, dict(x=1, y=2, w=3, z=4, theta=None))
1236
1237    def test_attrdel(self):
1238        ns1 = types.SimpleNamespace()
1239        ns2 = types.SimpleNamespace(x=1, y=2, w=3)
1240
1241        with self.assertRaises(AttributeError):
1242            del ns1.spam
1243        with self.assertRaises(AttributeError):
1244            del ns2.spam
1245
1246        del ns2.y
1247        self.assertEqual(vars(ns2), dict(w=3, x=1))
1248        ns2.y = 'spam'
1249        self.assertEqual(vars(ns2), dict(w=3, x=1, y='spam'))
1250        del ns2.y
1251        self.assertEqual(vars(ns2), dict(w=3, x=1))
1252
1253        ns1.spam = 5
1254        self.assertEqual(vars(ns1), dict(spam=5))
1255        del ns1.spam
1256        self.assertEqual(vars(ns1), {})
1257
1258    def test_repr(self):
1259        ns1 = types.SimpleNamespace(x=1, y=2, w=3)
1260        ns2 = types.SimpleNamespace()
1261        ns2.x = "spam"
1262        ns2._y = 5
1263        name = "namespace"
1264
1265        self.assertEqual(repr(ns1), "{name}(x=1, y=2, w=3)".format(name=name))
1266        self.assertEqual(repr(ns2), "{name}(x='spam', _y=5)".format(name=name))
1267
1268    def test_equal(self):
1269        ns1 = types.SimpleNamespace(x=1)
1270        ns2 = types.SimpleNamespace()
1271        ns2.x = 1
1272
1273        self.assertEqual(types.SimpleNamespace(), types.SimpleNamespace())
1274        self.assertEqual(ns1, ns2)
1275        self.assertNotEqual(ns2, types.SimpleNamespace())
1276
1277    def test_nested(self):
1278        ns1 = types.SimpleNamespace(a=1, b=2)
1279        ns2 = types.SimpleNamespace()
1280        ns3 = types.SimpleNamespace(x=ns1)
1281        ns2.spam = ns1
1282        ns2.ham = '?'
1283        ns2.spam = ns3
1284
1285        self.assertEqual(vars(ns1), dict(a=1, b=2))
1286        self.assertEqual(vars(ns2), dict(spam=ns3, ham='?'))
1287        self.assertEqual(ns2.spam, ns3)
1288        self.assertEqual(vars(ns3), dict(x=ns1))
1289        self.assertEqual(ns3.x.a, 1)
1290
1291    def test_recursive(self):
1292        ns1 = types.SimpleNamespace(c='cookie')
1293        ns2 = types.SimpleNamespace()
1294        ns3 = types.SimpleNamespace(x=1)
1295        ns1.spam = ns1
1296        ns2.spam = ns3
1297        ns3.spam = ns2
1298
1299        self.assertEqual(ns1.spam, ns1)
1300        self.assertEqual(ns1.spam.spam, ns1)
1301        self.assertEqual(ns1.spam.spam, ns1.spam)
1302        self.assertEqual(ns2.spam, ns3)
1303        self.assertEqual(ns3.spam, ns2)
1304        self.assertEqual(ns2.spam.spam, ns2)
1305
1306    def test_recursive_repr(self):
1307        ns1 = types.SimpleNamespace(c='cookie')
1308        ns2 = types.SimpleNamespace()
1309        ns3 = types.SimpleNamespace(x=1)
1310        ns1.spam = ns1
1311        ns2.spam = ns3
1312        ns3.spam = ns2
1313        name = "namespace"
1314        repr1 = "{name}(c='cookie', spam={name}(...))".format(name=name)
1315        repr2 = "{name}(spam={name}(x=1, spam={name}(...)))".format(name=name)
1316
1317        self.assertEqual(repr(ns1), repr1)
1318        self.assertEqual(repr(ns2), repr2)
1319
1320    def test_as_dict(self):
1321        ns = types.SimpleNamespace(spam='spamspamspam')
1322
1323        with self.assertRaises(TypeError):
1324            len(ns)
1325        with self.assertRaises(TypeError):
1326            iter(ns)
1327        with self.assertRaises(TypeError):
1328            'spam' in ns
1329        with self.assertRaises(TypeError):
1330            ns['spam']
1331
1332    def test_subclass(self):
1333        class Spam(types.SimpleNamespace):
1334            pass
1335
1336        spam = Spam(ham=8, eggs=9)
1337
1338        self.assertIs(type(spam), Spam)
1339        self.assertEqual(vars(spam), {'ham': 8, 'eggs': 9})
1340
1341    def test_pickle(self):
1342        ns = types.SimpleNamespace(breakfast="spam", lunch="spam")
1343
1344        for protocol in range(pickle.HIGHEST_PROTOCOL + 1):
1345            pname = "protocol {}".format(protocol)
1346            try:
1347                ns_pickled = pickle.dumps(ns, protocol)
1348            except TypeError as e:
1349                raise TypeError(pname) from e
1350            ns_roundtrip = pickle.loads(ns_pickled)
1351
1352            self.assertEqual(ns, ns_roundtrip, pname)
1353
1354    def test_fake_namespace_compare(self):
1355        # Issue #24257: Incorrect use of PyObject_IsInstance() caused
1356        # SystemError.
1357        class FakeSimpleNamespace(str):
1358            __class__ = types.SimpleNamespace
1359        self.assertFalse(types.SimpleNamespace() == FakeSimpleNamespace())
1360        self.assertTrue(types.SimpleNamespace() != FakeSimpleNamespace())
1361        with self.assertRaises(TypeError):
1362            types.SimpleNamespace() < FakeSimpleNamespace()
1363        with self.assertRaises(TypeError):
1364            types.SimpleNamespace() <= FakeSimpleNamespace()
1365        with self.assertRaises(TypeError):
1366            types.SimpleNamespace() > FakeSimpleNamespace()
1367        with self.assertRaises(TypeError):
1368            types.SimpleNamespace() >= FakeSimpleNamespace()
1369
1370
1371class CoroutineTests(unittest.TestCase):
1372    def test_wrong_args(self):
1373        samples = [None, 1, object()]
1374        for sample in samples:
1375            with self.assertRaisesRegex(TypeError,
1376                                        'types.coroutine.*expects a callable'):
1377                types.coroutine(sample)
1378
1379    def test_non_gen_values(self):
1380        @types.coroutine
1381        def foo():
1382            return 'spam'
1383        self.assertEqual(foo(), 'spam')
1384
1385        class Awaitable:
1386            def __await__(self):
1387                return ()
1388        aw = Awaitable()
1389        @types.coroutine
1390        def foo():
1391            return aw
1392        self.assertIs(aw, foo())
1393
1394        # decorate foo second time
1395        foo = types.coroutine(foo)
1396        self.assertIs(aw, foo())
1397
1398    def test_async_def(self):
1399        # Test that types.coroutine passes 'async def' coroutines
1400        # without modification
1401
1402        async def foo(): pass
1403        foo_code = foo.__code__
1404        foo_flags = foo.__code__.co_flags
1405        decorated_foo = types.coroutine(foo)
1406        self.assertIs(foo, decorated_foo)
1407        self.assertEqual(foo.__code__.co_flags, foo_flags)
1408        self.assertIs(decorated_foo.__code__, foo_code)
1409
1410        foo_coro = foo()
1411        def bar(): return foo_coro
1412        for _ in range(2):
1413            bar = types.coroutine(bar)
1414            coro = bar()
1415            self.assertIs(foo_coro, coro)
1416            self.assertEqual(coro.cr_code.co_flags, foo_flags)
1417            coro.close()
1418
1419    def test_duck_coro(self):
1420        class CoroLike:
1421            def send(self): pass
1422            def throw(self): pass
1423            def close(self): pass
1424            def __await__(self): return self
1425
1426        coro = CoroLike()
1427        @types.coroutine
1428        def foo():
1429            return coro
1430        self.assertIs(foo(), coro)
1431        self.assertIs(foo().__await__(), coro)
1432
1433    def test_duck_corogen(self):
1434        class CoroGenLike:
1435            def send(self): pass
1436            def throw(self): pass
1437            def close(self): pass
1438            def __await__(self): return self
1439            def __iter__(self): return self
1440            def __next__(self): pass
1441
1442        coro = CoroGenLike()
1443        @types.coroutine
1444        def foo():
1445            return coro
1446        self.assertIs(foo(), coro)
1447        self.assertIs(foo().__await__(), coro)
1448
1449    def test_duck_gen(self):
1450        class GenLike:
1451            def send(self): pass
1452            def throw(self): pass
1453            def close(self): pass
1454            def __iter__(self): pass
1455            def __next__(self): pass
1456
1457        # Setup generator mock object
1458        gen = unittest.mock.MagicMock(GenLike)
1459        gen.__iter__ = lambda gen: gen
1460        gen.__name__ = 'gen'
1461        gen.__qualname__ = 'test.gen'
1462        self.assertIsInstance(gen, collections.abc.Generator)
1463        self.assertIs(gen, iter(gen))
1464
1465        @types.coroutine
1466        def foo(): return gen
1467
1468        wrapper = foo()
1469        self.assertIsInstance(wrapper, types._GeneratorWrapper)
1470        self.assertIs(wrapper.__await__(), wrapper)
1471        # Wrapper proxies duck generators completely:
1472        self.assertIs(iter(wrapper), wrapper)
1473
1474        self.assertIsInstance(wrapper, collections.abc.Coroutine)
1475        self.assertIsInstance(wrapper, collections.abc.Awaitable)
1476
1477        self.assertIs(wrapper.__qualname__, gen.__qualname__)
1478        self.assertIs(wrapper.__name__, gen.__name__)
1479
1480        # Test AttributeErrors
1481        for name in {'gi_running', 'gi_frame', 'gi_code', 'gi_yieldfrom',
1482                     'cr_running', 'cr_frame', 'cr_code', 'cr_await'}:
1483            with self.assertRaises(AttributeError):
1484                getattr(wrapper, name)
1485
1486        # Test attributes pass-through
1487        gen.gi_running = object()
1488        gen.gi_frame = object()
1489        gen.gi_code = object()
1490        gen.gi_yieldfrom = object()
1491        self.assertIs(wrapper.gi_running, gen.gi_running)
1492        self.assertIs(wrapper.gi_frame, gen.gi_frame)
1493        self.assertIs(wrapper.gi_code, gen.gi_code)
1494        self.assertIs(wrapper.gi_yieldfrom, gen.gi_yieldfrom)
1495        self.assertIs(wrapper.cr_running, gen.gi_running)
1496        self.assertIs(wrapper.cr_frame, gen.gi_frame)
1497        self.assertIs(wrapper.cr_code, gen.gi_code)
1498        self.assertIs(wrapper.cr_await, gen.gi_yieldfrom)
1499
1500        wrapper.close()
1501        gen.close.assert_called_once_with()
1502
1503        wrapper.send(1)
1504        gen.send.assert_called_once_with(1)
1505        gen.reset_mock()
1506
1507        next(wrapper)
1508        gen.__next__.assert_called_once_with()
1509        gen.reset_mock()
1510
1511        wrapper.throw(1, 2, 3)
1512        gen.throw.assert_called_once_with(1, 2, 3)
1513        gen.reset_mock()
1514
1515        wrapper.throw(1, 2)
1516        gen.throw.assert_called_once_with(1, 2)
1517        gen.reset_mock()
1518
1519        wrapper.throw(1)
1520        gen.throw.assert_called_once_with(1)
1521        gen.reset_mock()
1522
1523        # Test exceptions propagation
1524        error = Exception()
1525        gen.throw.side_effect = error
1526        try:
1527            wrapper.throw(1)
1528        except Exception as ex:
1529            self.assertIs(ex, error)
1530        else:
1531            self.fail('wrapper did not propagate an exception')
1532
1533        # Test invalid args
1534        gen.reset_mock()
1535        with self.assertRaises(TypeError):
1536            wrapper.throw()
1537        self.assertFalse(gen.throw.called)
1538        with self.assertRaises(TypeError):
1539            wrapper.close(1)
1540        self.assertFalse(gen.close.called)
1541        with self.assertRaises(TypeError):
1542            wrapper.send()
1543        self.assertFalse(gen.send.called)
1544
1545        # Test that we do not double wrap
1546        @types.coroutine
1547        def bar(): return wrapper
1548        self.assertIs(wrapper, bar())
1549
1550        # Test weakrefs support
1551        ref = weakref.ref(wrapper)
1552        self.assertIs(ref(), wrapper)
1553
1554    def test_duck_functional_gen(self):
1555        class Generator:
1556            """Emulates the following generator (very clumsy):
1557
1558              def gen(fut):
1559                  result = yield fut
1560                  return result * 2
1561            """
1562            def __init__(self, fut):
1563                self._i = 0
1564                self._fut = fut
1565            def __iter__(self):
1566                return self
1567            def __next__(self):
1568                return self.send(None)
1569            def send(self, v):
1570                try:
1571                    if self._i == 0:
1572                        assert v is None
1573                        return self._fut
1574                    if self._i == 1:
1575                        raise StopIteration(v * 2)
1576                    if self._i > 1:
1577                        raise StopIteration
1578                finally:
1579                    self._i += 1
1580            def throw(self, tp, *exc):
1581                self._i = 100
1582                if tp is not GeneratorExit:
1583                    raise tp
1584            def close(self):
1585                self.throw(GeneratorExit)
1586
1587        @types.coroutine
1588        def foo(): return Generator('spam')
1589
1590        wrapper = foo()
1591        self.assertIsInstance(wrapper, types._GeneratorWrapper)
1592
1593        async def corofunc():
1594            return await foo() + 100
1595        coro = corofunc()
1596
1597        self.assertEqual(coro.send(None), 'spam')
1598        try:
1599            coro.send(20)
1600        except StopIteration as ex:
1601            self.assertEqual(ex.args[0], 140)
1602        else:
1603            self.fail('StopIteration was expected')
1604
1605    def test_gen(self):
1606        def gen_func():
1607            yield 1
1608            return (yield 2)
1609        gen = gen_func()
1610        @types.coroutine
1611        def foo(): return gen
1612        wrapper = foo()
1613        self.assertIsInstance(wrapper, types._GeneratorWrapper)
1614        self.assertIs(wrapper.__await__(), gen)
1615
1616        for name in ('__name__', '__qualname__', 'gi_code',
1617                     'gi_running', 'gi_frame'):
1618            self.assertIs(getattr(foo(), name),
1619                          getattr(gen, name))
1620        self.assertIs(foo().cr_code, gen.gi_code)
1621
1622        self.assertEqual(next(wrapper), 1)
1623        self.assertEqual(wrapper.send(None), 2)
1624        with self.assertRaisesRegex(StopIteration, 'spam'):
1625            wrapper.send('spam')
1626
1627        gen = gen_func()
1628        wrapper = foo()
1629        wrapper.send(None)
1630        with self.assertRaisesRegex(Exception, 'ham'):
1631            wrapper.throw(Exception, Exception('ham'))
1632
1633        # decorate foo second time
1634        foo = types.coroutine(foo)
1635        self.assertIs(foo().__await__(), gen)
1636
1637    def test_returning_itercoro(self):
1638        @types.coroutine
1639        def gen():
1640            yield
1641
1642        gencoro = gen()
1643
1644        @types.coroutine
1645        def foo():
1646            return gencoro
1647
1648        self.assertIs(foo(), gencoro)
1649
1650        # decorate foo second time
1651        foo = types.coroutine(foo)
1652        self.assertIs(foo(), gencoro)
1653
1654    def test_genfunc(self):
1655        def gen(): yield
1656        self.assertIs(types.coroutine(gen), gen)
1657        self.assertIs(types.coroutine(types.coroutine(gen)), gen)
1658
1659        self.assertTrue(gen.__code__.co_flags & inspect.CO_ITERABLE_COROUTINE)
1660        self.assertFalse(gen.__code__.co_flags & inspect.CO_COROUTINE)
1661
1662        g = gen()
1663        self.assertTrue(g.gi_code.co_flags & inspect.CO_ITERABLE_COROUTINE)
1664        self.assertFalse(g.gi_code.co_flags & inspect.CO_COROUTINE)
1665
1666        self.assertIs(types.coroutine(gen), gen)
1667
1668    def test_wrapper_object(self):
1669        def gen():
1670            yield
1671        @types.coroutine
1672        def coro():
1673            return gen()
1674
1675        wrapper = coro()
1676        self.assertIn('GeneratorWrapper', repr(wrapper))
1677        self.assertEqual(repr(wrapper), str(wrapper))
1678        self.assertTrue(set(dir(wrapper)).issuperset({
1679            '__await__', '__iter__', '__next__', 'cr_code', 'cr_running',
1680            'cr_frame', 'gi_code', 'gi_frame', 'gi_running', 'send',
1681            'close', 'throw'}))
1682
1683
1684if __name__ == '__main__':
1685    unittest.main()
1686