blob: 56848c1bf87eb57fda71298cddb1f48862965052 [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
Serhiy Storchaka3327a2d2017-12-15 14:13:41 +0200597 self.assertIsInstance(int.__dict__['from_bytes'], types.ClassMethodDescriptorType)
598 self.assertIsInstance(int.from_bytes, types.BuiltinMethodType)
599 self.assertIsInstance(int.__new__, types.BuiltinMethodType)
600
Benjamin Peterson0e102062010-08-25 23:13:17 +0000601
Victor Stinner0db176f2012-04-16 00:16:30 +0200602class MappingProxyTests(unittest.TestCase):
603 mappingproxy = types.MappingProxyType
604
605 def test_constructor(self):
606 class userdict(dict):
607 pass
608
609 mapping = {'x': 1, 'y': 2}
610 self.assertEqual(self.mappingproxy(mapping), mapping)
611 mapping = userdict(x=1, y=2)
612 self.assertEqual(self.mappingproxy(mapping), mapping)
613 mapping = collections.ChainMap({'x': 1}, {'y': 2})
614 self.assertEqual(self.mappingproxy(mapping), mapping)
615
616 self.assertRaises(TypeError, self.mappingproxy, 10)
617 self.assertRaises(TypeError, self.mappingproxy, ("a", "tuple"))
618 self.assertRaises(TypeError, self.mappingproxy, ["a", "list"])
619
620 def test_methods(self):
621 attrs = set(dir(self.mappingproxy({}))) - set(dir(object()))
622 self.assertEqual(attrs, {
623 '__contains__',
624 '__getitem__',
625 '__iter__',
626 '__len__',
627 'copy',
628 'get',
629 'items',
630 'keys',
631 'values',
632 })
633
634 def test_get(self):
635 view = self.mappingproxy({'a': 'A', 'b': 'B'})
636 self.assertEqual(view['a'], 'A')
637 self.assertEqual(view['b'], 'B')
638 self.assertRaises(KeyError, view.__getitem__, 'xxx')
639 self.assertEqual(view.get('a'), 'A')
640 self.assertIsNone(view.get('xxx'))
641 self.assertEqual(view.get('xxx', 42), 42)
642
643 def test_missing(self):
644 class dictmissing(dict):
645 def __missing__(self, key):
646 return "missing=%s" % key
647
648 view = self.mappingproxy(dictmissing(x=1))
649 self.assertEqual(view['x'], 1)
650 self.assertEqual(view['y'], 'missing=y')
651 self.assertEqual(view.get('x'), 1)
652 self.assertEqual(view.get('y'), None)
653 self.assertEqual(view.get('y', 42), 42)
654 self.assertTrue('x' in view)
655 self.assertFalse('y' in view)
656
657 def test_customdict(self):
658 class customdict(dict):
659 def __contains__(self, key):
660 if key == 'magic':
661 return True
662 else:
663 return dict.__contains__(self, key)
664
665 def __iter__(self):
666 return iter(('iter',))
667
668 def __len__(self):
669 return 500
670
671 def copy(self):
672 return 'copy'
673
674 def keys(self):
675 return 'keys'
676
677 def items(self):
678 return 'items'
679
680 def values(self):
681 return 'values'
682
683 def __getitem__(self, key):
684 return "getitem=%s" % dict.__getitem__(self, key)
685
686 def get(self, key, default=None):
687 return "get=%s" % dict.get(self, key, 'default=%r' % default)
688
689 custom = customdict({'key': 'value'})
690 view = self.mappingproxy(custom)
691 self.assertTrue('key' in view)
692 self.assertTrue('magic' in view)
693 self.assertFalse('xxx' in view)
694 self.assertEqual(view['key'], 'getitem=value')
695 self.assertRaises(KeyError, view.__getitem__, 'xxx')
696 self.assertEqual(tuple(view), ('iter',))
697 self.assertEqual(len(view), 500)
698 self.assertEqual(view.copy(), 'copy')
699 self.assertEqual(view.get('key'), 'get=value')
700 self.assertEqual(view.get('xxx'), 'get=default=None')
701 self.assertEqual(view.items(), 'items')
702 self.assertEqual(view.keys(), 'keys')
703 self.assertEqual(view.values(), 'values')
704
705 def test_chainmap(self):
706 d1 = {'x': 1}
707 d2 = {'y': 2}
708 mapping = collections.ChainMap(d1, d2)
709 view = self.mappingproxy(mapping)
710 self.assertTrue('x' in view)
711 self.assertTrue('y' in view)
712 self.assertFalse('z' in view)
713 self.assertEqual(view['x'], 1)
714 self.assertEqual(view['y'], 2)
715 self.assertRaises(KeyError, view.__getitem__, 'z')
716 self.assertEqual(tuple(sorted(view)), ('x', 'y'))
717 self.assertEqual(len(view), 2)
718 copy = view.copy()
719 self.assertIsNot(copy, mapping)
720 self.assertIsInstance(copy, collections.ChainMap)
721 self.assertEqual(copy, mapping)
722 self.assertEqual(view.get('x'), 1)
723 self.assertEqual(view.get('y'), 2)
724 self.assertIsNone(view.get('z'))
725 self.assertEqual(tuple(sorted(view.items())), (('x', 1), ('y', 2)))
726 self.assertEqual(tuple(sorted(view.keys())), ('x', 'y'))
727 self.assertEqual(tuple(sorted(view.values())), (1, 2))
728
729 def test_contains(self):
730 view = self.mappingproxy(dict.fromkeys('abc'))
731 self.assertTrue('a' in view)
732 self.assertTrue('b' in view)
733 self.assertTrue('c' in view)
734 self.assertFalse('xxx' in view)
735
736 def test_views(self):
737 mapping = {}
738 view = self.mappingproxy(mapping)
739 keys = view.keys()
740 values = view.values()
741 items = view.items()
742 self.assertEqual(list(keys), [])
743 self.assertEqual(list(values), [])
744 self.assertEqual(list(items), [])
745 mapping['key'] = 'value'
746 self.assertEqual(list(keys), ['key'])
747 self.assertEqual(list(values), ['value'])
748 self.assertEqual(list(items), [('key', 'value')])
749
750 def test_len(self):
751 for expected in range(6):
752 data = dict.fromkeys('abcde'[:expected])
753 self.assertEqual(len(data), expected)
754 view = self.mappingproxy(data)
755 self.assertEqual(len(view), expected)
756
757 def test_iterators(self):
758 keys = ('x', 'y')
759 values = (1, 2)
760 items = tuple(zip(keys, values))
761 view = self.mappingproxy(dict(items))
762 self.assertEqual(set(view), set(keys))
763 self.assertEqual(set(view.keys()), set(keys))
764 self.assertEqual(set(view.values()), set(values))
765 self.assertEqual(set(view.items()), set(items))
766
767 def test_copy(self):
768 original = {'key1': 27, 'key2': 51, 'key3': 93}
769 view = self.mappingproxy(original)
770 copy = view.copy()
771 self.assertEqual(type(copy), dict)
772 self.assertEqual(copy, original)
773 original['key1'] = 70
774 self.assertEqual(view['key1'], 70)
775 self.assertEqual(copy['key1'], 27)
776
777
Nick Coghlan7fc570a2012-05-20 02:34:13 +1000778class ClassCreationTests(unittest.TestCase):
779
780 class Meta(type):
781 def __init__(cls, name, bases, ns, **kw):
782 super().__init__(name, bases, ns)
783 @staticmethod
784 def __new__(mcls, name, bases, ns, **kw):
785 return super().__new__(mcls, name, bases, ns)
786 @classmethod
787 def __prepare__(mcls, name, bases, **kw):
788 ns = super().__prepare__(name, bases)
789 ns["y"] = 1
790 ns.update(kw)
791 return ns
792
793 def test_new_class_basics(self):
794 C = types.new_class("C")
795 self.assertEqual(C.__name__, "C")
796 self.assertEqual(C.__bases__, (object,))
797
798 def test_new_class_subclass(self):
799 C = types.new_class("C", (int,))
800 self.assertTrue(issubclass(C, int))
801
802 def test_new_class_meta(self):
803 Meta = self.Meta
804 settings = {"metaclass": Meta, "z": 2}
805 # We do this twice to make sure the passed in dict isn't mutated
806 for i in range(2):
807 C = types.new_class("C" + str(i), (), settings)
808 self.assertIsInstance(C, Meta)
809 self.assertEqual(C.y, 1)
810 self.assertEqual(C.z, 2)
811
812 def test_new_class_exec_body(self):
813 Meta = self.Meta
814 def func(ns):
815 ns["x"] = 0
816 C = types.new_class("C", (), {"metaclass": Meta, "z": 2}, func)
817 self.assertIsInstance(C, Meta)
818 self.assertEqual(C.x, 0)
819 self.assertEqual(C.y, 1)
820 self.assertEqual(C.z, 2)
821
Benjamin Peterson43f8f4c2012-09-27 18:10:17 -0400822 def test_new_class_metaclass_keywords(self):
Nick Coghlan7fc570a2012-05-20 02:34:13 +1000823 #Test that keywords are passed to the metaclass:
824 def meta_func(name, bases, ns, **kw):
825 return name, bases, ns, kw
826 res = types.new_class("X",
827 (int, object),
828 dict(metaclass=meta_func, x=0))
829 self.assertEqual(res, ("X", (int, object), {}, {"x": 0}))
830
831 def test_new_class_defaults(self):
832 # Test defaults/keywords:
833 C = types.new_class("C", (), {}, None)
834 self.assertEqual(C.__name__, "C")
835 self.assertEqual(C.__bases__, (object,))
836
837 def test_new_class_meta_with_base(self):
838 Meta = self.Meta
839 def func(ns):
840 ns["x"] = 0
841 C = types.new_class(name="C",
842 bases=(int,),
843 kwds=dict(metaclass=Meta, z=2),
844 exec_body=func)
845 self.assertTrue(issubclass(C, int))
846 self.assertIsInstance(C, Meta)
847 self.assertEqual(C.x, 0)
848 self.assertEqual(C.y, 1)
849 self.assertEqual(C.z, 2)
850
Ivan Levkivskyi2b5fd1e2017-12-14 23:32:56 +0100851 def test_new_class_with_mro_entry(self):
852 class A: pass
853 class C:
854 def __mro_entries__(self, bases):
855 return (A,)
856 c = C()
857 D = types.new_class('D', (c,), {})
858 self.assertEqual(D.__bases__, (A,))
859 self.assertEqual(D.__orig_bases__, (c,))
860 self.assertEqual(D.__mro__, (D, A, object))
861
862 def test_new_class_with_mro_entry_none(self):
863 class A: pass
864 class B: pass
865 class C:
866 def __mro_entries__(self, bases):
867 return ()
868 c = C()
869 D = types.new_class('D', (A, c, B), {})
870 self.assertEqual(D.__bases__, (A, B))
871 self.assertEqual(D.__orig_bases__, (A, c, B))
872 self.assertEqual(D.__mro__, (D, A, B, object))
873
874 def test_new_class_with_mro_entry_error(self):
875 class A: pass
876 class C:
877 def __mro_entries__(self, bases):
878 return A
879 c = C()
880 with self.assertRaises(TypeError):
881 types.new_class('D', (c,), {})
882
883 def test_new_class_with_mro_entry_multiple(self):
884 class A1: pass
885 class A2: pass
886 class B1: pass
887 class B2: pass
888 class A:
889 def __mro_entries__(self, bases):
890 return (A1, A2)
891 class B:
892 def __mro_entries__(self, bases):
893 return (B1, B2)
894 D = types.new_class('D', (A(), B()), {})
895 self.assertEqual(D.__bases__, (A1, A2, B1, B2))
896
897 def test_new_class_with_mro_entry_multiple_2(self):
898 class A1: pass
899 class A2: pass
900 class A3: pass
901 class B1: pass
902 class B2: pass
903 class A:
904 def __mro_entries__(self, bases):
905 return (A1, A2, A3)
906 class B:
907 def __mro_entries__(self, bases):
908 return (B1, B2)
909 class C: pass
910 D = types.new_class('D', (A(), C, B()), {})
911 self.assertEqual(D.__bases__, (A1, A2, A3, C, B1, B2))
912
Nick Coghlan7fc570a2012-05-20 02:34:13 +1000913 # Many of the following tests are derived from test_descr.py
914 def test_prepare_class(self):
915 # Basic test of metaclass derivation
916 expected_ns = {}
917 class A(type):
918 def __new__(*args, **kwargs):
919 return type.__new__(*args, **kwargs)
920
921 def __prepare__(*args):
922 return expected_ns
923
924 B = types.new_class("B", (object,))
925 C = types.new_class("C", (object,), {"metaclass": A})
926
927 # The most derived metaclass of D is A rather than type.
928 meta, ns, kwds = types.prepare_class("D", (B, C), {"metaclass": type})
929 self.assertIs(meta, A)
930 self.assertIs(ns, expected_ns)
931 self.assertEqual(len(kwds), 0)
932
Oren Milman5837d042017-09-27 17:04:37 +0300933 def test_bad___prepare__(self):
934 # __prepare__() must return a mapping.
935 class BadMeta(type):
936 @classmethod
937 def __prepare__(*args):
938 return None
939 with self.assertRaisesRegex(TypeError,
940 r'^BadMeta\.__prepare__\(\) must '
941 r'return a mapping, not NoneType$'):
942 class Foo(metaclass=BadMeta):
943 pass
944 # Also test the case in which the metaclass is not a type.
945 class BadMeta:
946 @classmethod
947 def __prepare__(*args):
948 return None
949 with self.assertRaisesRegex(TypeError,
950 r'^<metaclass>\.__prepare__\(\) must '
951 r'return a mapping, not NoneType$'):
952 class Bar(metaclass=BadMeta()):
953 pass
954
Ivan Levkivskyi2b5fd1e2017-12-14 23:32:56 +0100955 def test_resolve_bases(self):
956 class A: pass
957 class B: pass
958 class C:
959 def __mro_entries__(self, bases):
960 if A in bases:
961 return ()
962 return (A,)
963 c = C()
964 self.assertEqual(types.resolve_bases(()), ())
965 self.assertEqual(types.resolve_bases((c,)), (A,))
966 self.assertEqual(types.resolve_bases((C,)), (C,))
967 self.assertEqual(types.resolve_bases((A, C)), (A, C))
968 self.assertEqual(types.resolve_bases((c, A)), (A,))
969 self.assertEqual(types.resolve_bases((A, c)), (A,))
970 x = (A,)
971 y = (C,)
972 z = (A, C)
973 t = (A, C, B)
974 for bases in [x, y, z, t]:
975 self.assertIs(types.resolve_bases(bases), bases)
976
Nick Coghlan7fc570a2012-05-20 02:34:13 +1000977 def test_metaclass_derivation(self):
978 # issue1294232: correct metaclass calculation
979 new_calls = [] # to check the order of __new__ calls
980 class AMeta(type):
981 def __new__(mcls, name, bases, ns):
982 new_calls.append('AMeta')
983 return super().__new__(mcls, name, bases, ns)
984 @classmethod
985 def __prepare__(mcls, name, bases):
986 return {}
987
988 class BMeta(AMeta):
989 def __new__(mcls, name, bases, ns):
990 new_calls.append('BMeta')
991 return super().__new__(mcls, name, bases, ns)
992 @classmethod
993 def __prepare__(mcls, name, bases):
994 ns = super().__prepare__(name, bases)
995 ns['BMeta_was_here'] = True
996 return ns
997
998 A = types.new_class("A", (), {"metaclass": AMeta})
999 self.assertEqual(new_calls, ['AMeta'])
1000 new_calls.clear()
1001
1002 B = types.new_class("B", (), {"metaclass": BMeta})
1003 # BMeta.__new__ calls AMeta.__new__ with super:
1004 self.assertEqual(new_calls, ['BMeta', 'AMeta'])
1005 new_calls.clear()
1006
1007 C = types.new_class("C", (A, B))
1008 # The most derived metaclass is BMeta:
1009 self.assertEqual(new_calls, ['BMeta', 'AMeta'])
1010 new_calls.clear()
1011 # BMeta.__prepare__ should've been called:
1012 self.assertIn('BMeta_was_here', C.__dict__)
1013
1014 # The order of the bases shouldn't matter:
1015 C2 = types.new_class("C2", (B, A))
1016 self.assertEqual(new_calls, ['BMeta', 'AMeta'])
1017 new_calls.clear()
1018 self.assertIn('BMeta_was_here', C2.__dict__)
1019
1020 # Check correct metaclass calculation when a metaclass is declared:
1021 D = types.new_class("D", (C,), {"metaclass": type})
1022 self.assertEqual(new_calls, ['BMeta', 'AMeta'])
1023 new_calls.clear()
1024 self.assertIn('BMeta_was_here', D.__dict__)
1025
1026 E = types.new_class("E", (C,), {"metaclass": AMeta})
1027 self.assertEqual(new_calls, ['BMeta', 'AMeta'])
1028 new_calls.clear()
1029 self.assertIn('BMeta_was_here', E.__dict__)
1030
1031 def test_metaclass_override_function(self):
1032 # Special case: the given metaclass isn't a class,
1033 # so there is no metaclass calculation.
1034 class A(metaclass=self.Meta):
1035 pass
1036
1037 marker = object()
1038 def func(*args, **kwargs):
1039 return marker
1040
1041 X = types.new_class("X", (), {"metaclass": func})
1042 Y = types.new_class("Y", (object,), {"metaclass": func})
1043 Z = types.new_class("Z", (A,), {"metaclass": func})
1044 self.assertIs(marker, X)
1045 self.assertIs(marker, Y)
1046 self.assertIs(marker, Z)
1047
1048 def test_metaclass_override_callable(self):
1049 # The given metaclass is a class,
1050 # but not a descendant of type.
1051 new_calls = [] # to check the order of __new__ calls
1052 prepare_calls = [] # to track __prepare__ calls
1053 class ANotMeta:
1054 def __new__(mcls, *args, **kwargs):
1055 new_calls.append('ANotMeta')
1056 return super().__new__(mcls)
1057 @classmethod
1058 def __prepare__(mcls, name, bases):
1059 prepare_calls.append('ANotMeta')
1060 return {}
1061
1062 class BNotMeta(ANotMeta):
1063 def __new__(mcls, *args, **kwargs):
1064 new_calls.append('BNotMeta')
1065 return super().__new__(mcls)
1066 @classmethod
1067 def __prepare__(mcls, name, bases):
1068 prepare_calls.append('BNotMeta')
1069 return super().__prepare__(name, bases)
1070
1071 A = types.new_class("A", (), {"metaclass": ANotMeta})
1072 self.assertIs(ANotMeta, type(A))
1073 self.assertEqual(prepare_calls, ['ANotMeta'])
1074 prepare_calls.clear()
1075 self.assertEqual(new_calls, ['ANotMeta'])
1076 new_calls.clear()
1077
1078 B = types.new_class("B", (), {"metaclass": BNotMeta})
1079 self.assertIs(BNotMeta, type(B))
1080 self.assertEqual(prepare_calls, ['BNotMeta', 'ANotMeta'])
1081 prepare_calls.clear()
1082 self.assertEqual(new_calls, ['BNotMeta', 'ANotMeta'])
1083 new_calls.clear()
1084
1085 C = types.new_class("C", (A, B))
1086 self.assertIs(BNotMeta, type(C))
1087 self.assertEqual(prepare_calls, ['BNotMeta', 'ANotMeta'])
1088 prepare_calls.clear()
1089 self.assertEqual(new_calls, ['BNotMeta', 'ANotMeta'])
1090 new_calls.clear()
1091
1092 C2 = types.new_class("C2", (B, A))
1093 self.assertIs(BNotMeta, type(C2))
1094 self.assertEqual(prepare_calls, ['BNotMeta', 'ANotMeta'])
1095 prepare_calls.clear()
1096 self.assertEqual(new_calls, ['BNotMeta', 'ANotMeta'])
1097 new_calls.clear()
1098
1099 # This is a TypeError, because of a metaclass conflict:
1100 # BNotMeta is neither a subclass, nor a superclass of type
1101 with self.assertRaises(TypeError):
1102 D = types.new_class("D", (C,), {"metaclass": type})
1103
1104 E = types.new_class("E", (C,), {"metaclass": ANotMeta})
1105 self.assertIs(BNotMeta, type(E))
1106 self.assertEqual(prepare_calls, ['BNotMeta', 'ANotMeta'])
1107 prepare_calls.clear()
1108 self.assertEqual(new_calls, ['BNotMeta', 'ANotMeta'])
1109 new_calls.clear()
1110
1111 F = types.new_class("F", (object(), C))
1112 self.assertIs(BNotMeta, type(F))
1113 self.assertEqual(prepare_calls, ['BNotMeta', 'ANotMeta'])
1114 prepare_calls.clear()
1115 self.assertEqual(new_calls, ['BNotMeta', 'ANotMeta'])
1116 new_calls.clear()
1117
1118 F2 = types.new_class("F2", (C, object()))
1119 self.assertIs(BNotMeta, type(F2))
1120 self.assertEqual(prepare_calls, ['BNotMeta', 'ANotMeta'])
1121 prepare_calls.clear()
1122 self.assertEqual(new_calls, ['BNotMeta', 'ANotMeta'])
1123 new_calls.clear()
1124
1125 # TypeError: BNotMeta is neither a
1126 # subclass, nor a superclass of int
1127 with self.assertRaises(TypeError):
1128 X = types.new_class("X", (C, int()))
1129 with self.assertRaises(TypeError):
1130 X = types.new_class("X", (int(), C))
1131
Berker Peksag3f015a62016-08-19 11:04:07 +03001132 def test_one_argument_type(self):
1133 expected_message = 'type.__new__() takes exactly 3 arguments (1 given)'
1134
1135 # Only type itself can use the one-argument form (#27157)
1136 self.assertIs(type(5), int)
1137
1138 class M(type):
1139 pass
1140 with self.assertRaises(TypeError) as cm:
1141 M(5)
1142 self.assertEqual(str(cm.exception), expected_message)
1143
1144 class N(type, metaclass=M):
1145 pass
1146 with self.assertRaises(TypeError) as cm:
1147 N(5)
1148 self.assertEqual(str(cm.exception), expected_message)
1149
Nick Coghlan7fc570a2012-05-20 02:34:13 +10001150
Barry Warsaw409da152012-06-03 16:18:47 -04001151class SimpleNamespaceTests(unittest.TestCase):
1152
1153 def test_constructor(self):
1154 ns1 = types.SimpleNamespace()
1155 ns2 = types.SimpleNamespace(x=1, y=2)
1156 ns3 = types.SimpleNamespace(**dict(x=1, y=2))
1157
1158 with self.assertRaises(TypeError):
1159 types.SimpleNamespace(1, 2, 3)
Serhiy Storchaka79ba4712017-10-07 22:59:35 +03001160 with self.assertRaises(TypeError):
1161 types.SimpleNamespace(**{1: 2})
Barry Warsaw409da152012-06-03 16:18:47 -04001162
1163 self.assertEqual(len(ns1.__dict__), 0)
1164 self.assertEqual(vars(ns1), {})
1165 self.assertEqual(len(ns2.__dict__), 2)
1166 self.assertEqual(vars(ns2), {'y': 2, 'x': 1})
1167 self.assertEqual(len(ns3.__dict__), 2)
1168 self.assertEqual(vars(ns3), {'y': 2, 'x': 1})
1169
1170 def test_unbound(self):
1171 ns1 = vars(types.SimpleNamespace())
1172 ns2 = vars(types.SimpleNamespace(x=1, y=2))
1173
1174 self.assertEqual(ns1, {})
1175 self.assertEqual(ns2, {'y': 2, 'x': 1})
1176
1177 def test_underlying_dict(self):
1178 ns1 = types.SimpleNamespace()
1179 ns2 = types.SimpleNamespace(x=1, y=2)
1180 ns3 = types.SimpleNamespace(a=True, b=False)
1181 mapping = ns3.__dict__
1182 del ns3
1183
1184 self.assertEqual(ns1.__dict__, {})
1185 self.assertEqual(ns2.__dict__, {'y': 2, 'x': 1})
1186 self.assertEqual(mapping, dict(a=True, b=False))
1187
1188 def test_attrget(self):
1189 ns = types.SimpleNamespace(x=1, y=2, w=3)
1190
1191 self.assertEqual(ns.x, 1)
1192 self.assertEqual(ns.y, 2)
1193 self.assertEqual(ns.w, 3)
1194 with self.assertRaises(AttributeError):
1195 ns.z
1196
1197 def test_attrset(self):
1198 ns1 = types.SimpleNamespace()
1199 ns2 = types.SimpleNamespace(x=1, y=2, w=3)
1200 ns1.a = 'spam'
1201 ns1.b = 'ham'
1202 ns2.z = 4
1203 ns2.theta = None
1204
1205 self.assertEqual(ns1.__dict__, dict(a='spam', b='ham'))
1206 self.assertEqual(ns2.__dict__, dict(x=1, y=2, w=3, z=4, theta=None))
1207
1208 def test_attrdel(self):
1209 ns1 = types.SimpleNamespace()
1210 ns2 = types.SimpleNamespace(x=1, y=2, w=3)
1211
1212 with self.assertRaises(AttributeError):
1213 del ns1.spam
1214 with self.assertRaises(AttributeError):
1215 del ns2.spam
1216
1217 del ns2.y
1218 self.assertEqual(vars(ns2), dict(w=3, x=1))
1219 ns2.y = 'spam'
1220 self.assertEqual(vars(ns2), dict(w=3, x=1, y='spam'))
1221 del ns2.y
1222 self.assertEqual(vars(ns2), dict(w=3, x=1))
1223
1224 ns1.spam = 5
1225 self.assertEqual(vars(ns1), dict(spam=5))
1226 del ns1.spam
1227 self.assertEqual(vars(ns1), {})
1228
1229 def test_repr(self):
1230 ns1 = types.SimpleNamespace(x=1, y=2, w=3)
1231 ns2 = types.SimpleNamespace()
1232 ns2.x = "spam"
1233 ns2._y = 5
Eric Snowb5c8f922013-02-16 16:32:39 -07001234 name = "namespace"
Barry Warsaw409da152012-06-03 16:18:47 -04001235
Eric Snowb5c8f922013-02-16 16:32:39 -07001236 self.assertEqual(repr(ns1), "{name}(w=3, x=1, y=2)".format(name=name))
1237 self.assertEqual(repr(ns2), "{name}(_y=5, x='spam')".format(name=name))
1238
1239 def test_equal(self):
1240 ns1 = types.SimpleNamespace(x=1)
1241 ns2 = types.SimpleNamespace()
1242 ns2.x = 1
1243
1244 self.assertEqual(types.SimpleNamespace(), types.SimpleNamespace())
1245 self.assertEqual(ns1, ns2)
1246 self.assertNotEqual(ns2, types.SimpleNamespace())
Barry Warsaw409da152012-06-03 16:18:47 -04001247
1248 def test_nested(self):
1249 ns1 = types.SimpleNamespace(a=1, b=2)
1250 ns2 = types.SimpleNamespace()
1251 ns3 = types.SimpleNamespace(x=ns1)
1252 ns2.spam = ns1
1253 ns2.ham = '?'
1254 ns2.spam = ns3
1255
1256 self.assertEqual(vars(ns1), dict(a=1, b=2))
1257 self.assertEqual(vars(ns2), dict(spam=ns3, ham='?'))
1258 self.assertEqual(ns2.spam, ns3)
1259 self.assertEqual(vars(ns3), dict(x=ns1))
1260 self.assertEqual(ns3.x.a, 1)
1261
1262 def test_recursive(self):
1263 ns1 = types.SimpleNamespace(c='cookie')
1264 ns2 = types.SimpleNamespace()
1265 ns3 = types.SimpleNamespace(x=1)
1266 ns1.spam = ns1
1267 ns2.spam = ns3
1268 ns3.spam = ns2
1269
1270 self.assertEqual(ns1.spam, ns1)
1271 self.assertEqual(ns1.spam.spam, ns1)
1272 self.assertEqual(ns1.spam.spam, ns1.spam)
1273 self.assertEqual(ns2.spam, ns3)
1274 self.assertEqual(ns3.spam, ns2)
1275 self.assertEqual(ns2.spam.spam, ns2)
1276
1277 def test_recursive_repr(self):
1278 ns1 = types.SimpleNamespace(c='cookie')
1279 ns2 = types.SimpleNamespace()
1280 ns3 = types.SimpleNamespace(x=1)
1281 ns1.spam = ns1
1282 ns2.spam = ns3
1283 ns3.spam = ns2
Eric Snowb5c8f922013-02-16 16:32:39 -07001284 name = "namespace"
1285 repr1 = "{name}(c='cookie', spam={name}(...))".format(name=name)
1286 repr2 = "{name}(spam={name}(spam={name}(...), x=1))".format(name=name)
Barry Warsaw409da152012-06-03 16:18:47 -04001287
Eric Snowb5c8f922013-02-16 16:32:39 -07001288 self.assertEqual(repr(ns1), repr1)
1289 self.assertEqual(repr(ns2), repr2)
Barry Warsaw409da152012-06-03 16:18:47 -04001290
1291 def test_as_dict(self):
1292 ns = types.SimpleNamespace(spam='spamspamspam')
1293
1294 with self.assertRaises(TypeError):
1295 len(ns)
1296 with self.assertRaises(TypeError):
1297 iter(ns)
1298 with self.assertRaises(TypeError):
1299 'spam' in ns
1300 with self.assertRaises(TypeError):
1301 ns['spam']
1302
Eric Snow547298c2012-10-16 22:35:38 -07001303 def test_subclass(self):
1304 class Spam(types.SimpleNamespace):
1305 pass
1306
1307 spam = Spam(ham=8, eggs=9)
1308
1309 self.assertIs(type(spam), Spam)
1310 self.assertEqual(vars(spam), {'ham': 8, 'eggs': 9})
1311
Eric Snowb5c8f922013-02-16 16:32:39 -07001312 def test_pickle(self):
1313 ns = types.SimpleNamespace(breakfast="spam", lunch="spam")
1314
Eric Snow9d05c8c2013-02-16 18:20:32 -07001315 for protocol in range(pickle.HIGHEST_PROTOCOL + 1):
1316 pname = "protocol {}".format(protocol)
1317 try:
1318 ns_pickled = pickle.dumps(ns, protocol)
1319 except TypeError as e:
1320 raise TypeError(pname) from e
1321 ns_roundtrip = pickle.loads(ns_pickled)
Eric Snowb5c8f922013-02-16 16:32:39 -07001322
Eric Snow9d05c8c2013-02-16 18:20:32 -07001323 self.assertEqual(ns, ns_roundtrip, pname)
Eric Snowb5c8f922013-02-16 16:32:39 -07001324
Serhiy Storchaka08d230a2015-05-22 11:02:49 +03001325 def test_fake_namespace_compare(self):
1326 # Issue #24257: Incorrect use of PyObject_IsInstance() caused
1327 # SystemError.
1328 class FakeSimpleNamespace(str):
1329 __class__ = types.SimpleNamespace
1330 self.assertFalse(types.SimpleNamespace() == FakeSimpleNamespace())
1331 self.assertTrue(types.SimpleNamespace() != FakeSimpleNamespace())
1332 with self.assertRaises(TypeError):
1333 types.SimpleNamespace() < FakeSimpleNamespace()
1334 with self.assertRaises(TypeError):
1335 types.SimpleNamespace() <= FakeSimpleNamespace()
1336 with self.assertRaises(TypeError):
1337 types.SimpleNamespace() > FakeSimpleNamespace()
1338 with self.assertRaises(TypeError):
1339 types.SimpleNamespace() >= FakeSimpleNamespace()
1340
Barry Warsaw409da152012-06-03 16:18:47 -04001341
Yury Selivanov75445082015-05-11 22:57:16 -04001342class CoroutineTests(unittest.TestCase):
1343 def test_wrong_args(self):
Yury Selivanovc565cd52015-05-29 09:06:05 -04001344 samples = [None, 1, object()]
Yury Selivanov75445082015-05-11 22:57:16 -04001345 for sample in samples:
Yury Selivanovc565cd52015-05-29 09:06:05 -04001346 with self.assertRaisesRegex(TypeError,
1347 'types.coroutine.*expects a callable'):
Yury Selivanov75445082015-05-11 22:57:16 -04001348 types.coroutine(sample)
1349
Yury Selivanov00e33722015-06-24 11:44:51 -04001350 def test_non_gen_values(self):
Yury Selivanovc565cd52015-05-29 09:06:05 -04001351 @types.coroutine
1352 def foo():
Yury Selivanov5376ba92015-06-22 12:19:30 -04001353 return 'spam'
1354 self.assertEqual(foo(), 'spam')
1355
Yury Selivanov00e33722015-06-24 11:44:51 -04001356 class Awaitable:
1357 def __await__(self):
1358 return ()
1359 aw = Awaitable()
1360 @types.coroutine
1361 def foo():
1362 return aw
1363 self.assertIs(aw, foo())
1364
Yury Selivanov4887523c2015-07-23 15:58:37 +03001365 # decorate foo second time
1366 foo = types.coroutine(foo)
1367 self.assertIs(aw, foo())
1368
Yury Selivanov5376ba92015-06-22 12:19:30 -04001369 def test_async_def(self):
1370 # Test that types.coroutine passes 'async def' coroutines
1371 # without modification
1372
1373 async def foo(): pass
1374 foo_code = foo.__code__
1375 foo_flags = foo.__code__.co_flags
1376 decorated_foo = types.coroutine(foo)
1377 self.assertIs(foo, decorated_foo)
1378 self.assertEqual(foo.__code__.co_flags, foo_flags)
1379 self.assertIs(decorated_foo.__code__, foo_code)
1380
1381 foo_coro = foo()
Yury Selivanov5376ba92015-06-22 12:19:30 -04001382 def bar(): return foo_coro
Yury Selivanov4887523c2015-07-23 15:58:37 +03001383 for _ in range(2):
1384 bar = types.coroutine(bar)
1385 coro = bar()
1386 self.assertIs(foo_coro, coro)
1387 self.assertEqual(coro.cr_code.co_flags, foo_flags)
1388 coro.close()
Yury Selivanovc565cd52015-05-29 09:06:05 -04001389
1390 def test_duck_coro(self):
1391 class CoroLike:
1392 def send(self): pass
1393 def throw(self): pass
1394 def close(self): pass
Yury Selivanov13f77232015-05-29 16:19:18 -04001395 def __await__(self): return self
Yury Selivanovc565cd52015-05-29 09:06:05 -04001396
1397 coro = CoroLike()
1398 @types.coroutine
1399 def foo():
1400 return coro
Yury Selivanov5376ba92015-06-22 12:19:30 -04001401 self.assertIs(foo(), coro)
1402 self.assertIs(foo().__await__(), coro)
1403
1404 def test_duck_corogen(self):
1405 class CoroGenLike:
1406 def send(self): pass
1407 def throw(self): pass
1408 def close(self): pass
1409 def __await__(self): return self
1410 def __iter__(self): return self
1411 def __next__(self): pass
1412
1413 coro = CoroGenLike()
1414 @types.coroutine
1415 def foo():
1416 return coro
1417 self.assertIs(foo(), coro)
Yury Selivanov13f77232015-05-29 16:19:18 -04001418 self.assertIs(foo().__await__(), coro)
1419
1420 def test_duck_gen(self):
1421 class GenLike:
1422 def send(self): pass
1423 def throw(self): pass
1424 def close(self): pass
Yury Selivanov00e33722015-06-24 11:44:51 -04001425 def __iter__(self): pass
Yury Selivanov13f77232015-05-29 16:19:18 -04001426 def __next__(self): pass
1427
Yury Selivanov00e33722015-06-24 11:44:51 -04001428 # Setup generator mock object
1429 gen = unittest.mock.MagicMock(GenLike)
1430 gen.__iter__ = lambda gen: gen
1431 gen.__name__ = 'gen'
1432 gen.__qualname__ = 'test.gen'
1433 self.assertIsInstance(gen, collections.abc.Generator)
1434 self.assertIs(gen, iter(gen))
1435
Yury Selivanov13f77232015-05-29 16:19:18 -04001436 @types.coroutine
Yury Selivanov00e33722015-06-24 11:44:51 -04001437 def foo(): return gen
1438
1439 wrapper = foo()
1440 self.assertIsInstance(wrapper, types._GeneratorWrapper)
1441 self.assertIs(wrapper.__await__(), wrapper)
1442 # Wrapper proxies duck generators completely:
1443 self.assertIs(iter(wrapper), wrapper)
1444
1445 self.assertIsInstance(wrapper, collections.abc.Coroutine)
1446 self.assertIsInstance(wrapper, collections.abc.Awaitable)
1447
1448 self.assertIs(wrapper.__qualname__, gen.__qualname__)
1449 self.assertIs(wrapper.__name__, gen.__name__)
1450
1451 # Test AttributeErrors
Yury Selivanov53e62302015-07-03 00:35:02 -04001452 for name in {'gi_running', 'gi_frame', 'gi_code', 'gi_yieldfrom',
1453 'cr_running', 'cr_frame', 'cr_code', 'cr_await'}:
Yury Selivanov00e33722015-06-24 11:44:51 -04001454 with self.assertRaises(AttributeError):
1455 getattr(wrapper, name)
1456
1457 # Test attributes pass-through
1458 gen.gi_running = object()
1459 gen.gi_frame = object()
1460 gen.gi_code = object()
Yury Selivanov53e62302015-07-03 00:35:02 -04001461 gen.gi_yieldfrom = object()
Yury Selivanov00e33722015-06-24 11:44:51 -04001462 self.assertIs(wrapper.gi_running, gen.gi_running)
1463 self.assertIs(wrapper.gi_frame, gen.gi_frame)
1464 self.assertIs(wrapper.gi_code, gen.gi_code)
Yury Selivanov53e62302015-07-03 00:35:02 -04001465 self.assertIs(wrapper.gi_yieldfrom, gen.gi_yieldfrom)
Yury Selivanov00e33722015-06-24 11:44:51 -04001466 self.assertIs(wrapper.cr_running, gen.gi_running)
1467 self.assertIs(wrapper.cr_frame, gen.gi_frame)
1468 self.assertIs(wrapper.cr_code, gen.gi_code)
Yury Selivanov53e62302015-07-03 00:35:02 -04001469 self.assertIs(wrapper.cr_await, gen.gi_yieldfrom)
Yury Selivanov00e33722015-06-24 11:44:51 -04001470
1471 wrapper.close()
1472 gen.close.assert_called_once_with()
1473
1474 wrapper.send(1)
1475 gen.send.assert_called_once_with(1)
Yury Selivanovf847f1f2015-06-24 12:49:28 -04001476 gen.reset_mock()
1477
1478 next(wrapper)
1479 gen.__next__.assert_called_once_with()
1480 gen.reset_mock()
Yury Selivanov00e33722015-06-24 11:44:51 -04001481
1482 wrapper.throw(1, 2, 3)
1483 gen.throw.assert_called_once_with(1, 2, 3)
1484 gen.reset_mock()
1485
1486 wrapper.throw(1, 2)
1487 gen.throw.assert_called_once_with(1, 2)
1488 gen.reset_mock()
1489
1490 wrapper.throw(1)
1491 gen.throw.assert_called_once_with(1)
1492 gen.reset_mock()
1493
1494 # Test exceptions propagation
1495 error = Exception()
1496 gen.throw.side_effect = error
1497 try:
1498 wrapper.throw(1)
1499 except Exception as ex:
1500 self.assertIs(ex, error)
1501 else:
1502 self.fail('wrapper did not propagate an exception')
1503
1504 # Test invalid args
1505 gen.reset_mock()
1506 with self.assertRaises(TypeError):
1507 wrapper.throw()
1508 self.assertFalse(gen.throw.called)
1509 with self.assertRaises(TypeError):
1510 wrapper.close(1)
1511 self.assertFalse(gen.close.called)
1512 with self.assertRaises(TypeError):
1513 wrapper.send()
1514 self.assertFalse(gen.send.called)
1515
1516 # Test that we do not double wrap
1517 @types.coroutine
1518 def bar(): return wrapper
1519 self.assertIs(wrapper, bar())
1520
1521 # Test weakrefs support
1522 ref = weakref.ref(wrapper)
1523 self.assertIs(ref(), wrapper)
1524
1525 def test_duck_functional_gen(self):
1526 class Generator:
1527 """Emulates the following generator (very clumsy):
1528
1529 def gen(fut):
1530 result = yield fut
1531 return result * 2
1532 """
1533 def __init__(self, fut):
1534 self._i = 0
1535 self._fut = fut
1536 def __iter__(self):
1537 return self
1538 def __next__(self):
1539 return self.send(None)
1540 def send(self, v):
1541 try:
1542 if self._i == 0:
1543 assert v is None
1544 return self._fut
1545 if self._i == 1:
1546 raise StopIteration(v * 2)
1547 if self._i > 1:
1548 raise StopIteration
1549 finally:
1550 self._i += 1
1551 def throw(self, tp, *exc):
1552 self._i = 100
1553 if tp is not GeneratorExit:
1554 raise tp
1555 def close(self):
1556 self.throw(GeneratorExit)
1557
1558 @types.coroutine
1559 def foo(): return Generator('spam')
1560
1561 wrapper = foo()
1562 self.assertIsInstance(wrapper, types._GeneratorWrapper)
1563
1564 async def corofunc():
1565 return await foo() + 100
1566 coro = corofunc()
1567
1568 self.assertEqual(coro.send(None), 'spam')
1569 try:
1570 coro.send(20)
1571 except StopIteration as ex:
1572 self.assertEqual(ex.args[0], 140)
1573 else:
1574 self.fail('StopIteration was expected')
Yury Selivanov13f77232015-05-29 16:19:18 -04001575
1576 def test_gen(self):
Yury Selivanovf847f1f2015-06-24 12:49:28 -04001577 def gen_func():
1578 yield 1
1579 return (yield 2)
1580 gen = gen_func()
Yury Selivanov13f77232015-05-29 16:19:18 -04001581 @types.coroutine
1582 def foo(): return gen
Yury Selivanov00e33722015-06-24 11:44:51 -04001583 wrapper = foo()
1584 self.assertIsInstance(wrapper, types._GeneratorWrapper)
1585 self.assertIs(wrapper.__await__(), gen)
Yury Selivanov13f77232015-05-29 16:19:18 -04001586
1587 for name in ('__name__', '__qualname__', 'gi_code',
1588 'gi_running', 'gi_frame'):
1589 self.assertIs(getattr(foo(), name),
1590 getattr(gen, name))
Yury Selivanov5376ba92015-06-22 12:19:30 -04001591 self.assertIs(foo().cr_code, gen.gi_code)
Yury Selivanovc565cd52015-05-29 09:06:05 -04001592
Yury Selivanovf847f1f2015-06-24 12:49:28 -04001593 self.assertEqual(next(wrapper), 1)
1594 self.assertEqual(wrapper.send(None), 2)
1595 with self.assertRaisesRegex(StopIteration, 'spam'):
1596 wrapper.send('spam')
1597
1598 gen = gen_func()
1599 wrapper = foo()
1600 wrapper.send(None)
1601 with self.assertRaisesRegex(Exception, 'ham'):
1602 wrapper.throw(Exception, Exception('ham'))
1603
Yury Selivanov4887523c2015-07-23 15:58:37 +03001604 # decorate foo second time
1605 foo = types.coroutine(foo)
1606 self.assertIs(foo().__await__(), gen)
1607
Yury Selivanovfdbeb2b2015-07-03 13:11:35 -04001608 def test_returning_itercoro(self):
1609 @types.coroutine
1610 def gen():
1611 yield
1612
1613 gencoro = gen()
1614
1615 @types.coroutine
1616 def foo():
1617 return gencoro
1618
1619 self.assertIs(foo(), gencoro)
1620
Yury Selivanov4887523c2015-07-23 15:58:37 +03001621 # decorate foo second time
1622 foo = types.coroutine(foo)
1623 self.assertIs(foo(), gencoro)
1624
Yury Selivanov75445082015-05-11 22:57:16 -04001625 def test_genfunc(self):
Yury Selivanov00e33722015-06-24 11:44:51 -04001626 def gen(): yield
1627 self.assertIs(types.coroutine(gen), gen)
Yury Selivanov4887523c2015-07-23 15:58:37 +03001628 self.assertIs(types.coroutine(types.coroutine(gen)), gen)
Yury Selivanov75445082015-05-11 22:57:16 -04001629
1630 self.assertTrue(gen.__code__.co_flags & inspect.CO_ITERABLE_COROUTINE)
1631 self.assertFalse(gen.__code__.co_flags & inspect.CO_COROUTINE)
1632
1633 g = gen()
1634 self.assertTrue(g.gi_code.co_flags & inspect.CO_ITERABLE_COROUTINE)
1635 self.assertFalse(g.gi_code.co_flags & inspect.CO_COROUTINE)
Yury Selivanov75445082015-05-11 22:57:16 -04001636
Yury Selivanov00e33722015-06-24 11:44:51 -04001637 self.assertIs(types.coroutine(gen), gen)
1638
1639 def test_wrapper_object(self):
1640 def gen():
1641 yield
1642 @types.coroutine
1643 def coro():
1644 return gen()
1645
1646 wrapper = coro()
1647 self.assertIn('GeneratorWrapper', repr(wrapper))
1648 self.assertEqual(repr(wrapper), str(wrapper))
1649 self.assertTrue(set(dir(wrapper)).issuperset({
1650 '__await__', '__iter__', '__next__', 'cr_code', 'cr_running',
1651 'cr_frame', 'gi_code', 'gi_frame', 'gi_running', 'send',
1652 'close', 'throw'}))
1653
Yury Selivanov75445082015-05-11 22:57:16 -04001654
Thomas Wouters89f507f2006-12-13 04:49:30 +00001655if __name__ == '__main__':
Zachary Ware38c707e2015-04-13 15:00:43 -05001656 unittest.main()