blob: 28133a3560f3c5adbae851a129a79e07418a95fd [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)
Serhiy Storchaka79ba4712017-10-07 22:59:35 +03001072 with self.assertRaises(TypeError):
1073 types.SimpleNamespace(**{1: 2})
Barry Warsaw409da152012-06-03 16:18:47 -04001074
1075 self.assertEqual(len(ns1.__dict__), 0)
1076 self.assertEqual(vars(ns1), {})
1077 self.assertEqual(len(ns2.__dict__), 2)
1078 self.assertEqual(vars(ns2), {'y': 2, 'x': 1})
1079 self.assertEqual(len(ns3.__dict__), 2)
1080 self.assertEqual(vars(ns3), {'y': 2, 'x': 1})
1081
1082 def test_unbound(self):
1083 ns1 = vars(types.SimpleNamespace())
1084 ns2 = vars(types.SimpleNamespace(x=1, y=2))
1085
1086 self.assertEqual(ns1, {})
1087 self.assertEqual(ns2, {'y': 2, 'x': 1})
1088
1089 def test_underlying_dict(self):
1090 ns1 = types.SimpleNamespace()
1091 ns2 = types.SimpleNamespace(x=1, y=2)
1092 ns3 = types.SimpleNamespace(a=True, b=False)
1093 mapping = ns3.__dict__
1094 del ns3
1095
1096 self.assertEqual(ns1.__dict__, {})
1097 self.assertEqual(ns2.__dict__, {'y': 2, 'x': 1})
1098 self.assertEqual(mapping, dict(a=True, b=False))
1099
1100 def test_attrget(self):
1101 ns = types.SimpleNamespace(x=1, y=2, w=3)
1102
1103 self.assertEqual(ns.x, 1)
1104 self.assertEqual(ns.y, 2)
1105 self.assertEqual(ns.w, 3)
1106 with self.assertRaises(AttributeError):
1107 ns.z
1108
1109 def test_attrset(self):
1110 ns1 = types.SimpleNamespace()
1111 ns2 = types.SimpleNamespace(x=1, y=2, w=3)
1112 ns1.a = 'spam'
1113 ns1.b = 'ham'
1114 ns2.z = 4
1115 ns2.theta = None
1116
1117 self.assertEqual(ns1.__dict__, dict(a='spam', b='ham'))
1118 self.assertEqual(ns2.__dict__, dict(x=1, y=2, w=3, z=4, theta=None))
1119
1120 def test_attrdel(self):
1121 ns1 = types.SimpleNamespace()
1122 ns2 = types.SimpleNamespace(x=1, y=2, w=3)
1123
1124 with self.assertRaises(AttributeError):
1125 del ns1.spam
1126 with self.assertRaises(AttributeError):
1127 del ns2.spam
1128
1129 del ns2.y
1130 self.assertEqual(vars(ns2), dict(w=3, x=1))
1131 ns2.y = 'spam'
1132 self.assertEqual(vars(ns2), dict(w=3, x=1, y='spam'))
1133 del ns2.y
1134 self.assertEqual(vars(ns2), dict(w=3, x=1))
1135
1136 ns1.spam = 5
1137 self.assertEqual(vars(ns1), dict(spam=5))
1138 del ns1.spam
1139 self.assertEqual(vars(ns1), {})
1140
1141 def test_repr(self):
1142 ns1 = types.SimpleNamespace(x=1, y=2, w=3)
1143 ns2 = types.SimpleNamespace()
1144 ns2.x = "spam"
1145 ns2._y = 5
Eric Snowb5c8f922013-02-16 16:32:39 -07001146 name = "namespace"
Barry Warsaw409da152012-06-03 16:18:47 -04001147
Eric Snowb5c8f922013-02-16 16:32:39 -07001148 self.assertEqual(repr(ns1), "{name}(w=3, x=1, y=2)".format(name=name))
1149 self.assertEqual(repr(ns2), "{name}(_y=5, x='spam')".format(name=name))
1150
1151 def test_equal(self):
1152 ns1 = types.SimpleNamespace(x=1)
1153 ns2 = types.SimpleNamespace()
1154 ns2.x = 1
1155
1156 self.assertEqual(types.SimpleNamespace(), types.SimpleNamespace())
1157 self.assertEqual(ns1, ns2)
1158 self.assertNotEqual(ns2, types.SimpleNamespace())
Barry Warsaw409da152012-06-03 16:18:47 -04001159
1160 def test_nested(self):
1161 ns1 = types.SimpleNamespace(a=1, b=2)
1162 ns2 = types.SimpleNamespace()
1163 ns3 = types.SimpleNamespace(x=ns1)
1164 ns2.spam = ns1
1165 ns2.ham = '?'
1166 ns2.spam = ns3
1167
1168 self.assertEqual(vars(ns1), dict(a=1, b=2))
1169 self.assertEqual(vars(ns2), dict(spam=ns3, ham='?'))
1170 self.assertEqual(ns2.spam, ns3)
1171 self.assertEqual(vars(ns3), dict(x=ns1))
1172 self.assertEqual(ns3.x.a, 1)
1173
1174 def test_recursive(self):
1175 ns1 = types.SimpleNamespace(c='cookie')
1176 ns2 = types.SimpleNamespace()
1177 ns3 = types.SimpleNamespace(x=1)
1178 ns1.spam = ns1
1179 ns2.spam = ns3
1180 ns3.spam = ns2
1181
1182 self.assertEqual(ns1.spam, ns1)
1183 self.assertEqual(ns1.spam.spam, ns1)
1184 self.assertEqual(ns1.spam.spam, ns1.spam)
1185 self.assertEqual(ns2.spam, ns3)
1186 self.assertEqual(ns3.spam, ns2)
1187 self.assertEqual(ns2.spam.spam, ns2)
1188
1189 def test_recursive_repr(self):
1190 ns1 = types.SimpleNamespace(c='cookie')
1191 ns2 = types.SimpleNamespace()
1192 ns3 = types.SimpleNamespace(x=1)
1193 ns1.spam = ns1
1194 ns2.spam = ns3
1195 ns3.spam = ns2
Eric Snowb5c8f922013-02-16 16:32:39 -07001196 name = "namespace"
1197 repr1 = "{name}(c='cookie', spam={name}(...))".format(name=name)
1198 repr2 = "{name}(spam={name}(spam={name}(...), x=1))".format(name=name)
Barry Warsaw409da152012-06-03 16:18:47 -04001199
Eric Snowb5c8f922013-02-16 16:32:39 -07001200 self.assertEqual(repr(ns1), repr1)
1201 self.assertEqual(repr(ns2), repr2)
Barry Warsaw409da152012-06-03 16:18:47 -04001202
1203 def test_as_dict(self):
1204 ns = types.SimpleNamespace(spam='spamspamspam')
1205
1206 with self.assertRaises(TypeError):
1207 len(ns)
1208 with self.assertRaises(TypeError):
1209 iter(ns)
1210 with self.assertRaises(TypeError):
1211 'spam' in ns
1212 with self.assertRaises(TypeError):
1213 ns['spam']
1214
Eric Snow547298c2012-10-16 22:35:38 -07001215 def test_subclass(self):
1216 class Spam(types.SimpleNamespace):
1217 pass
1218
1219 spam = Spam(ham=8, eggs=9)
1220
1221 self.assertIs(type(spam), Spam)
1222 self.assertEqual(vars(spam), {'ham': 8, 'eggs': 9})
1223
Eric Snowb5c8f922013-02-16 16:32:39 -07001224 def test_pickle(self):
1225 ns = types.SimpleNamespace(breakfast="spam", lunch="spam")
1226
Eric Snow9d05c8c2013-02-16 18:20:32 -07001227 for protocol in range(pickle.HIGHEST_PROTOCOL + 1):
1228 pname = "protocol {}".format(protocol)
1229 try:
1230 ns_pickled = pickle.dumps(ns, protocol)
1231 except TypeError as e:
1232 raise TypeError(pname) from e
1233 ns_roundtrip = pickle.loads(ns_pickled)
Eric Snowb5c8f922013-02-16 16:32:39 -07001234
Eric Snow9d05c8c2013-02-16 18:20:32 -07001235 self.assertEqual(ns, ns_roundtrip, pname)
Eric Snowb5c8f922013-02-16 16:32:39 -07001236
Serhiy Storchaka08d230a2015-05-22 11:02:49 +03001237 def test_fake_namespace_compare(self):
1238 # Issue #24257: Incorrect use of PyObject_IsInstance() caused
1239 # SystemError.
1240 class FakeSimpleNamespace(str):
1241 __class__ = types.SimpleNamespace
1242 self.assertFalse(types.SimpleNamespace() == FakeSimpleNamespace())
1243 self.assertTrue(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 with self.assertRaises(TypeError):
1251 types.SimpleNamespace() >= FakeSimpleNamespace()
1252
Barry Warsaw409da152012-06-03 16:18:47 -04001253
Yury Selivanov75445082015-05-11 22:57:16 -04001254class CoroutineTests(unittest.TestCase):
1255 def test_wrong_args(self):
Yury Selivanovc565cd52015-05-29 09:06:05 -04001256 samples = [None, 1, object()]
Yury Selivanov75445082015-05-11 22:57:16 -04001257 for sample in samples:
Yury Selivanovc565cd52015-05-29 09:06:05 -04001258 with self.assertRaisesRegex(TypeError,
1259 'types.coroutine.*expects a callable'):
Yury Selivanov75445082015-05-11 22:57:16 -04001260 types.coroutine(sample)
1261
Yury Selivanov00e33722015-06-24 11:44:51 -04001262 def test_non_gen_values(self):
Yury Selivanovc565cd52015-05-29 09:06:05 -04001263 @types.coroutine
1264 def foo():
Yury Selivanov5376ba92015-06-22 12:19:30 -04001265 return 'spam'
1266 self.assertEqual(foo(), 'spam')
1267
Yury Selivanov00e33722015-06-24 11:44:51 -04001268 class Awaitable:
1269 def __await__(self):
1270 return ()
1271 aw = Awaitable()
1272 @types.coroutine
1273 def foo():
1274 return aw
1275 self.assertIs(aw, foo())
1276
Yury Selivanov4887523c2015-07-23 15:58:37 +03001277 # decorate foo second time
1278 foo = types.coroutine(foo)
1279 self.assertIs(aw, foo())
1280
Yury Selivanov5376ba92015-06-22 12:19:30 -04001281 def test_async_def(self):
1282 # Test that types.coroutine passes 'async def' coroutines
1283 # without modification
1284
1285 async def foo(): pass
1286 foo_code = foo.__code__
1287 foo_flags = foo.__code__.co_flags
1288 decorated_foo = types.coroutine(foo)
1289 self.assertIs(foo, decorated_foo)
1290 self.assertEqual(foo.__code__.co_flags, foo_flags)
1291 self.assertIs(decorated_foo.__code__, foo_code)
1292
1293 foo_coro = foo()
Yury Selivanov5376ba92015-06-22 12:19:30 -04001294 def bar(): return foo_coro
Yury Selivanov4887523c2015-07-23 15:58:37 +03001295 for _ in range(2):
1296 bar = types.coroutine(bar)
1297 coro = bar()
1298 self.assertIs(foo_coro, coro)
1299 self.assertEqual(coro.cr_code.co_flags, foo_flags)
1300 coro.close()
Yury Selivanovc565cd52015-05-29 09:06:05 -04001301
1302 def test_duck_coro(self):
1303 class CoroLike:
1304 def send(self): pass
1305 def throw(self): pass
1306 def close(self): pass
Yury Selivanov13f77232015-05-29 16:19:18 -04001307 def __await__(self): return self
Yury Selivanovc565cd52015-05-29 09:06:05 -04001308
1309 coro = CoroLike()
1310 @types.coroutine
1311 def foo():
1312 return coro
Yury Selivanov5376ba92015-06-22 12:19:30 -04001313 self.assertIs(foo(), coro)
1314 self.assertIs(foo().__await__(), coro)
1315
1316 def test_duck_corogen(self):
1317 class CoroGenLike:
1318 def send(self): pass
1319 def throw(self): pass
1320 def close(self): pass
1321 def __await__(self): return self
1322 def __iter__(self): return self
1323 def __next__(self): pass
1324
1325 coro = CoroGenLike()
1326 @types.coroutine
1327 def foo():
1328 return coro
1329 self.assertIs(foo(), coro)
Yury Selivanov13f77232015-05-29 16:19:18 -04001330 self.assertIs(foo().__await__(), coro)
1331
1332 def test_duck_gen(self):
1333 class GenLike:
1334 def send(self): pass
1335 def throw(self): pass
1336 def close(self): pass
Yury Selivanov00e33722015-06-24 11:44:51 -04001337 def __iter__(self): pass
Yury Selivanov13f77232015-05-29 16:19:18 -04001338 def __next__(self): pass
1339
Yury Selivanov00e33722015-06-24 11:44:51 -04001340 # Setup generator mock object
1341 gen = unittest.mock.MagicMock(GenLike)
1342 gen.__iter__ = lambda gen: gen
1343 gen.__name__ = 'gen'
1344 gen.__qualname__ = 'test.gen'
1345 self.assertIsInstance(gen, collections.abc.Generator)
1346 self.assertIs(gen, iter(gen))
1347
Yury Selivanov13f77232015-05-29 16:19:18 -04001348 @types.coroutine
Yury Selivanov00e33722015-06-24 11:44:51 -04001349 def foo(): return gen
1350
1351 wrapper = foo()
1352 self.assertIsInstance(wrapper, types._GeneratorWrapper)
1353 self.assertIs(wrapper.__await__(), wrapper)
1354 # Wrapper proxies duck generators completely:
1355 self.assertIs(iter(wrapper), wrapper)
1356
1357 self.assertIsInstance(wrapper, collections.abc.Coroutine)
1358 self.assertIsInstance(wrapper, collections.abc.Awaitable)
1359
1360 self.assertIs(wrapper.__qualname__, gen.__qualname__)
1361 self.assertIs(wrapper.__name__, gen.__name__)
1362
1363 # Test AttributeErrors
Yury Selivanov53e62302015-07-03 00:35:02 -04001364 for name in {'gi_running', 'gi_frame', 'gi_code', 'gi_yieldfrom',
1365 'cr_running', 'cr_frame', 'cr_code', 'cr_await'}:
Yury Selivanov00e33722015-06-24 11:44:51 -04001366 with self.assertRaises(AttributeError):
1367 getattr(wrapper, name)
1368
1369 # Test attributes pass-through
1370 gen.gi_running = object()
1371 gen.gi_frame = object()
1372 gen.gi_code = object()
Yury Selivanov53e62302015-07-03 00:35:02 -04001373 gen.gi_yieldfrom = object()
Yury Selivanov00e33722015-06-24 11:44:51 -04001374 self.assertIs(wrapper.gi_running, gen.gi_running)
1375 self.assertIs(wrapper.gi_frame, gen.gi_frame)
1376 self.assertIs(wrapper.gi_code, gen.gi_code)
Yury Selivanov53e62302015-07-03 00:35:02 -04001377 self.assertIs(wrapper.gi_yieldfrom, gen.gi_yieldfrom)
Yury Selivanov00e33722015-06-24 11:44:51 -04001378 self.assertIs(wrapper.cr_running, gen.gi_running)
1379 self.assertIs(wrapper.cr_frame, gen.gi_frame)
1380 self.assertIs(wrapper.cr_code, gen.gi_code)
Yury Selivanov53e62302015-07-03 00:35:02 -04001381 self.assertIs(wrapper.cr_await, gen.gi_yieldfrom)
Yury Selivanov00e33722015-06-24 11:44:51 -04001382
1383 wrapper.close()
1384 gen.close.assert_called_once_with()
1385
1386 wrapper.send(1)
1387 gen.send.assert_called_once_with(1)
Yury Selivanovf847f1f2015-06-24 12:49:28 -04001388 gen.reset_mock()
1389
1390 next(wrapper)
1391 gen.__next__.assert_called_once_with()
1392 gen.reset_mock()
Yury Selivanov00e33722015-06-24 11:44:51 -04001393
1394 wrapper.throw(1, 2, 3)
1395 gen.throw.assert_called_once_with(1, 2, 3)
1396 gen.reset_mock()
1397
1398 wrapper.throw(1, 2)
1399 gen.throw.assert_called_once_with(1, 2)
1400 gen.reset_mock()
1401
1402 wrapper.throw(1)
1403 gen.throw.assert_called_once_with(1)
1404 gen.reset_mock()
1405
1406 # Test exceptions propagation
1407 error = Exception()
1408 gen.throw.side_effect = error
1409 try:
1410 wrapper.throw(1)
1411 except Exception as ex:
1412 self.assertIs(ex, error)
1413 else:
1414 self.fail('wrapper did not propagate an exception')
1415
1416 # Test invalid args
1417 gen.reset_mock()
1418 with self.assertRaises(TypeError):
1419 wrapper.throw()
1420 self.assertFalse(gen.throw.called)
1421 with self.assertRaises(TypeError):
1422 wrapper.close(1)
1423 self.assertFalse(gen.close.called)
1424 with self.assertRaises(TypeError):
1425 wrapper.send()
1426 self.assertFalse(gen.send.called)
1427
1428 # Test that we do not double wrap
1429 @types.coroutine
1430 def bar(): return wrapper
1431 self.assertIs(wrapper, bar())
1432
1433 # Test weakrefs support
1434 ref = weakref.ref(wrapper)
1435 self.assertIs(ref(), wrapper)
1436
1437 def test_duck_functional_gen(self):
1438 class Generator:
1439 """Emulates the following generator (very clumsy):
1440
1441 def gen(fut):
1442 result = yield fut
1443 return result * 2
1444 """
1445 def __init__(self, fut):
1446 self._i = 0
1447 self._fut = fut
1448 def __iter__(self):
1449 return self
1450 def __next__(self):
1451 return self.send(None)
1452 def send(self, v):
1453 try:
1454 if self._i == 0:
1455 assert v is None
1456 return self._fut
1457 if self._i == 1:
1458 raise StopIteration(v * 2)
1459 if self._i > 1:
1460 raise StopIteration
1461 finally:
1462 self._i += 1
1463 def throw(self, tp, *exc):
1464 self._i = 100
1465 if tp is not GeneratorExit:
1466 raise tp
1467 def close(self):
1468 self.throw(GeneratorExit)
1469
1470 @types.coroutine
1471 def foo(): return Generator('spam')
1472
1473 wrapper = foo()
1474 self.assertIsInstance(wrapper, types._GeneratorWrapper)
1475
1476 async def corofunc():
1477 return await foo() + 100
1478 coro = corofunc()
1479
1480 self.assertEqual(coro.send(None), 'spam')
1481 try:
1482 coro.send(20)
1483 except StopIteration as ex:
1484 self.assertEqual(ex.args[0], 140)
1485 else:
1486 self.fail('StopIteration was expected')
Yury Selivanov13f77232015-05-29 16:19:18 -04001487
1488 def test_gen(self):
Yury Selivanovf847f1f2015-06-24 12:49:28 -04001489 def gen_func():
1490 yield 1
1491 return (yield 2)
1492 gen = gen_func()
Yury Selivanov13f77232015-05-29 16:19:18 -04001493 @types.coroutine
1494 def foo(): return gen
Yury Selivanov00e33722015-06-24 11:44:51 -04001495 wrapper = foo()
1496 self.assertIsInstance(wrapper, types._GeneratorWrapper)
1497 self.assertIs(wrapper.__await__(), gen)
Yury Selivanov13f77232015-05-29 16:19:18 -04001498
1499 for name in ('__name__', '__qualname__', 'gi_code',
1500 'gi_running', 'gi_frame'):
1501 self.assertIs(getattr(foo(), name),
1502 getattr(gen, name))
Yury Selivanov5376ba92015-06-22 12:19:30 -04001503 self.assertIs(foo().cr_code, gen.gi_code)
Yury Selivanovc565cd52015-05-29 09:06:05 -04001504
Yury Selivanovf847f1f2015-06-24 12:49:28 -04001505 self.assertEqual(next(wrapper), 1)
1506 self.assertEqual(wrapper.send(None), 2)
1507 with self.assertRaisesRegex(StopIteration, 'spam'):
1508 wrapper.send('spam')
1509
1510 gen = gen_func()
1511 wrapper = foo()
1512 wrapper.send(None)
1513 with self.assertRaisesRegex(Exception, 'ham'):
1514 wrapper.throw(Exception, Exception('ham'))
1515
Yury Selivanov4887523c2015-07-23 15:58:37 +03001516 # decorate foo second time
1517 foo = types.coroutine(foo)
1518 self.assertIs(foo().__await__(), gen)
1519
Yury Selivanovfdbeb2b2015-07-03 13:11:35 -04001520 def test_returning_itercoro(self):
1521 @types.coroutine
1522 def gen():
1523 yield
1524
1525 gencoro = gen()
1526
1527 @types.coroutine
1528 def foo():
1529 return gencoro
1530
1531 self.assertIs(foo(), gencoro)
1532
Yury Selivanov4887523c2015-07-23 15:58:37 +03001533 # decorate foo second time
1534 foo = types.coroutine(foo)
1535 self.assertIs(foo(), gencoro)
1536
Yury Selivanov75445082015-05-11 22:57:16 -04001537 def test_genfunc(self):
Yury Selivanov00e33722015-06-24 11:44:51 -04001538 def gen(): yield
1539 self.assertIs(types.coroutine(gen), gen)
Yury Selivanov4887523c2015-07-23 15:58:37 +03001540 self.assertIs(types.coroutine(types.coroutine(gen)), gen)
Yury Selivanov75445082015-05-11 22:57:16 -04001541
1542 self.assertTrue(gen.__code__.co_flags & inspect.CO_ITERABLE_COROUTINE)
1543 self.assertFalse(gen.__code__.co_flags & inspect.CO_COROUTINE)
1544
1545 g = gen()
1546 self.assertTrue(g.gi_code.co_flags & inspect.CO_ITERABLE_COROUTINE)
1547 self.assertFalse(g.gi_code.co_flags & inspect.CO_COROUTINE)
Yury Selivanov75445082015-05-11 22:57:16 -04001548
Yury Selivanov00e33722015-06-24 11:44:51 -04001549 self.assertIs(types.coroutine(gen), gen)
1550
1551 def test_wrapper_object(self):
1552 def gen():
1553 yield
1554 @types.coroutine
1555 def coro():
1556 return gen()
1557
1558 wrapper = coro()
1559 self.assertIn('GeneratorWrapper', repr(wrapper))
1560 self.assertEqual(repr(wrapper), str(wrapper))
1561 self.assertTrue(set(dir(wrapper)).issuperset({
1562 '__await__', '__iter__', '__next__', 'cr_code', 'cr_running',
1563 'cr_frame', 'gi_code', 'gi_frame', 'gi_running', 'send',
1564 'close', 'throw'}))
1565
Yury Selivanov75445082015-05-11 22:57:16 -04001566
Thomas Wouters89f507f2006-12-13 04:49:30 +00001567if __name__ == '__main__':
Zachary Ware38c707e2015-04-13 15:00:43 -05001568 unittest.main()