blob: 966ef6d8782575c48941edd18a92424a7be2ba22 [file] [log] [blame]
Guido van Rossum85f18201992-11-27 22:53:50 +00001# Python test set -- part 6, built-in types
2
Zachary Ware38c707e2015-04-13 15:00:43 -05003from test.support import run_with_locale
Yury Selivanov75445082015-05-11 22:57:16 -04004import collections.abc
5import inspect
Eric Snowb5c8f922013-02-16 16:32:39 -07006import pickle
Eric Smithb2c7af82008-04-30 02:12:09 +00007import locale
Victor Stinner0db176f2012-04-16 00:16:30 +02008import sys
9import types
Yury Selivanov00e33722015-06-24 11:44:51 -040010import unittest.mock
11import weakref
Guido van Rossum85f18201992-11-27 22:53:50 +000012
Thomas Wouters89f507f2006-12-13 04:49:30 +000013class TypesTests(unittest.TestCase):
Guido van Rossum85f18201992-11-27 22:53:50 +000014
Thomas Wouters89f507f2006-12-13 04:49:30 +000015 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')
Thomas Wouters89f507f2006-12-13 04:49:30 +000018 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')
Thomas Wouters89f507f2006-12-13 04:49:30 +000021 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
Thomas Wouters89f507f2006-12-13 04:49:30 +000026 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')
Guido van Rossum85f18201992-11-27 22:53:50 +000031
Thomas Wouters89f507f2006-12-13 04:49:30 +000032 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')
Neil Schemenauereff72442002-03-24 01:24:54 +000037
Thomas Wouters89f507f2006-12-13 04:49:30 +000038 def test_comparisons(self):
39 if 0 < 1 <= 1 == 1 >= 1 > 0 != 1: pass
40 else: self.fail('int comparisons failed')
Thomas Wouters89f507f2006-12-13 04:49:30 +000041 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')
Neil Schemenauereff72442002-03-24 01:24:54 +000047
Thomas Wouters89f507f2006-12-13 04:49:30 +000048 def test_float_constructor(self):
49 self.assertRaises(ValueError, float, '')
50 self.assertRaises(ValueError, float, '5\0')
Brett Cannona721aba2016-09-09 14:57:09 -070051 self.assertRaises(ValueError, float, '5_5\0')
Neil Schemenauereff72442002-03-24 01:24:54 +000052
Thomas Wouters89f507f2006-12-13 04:49:30 +000053 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")
Neil Schemenauereff72442002-03-24 01:24:54 +000057
Thomas Wouters89f507f2006-12-13 04:49:30 +000058 try: 5.0 // 0.0
59 except ZeroDivisionError: pass
60 else: self.fail("5.0 // 0.0 didn't raise ZeroDivisionError")
Neil Schemenauereff72442002-03-24 01:24:54 +000061
Thomas Wouters89f507f2006-12-13 04:49:30 +000062 try: 5.0 % 0.0
63 except ZeroDivisionError: pass
64 else: self.fail("5.0 % 0.0 didn't raise ZeroDivisionError")
Neil Schemenauereff72442002-03-24 01:24:54 +000065
Guido van Rossume2a383d2007-01-15 16:59:06 +000066 try: 5 / 0
Thomas Wouters89f507f2006-12-13 04:49:30 +000067 except ZeroDivisionError: pass
Christian Heimes7131fd92008-02-19 14:21:46 +000068 else: self.fail("5 / 0 didn't raise ZeroDivisionError")
Neil Schemenauereff72442002-03-24 01:24:54 +000069
Guido van Rossume2a383d2007-01-15 16:59:06 +000070 try: 5 // 0
Thomas Wouters89f507f2006-12-13 04:49:30 +000071 except ZeroDivisionError: pass
Christian Heimes7131fd92008-02-19 14:21:46 +000072 else: self.fail("5 // 0 didn't raise ZeroDivisionError")
Neil Schemenauereff72442002-03-24 01:24:54 +000073
Guido van Rossume2a383d2007-01-15 16:59:06 +000074 try: 5 % 0
Thomas Wouters89f507f2006-12-13 04:49:30 +000075 except ZeroDivisionError: pass
Christian Heimes7131fd92008-02-19 14:21:46 +000076 else: self.fail("5 % 0 didn't raise ZeroDivisionError")
Tim Petersa3c01ce2001-12-04 23:05:10 +000077
Thomas Wouters89f507f2006-12-13 04:49:30 +000078 def test_numeric_types(self):
Mark Dickinson5c2db372009-12-05 20:28:34 +000079 if 0 != 0.0 or 1 != 1.0 or -1 != -1.0:
80 self.fail('int/float value not equal')
Thomas Wouters89f507f2006-12-13 04:49:30 +000081 # calling built-in types without argument must return 0
82 if int() != 0: self.fail('int() does not return 0')
Thomas Wouters89f507f2006-12-13 04:49:30 +000083 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')
Thomas Wouters89f507f2006-12-13 04:49:30 +000086 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')
Neil Schemenauereff72442002-03-24 01:24:54 +000088
Christian Heimesc3f30c42008-02-22 16:37:40 +000089 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
Eric Smith0923d1d2009-04-16 20:16:10 +0000112 self.assertEqual('%g' % 1.0, '1')
113 self.assertEqual('%#g' % 1.0, '1.00000')
114
Thomas Wouters89f507f2006-12-13 04:49:30 +0000115 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.
Christian Heimesa37d4c62007-12-04 23:02:19 +0000131 m = -sys.maxsize - 1
Thomas Wouters89f507f2006-12-13 04:49:30 +0000132 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))
Mark Dickinson5c2db372009-12-05 20:28:34 +0000140 # Check for unified integral type
Thomas Wouters89f507f2006-12-13 04:49:30 +0000141 for divisor in 1, 2, 4, 8, 16, 32:
142 j = m // divisor - 1
143 prod = divisor * j
Guido van Rossume2a383d2007-01-15 16:59:06 +0000144 if type(prod) is not int:
Mark Dickinson5c2db372009-12-05 20:28:34 +0000145 self.fail("expected type(%r) to be int, not %r" %
Thomas Wouters89f507f2006-12-13 04:49:30 +0000146 (prod, type(prod)))
Mark Dickinson5c2db372009-12-05 20:28:34 +0000147 # Check for unified integral type
Christian Heimesa37d4c62007-12-04 23:02:19 +0000148 m = sys.maxsize
Thomas Wouters89f507f2006-12-13 04:49:30 +0000149 for divisor in 1, 2, 4, 8, 16, 32:
150 j = m // divisor + 1
151 prod = divisor * j
Guido van Rossume2a383d2007-01-15 16:59:06 +0000152 if type(prod) is not int:
Mark Dickinson5c2db372009-12-05 20:28:34 +0000153 self.fail("expected type(%r) to be int, not %r" %
Thomas Wouters89f507f2006-12-13 04:49:30 +0000154 (prod, type(prod)))
Neil Schemenauereff72442002-03-24 01:24:54 +0000155
Christian Heimesa37d4c62007-12-04 23:02:19 +0000156 x = sys.maxsize
Ezio Melottie9615932010-01-24 19:26:24 +0000157 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")
Neil Schemenauereff72442002-03-24 01:24:54 +0000163
Thomas Wouters89f507f2006-12-13 04:49:30 +0000164 try: 5 << -5
165 except ValueError: pass
166 else: self.fail('int negative shift <<')
Neil Schemenauereff72442002-03-24 01:24:54 +0000167
Thomas Wouters89f507f2006-12-13 04:49:30 +0000168 try: 5 >> -5
169 except ValueError: pass
170 else: self.fail('int negative shift >>')
Guido van Rossum85f18201992-11-27 22:53:50 +0000171
Thomas Wouters89f507f2006-12-13 04:49:30 +0000172 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')
Guido van Rossum85f18201992-11-27 22:53:50 +0000179
Thomas Wouters89f507f2006-12-13 04:49:30 +0000180 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')
Michael W. Hudson5efaf7e2002-06-11 10:55:12 +0000192
Thomas Wouters89f507f2006-12-13 04:49:30 +0000193 #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])
Guido van Rossume2a383d2007-01-15 16:59:06 +0000203 self.assertEqual(a[-100:100:2], '02468')
Thomas Wouters89f507f2006-12-13 04:49:30 +0000204
Thomas Wouters89f507f2006-12-13 04:49:30 +0000205 def test_type_function(self):
206 self.assertRaises(TypeError, type, 1, 2)
207 self.assertRaises(TypeError, type, 1, 2, 3, 4)
Guido van Rossum85f18201992-11-27 22:53:50 +0000208
Christian Heimes7131fd92008-02-19 14:21:46 +0000209 def test_int__format__(self):
210 def test(i, format_spec, result):
Mark Dickinson5c2db372009-12-05 20:28:34 +0000211 # just make sure we have the unified type for integers
Christian Heimes7131fd92008-02-19 14:21:46 +0000212 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
Eric Smithb1ebcc62008-07-15 13:02:41 +0000275 # 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')
Eric Smithd68af8f2008-07-16 00:15:35 +0000283 test(100, "#012b", '0b0001100100')
284 test(-100, "#012b", '-0b001100100')
Eric Smithb1ebcc62008-07-15 13:02:41 +0000285
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')
Eric Smithd68af8f2008-07-16 00:15:35 +0000293 test(100, "#012o", '0o0000000144')
294 test(-100, "#012o", '-0o000000144')
Eric Smithb1ebcc62008-07-15 13:02:41 +0000295
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')
Eric Smithd68af8f2008-07-16 00:15:35 +0000303 test(100, "#012x", '0x0000000064')
304 test(-100, "#012x", '-0x000000064')
305 test(123456, "#012x", '0x000001e240')
306 test(-123456, "#012x", '-0x00001e240')
Eric Smithb1ebcc62008-07-15 13:02:41 +0000307
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')
Eric Smithd68af8f2008-07-16 00:15:35 +0000315 test(100, "#012X", '0X0000000064')
316 test(-100, "#012X", '-0X000000064')
317 test(123456, "#012X", '0X000001E240')
318 test(-123456, "#012X", '-0X00001E240')
Eric Smithb1ebcc62008-07-15 13:02:41 +0000319
Eric Smitha3b1ac82009-04-03 14:45:06 +0000320 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
Eric Smith937491d2009-04-22 17:04:27 +0000329 # issue 5782, commas with no specifier type
330 test(1234, '010,', '00,001,234')
331
Mark Dickinson5c2db372009-12-05 20:28:34 +0000332 # Unified type for integers
333 test(10**100, 'd', '1' + '0' * 100)
334 test(10**100+100, 'd', '1' + '0' * 97 + '100')
335
Christian Heimes7131fd92008-02-19 14:21:46 +0000336 # 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)
Eric Smitha3b1ac82009-04-03 14:45:06 +0000345 # can't have ',' with 'n'
346 self.assertRaises(ValueError, 3 .__format__, ",n")
Eric Smith0923d1d2009-04-16 20:16:10 +0000347 # can't have ',' with 'c'
348 self.assertRaises(ValueError, 3 .__format__, ",c")
Eric V. Smitha12572f2014-04-15 22:37:55 -0400349 # can't have '#' with 'c'
350 self.assertRaises(ValueError, 3 .__format__, "#c")
Christian Heimes7131fd92008-02-19 14:21:46 +0000351
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
Eric Smith5807c412008-05-11 21:00:57 +0000362 for format_spec in 'eEfFgG%':
Christian Heimes7131fd92008-02-19 14:21:46 +0000363 for value in [0, 1, -1, 100, -100, 1234567890, -1234567890]:
364 self.assertEqual(value.__format__(format_spec),
365 float(value).__format__(format_spec))
366
Eric Smithabb28c62010-02-23 00:22:24 +0000367 # 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
Eric Smithb2c7af82008-04-30 02:12:09 +0000378 @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)
Garvit Khatri1cf93a72017-03-28 23:43:38 +0800384 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'))
Eric Smithb2c7af82008-04-30 02:12:09 +0000386
Eric Smith5807c412008-05-11 21:00:57 +0000387 @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):
Garvit Khatri1cf93a72017-03-28 23:43:38 +0800393 self.assertEqual(locale.format_string('%d', x, grouping=True), format(x, 'n'))
Eric Smith5807c412008-05-11 21:00:57 +0000394
395 # move to the next integer to test
396 x = x // 10
397
Eric Smithb151a452008-06-24 11:21:04 +0000398 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
Christian Heimes7131fd92008-02-19 14:21:46 +0000406 def test_float__format__(self):
Christian Heimes7131fd92008-02-19 14:21:46 +0000407 def test(f, format_spec, result):
Christian Heimes7131fd92008-02-19 14:21:46 +0000408 self.assertEqual(f.__format__(format_spec), result)
Eric Smith984bb582010-11-25 16:08:06 +0000409 self.assertEqual(format(f, format_spec), result)
Christian Heimes7131fd92008-02-19 14:21:46 +0000410
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
Eric Smith2ad79e82008-07-19 00:33:23 +0000418 # 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
Christian Heimes7131fd92008-02-19 14:21:46 +0000424 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')
Mark Dickinson33841c32009-05-01 15:37:04 +0000440
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], '.')
Benjamin Peterson577473f2010-01-19 00:09:57 +0000451 self.assertIn(result[:12], ('112340000000', '112339999999'))
Mark Dickinson33841c32009-05-01 15:37:04 +0000452 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], '.')
Benjamin Peterson577473f2010-01-19 00:09:57 +0000457 self.assertIn(result[:12], ('112340000000', '112339999999'))
Mark Dickinson33841c32009-05-01 15:37:04 +0000458
Christian Heimes7131fd92008-02-19 14:21:46 +0000459
Christian Heimesc3f30c42008-02-22 16:37:40 +0000460 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')
Christian Heimes7131fd92008-02-19 14:21:46 +0000466
Christian Heimesb186d002008-03-18 15:15:01 +0000467 # No format code means use g, but must have a decimal
468 # and a number after the decimal. This is tricky, because
469 # a totaly empty format specifier means something else.
470 # So, just use a sign flag
471 test(1e200, '+g', '+1e+200')
Eric Smith0923d1d2009-04-16 20:16:10 +0000472 test(1e200, '+', '+1e+200')
473
Christian Heimesb186d002008-03-18 15:15:01 +0000474 test(1.1e200, '+g', '+1.1e+200')
475 test(1.1e200, '+', '+1.1e+200')
476
Eric Smith0923d1d2009-04-16 20:16:10 +0000477 # 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
Eric Smith937491d2009-04-22 17:04:27 +0000487 # issue 5782, commas with no specifier type
488 test(1.2, '010,.2', '0,000,001.2')
489
Eric Smith0923d1d2009-04-16 20:16:10 +0000490 # 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
Christian Heimes7131fd92008-02-19 14:21:46 +0000503 # % 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
Eric Smith984bb582010-11-25 16:08:06 +0000523 # 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%')
Eric Smithb1ebcc62008-07-15 13:02:41 +0000544
Eric Smithabb28c62010-02-23 00:22:24 +0000545 # 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
Eric Smith0923d1d2009-04-16 20:16:10 +0000556 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)
Christian Heimes7131fd92008-02-19 14:21:46 +0000574
Benjamin Peterson0e102062010-08-25 23:13:17 +0000575 def test_internal_sizes(self):
576 self.assertGreater(object.__basicsize__, 0)
577 self.assertGreater(tuple.__itemsize__, 0)
578
Guido van Rossum934aba62017-02-01 10:55:58 -0800579 def test_slot_wrapper_types(self):
Jim Fasarakis-Hilliard08c16012017-04-25 21:26:36 +0300580 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)
Guido van Rossum934aba62017-02-01 10:55:58 -0800584
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
Benjamin Peterson0e102062010-08-25 23:13:17 +0000597
Victor Stinner0db176f2012-04-16 00:16:30 +0200598class MappingProxyTests(unittest.TestCase):
599 mappingproxy = types.MappingProxyType
600
601 def test_constructor(self):
602 class userdict(dict):
603 pass
604
605 mapping = {'x': 1, 'y': 2}
606 self.assertEqual(self.mappingproxy(mapping), mapping)
607 mapping = userdict(x=1, y=2)
608 self.assertEqual(self.mappingproxy(mapping), mapping)
609 mapping = collections.ChainMap({'x': 1}, {'y': 2})
610 self.assertEqual(self.mappingproxy(mapping), mapping)
611
612 self.assertRaises(TypeError, self.mappingproxy, 10)
613 self.assertRaises(TypeError, self.mappingproxy, ("a", "tuple"))
614 self.assertRaises(TypeError, self.mappingproxy, ["a", "list"])
615
616 def test_methods(self):
617 attrs = set(dir(self.mappingproxy({}))) - set(dir(object()))
618 self.assertEqual(attrs, {
619 '__contains__',
620 '__getitem__',
621 '__iter__',
622 '__len__',
623 'copy',
624 'get',
625 'items',
626 'keys',
627 'values',
628 })
629
630 def test_get(self):
631 view = self.mappingproxy({'a': 'A', 'b': 'B'})
632 self.assertEqual(view['a'], 'A')
633 self.assertEqual(view['b'], 'B')
634 self.assertRaises(KeyError, view.__getitem__, 'xxx')
635 self.assertEqual(view.get('a'), 'A')
636 self.assertIsNone(view.get('xxx'))
637 self.assertEqual(view.get('xxx', 42), 42)
638
639 def test_missing(self):
640 class dictmissing(dict):
641 def __missing__(self, key):
642 return "missing=%s" % key
643
644 view = self.mappingproxy(dictmissing(x=1))
645 self.assertEqual(view['x'], 1)
646 self.assertEqual(view['y'], 'missing=y')
647 self.assertEqual(view.get('x'), 1)
648 self.assertEqual(view.get('y'), None)
649 self.assertEqual(view.get('y', 42), 42)
650 self.assertTrue('x' in view)
651 self.assertFalse('y' in view)
652
653 def test_customdict(self):
654 class customdict(dict):
655 def __contains__(self, key):
656 if key == 'magic':
657 return True
658 else:
659 return dict.__contains__(self, key)
660
661 def __iter__(self):
662 return iter(('iter',))
663
664 def __len__(self):
665 return 500
666
667 def copy(self):
668 return 'copy'
669
670 def keys(self):
671 return 'keys'
672
673 def items(self):
674 return 'items'
675
676 def values(self):
677 return 'values'
678
679 def __getitem__(self, key):
680 return "getitem=%s" % dict.__getitem__(self, key)
681
682 def get(self, key, default=None):
683 return "get=%s" % dict.get(self, key, 'default=%r' % default)
684
685 custom = customdict({'key': 'value'})
686 view = self.mappingproxy(custom)
687 self.assertTrue('key' in view)
688 self.assertTrue('magic' in view)
689 self.assertFalse('xxx' in view)
690 self.assertEqual(view['key'], 'getitem=value')
691 self.assertRaises(KeyError, view.__getitem__, 'xxx')
692 self.assertEqual(tuple(view), ('iter',))
693 self.assertEqual(len(view), 500)
694 self.assertEqual(view.copy(), 'copy')
695 self.assertEqual(view.get('key'), 'get=value')
696 self.assertEqual(view.get('xxx'), 'get=default=None')
697 self.assertEqual(view.items(), 'items')
698 self.assertEqual(view.keys(), 'keys')
699 self.assertEqual(view.values(), 'values')
700
701 def test_chainmap(self):
702 d1 = {'x': 1}
703 d2 = {'y': 2}
704 mapping = collections.ChainMap(d1, d2)
705 view = self.mappingproxy(mapping)
706 self.assertTrue('x' in view)
707 self.assertTrue('y' in view)
708 self.assertFalse('z' in view)
709 self.assertEqual(view['x'], 1)
710 self.assertEqual(view['y'], 2)
711 self.assertRaises(KeyError, view.__getitem__, 'z')
712 self.assertEqual(tuple(sorted(view)), ('x', 'y'))
713 self.assertEqual(len(view), 2)
714 copy = view.copy()
715 self.assertIsNot(copy, mapping)
716 self.assertIsInstance(copy, collections.ChainMap)
717 self.assertEqual(copy, mapping)
718 self.assertEqual(view.get('x'), 1)
719 self.assertEqual(view.get('y'), 2)
720 self.assertIsNone(view.get('z'))
721 self.assertEqual(tuple(sorted(view.items())), (('x', 1), ('y', 2)))
722 self.assertEqual(tuple(sorted(view.keys())), ('x', 'y'))
723 self.assertEqual(tuple(sorted(view.values())), (1, 2))
724
725 def test_contains(self):
726 view = self.mappingproxy(dict.fromkeys('abc'))
727 self.assertTrue('a' in view)
728 self.assertTrue('b' in view)
729 self.assertTrue('c' in view)
730 self.assertFalse('xxx' in view)
731
732 def test_views(self):
733 mapping = {}
734 view = self.mappingproxy(mapping)
735 keys = view.keys()
736 values = view.values()
737 items = view.items()
738 self.assertEqual(list(keys), [])
739 self.assertEqual(list(values), [])
740 self.assertEqual(list(items), [])
741 mapping['key'] = 'value'
742 self.assertEqual(list(keys), ['key'])
743 self.assertEqual(list(values), ['value'])
744 self.assertEqual(list(items), [('key', 'value')])
745
746 def test_len(self):
747 for expected in range(6):
748 data = dict.fromkeys('abcde'[:expected])
749 self.assertEqual(len(data), expected)
750 view = self.mappingproxy(data)
751 self.assertEqual(len(view), expected)
752
753 def test_iterators(self):
754 keys = ('x', 'y')
755 values = (1, 2)
756 items = tuple(zip(keys, values))
757 view = self.mappingproxy(dict(items))
758 self.assertEqual(set(view), set(keys))
759 self.assertEqual(set(view.keys()), set(keys))
760 self.assertEqual(set(view.values()), set(values))
761 self.assertEqual(set(view.items()), set(items))
762
763 def test_copy(self):
764 original = {'key1': 27, 'key2': 51, 'key3': 93}
765 view = self.mappingproxy(original)
766 copy = view.copy()
767 self.assertEqual(type(copy), dict)
768 self.assertEqual(copy, original)
769 original['key1'] = 70
770 self.assertEqual(view['key1'], 70)
771 self.assertEqual(copy['key1'], 27)
772
773
Nick Coghlan7fc570a2012-05-20 02:34:13 +1000774class ClassCreationTests(unittest.TestCase):
775
776 class Meta(type):
777 def __init__(cls, name, bases, ns, **kw):
778 super().__init__(name, bases, ns)
779 @staticmethod
780 def __new__(mcls, name, bases, ns, **kw):
781 return super().__new__(mcls, name, bases, ns)
782 @classmethod
783 def __prepare__(mcls, name, bases, **kw):
784 ns = super().__prepare__(name, bases)
785 ns["y"] = 1
786 ns.update(kw)
787 return ns
788
789 def test_new_class_basics(self):
790 C = types.new_class("C")
791 self.assertEqual(C.__name__, "C")
792 self.assertEqual(C.__bases__, (object,))
793
794 def test_new_class_subclass(self):
795 C = types.new_class("C", (int,))
796 self.assertTrue(issubclass(C, int))
797
798 def test_new_class_meta(self):
799 Meta = self.Meta
800 settings = {"metaclass": Meta, "z": 2}
801 # We do this twice to make sure the passed in dict isn't mutated
802 for i in range(2):
803 C = types.new_class("C" + str(i), (), settings)
804 self.assertIsInstance(C, Meta)
805 self.assertEqual(C.y, 1)
806 self.assertEqual(C.z, 2)
807
808 def test_new_class_exec_body(self):
809 Meta = self.Meta
810 def func(ns):
811 ns["x"] = 0
812 C = types.new_class("C", (), {"metaclass": Meta, "z": 2}, func)
813 self.assertIsInstance(C, Meta)
814 self.assertEqual(C.x, 0)
815 self.assertEqual(C.y, 1)
816 self.assertEqual(C.z, 2)
817
Benjamin Peterson43f8f4c2012-09-27 18:10:17 -0400818 def test_new_class_metaclass_keywords(self):
Nick Coghlan7fc570a2012-05-20 02:34:13 +1000819 #Test that keywords are passed to the metaclass:
820 def meta_func(name, bases, ns, **kw):
821 return name, bases, ns, kw
822 res = types.new_class("X",
823 (int, object),
824 dict(metaclass=meta_func, x=0))
825 self.assertEqual(res, ("X", (int, object), {}, {"x": 0}))
826
827 def test_new_class_defaults(self):
828 # Test defaults/keywords:
829 C = types.new_class("C", (), {}, None)
830 self.assertEqual(C.__name__, "C")
831 self.assertEqual(C.__bases__, (object,))
832
833 def test_new_class_meta_with_base(self):
834 Meta = self.Meta
835 def func(ns):
836 ns["x"] = 0
837 C = types.new_class(name="C",
838 bases=(int,),
839 kwds=dict(metaclass=Meta, z=2),
840 exec_body=func)
841 self.assertTrue(issubclass(C, int))
842 self.assertIsInstance(C, Meta)
843 self.assertEqual(C.x, 0)
844 self.assertEqual(C.y, 1)
845 self.assertEqual(C.z, 2)
846
847 # Many of the following tests are derived from test_descr.py
848 def test_prepare_class(self):
849 # Basic test of metaclass derivation
850 expected_ns = {}
851 class A(type):
852 def __new__(*args, **kwargs):
853 return type.__new__(*args, **kwargs)
854
855 def __prepare__(*args):
856 return expected_ns
857
858 B = types.new_class("B", (object,))
859 C = types.new_class("C", (object,), {"metaclass": A})
860
861 # The most derived metaclass of D is A rather than type.
862 meta, ns, kwds = types.prepare_class("D", (B, C), {"metaclass": type})
863 self.assertIs(meta, A)
864 self.assertIs(ns, expected_ns)
865 self.assertEqual(len(kwds), 0)
866
Oren Milman5837d042017-09-27 17:04:37 +0300867 def test_bad___prepare__(self):
868 # __prepare__() must return a mapping.
869 class BadMeta(type):
870 @classmethod
871 def __prepare__(*args):
872 return None
873 with self.assertRaisesRegex(TypeError,
874 r'^BadMeta\.__prepare__\(\) must '
875 r'return a mapping, not NoneType$'):
876 class Foo(metaclass=BadMeta):
877 pass
878 # Also test the case in which the metaclass is not a type.
879 class BadMeta:
880 @classmethod
881 def __prepare__(*args):
882 return None
883 with self.assertRaisesRegex(TypeError,
884 r'^<metaclass>\.__prepare__\(\) must '
885 r'return a mapping, not NoneType$'):
886 class Bar(metaclass=BadMeta()):
887 pass
888
Nick Coghlan7fc570a2012-05-20 02:34:13 +1000889 def test_metaclass_derivation(self):
890 # issue1294232: correct metaclass calculation
891 new_calls = [] # to check the order of __new__ calls
892 class AMeta(type):
893 def __new__(mcls, name, bases, ns):
894 new_calls.append('AMeta')
895 return super().__new__(mcls, name, bases, ns)
896 @classmethod
897 def __prepare__(mcls, name, bases):
898 return {}
899
900 class BMeta(AMeta):
901 def __new__(mcls, name, bases, ns):
902 new_calls.append('BMeta')
903 return super().__new__(mcls, name, bases, ns)
904 @classmethod
905 def __prepare__(mcls, name, bases):
906 ns = super().__prepare__(name, bases)
907 ns['BMeta_was_here'] = True
908 return ns
909
910 A = types.new_class("A", (), {"metaclass": AMeta})
911 self.assertEqual(new_calls, ['AMeta'])
912 new_calls.clear()
913
914 B = types.new_class("B", (), {"metaclass": BMeta})
915 # BMeta.__new__ calls AMeta.__new__ with super:
916 self.assertEqual(new_calls, ['BMeta', 'AMeta'])
917 new_calls.clear()
918
919 C = types.new_class("C", (A, B))
920 # The most derived metaclass is BMeta:
921 self.assertEqual(new_calls, ['BMeta', 'AMeta'])
922 new_calls.clear()
923 # BMeta.__prepare__ should've been called:
924 self.assertIn('BMeta_was_here', C.__dict__)
925
926 # The order of the bases shouldn't matter:
927 C2 = types.new_class("C2", (B, A))
928 self.assertEqual(new_calls, ['BMeta', 'AMeta'])
929 new_calls.clear()
930 self.assertIn('BMeta_was_here', C2.__dict__)
931
932 # Check correct metaclass calculation when a metaclass is declared:
933 D = types.new_class("D", (C,), {"metaclass": type})
934 self.assertEqual(new_calls, ['BMeta', 'AMeta'])
935 new_calls.clear()
936 self.assertIn('BMeta_was_here', D.__dict__)
937
938 E = types.new_class("E", (C,), {"metaclass": AMeta})
939 self.assertEqual(new_calls, ['BMeta', 'AMeta'])
940 new_calls.clear()
941 self.assertIn('BMeta_was_here', E.__dict__)
942
943 def test_metaclass_override_function(self):
944 # Special case: the given metaclass isn't a class,
945 # so there is no metaclass calculation.
946 class A(metaclass=self.Meta):
947 pass
948
949 marker = object()
950 def func(*args, **kwargs):
951 return marker
952
953 X = types.new_class("X", (), {"metaclass": func})
954 Y = types.new_class("Y", (object,), {"metaclass": func})
955 Z = types.new_class("Z", (A,), {"metaclass": func})
956 self.assertIs(marker, X)
957 self.assertIs(marker, Y)
958 self.assertIs(marker, Z)
959
960 def test_metaclass_override_callable(self):
961 # The given metaclass is a class,
962 # but not a descendant of type.
963 new_calls = [] # to check the order of __new__ calls
964 prepare_calls = [] # to track __prepare__ calls
965 class ANotMeta:
966 def __new__(mcls, *args, **kwargs):
967 new_calls.append('ANotMeta')
968 return super().__new__(mcls)
969 @classmethod
970 def __prepare__(mcls, name, bases):
971 prepare_calls.append('ANotMeta')
972 return {}
973
974 class BNotMeta(ANotMeta):
975 def __new__(mcls, *args, **kwargs):
976 new_calls.append('BNotMeta')
977 return super().__new__(mcls)
978 @classmethod
979 def __prepare__(mcls, name, bases):
980 prepare_calls.append('BNotMeta')
981 return super().__prepare__(name, bases)
982
983 A = types.new_class("A", (), {"metaclass": ANotMeta})
984 self.assertIs(ANotMeta, type(A))
985 self.assertEqual(prepare_calls, ['ANotMeta'])
986 prepare_calls.clear()
987 self.assertEqual(new_calls, ['ANotMeta'])
988 new_calls.clear()
989
990 B = types.new_class("B", (), {"metaclass": BNotMeta})
991 self.assertIs(BNotMeta, type(B))
992 self.assertEqual(prepare_calls, ['BNotMeta', 'ANotMeta'])
993 prepare_calls.clear()
994 self.assertEqual(new_calls, ['BNotMeta', 'ANotMeta'])
995 new_calls.clear()
996
997 C = types.new_class("C", (A, B))
998 self.assertIs(BNotMeta, type(C))
999 self.assertEqual(prepare_calls, ['BNotMeta', 'ANotMeta'])
1000 prepare_calls.clear()
1001 self.assertEqual(new_calls, ['BNotMeta', 'ANotMeta'])
1002 new_calls.clear()
1003
1004 C2 = types.new_class("C2", (B, A))
1005 self.assertIs(BNotMeta, type(C2))
1006 self.assertEqual(prepare_calls, ['BNotMeta', 'ANotMeta'])
1007 prepare_calls.clear()
1008 self.assertEqual(new_calls, ['BNotMeta', 'ANotMeta'])
1009 new_calls.clear()
1010
1011 # This is a TypeError, because of a metaclass conflict:
1012 # BNotMeta is neither a subclass, nor a superclass of type
1013 with self.assertRaises(TypeError):
1014 D = types.new_class("D", (C,), {"metaclass": type})
1015
1016 E = types.new_class("E", (C,), {"metaclass": ANotMeta})
1017 self.assertIs(BNotMeta, type(E))
1018 self.assertEqual(prepare_calls, ['BNotMeta', 'ANotMeta'])
1019 prepare_calls.clear()
1020 self.assertEqual(new_calls, ['BNotMeta', 'ANotMeta'])
1021 new_calls.clear()
1022
1023 F = types.new_class("F", (object(), C))
1024 self.assertIs(BNotMeta, type(F))
1025 self.assertEqual(prepare_calls, ['BNotMeta', 'ANotMeta'])
1026 prepare_calls.clear()
1027 self.assertEqual(new_calls, ['BNotMeta', 'ANotMeta'])
1028 new_calls.clear()
1029
1030 F2 = types.new_class("F2", (C, object()))
1031 self.assertIs(BNotMeta, type(F2))
1032 self.assertEqual(prepare_calls, ['BNotMeta', 'ANotMeta'])
1033 prepare_calls.clear()
1034 self.assertEqual(new_calls, ['BNotMeta', 'ANotMeta'])
1035 new_calls.clear()
1036
1037 # TypeError: BNotMeta is neither a
1038 # subclass, nor a superclass of int
1039 with self.assertRaises(TypeError):
1040 X = types.new_class("X", (C, int()))
1041 with self.assertRaises(TypeError):
1042 X = types.new_class("X", (int(), C))
1043
Berker Peksag3f015a62016-08-19 11:04:07 +03001044 def test_one_argument_type(self):
1045 expected_message = 'type.__new__() takes exactly 3 arguments (1 given)'
1046
1047 # Only type itself can use the one-argument form (#27157)
1048 self.assertIs(type(5), int)
1049
1050 class M(type):
1051 pass
1052 with self.assertRaises(TypeError) as cm:
1053 M(5)
1054 self.assertEqual(str(cm.exception), expected_message)
1055
1056 class N(type, metaclass=M):
1057 pass
1058 with self.assertRaises(TypeError) as cm:
1059 N(5)
1060 self.assertEqual(str(cm.exception), expected_message)
1061
Nick Coghlan7fc570a2012-05-20 02:34:13 +10001062
Barry Warsaw409da152012-06-03 16:18:47 -04001063class SimpleNamespaceTests(unittest.TestCase):
1064
1065 def test_constructor(self):
1066 ns1 = types.SimpleNamespace()
1067 ns2 = types.SimpleNamespace(x=1, y=2)
1068 ns3 = types.SimpleNamespace(**dict(x=1, y=2))
1069
1070 with self.assertRaises(TypeError):
1071 types.SimpleNamespace(1, 2, 3)
1072
1073 self.assertEqual(len(ns1.__dict__), 0)
1074 self.assertEqual(vars(ns1), {})
1075 self.assertEqual(len(ns2.__dict__), 2)
1076 self.assertEqual(vars(ns2), {'y': 2, 'x': 1})
1077 self.assertEqual(len(ns3.__dict__), 2)
1078 self.assertEqual(vars(ns3), {'y': 2, 'x': 1})
1079
1080 def test_unbound(self):
1081 ns1 = vars(types.SimpleNamespace())
1082 ns2 = vars(types.SimpleNamespace(x=1, y=2))
1083
1084 self.assertEqual(ns1, {})
1085 self.assertEqual(ns2, {'y': 2, 'x': 1})
1086
1087 def test_underlying_dict(self):
1088 ns1 = types.SimpleNamespace()
1089 ns2 = types.SimpleNamespace(x=1, y=2)
1090 ns3 = types.SimpleNamespace(a=True, b=False)
1091 mapping = ns3.__dict__
1092 del ns3
1093
1094 self.assertEqual(ns1.__dict__, {})
1095 self.assertEqual(ns2.__dict__, {'y': 2, 'x': 1})
1096 self.assertEqual(mapping, dict(a=True, b=False))
1097
1098 def test_attrget(self):
1099 ns = types.SimpleNamespace(x=1, y=2, w=3)
1100
1101 self.assertEqual(ns.x, 1)
1102 self.assertEqual(ns.y, 2)
1103 self.assertEqual(ns.w, 3)
1104 with self.assertRaises(AttributeError):
1105 ns.z
1106
1107 def test_attrset(self):
1108 ns1 = types.SimpleNamespace()
1109 ns2 = types.SimpleNamespace(x=1, y=2, w=3)
1110 ns1.a = 'spam'
1111 ns1.b = 'ham'
1112 ns2.z = 4
1113 ns2.theta = None
1114
1115 self.assertEqual(ns1.__dict__, dict(a='spam', b='ham'))
1116 self.assertEqual(ns2.__dict__, dict(x=1, y=2, w=3, z=4, theta=None))
1117
1118 def test_attrdel(self):
1119 ns1 = types.SimpleNamespace()
1120 ns2 = types.SimpleNamespace(x=1, y=2, w=3)
1121
1122 with self.assertRaises(AttributeError):
1123 del ns1.spam
1124 with self.assertRaises(AttributeError):
1125 del ns2.spam
1126
1127 del ns2.y
1128 self.assertEqual(vars(ns2), dict(w=3, x=1))
1129 ns2.y = 'spam'
1130 self.assertEqual(vars(ns2), dict(w=3, x=1, y='spam'))
1131 del ns2.y
1132 self.assertEqual(vars(ns2), dict(w=3, x=1))
1133
1134 ns1.spam = 5
1135 self.assertEqual(vars(ns1), dict(spam=5))
1136 del ns1.spam
1137 self.assertEqual(vars(ns1), {})
1138
1139 def test_repr(self):
1140 ns1 = types.SimpleNamespace(x=1, y=2, w=3)
1141 ns2 = types.SimpleNamespace()
1142 ns2.x = "spam"
1143 ns2._y = 5
Eric Snowb5c8f922013-02-16 16:32:39 -07001144 name = "namespace"
Barry Warsaw409da152012-06-03 16:18:47 -04001145
Eric Snowb5c8f922013-02-16 16:32:39 -07001146 self.assertEqual(repr(ns1), "{name}(w=3, x=1, y=2)".format(name=name))
1147 self.assertEqual(repr(ns2), "{name}(_y=5, x='spam')".format(name=name))
1148
1149 def test_equal(self):
1150 ns1 = types.SimpleNamespace(x=1)
1151 ns2 = types.SimpleNamespace()
1152 ns2.x = 1
1153
1154 self.assertEqual(types.SimpleNamespace(), types.SimpleNamespace())
1155 self.assertEqual(ns1, ns2)
1156 self.assertNotEqual(ns2, types.SimpleNamespace())
Barry Warsaw409da152012-06-03 16:18:47 -04001157
1158 def test_nested(self):
1159 ns1 = types.SimpleNamespace(a=1, b=2)
1160 ns2 = types.SimpleNamespace()
1161 ns3 = types.SimpleNamespace(x=ns1)
1162 ns2.spam = ns1
1163 ns2.ham = '?'
1164 ns2.spam = ns3
1165
1166 self.assertEqual(vars(ns1), dict(a=1, b=2))
1167 self.assertEqual(vars(ns2), dict(spam=ns3, ham='?'))
1168 self.assertEqual(ns2.spam, ns3)
1169 self.assertEqual(vars(ns3), dict(x=ns1))
1170 self.assertEqual(ns3.x.a, 1)
1171
1172 def test_recursive(self):
1173 ns1 = types.SimpleNamespace(c='cookie')
1174 ns2 = types.SimpleNamespace()
1175 ns3 = types.SimpleNamespace(x=1)
1176 ns1.spam = ns1
1177 ns2.spam = ns3
1178 ns3.spam = ns2
1179
1180 self.assertEqual(ns1.spam, ns1)
1181 self.assertEqual(ns1.spam.spam, ns1)
1182 self.assertEqual(ns1.spam.spam, ns1.spam)
1183 self.assertEqual(ns2.spam, ns3)
1184 self.assertEqual(ns3.spam, ns2)
1185 self.assertEqual(ns2.spam.spam, ns2)
1186
1187 def test_recursive_repr(self):
1188 ns1 = types.SimpleNamespace(c='cookie')
1189 ns2 = types.SimpleNamespace()
1190 ns3 = types.SimpleNamespace(x=1)
1191 ns1.spam = ns1
1192 ns2.spam = ns3
1193 ns3.spam = ns2
Eric Snowb5c8f922013-02-16 16:32:39 -07001194 name = "namespace"
1195 repr1 = "{name}(c='cookie', spam={name}(...))".format(name=name)
1196 repr2 = "{name}(spam={name}(spam={name}(...), x=1))".format(name=name)
Barry Warsaw409da152012-06-03 16:18:47 -04001197
Eric Snowb5c8f922013-02-16 16:32:39 -07001198 self.assertEqual(repr(ns1), repr1)
1199 self.assertEqual(repr(ns2), repr2)
Barry Warsaw409da152012-06-03 16:18:47 -04001200
1201 def test_as_dict(self):
1202 ns = types.SimpleNamespace(spam='spamspamspam')
1203
1204 with self.assertRaises(TypeError):
1205 len(ns)
1206 with self.assertRaises(TypeError):
1207 iter(ns)
1208 with self.assertRaises(TypeError):
1209 'spam' in ns
1210 with self.assertRaises(TypeError):
1211 ns['spam']
1212
Eric Snow547298c2012-10-16 22:35:38 -07001213 def test_subclass(self):
1214 class Spam(types.SimpleNamespace):
1215 pass
1216
1217 spam = Spam(ham=8, eggs=9)
1218
1219 self.assertIs(type(spam), Spam)
1220 self.assertEqual(vars(spam), {'ham': 8, 'eggs': 9})
1221
Eric Snowb5c8f922013-02-16 16:32:39 -07001222 def test_pickle(self):
1223 ns = types.SimpleNamespace(breakfast="spam", lunch="spam")
1224
Eric Snow9d05c8c2013-02-16 18:20:32 -07001225 for protocol in range(pickle.HIGHEST_PROTOCOL + 1):
1226 pname = "protocol {}".format(protocol)
1227 try:
1228 ns_pickled = pickle.dumps(ns, protocol)
1229 except TypeError as e:
1230 raise TypeError(pname) from e
1231 ns_roundtrip = pickle.loads(ns_pickled)
Eric Snowb5c8f922013-02-16 16:32:39 -07001232
Eric Snow9d05c8c2013-02-16 18:20:32 -07001233 self.assertEqual(ns, ns_roundtrip, pname)
Eric Snowb5c8f922013-02-16 16:32:39 -07001234
Serhiy Storchaka08d230a2015-05-22 11:02:49 +03001235 def test_fake_namespace_compare(self):
1236 # Issue #24257: Incorrect use of PyObject_IsInstance() caused
1237 # SystemError.
1238 class FakeSimpleNamespace(str):
1239 __class__ = types.SimpleNamespace
1240 self.assertFalse(types.SimpleNamespace() == FakeSimpleNamespace())
1241 self.assertTrue(types.SimpleNamespace() != FakeSimpleNamespace())
1242 with self.assertRaises(TypeError):
1243 types.SimpleNamespace() < FakeSimpleNamespace()
1244 with self.assertRaises(TypeError):
1245 types.SimpleNamespace() <= FakeSimpleNamespace()
1246 with self.assertRaises(TypeError):
1247 types.SimpleNamespace() > FakeSimpleNamespace()
1248 with self.assertRaises(TypeError):
1249 types.SimpleNamespace() >= FakeSimpleNamespace()
1250
Barry Warsaw409da152012-06-03 16:18:47 -04001251
Yury Selivanov75445082015-05-11 22:57:16 -04001252class CoroutineTests(unittest.TestCase):
1253 def test_wrong_args(self):
Yury Selivanovc565cd52015-05-29 09:06:05 -04001254 samples = [None, 1, object()]
Yury Selivanov75445082015-05-11 22:57:16 -04001255 for sample in samples:
Yury Selivanovc565cd52015-05-29 09:06:05 -04001256 with self.assertRaisesRegex(TypeError,
1257 'types.coroutine.*expects a callable'):
Yury Selivanov75445082015-05-11 22:57:16 -04001258 types.coroutine(sample)
1259
Yury Selivanov00e33722015-06-24 11:44:51 -04001260 def test_non_gen_values(self):
Yury Selivanovc565cd52015-05-29 09:06:05 -04001261 @types.coroutine
1262 def foo():
Yury Selivanov5376ba92015-06-22 12:19:30 -04001263 return 'spam'
1264 self.assertEqual(foo(), 'spam')
1265
Yury Selivanov00e33722015-06-24 11:44:51 -04001266 class Awaitable:
1267 def __await__(self):
1268 return ()
1269 aw = Awaitable()
1270 @types.coroutine
1271 def foo():
1272 return aw
1273 self.assertIs(aw, foo())
1274
Yury Selivanov4887523c2015-07-23 15:58:37 +03001275 # decorate foo second time
1276 foo = types.coroutine(foo)
1277 self.assertIs(aw, foo())
1278
Yury Selivanov5376ba92015-06-22 12:19:30 -04001279 def test_async_def(self):
1280 # Test that types.coroutine passes 'async def' coroutines
1281 # without modification
1282
1283 async def foo(): pass
1284 foo_code = foo.__code__
1285 foo_flags = foo.__code__.co_flags
1286 decorated_foo = types.coroutine(foo)
1287 self.assertIs(foo, decorated_foo)
1288 self.assertEqual(foo.__code__.co_flags, foo_flags)
1289 self.assertIs(decorated_foo.__code__, foo_code)
1290
1291 foo_coro = foo()
Yury Selivanov5376ba92015-06-22 12:19:30 -04001292 def bar(): return foo_coro
Yury Selivanov4887523c2015-07-23 15:58:37 +03001293 for _ in range(2):
1294 bar = types.coroutine(bar)
1295 coro = bar()
1296 self.assertIs(foo_coro, coro)
1297 self.assertEqual(coro.cr_code.co_flags, foo_flags)
1298 coro.close()
Yury Selivanovc565cd52015-05-29 09:06:05 -04001299
1300 def test_duck_coro(self):
1301 class CoroLike:
1302 def send(self): pass
1303 def throw(self): pass
1304 def close(self): pass
Yury Selivanov13f77232015-05-29 16:19:18 -04001305 def __await__(self): return self
Yury Selivanovc565cd52015-05-29 09:06:05 -04001306
1307 coro = CoroLike()
1308 @types.coroutine
1309 def foo():
1310 return coro
Yury Selivanov5376ba92015-06-22 12:19:30 -04001311 self.assertIs(foo(), coro)
1312 self.assertIs(foo().__await__(), coro)
1313
1314 def test_duck_corogen(self):
1315 class CoroGenLike:
1316 def send(self): pass
1317 def throw(self): pass
1318 def close(self): pass
1319 def __await__(self): return self
1320 def __iter__(self): return self
1321 def __next__(self): pass
1322
1323 coro = CoroGenLike()
1324 @types.coroutine
1325 def foo():
1326 return coro
1327 self.assertIs(foo(), coro)
Yury Selivanov13f77232015-05-29 16:19:18 -04001328 self.assertIs(foo().__await__(), coro)
1329
1330 def test_duck_gen(self):
1331 class GenLike:
1332 def send(self): pass
1333 def throw(self): pass
1334 def close(self): pass
Yury Selivanov00e33722015-06-24 11:44:51 -04001335 def __iter__(self): pass
Yury Selivanov13f77232015-05-29 16:19:18 -04001336 def __next__(self): pass
1337
Yury Selivanov00e33722015-06-24 11:44:51 -04001338 # Setup generator mock object
1339 gen = unittest.mock.MagicMock(GenLike)
1340 gen.__iter__ = lambda gen: gen
1341 gen.__name__ = 'gen'
1342 gen.__qualname__ = 'test.gen'
1343 self.assertIsInstance(gen, collections.abc.Generator)
1344 self.assertIs(gen, iter(gen))
1345
Yury Selivanov13f77232015-05-29 16:19:18 -04001346 @types.coroutine
Yury Selivanov00e33722015-06-24 11:44:51 -04001347 def foo(): return gen
1348
1349 wrapper = foo()
1350 self.assertIsInstance(wrapper, types._GeneratorWrapper)
1351 self.assertIs(wrapper.__await__(), wrapper)
1352 # Wrapper proxies duck generators completely:
1353 self.assertIs(iter(wrapper), wrapper)
1354
1355 self.assertIsInstance(wrapper, collections.abc.Coroutine)
1356 self.assertIsInstance(wrapper, collections.abc.Awaitable)
1357
1358 self.assertIs(wrapper.__qualname__, gen.__qualname__)
1359 self.assertIs(wrapper.__name__, gen.__name__)
1360
1361 # Test AttributeErrors
Yury Selivanov53e62302015-07-03 00:35:02 -04001362 for name in {'gi_running', 'gi_frame', 'gi_code', 'gi_yieldfrom',
1363 'cr_running', 'cr_frame', 'cr_code', 'cr_await'}:
Yury Selivanov00e33722015-06-24 11:44:51 -04001364 with self.assertRaises(AttributeError):
1365 getattr(wrapper, name)
1366
1367 # Test attributes pass-through
1368 gen.gi_running = object()
1369 gen.gi_frame = object()
1370 gen.gi_code = object()
Yury Selivanov53e62302015-07-03 00:35:02 -04001371 gen.gi_yieldfrom = object()
Yury Selivanov00e33722015-06-24 11:44:51 -04001372 self.assertIs(wrapper.gi_running, gen.gi_running)
1373 self.assertIs(wrapper.gi_frame, gen.gi_frame)
1374 self.assertIs(wrapper.gi_code, gen.gi_code)
Yury Selivanov53e62302015-07-03 00:35:02 -04001375 self.assertIs(wrapper.gi_yieldfrom, gen.gi_yieldfrom)
Yury Selivanov00e33722015-06-24 11:44:51 -04001376 self.assertIs(wrapper.cr_running, gen.gi_running)
1377 self.assertIs(wrapper.cr_frame, gen.gi_frame)
1378 self.assertIs(wrapper.cr_code, gen.gi_code)
Yury Selivanov53e62302015-07-03 00:35:02 -04001379 self.assertIs(wrapper.cr_await, gen.gi_yieldfrom)
Yury Selivanov00e33722015-06-24 11:44:51 -04001380
1381 wrapper.close()
1382 gen.close.assert_called_once_with()
1383
1384 wrapper.send(1)
1385 gen.send.assert_called_once_with(1)
Yury Selivanovf847f1f2015-06-24 12:49:28 -04001386 gen.reset_mock()
1387
1388 next(wrapper)
1389 gen.__next__.assert_called_once_with()
1390 gen.reset_mock()
Yury Selivanov00e33722015-06-24 11:44:51 -04001391
1392 wrapper.throw(1, 2, 3)
1393 gen.throw.assert_called_once_with(1, 2, 3)
1394 gen.reset_mock()
1395
1396 wrapper.throw(1, 2)
1397 gen.throw.assert_called_once_with(1, 2)
1398 gen.reset_mock()
1399
1400 wrapper.throw(1)
1401 gen.throw.assert_called_once_with(1)
1402 gen.reset_mock()
1403
1404 # Test exceptions propagation
1405 error = Exception()
1406 gen.throw.side_effect = error
1407 try:
1408 wrapper.throw(1)
1409 except Exception as ex:
1410 self.assertIs(ex, error)
1411 else:
1412 self.fail('wrapper did not propagate an exception')
1413
1414 # Test invalid args
1415 gen.reset_mock()
1416 with self.assertRaises(TypeError):
1417 wrapper.throw()
1418 self.assertFalse(gen.throw.called)
1419 with self.assertRaises(TypeError):
1420 wrapper.close(1)
1421 self.assertFalse(gen.close.called)
1422 with self.assertRaises(TypeError):
1423 wrapper.send()
1424 self.assertFalse(gen.send.called)
1425
1426 # Test that we do not double wrap
1427 @types.coroutine
1428 def bar(): return wrapper
1429 self.assertIs(wrapper, bar())
1430
1431 # Test weakrefs support
1432 ref = weakref.ref(wrapper)
1433 self.assertIs(ref(), wrapper)
1434
1435 def test_duck_functional_gen(self):
1436 class Generator:
1437 """Emulates the following generator (very clumsy):
1438
1439 def gen(fut):
1440 result = yield fut
1441 return result * 2
1442 """
1443 def __init__(self, fut):
1444 self._i = 0
1445 self._fut = fut
1446 def __iter__(self):
1447 return self
1448 def __next__(self):
1449 return self.send(None)
1450 def send(self, v):
1451 try:
1452 if self._i == 0:
1453 assert v is None
1454 return self._fut
1455 if self._i == 1:
1456 raise StopIteration(v * 2)
1457 if self._i > 1:
1458 raise StopIteration
1459 finally:
1460 self._i += 1
1461 def throw(self, tp, *exc):
1462 self._i = 100
1463 if tp is not GeneratorExit:
1464 raise tp
1465 def close(self):
1466 self.throw(GeneratorExit)
1467
1468 @types.coroutine
1469 def foo(): return Generator('spam')
1470
1471 wrapper = foo()
1472 self.assertIsInstance(wrapper, types._GeneratorWrapper)
1473
1474 async def corofunc():
1475 return await foo() + 100
1476 coro = corofunc()
1477
1478 self.assertEqual(coro.send(None), 'spam')
1479 try:
1480 coro.send(20)
1481 except StopIteration as ex:
1482 self.assertEqual(ex.args[0], 140)
1483 else:
1484 self.fail('StopIteration was expected')
Yury Selivanov13f77232015-05-29 16:19:18 -04001485
1486 def test_gen(self):
Yury Selivanovf847f1f2015-06-24 12:49:28 -04001487 def gen_func():
1488 yield 1
1489 return (yield 2)
1490 gen = gen_func()
Yury Selivanov13f77232015-05-29 16:19:18 -04001491 @types.coroutine
1492 def foo(): return gen
Yury Selivanov00e33722015-06-24 11:44:51 -04001493 wrapper = foo()
1494 self.assertIsInstance(wrapper, types._GeneratorWrapper)
1495 self.assertIs(wrapper.__await__(), gen)
Yury Selivanov13f77232015-05-29 16:19:18 -04001496
1497 for name in ('__name__', '__qualname__', 'gi_code',
1498 'gi_running', 'gi_frame'):
1499 self.assertIs(getattr(foo(), name),
1500 getattr(gen, name))
Yury Selivanov5376ba92015-06-22 12:19:30 -04001501 self.assertIs(foo().cr_code, gen.gi_code)
Yury Selivanovc565cd52015-05-29 09:06:05 -04001502
Yury Selivanovf847f1f2015-06-24 12:49:28 -04001503 self.assertEqual(next(wrapper), 1)
1504 self.assertEqual(wrapper.send(None), 2)
1505 with self.assertRaisesRegex(StopIteration, 'spam'):
1506 wrapper.send('spam')
1507
1508 gen = gen_func()
1509 wrapper = foo()
1510 wrapper.send(None)
1511 with self.assertRaisesRegex(Exception, 'ham'):
1512 wrapper.throw(Exception, Exception('ham'))
1513
Yury Selivanov4887523c2015-07-23 15:58:37 +03001514 # decorate foo second time
1515 foo = types.coroutine(foo)
1516 self.assertIs(foo().__await__(), gen)
1517
Yury Selivanovfdbeb2b2015-07-03 13:11:35 -04001518 def test_returning_itercoro(self):
1519 @types.coroutine
1520 def gen():
1521 yield
1522
1523 gencoro = gen()
1524
1525 @types.coroutine
1526 def foo():
1527 return gencoro
1528
1529 self.assertIs(foo(), gencoro)
1530
Yury Selivanov4887523c2015-07-23 15:58:37 +03001531 # decorate foo second time
1532 foo = types.coroutine(foo)
1533 self.assertIs(foo(), gencoro)
1534
Yury Selivanov75445082015-05-11 22:57:16 -04001535 def test_genfunc(self):
Yury Selivanov00e33722015-06-24 11:44:51 -04001536 def gen(): yield
1537 self.assertIs(types.coroutine(gen), gen)
Yury Selivanov4887523c2015-07-23 15:58:37 +03001538 self.assertIs(types.coroutine(types.coroutine(gen)), gen)
Yury Selivanov75445082015-05-11 22:57:16 -04001539
1540 self.assertTrue(gen.__code__.co_flags & inspect.CO_ITERABLE_COROUTINE)
1541 self.assertFalse(gen.__code__.co_flags & inspect.CO_COROUTINE)
1542
1543 g = gen()
1544 self.assertTrue(g.gi_code.co_flags & inspect.CO_ITERABLE_COROUTINE)
1545 self.assertFalse(g.gi_code.co_flags & inspect.CO_COROUTINE)
Yury Selivanov75445082015-05-11 22:57:16 -04001546
Yury Selivanov00e33722015-06-24 11:44:51 -04001547 self.assertIs(types.coroutine(gen), gen)
1548
1549 def test_wrapper_object(self):
1550 def gen():
1551 yield
1552 @types.coroutine
1553 def coro():
1554 return gen()
1555
1556 wrapper = coro()
1557 self.assertIn('GeneratorWrapper', repr(wrapper))
1558 self.assertEqual(repr(wrapper), str(wrapper))
1559 self.assertTrue(set(dir(wrapper)).issuperset({
1560 '__await__', '__iter__', '__next__', 'cr_code', 'cr_running',
1561 'cr_frame', 'gi_code', 'gi_frame', 'gi_running', 'send',
1562 'close', 'throw'}))
1563
Yury Selivanov75445082015-05-11 22:57:16 -04001564
Thomas Wouters89f507f2006-12-13 04:49:30 +00001565if __name__ == '__main__':
Zachary Ware38c707e2015-04-13 15:00:43 -05001566 unittest.main()