blob: 5e741153f42d6c14e6b7e50720a6b611dd9c1fd1 [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')
Neil Schemenauereff72442002-03-24 01:24:54 +000051
Thomas Wouters89f507f2006-12-13 04:49:30 +000052 def test_zero_division(self):
53 try: 5.0 / 0.0
54 except ZeroDivisionError: pass
55 else: self.fail("5.0 / 0.0 didn't raise ZeroDivisionError")
Neil Schemenauereff72442002-03-24 01:24:54 +000056
Thomas Wouters89f507f2006-12-13 04:49:30 +000057 try: 5.0 // 0.0
58 except ZeroDivisionError: pass
59 else: self.fail("5.0 // 0.0 didn't raise ZeroDivisionError")
Neil Schemenauereff72442002-03-24 01:24:54 +000060
Thomas Wouters89f507f2006-12-13 04:49:30 +000061 try: 5.0 % 0.0
62 except ZeroDivisionError: pass
63 else: self.fail("5.0 % 0.0 didn't raise ZeroDivisionError")
Neil Schemenauereff72442002-03-24 01:24:54 +000064
Guido van Rossume2a383d2007-01-15 16:59:06 +000065 try: 5 / 0
Thomas Wouters89f507f2006-12-13 04:49:30 +000066 except ZeroDivisionError: pass
Christian Heimes7131fd92008-02-19 14:21:46 +000067 else: self.fail("5 / 0 didn't raise ZeroDivisionError")
Neil Schemenauereff72442002-03-24 01:24:54 +000068
Guido van Rossume2a383d2007-01-15 16:59:06 +000069 try: 5 // 0
Thomas Wouters89f507f2006-12-13 04:49:30 +000070 except ZeroDivisionError: pass
Christian Heimes7131fd92008-02-19 14:21:46 +000071 else: self.fail("5 // 0 didn't raise ZeroDivisionError")
Neil Schemenauereff72442002-03-24 01:24:54 +000072
Guido van Rossume2a383d2007-01-15 16:59:06 +000073 try: 5 % 0
Thomas Wouters89f507f2006-12-13 04:49:30 +000074 except ZeroDivisionError: pass
Christian Heimes7131fd92008-02-19 14:21:46 +000075 else: self.fail("5 % 0 didn't raise ZeroDivisionError")
Tim Petersa3c01ce2001-12-04 23:05:10 +000076
Thomas Wouters89f507f2006-12-13 04:49:30 +000077 def test_numeric_types(self):
Mark Dickinson5c2db372009-12-05 20:28:34 +000078 if 0 != 0.0 or 1 != 1.0 or -1 != -1.0:
79 self.fail('int/float value not equal')
Thomas Wouters89f507f2006-12-13 04:49:30 +000080 # calling built-in types without argument must return 0
81 if int() != 0: self.fail('int() does not return 0')
Thomas Wouters89f507f2006-12-13 04:49:30 +000082 if float() != 0.0: self.fail('float() does not return 0.0')
83 if int(1.9) == 1 == int(1.1) and int(-1.1) == -1 == int(-1.9): pass
84 else: self.fail('int() does not round properly')
Thomas Wouters89f507f2006-12-13 04:49:30 +000085 if float(1) == 1.0 and float(-1) == -1.0 and float(0) == 0.0: pass
86 else: self.fail('float() does not work properly')
Neil Schemenauereff72442002-03-24 01:24:54 +000087
Christian Heimesc3f30c42008-02-22 16:37:40 +000088 def test_float_to_string(self):
89 def test(f, result):
90 self.assertEqual(f.__format__('e'), result)
91 self.assertEqual('%e' % f, result)
92
93 # test all 2 digit exponents, both with __format__ and with
94 # '%' formatting
95 for i in range(-99, 100):
96 test(float('1.5e'+str(i)), '1.500000e{0:+03d}'.format(i))
97
98 # test some 3 digit exponents
99 self.assertEqual(1.5e100.__format__('e'), '1.500000e+100')
100 self.assertEqual('%e' % 1.5e100, '1.500000e+100')
101
102 self.assertEqual(1.5e101.__format__('e'), '1.500000e+101')
103 self.assertEqual('%e' % 1.5e101, '1.500000e+101')
104
105 self.assertEqual(1.5e-100.__format__('e'), '1.500000e-100')
106 self.assertEqual('%e' % 1.5e-100, '1.500000e-100')
107
108 self.assertEqual(1.5e-101.__format__('e'), '1.500000e-101')
109 self.assertEqual('%e' % 1.5e-101, '1.500000e-101')
110
Eric Smith0923d1d2009-04-16 20:16:10 +0000111 self.assertEqual('%g' % 1.0, '1')
112 self.assertEqual('%#g' % 1.0, '1.00000')
113
Thomas Wouters89f507f2006-12-13 04:49:30 +0000114 def test_normal_integers(self):
115 # Ensure the first 256 integers are shared
116 a = 256
117 b = 128*2
118 if a is not b: self.fail('256 is not shared')
119 if 12 + 24 != 36: self.fail('int op')
120 if 12 + (-24) != -12: self.fail('int op')
121 if (-12) + 24 != 12: self.fail('int op')
122 if (-12) + (-24) != -36: self.fail('int op')
123 if not 12 < 24: self.fail('int op')
124 if not -24 < -12: self.fail('int op')
125 # Test for a particular bug in integer multiply
126 xsize, ysize, zsize = 238, 356, 4
127 if not (xsize*ysize*zsize == zsize*xsize*ysize == 338912):
128 self.fail('int mul commutativity')
129 # And another.
Christian Heimesa37d4c62007-12-04 23:02:19 +0000130 m = -sys.maxsize - 1
Thomas Wouters89f507f2006-12-13 04:49:30 +0000131 for divisor in 1, 2, 4, 8, 16, 32:
132 j = m // divisor
133 prod = divisor * j
134 if prod != m:
135 self.fail("%r * %r == %r != %r" % (divisor, j, prod, m))
136 if type(prod) is not int:
137 self.fail("expected type(prod) to be int, not %r" %
138 type(prod))
Mark Dickinson5c2db372009-12-05 20:28:34 +0000139 # Check for unified integral type
Thomas Wouters89f507f2006-12-13 04:49:30 +0000140 for divisor in 1, 2, 4, 8, 16, 32:
141 j = m // divisor - 1
142 prod = divisor * j
Guido van Rossume2a383d2007-01-15 16:59:06 +0000143 if type(prod) is not int:
Mark Dickinson5c2db372009-12-05 20:28:34 +0000144 self.fail("expected type(%r) to be int, not %r" %
Thomas Wouters89f507f2006-12-13 04:49:30 +0000145 (prod, type(prod)))
Mark Dickinson5c2db372009-12-05 20:28:34 +0000146 # Check for unified integral type
Christian Heimesa37d4c62007-12-04 23:02:19 +0000147 m = sys.maxsize
Thomas Wouters89f507f2006-12-13 04:49:30 +0000148 for divisor in 1, 2, 4, 8, 16, 32:
149 j = m // divisor + 1
150 prod = divisor * j
Guido van Rossume2a383d2007-01-15 16:59:06 +0000151 if type(prod) is not int:
Mark Dickinson5c2db372009-12-05 20:28:34 +0000152 self.fail("expected type(%r) to be int, not %r" %
Thomas Wouters89f507f2006-12-13 04:49:30 +0000153 (prod, type(prod)))
Neil Schemenauereff72442002-03-24 01:24:54 +0000154
Christian Heimesa37d4c62007-12-04 23:02:19 +0000155 x = sys.maxsize
Ezio Melottie9615932010-01-24 19:26:24 +0000156 self.assertIsInstance(x + 1, int,
157 "(sys.maxsize + 1) should have returned int")
158 self.assertIsInstance(-x - 1, int,
159 "(-sys.maxsize - 1) should have returned int")
160 self.assertIsInstance(-x - 2, int,
161 "(-sys.maxsize - 2) should have returned int")
Neil Schemenauereff72442002-03-24 01:24:54 +0000162
Thomas Wouters89f507f2006-12-13 04:49:30 +0000163 try: 5 << -5
164 except ValueError: pass
165 else: self.fail('int negative shift <<')
Neil Schemenauereff72442002-03-24 01:24:54 +0000166
Thomas Wouters89f507f2006-12-13 04:49:30 +0000167 try: 5 >> -5
168 except ValueError: pass
169 else: self.fail('int negative shift >>')
Guido van Rossum85f18201992-11-27 22:53:50 +0000170
Thomas Wouters89f507f2006-12-13 04:49:30 +0000171 def test_floats(self):
172 if 12.0 + 24.0 != 36.0: self.fail('float op')
173 if 12.0 + (-24.0) != -12.0: self.fail('float op')
174 if (-12.0) + 24.0 != 12.0: self.fail('float op')
175 if (-12.0) + (-24.0) != -36.0: self.fail('float op')
176 if not 12.0 < 24.0: self.fail('float op')
177 if not -24.0 < -12.0: self.fail('float op')
Guido van Rossum85f18201992-11-27 22:53:50 +0000178
Thomas Wouters89f507f2006-12-13 04:49:30 +0000179 def test_strings(self):
180 if len('') != 0: self.fail('len(\'\')')
181 if len('a') != 1: self.fail('len(\'a\')')
182 if len('abcdef') != 6: self.fail('len(\'abcdef\')')
183 if 'xyz' + 'abcde' != 'xyzabcde': self.fail('string concatenation')
184 if 'xyz'*3 != 'xyzxyzxyz': self.fail('string repetition *3')
185 if 0*'abcde' != '': self.fail('string repetition 0*')
186 if min('abc') != 'a' or max('abc') != 'c': self.fail('min/max string')
187 if 'a' in 'abc' and 'b' in 'abc' and 'c' in 'abc' and 'd' not in 'abc': pass
188 else: self.fail('in/not in string')
189 x = 'x'*103
190 if '%s!'%x != x+'!': self.fail('nasty string formatting bug')
Michael W. Hudson5efaf7e2002-06-11 10:55:12 +0000191
Thomas Wouters89f507f2006-12-13 04:49:30 +0000192 #extended slices for strings
193 a = '0123456789'
194 self.assertEqual(a[::], a)
195 self.assertEqual(a[::2], '02468')
196 self.assertEqual(a[1::2], '13579')
197 self.assertEqual(a[::-1],'9876543210')
198 self.assertEqual(a[::-2], '97531')
199 self.assertEqual(a[3::-2], '31')
200 self.assertEqual(a[-100:100:], a)
201 self.assertEqual(a[100:-100:-1], a[::-1])
Guido van Rossume2a383d2007-01-15 16:59:06 +0000202 self.assertEqual(a[-100:100:2], '02468')
Thomas Wouters89f507f2006-12-13 04:49:30 +0000203
Thomas Wouters89f507f2006-12-13 04:49:30 +0000204 def test_type_function(self):
205 self.assertRaises(TypeError, type, 1, 2)
206 self.assertRaises(TypeError, type, 1, 2, 3, 4)
Guido van Rossum85f18201992-11-27 22:53:50 +0000207
Christian Heimes7131fd92008-02-19 14:21:46 +0000208 def test_int__format__(self):
209 def test(i, format_spec, result):
Mark Dickinson5c2db372009-12-05 20:28:34 +0000210 # just make sure we have the unified type for integers
Christian Heimes7131fd92008-02-19 14:21:46 +0000211 assert type(i) == int
212 assert type(format_spec) == str
213 self.assertEqual(i.__format__(format_spec), result)
214
215 test(123456789, 'd', '123456789')
216 test(123456789, 'd', '123456789')
217
218 test(1, 'c', '\01')
219
220 # sign and aligning are interdependent
221 test(1, "-", '1')
222 test(-1, "-", '-1')
223 test(1, "-3", ' 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, " ", ' 1')
230 test(-1, " ", '-1')
231
232 # hex
233 test(3, "x", "3")
234 test(3, "X", "3")
235 test(1234, "x", "4d2")
236 test(-1234, "x", "-4d2")
237 test(1234, "8x", " 4d2")
238 test(-1234, "8x", " -4d2")
239 test(1234, "x", "4d2")
240 test(-1234, "x", "-4d2")
241 test(-3, "x", "-3")
242 test(-3, "X", "-3")
243 test(int('be', 16), "x", "be")
244 test(int('be', 16), "X", "BE")
245 test(-int('be', 16), "x", "-be")
246 test(-int('be', 16), "X", "-BE")
247
248 # octal
249 test(3, "o", "3")
250 test(-3, "o", "-3")
251 test(65, "o", "101")
252 test(-65, "o", "-101")
253 test(1234, "o", "2322")
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
262 # binary
263 test(3, "b", "11")
264 test(-3, "b", "-11")
265 test(1234, "b", "10011010010")
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
Eric Smithb1ebcc62008-07-15 13:02:41 +0000274 # alternate (#) formatting
275 test(0, "#b", '0b0')
276 test(0, "-#b", '0b0')
277 test(1, "-#b", '0b1')
278 test(-1, "-#b", '-0b1')
279 test(-1, "-#5b", ' -0b1')
280 test(1, "+#5b", ' +0b1')
281 test(100, "+#b", '+0b1100100')
Eric Smithd68af8f2008-07-16 00:15:35 +0000282 test(100, "#012b", '0b0001100100')
283 test(-100, "#012b", '-0b001100100')
Eric Smithb1ebcc62008-07-15 13:02:41 +0000284
285 test(0, "#o", '0o0')
286 test(0, "-#o", '0o0')
287 test(1, "-#o", '0o1')
288 test(-1, "-#o", '-0o1')
289 test(-1, "-#5o", ' -0o1')
290 test(1, "+#5o", ' +0o1')
291 test(100, "+#o", '+0o144')
Eric Smithd68af8f2008-07-16 00:15:35 +0000292 test(100, "#012o", '0o0000000144')
293 test(-100, "#012o", '-0o000000144')
Eric Smithb1ebcc62008-07-15 13:02:41 +0000294
295 test(0, "#x", '0x0')
296 test(0, "-#x", '0x0')
297 test(1, "-#x", '0x1')
298 test(-1, "-#x", '-0x1')
299 test(-1, "-#5x", ' -0x1')
300 test(1, "+#5x", ' +0x1')
301 test(100, "+#x", '+0x64')
Eric Smithd68af8f2008-07-16 00:15:35 +0000302 test(100, "#012x", '0x0000000064')
303 test(-100, "#012x", '-0x000000064')
304 test(123456, "#012x", '0x000001e240')
305 test(-123456, "#012x", '-0x00001e240')
Eric Smithb1ebcc62008-07-15 13:02:41 +0000306
307 test(0, "#X", '0X0')
308 test(0, "-#X", '0X0')
309 test(1, "-#X", '0X1')
310 test(-1, "-#X", '-0X1')
311 test(-1, "-#5X", ' -0X1')
312 test(1, "+#5X", ' +0X1')
313 test(100, "+#X", '+0X64')
Eric Smithd68af8f2008-07-16 00:15:35 +0000314 test(100, "#012X", '0X0000000064')
315 test(-100, "#012X", '-0X000000064')
316 test(123456, "#012X", '0X000001E240')
317 test(-123456, "#012X", '-0X00001E240')
Eric Smithb1ebcc62008-07-15 13:02:41 +0000318
Eric Smitha3b1ac82009-04-03 14:45:06 +0000319 test(123, ',', '123')
320 test(-123, ',', '-123')
321 test(1234, ',', '1,234')
322 test(-1234, ',', '-1,234')
323 test(123456, ',', '123,456')
324 test(-123456, ',', '-123,456')
325 test(1234567, ',', '1,234,567')
326 test(-1234567, ',', '-1,234,567')
327
Eric Smith937491d2009-04-22 17:04:27 +0000328 # issue 5782, commas with no specifier type
329 test(1234, '010,', '00,001,234')
330
Mark Dickinson5c2db372009-12-05 20:28:34 +0000331 # Unified type for integers
332 test(10**100, 'd', '1' + '0' * 100)
333 test(10**100+100, 'd', '1' + '0' * 97 + '100')
334
Christian Heimes7131fd92008-02-19 14:21:46 +0000335 # make sure these are errors
336
337 # precision disallowed
338 self.assertRaises(ValueError, 3 .__format__, "1.3")
339 # sign not allowed with 'c'
340 self.assertRaises(ValueError, 3 .__format__, "+c")
341 # format spec must be string
342 self.assertRaises(TypeError, 3 .__format__, None)
343 self.assertRaises(TypeError, 3 .__format__, 0)
Eric Smitha3b1ac82009-04-03 14:45:06 +0000344 # can't have ',' with 'n'
345 self.assertRaises(ValueError, 3 .__format__, ",n")
Eric Smith0923d1d2009-04-16 20:16:10 +0000346 # can't have ',' with 'c'
347 self.assertRaises(ValueError, 3 .__format__, ",c")
Eric V. Smitha12572f2014-04-15 22:37:55 -0400348 # can't have '#' with 'c'
349 self.assertRaises(ValueError, 3 .__format__, "#c")
Christian Heimes7131fd92008-02-19 14:21:46 +0000350
351 # ensure that only int and float type specifiers work
352 for format_spec in ([chr(x) for x in range(ord('a'), ord('z')+1)] +
353 [chr(x) for x in range(ord('A'), ord('Z')+1)]):
354 if not format_spec in 'bcdoxXeEfFgGn%':
355 self.assertRaises(ValueError, 0 .__format__, format_spec)
356 self.assertRaises(ValueError, 1 .__format__, format_spec)
357 self.assertRaises(ValueError, (-1) .__format__, format_spec)
358
359 # ensure that float type specifiers work; format converts
360 # the int to a float
Eric Smith5807c412008-05-11 21:00:57 +0000361 for format_spec in 'eEfFgG%':
Christian Heimes7131fd92008-02-19 14:21:46 +0000362 for value in [0, 1, -1, 100, -100, 1234567890, -1234567890]:
363 self.assertEqual(value.__format__(format_spec),
364 float(value).__format__(format_spec))
365
Eric Smithabb28c62010-02-23 00:22:24 +0000366 # Issue 6902
367 test(123456, "0<20", '12345600000000000000')
368 test(123456, "1<20", '12345611111111111111')
369 test(123456, "*<20", '123456**************')
370 test(123456, "0>20", '00000000000000123456')
371 test(123456, "1>20", '11111111111111123456')
372 test(123456, "*>20", '**************123456')
373 test(123456, "0=20", '00000000000000123456')
374 test(123456, "1=20", '11111111111111123456')
375 test(123456, "*=20", '**************123456')
376
Eric Smithb2c7af82008-04-30 02:12:09 +0000377 @run_with_locale('LC_NUMERIC', 'en_US.UTF8')
378 def test_float__format__locale(self):
379 # test locale support for __format__ code 'n'
380
381 for i in range(-10, 10):
382 x = 1234567890.0 * (10.0 ** i)
383 self.assertEqual(locale.format('%g', x, grouping=True), format(x, 'n'))
384 self.assertEqual(locale.format('%.10g', x, grouping=True), format(x, '.10n'))
385
Eric Smith5807c412008-05-11 21:00:57 +0000386 @run_with_locale('LC_NUMERIC', 'en_US.UTF8')
387 def test_int__format__locale(self):
388 # test locale support for __format__ code 'n' for integers
389
390 x = 123456789012345678901234567890
391 for i in range(0, 30):
392 self.assertEqual(locale.format('%d', x, grouping=True), format(x, 'n'))
393
394 # move to the next integer to test
395 x = x // 10
396
Eric Smithb151a452008-06-24 11:21:04 +0000397 rfmt = ">20n"
398 lfmt = "<20n"
399 cfmt = "^20n"
400 for x in (1234, 12345, 123456, 1234567, 12345678, 123456789, 1234567890, 12345678900):
401 self.assertEqual(len(format(0, rfmt)), len(format(x, rfmt)))
402 self.assertEqual(len(format(0, lfmt)), len(format(x, lfmt)))
403 self.assertEqual(len(format(0, cfmt)), len(format(x, cfmt)))
404
Christian Heimes7131fd92008-02-19 14:21:46 +0000405 def test_float__format__(self):
Christian Heimes7131fd92008-02-19 14:21:46 +0000406 def test(f, format_spec, result):
Christian Heimes7131fd92008-02-19 14:21:46 +0000407 self.assertEqual(f.__format__(format_spec), result)
Eric Smith984bb582010-11-25 16:08:06 +0000408 self.assertEqual(format(f, format_spec), result)
Christian Heimes7131fd92008-02-19 14:21:46 +0000409
410 test(0.0, 'f', '0.000000')
411
412 # the default is 'g', except for empty format spec
413 test(0.0, '', '0.0')
414 test(0.01, '', '0.01')
415 test(0.01, 'g', '0.01')
416
Eric Smith2ad79e82008-07-19 00:33:23 +0000417 # test for issue 3411
418 test(1.23, '1', '1.23')
419 test(-1.23, '1', '-1.23')
420 test(1.23, '1g', '1.23')
421 test(-1.23, '1g', '-1.23')
422
Christian Heimes7131fd92008-02-19 14:21:46 +0000423 test( 1.0, ' g', ' 1')
424 test(-1.0, ' g', '-1')
425 test( 1.0, '+g', '+1')
426 test(-1.0, '+g', '-1')
427 test(1.1234e200, 'g', '1.1234e+200')
428 test(1.1234e200, 'G', '1.1234E+200')
429
430
431 test(1.0, 'f', '1.000000')
432
433 test(-1.0, 'f', '-1.000000')
434
435 test( 1.0, ' f', ' 1.000000')
436 test(-1.0, ' f', '-1.000000')
437 test( 1.0, '+f', '+1.000000')
438 test(-1.0, '+f', '-1.000000')
Mark Dickinson33841c32009-05-01 15:37:04 +0000439
440 # Python versions <= 3.0 switched from 'f' to 'g' formatting for
441 # values larger than 1e50. No longer.
442 f = 1.1234e90
443 for fmt in 'f', 'F':
444 # don't do a direct equality check, since on some
445 # platforms only the first few digits of dtoa
446 # will be reliable
447 result = f.__format__(fmt)
448 self.assertEqual(len(result), 98)
449 self.assertEqual(result[-7], '.')
Benjamin Peterson577473f2010-01-19 00:09:57 +0000450 self.assertIn(result[:12], ('112340000000', '112339999999'))
Mark Dickinson33841c32009-05-01 15:37:04 +0000451 f = 1.1234e200
452 for fmt in 'f', 'F':
453 result = f.__format__(fmt)
454 self.assertEqual(len(result), 208)
455 self.assertEqual(result[-7], '.')
Benjamin Peterson577473f2010-01-19 00:09:57 +0000456 self.assertIn(result[:12], ('112340000000', '112339999999'))
Mark Dickinson33841c32009-05-01 15:37:04 +0000457
Christian Heimes7131fd92008-02-19 14:21:46 +0000458
Christian Heimesc3f30c42008-02-22 16:37:40 +0000459 test( 1.0, 'e', '1.000000e+00')
460 test(-1.0, 'e', '-1.000000e+00')
461 test( 1.0, 'E', '1.000000E+00')
462 test(-1.0, 'E', '-1.000000E+00')
463 test(1.1234e20, 'e', '1.123400e+20')
464 test(1.1234e20, 'E', '1.123400E+20')
Christian Heimes7131fd92008-02-19 14:21:46 +0000465
Christian Heimesb186d002008-03-18 15:15:01 +0000466 # No format code means use g, but must have a decimal
467 # and a number after the decimal. This is tricky, because
468 # a totaly empty format specifier means something else.
469 # So, just use a sign flag
470 test(1e200, '+g', '+1e+200')
Eric Smith0923d1d2009-04-16 20:16:10 +0000471 test(1e200, '+', '+1e+200')
472
Christian Heimesb186d002008-03-18 15:15:01 +0000473 test(1.1e200, '+g', '+1.1e+200')
474 test(1.1e200, '+', '+1.1e+200')
475
Eric Smith0923d1d2009-04-16 20:16:10 +0000476 # 0 padding
477 test(1234., '010f', '1234.000000')
478 test(1234., '011f', '1234.000000')
479 test(1234., '012f', '01234.000000')
480 test(-1234., '011f', '-1234.000000')
481 test(-1234., '012f', '-1234.000000')
482 test(-1234., '013f', '-01234.000000')
483 test(-1234.12341234, '013f', '-01234.123412')
484 test(-123456.12341234, '011.2f', '-0123456.12')
485
Eric Smith937491d2009-04-22 17:04:27 +0000486 # issue 5782, commas with no specifier type
487 test(1.2, '010,.2', '0,000,001.2')
488
Eric Smith0923d1d2009-04-16 20:16:10 +0000489 # 0 padding with commas
490 test(1234., '011,f', '1,234.000000')
491 test(1234., '012,f', '1,234.000000')
492 test(1234., '013,f', '01,234.000000')
493 test(-1234., '012,f', '-1,234.000000')
494 test(-1234., '013,f', '-1,234.000000')
495 test(-1234., '014,f', '-01,234.000000')
496 test(-12345., '015,f', '-012,345.000000')
497 test(-123456., '016,f', '-0,123,456.000000')
498 test(-123456., '017,f', '-0,123,456.000000')
499 test(-123456.12341234, '017,f', '-0,123,456.123412')
500 test(-123456.12341234, '013,.2f', '-0,123,456.12')
501
Christian Heimes7131fd92008-02-19 14:21:46 +0000502 # % formatting
503 test(-1.0, '%', '-100.000000%')
504
505 # format spec must be string
506 self.assertRaises(TypeError, 3.0.__format__, None)
507 self.assertRaises(TypeError, 3.0.__format__, 0)
508
509 # other format specifiers shouldn't work on floats,
510 # in particular int specifiers
511 for format_spec in ([chr(x) for x in range(ord('a'), ord('z')+1)] +
512 [chr(x) for x in range(ord('A'), ord('Z')+1)]):
513 if not format_spec in 'eEfFgGn%':
514 self.assertRaises(ValueError, format, 0.0, format_spec)
515 self.assertRaises(ValueError, format, 1.0, format_spec)
516 self.assertRaises(ValueError, format, -1.0, format_spec)
517 self.assertRaises(ValueError, format, 1e100, format_spec)
518 self.assertRaises(ValueError, format, -1e100, format_spec)
519 self.assertRaises(ValueError, format, 1e-100, format_spec)
520 self.assertRaises(ValueError, format, -1e-100, format_spec)
521
Eric Smith984bb582010-11-25 16:08:06 +0000522 # Alternate float formatting
523 test(1.0, '.0e', '1e+00')
524 test(1.0, '#.0e', '1.e+00')
525 test(1.0, '.0f', '1')
526 test(1.0, '#.0f', '1.')
527 test(1.1, 'g', '1.1')
528 test(1.1, '#g', '1.10000')
529 test(1.0, '.0%', '100%')
530 test(1.0, '#.0%', '100.%')
531
532 # Issue 7094: Alternate formatting (specified by #)
533 test(1.0, '0e', '1.000000e+00')
534 test(1.0, '#0e', '1.000000e+00')
535 test(1.0, '0f', '1.000000' )
536 test(1.0, '#0f', '1.000000')
537 test(1.0, '.1e', '1.0e+00')
538 test(1.0, '#.1e', '1.0e+00')
539 test(1.0, '.1f', '1.0')
540 test(1.0, '#.1f', '1.0')
541 test(1.0, '.1%', '100.0%')
542 test(1.0, '#.1%', '100.0%')
Eric Smithb1ebcc62008-07-15 13:02:41 +0000543
Eric Smithabb28c62010-02-23 00:22:24 +0000544 # Issue 6902
545 test(12345.6, "0<20", '12345.60000000000000')
546 test(12345.6, "1<20", '12345.61111111111111')
547 test(12345.6, "*<20", '12345.6*************')
548 test(12345.6, "0>20", '000000000000012345.6')
549 test(12345.6, "1>20", '111111111111112345.6')
550 test(12345.6, "*>20", '*************12345.6')
551 test(12345.6, "0=20", '000000000000012345.6')
552 test(12345.6, "1=20", '111111111111112345.6')
553 test(12345.6, "*=20", '*************12345.6')
554
Eric Smith0923d1d2009-04-16 20:16:10 +0000555 def test_format_spec_errors(self):
556 # int, float, and string all share the same format spec
557 # mini-language parser.
558
559 # Check that we can't ask for too many digits. This is
560 # probably a CPython specific test. It tries to put the width
561 # into a C long.
562 self.assertRaises(ValueError, format, 0, '1'*10000 + 'd')
563
564 # Similar with the precision.
565 self.assertRaises(ValueError, format, 0, '.' + '1'*10000 + 'd')
566
567 # And may as well test both.
568 self.assertRaises(ValueError, format, 0, '1'*1000 + '.' + '1'*10000 + 'd')
569
570 # Make sure commas aren't allowed with various type codes
571 for code in 'xXobns':
572 self.assertRaises(ValueError, format, 0, ',' + code)
Christian Heimes7131fd92008-02-19 14:21:46 +0000573
Benjamin Peterson0e102062010-08-25 23:13:17 +0000574 def test_internal_sizes(self):
575 self.assertGreater(object.__basicsize__, 0)
576 self.assertGreater(tuple.__itemsize__, 0)
577
578
Victor Stinner0db176f2012-04-16 00:16:30 +0200579class MappingProxyTests(unittest.TestCase):
580 mappingproxy = types.MappingProxyType
581
582 def test_constructor(self):
583 class userdict(dict):
584 pass
585
586 mapping = {'x': 1, 'y': 2}
587 self.assertEqual(self.mappingproxy(mapping), mapping)
588 mapping = userdict(x=1, y=2)
589 self.assertEqual(self.mappingproxy(mapping), mapping)
590 mapping = collections.ChainMap({'x': 1}, {'y': 2})
591 self.assertEqual(self.mappingproxy(mapping), mapping)
592
593 self.assertRaises(TypeError, self.mappingproxy, 10)
594 self.assertRaises(TypeError, self.mappingproxy, ("a", "tuple"))
595 self.assertRaises(TypeError, self.mappingproxy, ["a", "list"])
596
597 def test_methods(self):
598 attrs = set(dir(self.mappingproxy({}))) - set(dir(object()))
599 self.assertEqual(attrs, {
600 '__contains__',
601 '__getitem__',
602 '__iter__',
603 '__len__',
604 'copy',
605 'get',
606 'items',
607 'keys',
608 'values',
609 })
610
611 def test_get(self):
612 view = self.mappingproxy({'a': 'A', 'b': 'B'})
613 self.assertEqual(view['a'], 'A')
614 self.assertEqual(view['b'], 'B')
615 self.assertRaises(KeyError, view.__getitem__, 'xxx')
616 self.assertEqual(view.get('a'), 'A')
617 self.assertIsNone(view.get('xxx'))
618 self.assertEqual(view.get('xxx', 42), 42)
619
620 def test_missing(self):
621 class dictmissing(dict):
622 def __missing__(self, key):
623 return "missing=%s" % key
624
625 view = self.mappingproxy(dictmissing(x=1))
626 self.assertEqual(view['x'], 1)
627 self.assertEqual(view['y'], 'missing=y')
628 self.assertEqual(view.get('x'), 1)
629 self.assertEqual(view.get('y'), None)
630 self.assertEqual(view.get('y', 42), 42)
631 self.assertTrue('x' in view)
632 self.assertFalse('y' in view)
633
634 def test_customdict(self):
635 class customdict(dict):
636 def __contains__(self, key):
637 if key == 'magic':
638 return True
639 else:
640 return dict.__contains__(self, key)
641
642 def __iter__(self):
643 return iter(('iter',))
644
645 def __len__(self):
646 return 500
647
648 def copy(self):
649 return 'copy'
650
651 def keys(self):
652 return 'keys'
653
654 def items(self):
655 return 'items'
656
657 def values(self):
658 return 'values'
659
660 def __getitem__(self, key):
661 return "getitem=%s" % dict.__getitem__(self, key)
662
663 def get(self, key, default=None):
664 return "get=%s" % dict.get(self, key, 'default=%r' % default)
665
666 custom = customdict({'key': 'value'})
667 view = self.mappingproxy(custom)
668 self.assertTrue('key' in view)
669 self.assertTrue('magic' in view)
670 self.assertFalse('xxx' in view)
671 self.assertEqual(view['key'], 'getitem=value')
672 self.assertRaises(KeyError, view.__getitem__, 'xxx')
673 self.assertEqual(tuple(view), ('iter',))
674 self.assertEqual(len(view), 500)
675 self.assertEqual(view.copy(), 'copy')
676 self.assertEqual(view.get('key'), 'get=value')
677 self.assertEqual(view.get('xxx'), 'get=default=None')
678 self.assertEqual(view.items(), 'items')
679 self.assertEqual(view.keys(), 'keys')
680 self.assertEqual(view.values(), 'values')
681
682 def test_chainmap(self):
683 d1 = {'x': 1}
684 d2 = {'y': 2}
685 mapping = collections.ChainMap(d1, d2)
686 view = self.mappingproxy(mapping)
687 self.assertTrue('x' in view)
688 self.assertTrue('y' in view)
689 self.assertFalse('z' in view)
690 self.assertEqual(view['x'], 1)
691 self.assertEqual(view['y'], 2)
692 self.assertRaises(KeyError, view.__getitem__, 'z')
693 self.assertEqual(tuple(sorted(view)), ('x', 'y'))
694 self.assertEqual(len(view), 2)
695 copy = view.copy()
696 self.assertIsNot(copy, mapping)
697 self.assertIsInstance(copy, collections.ChainMap)
698 self.assertEqual(copy, mapping)
699 self.assertEqual(view.get('x'), 1)
700 self.assertEqual(view.get('y'), 2)
701 self.assertIsNone(view.get('z'))
702 self.assertEqual(tuple(sorted(view.items())), (('x', 1), ('y', 2)))
703 self.assertEqual(tuple(sorted(view.keys())), ('x', 'y'))
704 self.assertEqual(tuple(sorted(view.values())), (1, 2))
705
706 def test_contains(self):
707 view = self.mappingproxy(dict.fromkeys('abc'))
708 self.assertTrue('a' in view)
709 self.assertTrue('b' in view)
710 self.assertTrue('c' in view)
711 self.assertFalse('xxx' in view)
712
713 def test_views(self):
714 mapping = {}
715 view = self.mappingproxy(mapping)
716 keys = view.keys()
717 values = view.values()
718 items = view.items()
719 self.assertEqual(list(keys), [])
720 self.assertEqual(list(values), [])
721 self.assertEqual(list(items), [])
722 mapping['key'] = 'value'
723 self.assertEqual(list(keys), ['key'])
724 self.assertEqual(list(values), ['value'])
725 self.assertEqual(list(items), [('key', 'value')])
726
727 def test_len(self):
728 for expected in range(6):
729 data = dict.fromkeys('abcde'[:expected])
730 self.assertEqual(len(data), expected)
731 view = self.mappingproxy(data)
732 self.assertEqual(len(view), expected)
733
734 def test_iterators(self):
735 keys = ('x', 'y')
736 values = (1, 2)
737 items = tuple(zip(keys, values))
738 view = self.mappingproxy(dict(items))
739 self.assertEqual(set(view), set(keys))
740 self.assertEqual(set(view.keys()), set(keys))
741 self.assertEqual(set(view.values()), set(values))
742 self.assertEqual(set(view.items()), set(items))
743
744 def test_copy(self):
745 original = {'key1': 27, 'key2': 51, 'key3': 93}
746 view = self.mappingproxy(original)
747 copy = view.copy()
748 self.assertEqual(type(copy), dict)
749 self.assertEqual(copy, original)
750 original['key1'] = 70
751 self.assertEqual(view['key1'], 70)
752 self.assertEqual(copy['key1'], 27)
753
754
Nick Coghlan7fc570a2012-05-20 02:34:13 +1000755class ClassCreationTests(unittest.TestCase):
756
757 class Meta(type):
758 def __init__(cls, name, bases, ns, **kw):
759 super().__init__(name, bases, ns)
760 @staticmethod
761 def __new__(mcls, name, bases, ns, **kw):
762 return super().__new__(mcls, name, bases, ns)
763 @classmethod
764 def __prepare__(mcls, name, bases, **kw):
765 ns = super().__prepare__(name, bases)
766 ns["y"] = 1
767 ns.update(kw)
768 return ns
769
770 def test_new_class_basics(self):
771 C = types.new_class("C")
772 self.assertEqual(C.__name__, "C")
773 self.assertEqual(C.__bases__, (object,))
774
775 def test_new_class_subclass(self):
776 C = types.new_class("C", (int,))
777 self.assertTrue(issubclass(C, int))
778
779 def test_new_class_meta(self):
780 Meta = self.Meta
781 settings = {"metaclass": Meta, "z": 2}
782 # We do this twice to make sure the passed in dict isn't mutated
783 for i in range(2):
784 C = types.new_class("C" + str(i), (), settings)
785 self.assertIsInstance(C, Meta)
786 self.assertEqual(C.y, 1)
787 self.assertEqual(C.z, 2)
788
789 def test_new_class_exec_body(self):
790 Meta = self.Meta
791 def func(ns):
792 ns["x"] = 0
793 C = types.new_class("C", (), {"metaclass": Meta, "z": 2}, func)
794 self.assertIsInstance(C, Meta)
795 self.assertEqual(C.x, 0)
796 self.assertEqual(C.y, 1)
797 self.assertEqual(C.z, 2)
798
Benjamin Peterson43f8f4c2012-09-27 18:10:17 -0400799 def test_new_class_metaclass_keywords(self):
Nick Coghlan7fc570a2012-05-20 02:34:13 +1000800 #Test that keywords are passed to the metaclass:
801 def meta_func(name, bases, ns, **kw):
802 return name, bases, ns, kw
803 res = types.new_class("X",
804 (int, object),
805 dict(metaclass=meta_func, x=0))
806 self.assertEqual(res, ("X", (int, object), {}, {"x": 0}))
807
808 def test_new_class_defaults(self):
809 # Test defaults/keywords:
810 C = types.new_class("C", (), {}, None)
811 self.assertEqual(C.__name__, "C")
812 self.assertEqual(C.__bases__, (object,))
813
814 def test_new_class_meta_with_base(self):
815 Meta = self.Meta
816 def func(ns):
817 ns["x"] = 0
818 C = types.new_class(name="C",
819 bases=(int,),
820 kwds=dict(metaclass=Meta, z=2),
821 exec_body=func)
822 self.assertTrue(issubclass(C, int))
823 self.assertIsInstance(C, Meta)
824 self.assertEqual(C.x, 0)
825 self.assertEqual(C.y, 1)
826 self.assertEqual(C.z, 2)
827
828 # Many of the following tests are derived from test_descr.py
829 def test_prepare_class(self):
830 # Basic test of metaclass derivation
831 expected_ns = {}
832 class A(type):
833 def __new__(*args, **kwargs):
834 return type.__new__(*args, **kwargs)
835
836 def __prepare__(*args):
837 return expected_ns
838
839 B = types.new_class("B", (object,))
840 C = types.new_class("C", (object,), {"metaclass": A})
841
842 # The most derived metaclass of D is A rather than type.
843 meta, ns, kwds = types.prepare_class("D", (B, C), {"metaclass": type})
844 self.assertIs(meta, A)
845 self.assertIs(ns, expected_ns)
846 self.assertEqual(len(kwds), 0)
847
848 def test_metaclass_derivation(self):
849 # issue1294232: correct metaclass calculation
850 new_calls = [] # to check the order of __new__ calls
851 class AMeta(type):
852 def __new__(mcls, name, bases, ns):
853 new_calls.append('AMeta')
854 return super().__new__(mcls, name, bases, ns)
855 @classmethod
856 def __prepare__(mcls, name, bases):
857 return {}
858
859 class BMeta(AMeta):
860 def __new__(mcls, name, bases, ns):
861 new_calls.append('BMeta')
862 return super().__new__(mcls, name, bases, ns)
863 @classmethod
864 def __prepare__(mcls, name, bases):
865 ns = super().__prepare__(name, bases)
866 ns['BMeta_was_here'] = True
867 return ns
868
869 A = types.new_class("A", (), {"metaclass": AMeta})
870 self.assertEqual(new_calls, ['AMeta'])
871 new_calls.clear()
872
873 B = types.new_class("B", (), {"metaclass": BMeta})
874 # BMeta.__new__ calls AMeta.__new__ with super:
875 self.assertEqual(new_calls, ['BMeta', 'AMeta'])
876 new_calls.clear()
877
878 C = types.new_class("C", (A, B))
879 # The most derived metaclass is BMeta:
880 self.assertEqual(new_calls, ['BMeta', 'AMeta'])
881 new_calls.clear()
882 # BMeta.__prepare__ should've been called:
883 self.assertIn('BMeta_was_here', C.__dict__)
884
885 # The order of the bases shouldn't matter:
886 C2 = types.new_class("C2", (B, A))
887 self.assertEqual(new_calls, ['BMeta', 'AMeta'])
888 new_calls.clear()
889 self.assertIn('BMeta_was_here', C2.__dict__)
890
891 # Check correct metaclass calculation when a metaclass is declared:
892 D = types.new_class("D", (C,), {"metaclass": type})
893 self.assertEqual(new_calls, ['BMeta', 'AMeta'])
894 new_calls.clear()
895 self.assertIn('BMeta_was_here', D.__dict__)
896
897 E = types.new_class("E", (C,), {"metaclass": AMeta})
898 self.assertEqual(new_calls, ['BMeta', 'AMeta'])
899 new_calls.clear()
900 self.assertIn('BMeta_was_here', E.__dict__)
901
902 def test_metaclass_override_function(self):
903 # Special case: the given metaclass isn't a class,
904 # so there is no metaclass calculation.
905 class A(metaclass=self.Meta):
906 pass
907
908 marker = object()
909 def func(*args, **kwargs):
910 return marker
911
912 X = types.new_class("X", (), {"metaclass": func})
913 Y = types.new_class("Y", (object,), {"metaclass": func})
914 Z = types.new_class("Z", (A,), {"metaclass": func})
915 self.assertIs(marker, X)
916 self.assertIs(marker, Y)
917 self.assertIs(marker, Z)
918
919 def test_metaclass_override_callable(self):
920 # The given metaclass is a class,
921 # but not a descendant of type.
922 new_calls = [] # to check the order of __new__ calls
923 prepare_calls = [] # to track __prepare__ calls
924 class ANotMeta:
925 def __new__(mcls, *args, **kwargs):
926 new_calls.append('ANotMeta')
927 return super().__new__(mcls)
928 @classmethod
929 def __prepare__(mcls, name, bases):
930 prepare_calls.append('ANotMeta')
931 return {}
932
933 class BNotMeta(ANotMeta):
934 def __new__(mcls, *args, **kwargs):
935 new_calls.append('BNotMeta')
936 return super().__new__(mcls)
937 @classmethod
938 def __prepare__(mcls, name, bases):
939 prepare_calls.append('BNotMeta')
940 return super().__prepare__(name, bases)
941
942 A = types.new_class("A", (), {"metaclass": ANotMeta})
943 self.assertIs(ANotMeta, type(A))
944 self.assertEqual(prepare_calls, ['ANotMeta'])
945 prepare_calls.clear()
946 self.assertEqual(new_calls, ['ANotMeta'])
947 new_calls.clear()
948
949 B = types.new_class("B", (), {"metaclass": BNotMeta})
950 self.assertIs(BNotMeta, type(B))
951 self.assertEqual(prepare_calls, ['BNotMeta', 'ANotMeta'])
952 prepare_calls.clear()
953 self.assertEqual(new_calls, ['BNotMeta', 'ANotMeta'])
954 new_calls.clear()
955
956 C = types.new_class("C", (A, B))
957 self.assertIs(BNotMeta, type(C))
958 self.assertEqual(prepare_calls, ['BNotMeta', 'ANotMeta'])
959 prepare_calls.clear()
960 self.assertEqual(new_calls, ['BNotMeta', 'ANotMeta'])
961 new_calls.clear()
962
963 C2 = types.new_class("C2", (B, A))
964 self.assertIs(BNotMeta, type(C2))
965 self.assertEqual(prepare_calls, ['BNotMeta', 'ANotMeta'])
966 prepare_calls.clear()
967 self.assertEqual(new_calls, ['BNotMeta', 'ANotMeta'])
968 new_calls.clear()
969
970 # This is a TypeError, because of a metaclass conflict:
971 # BNotMeta is neither a subclass, nor a superclass of type
972 with self.assertRaises(TypeError):
973 D = types.new_class("D", (C,), {"metaclass": type})
974
975 E = types.new_class("E", (C,), {"metaclass": ANotMeta})
976 self.assertIs(BNotMeta, type(E))
977 self.assertEqual(prepare_calls, ['BNotMeta', 'ANotMeta'])
978 prepare_calls.clear()
979 self.assertEqual(new_calls, ['BNotMeta', 'ANotMeta'])
980 new_calls.clear()
981
982 F = types.new_class("F", (object(), C))
983 self.assertIs(BNotMeta, type(F))
984 self.assertEqual(prepare_calls, ['BNotMeta', 'ANotMeta'])
985 prepare_calls.clear()
986 self.assertEqual(new_calls, ['BNotMeta', 'ANotMeta'])
987 new_calls.clear()
988
989 F2 = types.new_class("F2", (C, object()))
990 self.assertIs(BNotMeta, type(F2))
991 self.assertEqual(prepare_calls, ['BNotMeta', 'ANotMeta'])
992 prepare_calls.clear()
993 self.assertEqual(new_calls, ['BNotMeta', 'ANotMeta'])
994 new_calls.clear()
995
996 # TypeError: BNotMeta is neither a
997 # subclass, nor a superclass of int
998 with self.assertRaises(TypeError):
999 X = types.new_class("X", (C, int()))
1000 with self.assertRaises(TypeError):
1001 X = types.new_class("X", (int(), C))
1002
1003
Barry Warsaw409da152012-06-03 16:18:47 -04001004class SimpleNamespaceTests(unittest.TestCase):
1005
1006 def test_constructor(self):
1007 ns1 = types.SimpleNamespace()
1008 ns2 = types.SimpleNamespace(x=1, y=2)
1009 ns3 = types.SimpleNamespace(**dict(x=1, y=2))
1010
1011 with self.assertRaises(TypeError):
1012 types.SimpleNamespace(1, 2, 3)
1013
1014 self.assertEqual(len(ns1.__dict__), 0)
1015 self.assertEqual(vars(ns1), {})
1016 self.assertEqual(len(ns2.__dict__), 2)
1017 self.assertEqual(vars(ns2), {'y': 2, 'x': 1})
1018 self.assertEqual(len(ns3.__dict__), 2)
1019 self.assertEqual(vars(ns3), {'y': 2, 'x': 1})
1020
1021 def test_unbound(self):
1022 ns1 = vars(types.SimpleNamespace())
1023 ns2 = vars(types.SimpleNamespace(x=1, y=2))
1024
1025 self.assertEqual(ns1, {})
1026 self.assertEqual(ns2, {'y': 2, 'x': 1})
1027
1028 def test_underlying_dict(self):
1029 ns1 = types.SimpleNamespace()
1030 ns2 = types.SimpleNamespace(x=1, y=2)
1031 ns3 = types.SimpleNamespace(a=True, b=False)
1032 mapping = ns3.__dict__
1033 del ns3
1034
1035 self.assertEqual(ns1.__dict__, {})
1036 self.assertEqual(ns2.__dict__, {'y': 2, 'x': 1})
1037 self.assertEqual(mapping, dict(a=True, b=False))
1038
1039 def test_attrget(self):
1040 ns = types.SimpleNamespace(x=1, y=2, w=3)
1041
1042 self.assertEqual(ns.x, 1)
1043 self.assertEqual(ns.y, 2)
1044 self.assertEqual(ns.w, 3)
1045 with self.assertRaises(AttributeError):
1046 ns.z
1047
1048 def test_attrset(self):
1049 ns1 = types.SimpleNamespace()
1050 ns2 = types.SimpleNamespace(x=1, y=2, w=3)
1051 ns1.a = 'spam'
1052 ns1.b = 'ham'
1053 ns2.z = 4
1054 ns2.theta = None
1055
1056 self.assertEqual(ns1.__dict__, dict(a='spam', b='ham'))
1057 self.assertEqual(ns2.__dict__, dict(x=1, y=2, w=3, z=4, theta=None))
1058
1059 def test_attrdel(self):
1060 ns1 = types.SimpleNamespace()
1061 ns2 = types.SimpleNamespace(x=1, y=2, w=3)
1062
1063 with self.assertRaises(AttributeError):
1064 del ns1.spam
1065 with self.assertRaises(AttributeError):
1066 del ns2.spam
1067
1068 del ns2.y
1069 self.assertEqual(vars(ns2), dict(w=3, x=1))
1070 ns2.y = 'spam'
1071 self.assertEqual(vars(ns2), dict(w=3, x=1, y='spam'))
1072 del ns2.y
1073 self.assertEqual(vars(ns2), dict(w=3, x=1))
1074
1075 ns1.spam = 5
1076 self.assertEqual(vars(ns1), dict(spam=5))
1077 del ns1.spam
1078 self.assertEqual(vars(ns1), {})
1079
1080 def test_repr(self):
1081 ns1 = types.SimpleNamespace(x=1, y=2, w=3)
1082 ns2 = types.SimpleNamespace()
1083 ns2.x = "spam"
1084 ns2._y = 5
Eric Snowb5c8f922013-02-16 16:32:39 -07001085 name = "namespace"
Barry Warsaw409da152012-06-03 16:18:47 -04001086
Eric Snowb5c8f922013-02-16 16:32:39 -07001087 self.assertEqual(repr(ns1), "{name}(w=3, x=1, y=2)".format(name=name))
1088 self.assertEqual(repr(ns2), "{name}(_y=5, x='spam')".format(name=name))
1089
1090 def test_equal(self):
1091 ns1 = types.SimpleNamespace(x=1)
1092 ns2 = types.SimpleNamespace()
1093 ns2.x = 1
1094
1095 self.assertEqual(types.SimpleNamespace(), types.SimpleNamespace())
1096 self.assertEqual(ns1, ns2)
1097 self.assertNotEqual(ns2, types.SimpleNamespace())
Barry Warsaw409da152012-06-03 16:18:47 -04001098
1099 def test_nested(self):
1100 ns1 = types.SimpleNamespace(a=1, b=2)
1101 ns2 = types.SimpleNamespace()
1102 ns3 = types.SimpleNamespace(x=ns1)
1103 ns2.spam = ns1
1104 ns2.ham = '?'
1105 ns2.spam = ns3
1106
1107 self.assertEqual(vars(ns1), dict(a=1, b=2))
1108 self.assertEqual(vars(ns2), dict(spam=ns3, ham='?'))
1109 self.assertEqual(ns2.spam, ns3)
1110 self.assertEqual(vars(ns3), dict(x=ns1))
1111 self.assertEqual(ns3.x.a, 1)
1112
1113 def test_recursive(self):
1114 ns1 = types.SimpleNamespace(c='cookie')
1115 ns2 = types.SimpleNamespace()
1116 ns3 = types.SimpleNamespace(x=1)
1117 ns1.spam = ns1
1118 ns2.spam = ns3
1119 ns3.spam = ns2
1120
1121 self.assertEqual(ns1.spam, ns1)
1122 self.assertEqual(ns1.spam.spam, ns1)
1123 self.assertEqual(ns1.spam.spam, ns1.spam)
1124 self.assertEqual(ns2.spam, ns3)
1125 self.assertEqual(ns3.spam, ns2)
1126 self.assertEqual(ns2.spam.spam, ns2)
1127
1128 def test_recursive_repr(self):
1129 ns1 = types.SimpleNamespace(c='cookie')
1130 ns2 = types.SimpleNamespace()
1131 ns3 = types.SimpleNamespace(x=1)
1132 ns1.spam = ns1
1133 ns2.spam = ns3
1134 ns3.spam = ns2
Eric Snowb5c8f922013-02-16 16:32:39 -07001135 name = "namespace"
1136 repr1 = "{name}(c='cookie', spam={name}(...))".format(name=name)
1137 repr2 = "{name}(spam={name}(spam={name}(...), x=1))".format(name=name)
Barry Warsaw409da152012-06-03 16:18:47 -04001138
Eric Snowb5c8f922013-02-16 16:32:39 -07001139 self.assertEqual(repr(ns1), repr1)
1140 self.assertEqual(repr(ns2), repr2)
Barry Warsaw409da152012-06-03 16:18:47 -04001141
1142 def test_as_dict(self):
1143 ns = types.SimpleNamespace(spam='spamspamspam')
1144
1145 with self.assertRaises(TypeError):
1146 len(ns)
1147 with self.assertRaises(TypeError):
1148 iter(ns)
1149 with self.assertRaises(TypeError):
1150 'spam' in ns
1151 with self.assertRaises(TypeError):
1152 ns['spam']
1153
Eric Snow547298c2012-10-16 22:35:38 -07001154 def test_subclass(self):
1155 class Spam(types.SimpleNamespace):
1156 pass
1157
1158 spam = Spam(ham=8, eggs=9)
1159
1160 self.assertIs(type(spam), Spam)
1161 self.assertEqual(vars(spam), {'ham': 8, 'eggs': 9})
1162
Eric Snowb5c8f922013-02-16 16:32:39 -07001163 def test_pickle(self):
1164 ns = types.SimpleNamespace(breakfast="spam", lunch="spam")
1165
Eric Snow9d05c8c2013-02-16 18:20:32 -07001166 for protocol in range(pickle.HIGHEST_PROTOCOL + 1):
1167 pname = "protocol {}".format(protocol)
1168 try:
1169 ns_pickled = pickle.dumps(ns, protocol)
1170 except TypeError as e:
1171 raise TypeError(pname) from e
1172 ns_roundtrip = pickle.loads(ns_pickled)
Eric Snowb5c8f922013-02-16 16:32:39 -07001173
Eric Snow9d05c8c2013-02-16 18:20:32 -07001174 self.assertEqual(ns, ns_roundtrip, pname)
Eric Snowb5c8f922013-02-16 16:32:39 -07001175
Serhiy Storchaka08d230a2015-05-22 11:02:49 +03001176 def test_fake_namespace_compare(self):
1177 # Issue #24257: Incorrect use of PyObject_IsInstance() caused
1178 # SystemError.
1179 class FakeSimpleNamespace(str):
1180 __class__ = types.SimpleNamespace
1181 self.assertFalse(types.SimpleNamespace() == FakeSimpleNamespace())
1182 self.assertTrue(types.SimpleNamespace() != FakeSimpleNamespace())
1183 with self.assertRaises(TypeError):
1184 types.SimpleNamespace() < FakeSimpleNamespace()
1185 with self.assertRaises(TypeError):
1186 types.SimpleNamespace() <= FakeSimpleNamespace()
1187 with self.assertRaises(TypeError):
1188 types.SimpleNamespace() > FakeSimpleNamespace()
1189 with self.assertRaises(TypeError):
1190 types.SimpleNamespace() >= FakeSimpleNamespace()
1191
Barry Warsaw409da152012-06-03 16:18:47 -04001192
Yury Selivanov75445082015-05-11 22:57:16 -04001193class CoroutineTests(unittest.TestCase):
1194 def test_wrong_args(self):
Yury Selivanovc565cd52015-05-29 09:06:05 -04001195 samples = [None, 1, object()]
Yury Selivanov75445082015-05-11 22:57:16 -04001196 for sample in samples:
Yury Selivanovc565cd52015-05-29 09:06:05 -04001197 with self.assertRaisesRegex(TypeError,
1198 'types.coroutine.*expects a callable'):
Yury Selivanov75445082015-05-11 22:57:16 -04001199 types.coroutine(sample)
1200
Yury Selivanov00e33722015-06-24 11:44:51 -04001201 def test_non_gen_values(self):
Yury Selivanovc565cd52015-05-29 09:06:05 -04001202 @types.coroutine
1203 def foo():
Yury Selivanov5376ba92015-06-22 12:19:30 -04001204 return 'spam'
1205 self.assertEqual(foo(), 'spam')
1206
Yury Selivanov00e33722015-06-24 11:44:51 -04001207 class Awaitable:
1208 def __await__(self):
1209 return ()
1210 aw = Awaitable()
1211 @types.coroutine
1212 def foo():
1213 return aw
1214 self.assertIs(aw, foo())
1215
Yury Selivanov4887523c2015-07-23 15:58:37 +03001216 # decorate foo second time
1217 foo = types.coroutine(foo)
1218 self.assertIs(aw, foo())
1219
Yury Selivanov5376ba92015-06-22 12:19:30 -04001220 def test_async_def(self):
1221 # Test that types.coroutine passes 'async def' coroutines
1222 # without modification
1223
1224 async def foo(): pass
1225 foo_code = foo.__code__
1226 foo_flags = foo.__code__.co_flags
1227 decorated_foo = types.coroutine(foo)
1228 self.assertIs(foo, decorated_foo)
1229 self.assertEqual(foo.__code__.co_flags, foo_flags)
1230 self.assertIs(decorated_foo.__code__, foo_code)
1231
1232 foo_coro = foo()
Yury Selivanov5376ba92015-06-22 12:19:30 -04001233 def bar(): return foo_coro
Yury Selivanov4887523c2015-07-23 15:58:37 +03001234 for _ in range(2):
1235 bar = types.coroutine(bar)
1236 coro = bar()
1237 self.assertIs(foo_coro, coro)
1238 self.assertEqual(coro.cr_code.co_flags, foo_flags)
1239 coro.close()
Yury Selivanovc565cd52015-05-29 09:06:05 -04001240
1241 def test_duck_coro(self):
1242 class CoroLike:
1243 def send(self): pass
1244 def throw(self): pass
1245 def close(self): pass
Yury Selivanov13f77232015-05-29 16:19:18 -04001246 def __await__(self): return self
Yury Selivanovc565cd52015-05-29 09:06:05 -04001247
1248 coro = CoroLike()
1249 @types.coroutine
1250 def foo():
1251 return coro
Yury Selivanov5376ba92015-06-22 12:19:30 -04001252 self.assertIs(foo(), coro)
1253 self.assertIs(foo().__await__(), coro)
1254
1255 def test_duck_corogen(self):
1256 class CoroGenLike:
1257 def send(self): pass
1258 def throw(self): pass
1259 def close(self): pass
1260 def __await__(self): return self
1261 def __iter__(self): return self
1262 def __next__(self): pass
1263
1264 coro = CoroGenLike()
1265 @types.coroutine
1266 def foo():
1267 return coro
1268 self.assertIs(foo(), coro)
Yury Selivanov13f77232015-05-29 16:19:18 -04001269 self.assertIs(foo().__await__(), coro)
1270
1271 def test_duck_gen(self):
1272 class GenLike:
1273 def send(self): pass
1274 def throw(self): pass
1275 def close(self): pass
Yury Selivanov00e33722015-06-24 11:44:51 -04001276 def __iter__(self): pass
Yury Selivanov13f77232015-05-29 16:19:18 -04001277 def __next__(self): pass
1278
Yury Selivanov00e33722015-06-24 11:44:51 -04001279 # Setup generator mock object
1280 gen = unittest.mock.MagicMock(GenLike)
1281 gen.__iter__ = lambda gen: gen
1282 gen.__name__ = 'gen'
1283 gen.__qualname__ = 'test.gen'
1284 self.assertIsInstance(gen, collections.abc.Generator)
1285 self.assertIs(gen, iter(gen))
1286
Yury Selivanov13f77232015-05-29 16:19:18 -04001287 @types.coroutine
Yury Selivanov00e33722015-06-24 11:44:51 -04001288 def foo(): return gen
1289
1290 wrapper = foo()
1291 self.assertIsInstance(wrapper, types._GeneratorWrapper)
1292 self.assertIs(wrapper.__await__(), wrapper)
1293 # Wrapper proxies duck generators completely:
1294 self.assertIs(iter(wrapper), wrapper)
1295
1296 self.assertIsInstance(wrapper, collections.abc.Coroutine)
1297 self.assertIsInstance(wrapper, collections.abc.Awaitable)
1298
1299 self.assertIs(wrapper.__qualname__, gen.__qualname__)
1300 self.assertIs(wrapper.__name__, gen.__name__)
1301
1302 # Test AttributeErrors
Yury Selivanov53e62302015-07-03 00:35:02 -04001303 for name in {'gi_running', 'gi_frame', 'gi_code', 'gi_yieldfrom',
1304 'cr_running', 'cr_frame', 'cr_code', 'cr_await'}:
Yury Selivanov00e33722015-06-24 11:44:51 -04001305 with self.assertRaises(AttributeError):
1306 getattr(wrapper, name)
1307
1308 # Test attributes pass-through
1309 gen.gi_running = object()
1310 gen.gi_frame = object()
1311 gen.gi_code = object()
Yury Selivanov53e62302015-07-03 00:35:02 -04001312 gen.gi_yieldfrom = object()
Yury Selivanov00e33722015-06-24 11:44:51 -04001313 self.assertIs(wrapper.gi_running, gen.gi_running)
1314 self.assertIs(wrapper.gi_frame, gen.gi_frame)
1315 self.assertIs(wrapper.gi_code, gen.gi_code)
Yury Selivanov53e62302015-07-03 00:35:02 -04001316 self.assertIs(wrapper.gi_yieldfrom, gen.gi_yieldfrom)
Yury Selivanov00e33722015-06-24 11:44:51 -04001317 self.assertIs(wrapper.cr_running, gen.gi_running)
1318 self.assertIs(wrapper.cr_frame, gen.gi_frame)
1319 self.assertIs(wrapper.cr_code, gen.gi_code)
Yury Selivanov53e62302015-07-03 00:35:02 -04001320 self.assertIs(wrapper.cr_await, gen.gi_yieldfrom)
Yury Selivanov00e33722015-06-24 11:44:51 -04001321
1322 wrapper.close()
1323 gen.close.assert_called_once_with()
1324
1325 wrapper.send(1)
1326 gen.send.assert_called_once_with(1)
Yury Selivanovf847f1f2015-06-24 12:49:28 -04001327 gen.reset_mock()
1328
1329 next(wrapper)
1330 gen.__next__.assert_called_once_with()
1331 gen.reset_mock()
Yury Selivanov00e33722015-06-24 11:44:51 -04001332
1333 wrapper.throw(1, 2, 3)
1334 gen.throw.assert_called_once_with(1, 2, 3)
1335 gen.reset_mock()
1336
1337 wrapper.throw(1, 2)
1338 gen.throw.assert_called_once_with(1, 2)
1339 gen.reset_mock()
1340
1341 wrapper.throw(1)
1342 gen.throw.assert_called_once_with(1)
1343 gen.reset_mock()
1344
1345 # Test exceptions propagation
1346 error = Exception()
1347 gen.throw.side_effect = error
1348 try:
1349 wrapper.throw(1)
1350 except Exception as ex:
1351 self.assertIs(ex, error)
1352 else:
1353 self.fail('wrapper did not propagate an exception')
1354
1355 # Test invalid args
1356 gen.reset_mock()
1357 with self.assertRaises(TypeError):
1358 wrapper.throw()
1359 self.assertFalse(gen.throw.called)
1360 with self.assertRaises(TypeError):
1361 wrapper.close(1)
1362 self.assertFalse(gen.close.called)
1363 with self.assertRaises(TypeError):
1364 wrapper.send()
1365 self.assertFalse(gen.send.called)
1366
1367 # Test that we do not double wrap
1368 @types.coroutine
1369 def bar(): return wrapper
1370 self.assertIs(wrapper, bar())
1371
1372 # Test weakrefs support
1373 ref = weakref.ref(wrapper)
1374 self.assertIs(ref(), wrapper)
1375
1376 def test_duck_functional_gen(self):
1377 class Generator:
1378 """Emulates the following generator (very clumsy):
1379
1380 def gen(fut):
1381 result = yield fut
1382 return result * 2
1383 """
1384 def __init__(self, fut):
1385 self._i = 0
1386 self._fut = fut
1387 def __iter__(self):
1388 return self
1389 def __next__(self):
1390 return self.send(None)
1391 def send(self, v):
1392 try:
1393 if self._i == 0:
1394 assert v is None
1395 return self._fut
1396 if self._i == 1:
1397 raise StopIteration(v * 2)
1398 if self._i > 1:
1399 raise StopIteration
1400 finally:
1401 self._i += 1
1402 def throw(self, tp, *exc):
1403 self._i = 100
1404 if tp is not GeneratorExit:
1405 raise tp
1406 def close(self):
1407 self.throw(GeneratorExit)
1408
1409 @types.coroutine
1410 def foo(): return Generator('spam')
1411
1412 wrapper = foo()
1413 self.assertIsInstance(wrapper, types._GeneratorWrapper)
1414
1415 async def corofunc():
1416 return await foo() + 100
1417 coro = corofunc()
1418
1419 self.assertEqual(coro.send(None), 'spam')
1420 try:
1421 coro.send(20)
1422 except StopIteration as ex:
1423 self.assertEqual(ex.args[0], 140)
1424 else:
1425 self.fail('StopIteration was expected')
Yury Selivanov13f77232015-05-29 16:19:18 -04001426
1427 def test_gen(self):
Yury Selivanovf847f1f2015-06-24 12:49:28 -04001428 def gen_func():
1429 yield 1
1430 return (yield 2)
1431 gen = gen_func()
Yury Selivanov13f77232015-05-29 16:19:18 -04001432 @types.coroutine
1433 def foo(): return gen
Yury Selivanov00e33722015-06-24 11:44:51 -04001434 wrapper = foo()
1435 self.assertIsInstance(wrapper, types._GeneratorWrapper)
1436 self.assertIs(wrapper.__await__(), gen)
Yury Selivanov13f77232015-05-29 16:19:18 -04001437
1438 for name in ('__name__', '__qualname__', 'gi_code',
1439 'gi_running', 'gi_frame'):
1440 self.assertIs(getattr(foo(), name),
1441 getattr(gen, name))
Yury Selivanov5376ba92015-06-22 12:19:30 -04001442 self.assertIs(foo().cr_code, gen.gi_code)
Yury Selivanovc565cd52015-05-29 09:06:05 -04001443
Yury Selivanovf847f1f2015-06-24 12:49:28 -04001444 self.assertEqual(next(wrapper), 1)
1445 self.assertEqual(wrapper.send(None), 2)
1446 with self.assertRaisesRegex(StopIteration, 'spam'):
1447 wrapper.send('spam')
1448
1449 gen = gen_func()
1450 wrapper = foo()
1451 wrapper.send(None)
1452 with self.assertRaisesRegex(Exception, 'ham'):
1453 wrapper.throw(Exception, Exception('ham'))
1454
Yury Selivanov4887523c2015-07-23 15:58:37 +03001455 # decorate foo second time
1456 foo = types.coroutine(foo)
1457 self.assertIs(foo().__await__(), gen)
1458
Yury Selivanovfdbeb2b2015-07-03 13:11:35 -04001459 def test_returning_itercoro(self):
1460 @types.coroutine
1461 def gen():
1462 yield
1463
1464 gencoro = gen()
1465
1466 @types.coroutine
1467 def foo():
1468 return gencoro
1469
1470 self.assertIs(foo(), gencoro)
1471
Yury Selivanov4887523c2015-07-23 15:58:37 +03001472 # decorate foo second time
1473 foo = types.coroutine(foo)
1474 self.assertIs(foo(), gencoro)
1475
Yury Selivanov75445082015-05-11 22:57:16 -04001476 def test_genfunc(self):
Yury Selivanov00e33722015-06-24 11:44:51 -04001477 def gen(): yield
1478 self.assertIs(types.coroutine(gen), gen)
Yury Selivanov4887523c2015-07-23 15:58:37 +03001479 self.assertIs(types.coroutine(types.coroutine(gen)), gen)
Yury Selivanov75445082015-05-11 22:57:16 -04001480
1481 self.assertTrue(gen.__code__.co_flags & inspect.CO_ITERABLE_COROUTINE)
1482 self.assertFalse(gen.__code__.co_flags & inspect.CO_COROUTINE)
1483
1484 g = gen()
1485 self.assertTrue(g.gi_code.co_flags & inspect.CO_ITERABLE_COROUTINE)
1486 self.assertFalse(g.gi_code.co_flags & inspect.CO_COROUTINE)
Yury Selivanov75445082015-05-11 22:57:16 -04001487
Yury Selivanov00e33722015-06-24 11:44:51 -04001488 self.assertIs(types.coroutine(gen), gen)
1489
1490 def test_wrapper_object(self):
1491 def gen():
1492 yield
1493 @types.coroutine
1494 def coro():
1495 return gen()
1496
1497 wrapper = coro()
1498 self.assertIn('GeneratorWrapper', repr(wrapper))
1499 self.assertEqual(repr(wrapper), str(wrapper))
1500 self.assertTrue(set(dir(wrapper)).issuperset({
1501 '__await__', '__iter__', '__next__', 'cr_code', 'cr_running',
1502 'cr_frame', 'gi_code', 'gi_frame', 'gi_running', 'send',
1503 'close', 'throw'}))
1504
Yury Selivanov75445082015-05-11 22:57:16 -04001505
Thomas Wouters89f507f2006-12-13 04:49:30 +00001506if __name__ == '__main__':
Zachary Ware38c707e2015-04-13 15:00:43 -05001507 unittest.main()