blob: 738588e9efc831512c6f778d24bad4a114f8627c [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 Selivanov5376ba92015-06-22 12:19:30 -04001216 def test_async_def(self):
1217 # Test that types.coroutine passes 'async def' coroutines
1218 # without modification
1219
1220 async def foo(): pass
1221 foo_code = foo.__code__
1222 foo_flags = foo.__code__.co_flags
1223 decorated_foo = types.coroutine(foo)
1224 self.assertIs(foo, decorated_foo)
1225 self.assertEqual(foo.__code__.co_flags, foo_flags)
1226 self.assertIs(decorated_foo.__code__, foo_code)
1227
1228 foo_coro = foo()
1229 @types.coroutine
1230 def bar(): return foo_coro
1231 coro = bar()
1232 self.assertIs(foo_coro, coro)
1233 self.assertEqual(coro.cr_code.co_flags, foo_flags)
1234 coro.close()
Yury Selivanovc565cd52015-05-29 09:06:05 -04001235
1236 def test_duck_coro(self):
1237 class CoroLike:
1238 def send(self): pass
1239 def throw(self): pass
1240 def close(self): pass
Yury Selivanov13f77232015-05-29 16:19:18 -04001241 def __await__(self): return self
Yury Selivanovc565cd52015-05-29 09:06:05 -04001242
1243 coro = CoroLike()
1244 @types.coroutine
1245 def foo():
1246 return coro
Yury Selivanov5376ba92015-06-22 12:19:30 -04001247 self.assertIs(foo(), coro)
1248 self.assertIs(foo().__await__(), coro)
1249
1250 def test_duck_corogen(self):
1251 class CoroGenLike:
1252 def send(self): pass
1253 def throw(self): pass
1254 def close(self): pass
1255 def __await__(self): return self
1256 def __iter__(self): return self
1257 def __next__(self): pass
1258
1259 coro = CoroGenLike()
1260 @types.coroutine
1261 def foo():
1262 return coro
1263 self.assertIs(foo(), coro)
Yury Selivanov13f77232015-05-29 16:19:18 -04001264 self.assertIs(foo().__await__(), coro)
1265
1266 def test_duck_gen(self):
1267 class GenLike:
1268 def send(self): pass
1269 def throw(self): pass
1270 def close(self): pass
Yury Selivanov00e33722015-06-24 11:44:51 -04001271 def __iter__(self): pass
Yury Selivanov13f77232015-05-29 16:19:18 -04001272 def __next__(self): pass
1273
Yury Selivanov00e33722015-06-24 11:44:51 -04001274 # Setup generator mock object
1275 gen = unittest.mock.MagicMock(GenLike)
1276 gen.__iter__ = lambda gen: gen
1277 gen.__name__ = 'gen'
1278 gen.__qualname__ = 'test.gen'
1279 self.assertIsInstance(gen, collections.abc.Generator)
1280 self.assertIs(gen, iter(gen))
1281
Yury Selivanov13f77232015-05-29 16:19:18 -04001282 @types.coroutine
Yury Selivanov00e33722015-06-24 11:44:51 -04001283 def foo(): return gen
1284
1285 wrapper = foo()
1286 self.assertIsInstance(wrapper, types._GeneratorWrapper)
1287 self.assertIs(wrapper.__await__(), wrapper)
1288 # Wrapper proxies duck generators completely:
1289 self.assertIs(iter(wrapper), wrapper)
1290
1291 self.assertIsInstance(wrapper, collections.abc.Coroutine)
1292 self.assertIsInstance(wrapper, collections.abc.Awaitable)
1293
1294 self.assertIs(wrapper.__qualname__, gen.__qualname__)
1295 self.assertIs(wrapper.__name__, gen.__name__)
1296
1297 # Test AttributeErrors
Yury Selivanov53e62302015-07-03 00:35:02 -04001298 for name in {'gi_running', 'gi_frame', 'gi_code', 'gi_yieldfrom',
1299 'cr_running', 'cr_frame', 'cr_code', 'cr_await'}:
Yury Selivanov00e33722015-06-24 11:44:51 -04001300 with self.assertRaises(AttributeError):
1301 getattr(wrapper, name)
1302
1303 # Test attributes pass-through
1304 gen.gi_running = object()
1305 gen.gi_frame = object()
1306 gen.gi_code = object()
Yury Selivanov53e62302015-07-03 00:35:02 -04001307 gen.gi_yieldfrom = object()
Yury Selivanov00e33722015-06-24 11:44:51 -04001308 self.assertIs(wrapper.gi_running, gen.gi_running)
1309 self.assertIs(wrapper.gi_frame, gen.gi_frame)
1310 self.assertIs(wrapper.gi_code, gen.gi_code)
Yury Selivanov53e62302015-07-03 00:35:02 -04001311 self.assertIs(wrapper.gi_yieldfrom, gen.gi_yieldfrom)
Yury Selivanov00e33722015-06-24 11:44:51 -04001312 self.assertIs(wrapper.cr_running, gen.gi_running)
1313 self.assertIs(wrapper.cr_frame, gen.gi_frame)
1314 self.assertIs(wrapper.cr_code, gen.gi_code)
Yury Selivanov53e62302015-07-03 00:35:02 -04001315 self.assertIs(wrapper.cr_await, gen.gi_yieldfrom)
Yury Selivanov00e33722015-06-24 11:44:51 -04001316
1317 wrapper.close()
1318 gen.close.assert_called_once_with()
1319
1320 wrapper.send(1)
1321 gen.send.assert_called_once_with(1)
Yury Selivanovf847f1f2015-06-24 12:49:28 -04001322 gen.reset_mock()
1323
1324 next(wrapper)
1325 gen.__next__.assert_called_once_with()
1326 gen.reset_mock()
Yury Selivanov00e33722015-06-24 11:44:51 -04001327
1328 wrapper.throw(1, 2, 3)
1329 gen.throw.assert_called_once_with(1, 2, 3)
1330 gen.reset_mock()
1331
1332 wrapper.throw(1, 2)
1333 gen.throw.assert_called_once_with(1, 2)
1334 gen.reset_mock()
1335
1336 wrapper.throw(1)
1337 gen.throw.assert_called_once_with(1)
1338 gen.reset_mock()
1339
1340 # Test exceptions propagation
1341 error = Exception()
1342 gen.throw.side_effect = error
1343 try:
1344 wrapper.throw(1)
1345 except Exception as ex:
1346 self.assertIs(ex, error)
1347 else:
1348 self.fail('wrapper did not propagate an exception')
1349
1350 # Test invalid args
1351 gen.reset_mock()
1352 with self.assertRaises(TypeError):
1353 wrapper.throw()
1354 self.assertFalse(gen.throw.called)
1355 with self.assertRaises(TypeError):
1356 wrapper.close(1)
1357 self.assertFalse(gen.close.called)
1358 with self.assertRaises(TypeError):
1359 wrapper.send()
1360 self.assertFalse(gen.send.called)
1361
1362 # Test that we do not double wrap
1363 @types.coroutine
1364 def bar(): return wrapper
1365 self.assertIs(wrapper, bar())
1366
1367 # Test weakrefs support
1368 ref = weakref.ref(wrapper)
1369 self.assertIs(ref(), wrapper)
1370
1371 def test_duck_functional_gen(self):
1372 class Generator:
1373 """Emulates the following generator (very clumsy):
1374
1375 def gen(fut):
1376 result = yield fut
1377 return result * 2
1378 """
1379 def __init__(self, fut):
1380 self._i = 0
1381 self._fut = fut
1382 def __iter__(self):
1383 return self
1384 def __next__(self):
1385 return self.send(None)
1386 def send(self, v):
1387 try:
1388 if self._i == 0:
1389 assert v is None
1390 return self._fut
1391 if self._i == 1:
1392 raise StopIteration(v * 2)
1393 if self._i > 1:
1394 raise StopIteration
1395 finally:
1396 self._i += 1
1397 def throw(self, tp, *exc):
1398 self._i = 100
1399 if tp is not GeneratorExit:
1400 raise tp
1401 def close(self):
1402 self.throw(GeneratorExit)
1403
1404 @types.coroutine
1405 def foo(): return Generator('spam')
1406
1407 wrapper = foo()
1408 self.assertIsInstance(wrapper, types._GeneratorWrapper)
1409
1410 async def corofunc():
1411 return await foo() + 100
1412 coro = corofunc()
1413
1414 self.assertEqual(coro.send(None), 'spam')
1415 try:
1416 coro.send(20)
1417 except StopIteration as ex:
1418 self.assertEqual(ex.args[0], 140)
1419 else:
1420 self.fail('StopIteration was expected')
Yury Selivanov13f77232015-05-29 16:19:18 -04001421
1422 def test_gen(self):
Yury Selivanovf847f1f2015-06-24 12:49:28 -04001423 def gen_func():
1424 yield 1
1425 return (yield 2)
1426 gen = gen_func()
Yury Selivanov13f77232015-05-29 16:19:18 -04001427 @types.coroutine
1428 def foo(): return gen
Yury Selivanov00e33722015-06-24 11:44:51 -04001429 wrapper = foo()
1430 self.assertIsInstance(wrapper, types._GeneratorWrapper)
1431 self.assertIs(wrapper.__await__(), gen)
Yury Selivanov13f77232015-05-29 16:19:18 -04001432
1433 for name in ('__name__', '__qualname__', 'gi_code',
1434 'gi_running', 'gi_frame'):
1435 self.assertIs(getattr(foo(), name),
1436 getattr(gen, name))
Yury Selivanov5376ba92015-06-22 12:19:30 -04001437 self.assertIs(foo().cr_code, gen.gi_code)
Yury Selivanovc565cd52015-05-29 09:06:05 -04001438
Yury Selivanovf847f1f2015-06-24 12:49:28 -04001439 self.assertEqual(next(wrapper), 1)
1440 self.assertEqual(wrapper.send(None), 2)
1441 with self.assertRaisesRegex(StopIteration, 'spam'):
1442 wrapper.send('spam')
1443
1444 gen = gen_func()
1445 wrapper = foo()
1446 wrapper.send(None)
1447 with self.assertRaisesRegex(Exception, 'ham'):
1448 wrapper.throw(Exception, Exception('ham'))
1449
Yury Selivanovfdbeb2b2015-07-03 13:11:35 -04001450 def test_returning_itercoro(self):
1451 @types.coroutine
1452 def gen():
1453 yield
1454
1455 gencoro = gen()
1456
1457 @types.coroutine
1458 def foo():
1459 return gencoro
1460
1461 self.assertIs(foo(), gencoro)
1462
Yury Selivanov75445082015-05-11 22:57:16 -04001463 def test_genfunc(self):
Yury Selivanov00e33722015-06-24 11:44:51 -04001464 def gen(): yield
1465 self.assertIs(types.coroutine(gen), gen)
Yury Selivanov75445082015-05-11 22:57:16 -04001466
1467 self.assertTrue(gen.__code__.co_flags & inspect.CO_ITERABLE_COROUTINE)
1468 self.assertFalse(gen.__code__.co_flags & inspect.CO_COROUTINE)
1469
1470 g = gen()
1471 self.assertTrue(g.gi_code.co_flags & inspect.CO_ITERABLE_COROUTINE)
1472 self.assertFalse(g.gi_code.co_flags & inspect.CO_COROUTINE)
Yury Selivanov75445082015-05-11 22:57:16 -04001473
Yury Selivanov00e33722015-06-24 11:44:51 -04001474 self.assertIs(types.coroutine(gen), gen)
1475
1476 def test_wrapper_object(self):
1477 def gen():
1478 yield
1479 @types.coroutine
1480 def coro():
1481 return gen()
1482
1483 wrapper = coro()
1484 self.assertIn('GeneratorWrapper', repr(wrapper))
1485 self.assertEqual(repr(wrapper), str(wrapper))
1486 self.assertTrue(set(dir(wrapper)).issuperset({
1487 '__await__', '__iter__', '__next__', 'cr_code', 'cr_running',
1488 'cr_frame', 'gi_code', 'gi_frame', 'gi_running', 'send',
1489 'close', 'throw'}))
1490
Yury Selivanov75445082015-05-11 22:57:16 -04001491
Thomas Wouters89f507f2006-12-13 04:49:30 +00001492if __name__ == '__main__':
Zachary Ware38c707e2015-04-13 15:00:43 -05001493 unittest.main()