blob: 17ec6458b336db0e7d3b85f13d2845f781170a00 [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
10import unittest
Guido van Rossum85f18201992-11-27 22:53:50 +000011
Thomas Wouters89f507f2006-12-13 04:49:30 +000012class TypesTests(unittest.TestCase):
Guido van Rossum85f18201992-11-27 22:53:50 +000013
Thomas Wouters89f507f2006-12-13 04:49:30 +000014 def test_truth_values(self):
15 if None: self.fail('None is true instead of false')
16 if 0: self.fail('0 is true instead of false')
Thomas Wouters89f507f2006-12-13 04:49:30 +000017 if 0.0: self.fail('0.0 is true instead of false')
18 if '': self.fail('\'\' is true instead of false')
19 if not 1: self.fail('1 is false instead of true')
Thomas Wouters89f507f2006-12-13 04:49:30 +000020 if not 1.0: self.fail('1.0 is false instead of true')
21 if not 'x': self.fail('\'x\' is false instead of true')
22 if not {'x': 1}: self.fail('{\'x\': 1} is false instead of true')
23 def f(): pass
24 class C: pass
Thomas Wouters89f507f2006-12-13 04:49:30 +000025 x = C()
26 if not f: self.fail('f is false instead of true')
27 if not C: self.fail('C is false instead of true')
28 if not sys: self.fail('sys is false instead of true')
29 if not x: self.fail('x is false instead of true')
Guido van Rossum85f18201992-11-27 22:53:50 +000030
Thomas Wouters89f507f2006-12-13 04:49:30 +000031 def test_boolean_ops(self):
32 if 0 or 0: self.fail('0 or 0 is true instead of false')
33 if 1 and 1: pass
34 else: self.fail('1 and 1 is false instead of true')
35 if not 1: self.fail('not 1 is true instead of false')
Neil Schemenauereff72442002-03-24 01:24:54 +000036
Thomas Wouters89f507f2006-12-13 04:49:30 +000037 def test_comparisons(self):
38 if 0 < 1 <= 1 == 1 >= 1 > 0 != 1: pass
39 else: self.fail('int comparisons failed')
Thomas Wouters89f507f2006-12-13 04:49:30 +000040 if 0.0 < 1.0 <= 1.0 == 1.0 >= 1.0 > 0.0 != 1.0: pass
41 else: self.fail('float comparisons failed')
42 if '' < 'a' <= 'a' == 'a' < 'abc' < 'abd' < 'b': pass
43 else: self.fail('string comparisons failed')
44 if None is None: pass
45 else: self.fail('identity test failed')
Neil Schemenauereff72442002-03-24 01:24:54 +000046
Thomas Wouters89f507f2006-12-13 04:49:30 +000047 def test_float_constructor(self):
48 self.assertRaises(ValueError, float, '')
49 self.assertRaises(ValueError, float, '5\0')
Neil Schemenauereff72442002-03-24 01:24:54 +000050
Thomas Wouters89f507f2006-12-13 04:49:30 +000051 def test_zero_division(self):
52 try: 5.0 / 0.0
53 except ZeroDivisionError: pass
54 else: self.fail("5.0 / 0.0 didn't raise ZeroDivisionError")
Neil Schemenauereff72442002-03-24 01:24:54 +000055
Thomas Wouters89f507f2006-12-13 04:49:30 +000056 try: 5.0 // 0.0
57 except ZeroDivisionError: pass
58 else: self.fail("5.0 // 0.0 didn't raise ZeroDivisionError")
Neil Schemenauereff72442002-03-24 01:24:54 +000059
Thomas Wouters89f507f2006-12-13 04:49:30 +000060 try: 5.0 % 0.0
61 except ZeroDivisionError: pass
62 else: self.fail("5.0 % 0.0 didn't raise ZeroDivisionError")
Neil Schemenauereff72442002-03-24 01:24:54 +000063
Guido van Rossume2a383d2007-01-15 16:59:06 +000064 try: 5 / 0
Thomas Wouters89f507f2006-12-13 04:49:30 +000065 except ZeroDivisionError: pass
Christian Heimes7131fd92008-02-19 14:21:46 +000066 else: self.fail("5 / 0 didn't raise ZeroDivisionError")
Neil Schemenauereff72442002-03-24 01:24:54 +000067
Guido van Rossume2a383d2007-01-15 16:59:06 +000068 try: 5 // 0
Thomas Wouters89f507f2006-12-13 04:49:30 +000069 except ZeroDivisionError: pass
Christian Heimes7131fd92008-02-19 14:21:46 +000070 else: self.fail("5 // 0 didn't raise ZeroDivisionError")
Neil Schemenauereff72442002-03-24 01:24:54 +000071
Guido van Rossume2a383d2007-01-15 16:59:06 +000072 try: 5 % 0
Thomas Wouters89f507f2006-12-13 04:49:30 +000073 except ZeroDivisionError: pass
Christian Heimes7131fd92008-02-19 14:21:46 +000074 else: self.fail("5 % 0 didn't raise ZeroDivisionError")
Tim Petersa3c01ce2001-12-04 23:05:10 +000075
Thomas Wouters89f507f2006-12-13 04:49:30 +000076 def test_numeric_types(self):
Mark Dickinson5c2db372009-12-05 20:28:34 +000077 if 0 != 0.0 or 1 != 1.0 or -1 != -1.0:
78 self.fail('int/float value not equal')
Thomas Wouters89f507f2006-12-13 04:49:30 +000079 # calling built-in types without argument must return 0
80 if int() != 0: self.fail('int() does not return 0')
Thomas Wouters89f507f2006-12-13 04:49:30 +000081 if float() != 0.0: self.fail('float() does not return 0.0')
82 if int(1.9) == 1 == int(1.1) and int(-1.1) == -1 == int(-1.9): pass
83 else: self.fail('int() does not round properly')
Thomas Wouters89f507f2006-12-13 04:49:30 +000084 if float(1) == 1.0 and float(-1) == -1.0 and float(0) == 0.0: pass
85 else: self.fail('float() does not work properly')
Neil Schemenauereff72442002-03-24 01:24:54 +000086
Christian Heimesc3f30c42008-02-22 16:37:40 +000087 def test_float_to_string(self):
88 def test(f, result):
89 self.assertEqual(f.__format__('e'), result)
90 self.assertEqual('%e' % f, result)
91
92 # test all 2 digit exponents, both with __format__ and with
93 # '%' formatting
94 for i in range(-99, 100):
95 test(float('1.5e'+str(i)), '1.500000e{0:+03d}'.format(i))
96
97 # test some 3 digit exponents
98 self.assertEqual(1.5e100.__format__('e'), '1.500000e+100')
99 self.assertEqual('%e' % 1.5e100, '1.500000e+100')
100
101 self.assertEqual(1.5e101.__format__('e'), '1.500000e+101')
102 self.assertEqual('%e' % 1.5e101, '1.500000e+101')
103
104 self.assertEqual(1.5e-100.__format__('e'), '1.500000e-100')
105 self.assertEqual('%e' % 1.5e-100, '1.500000e-100')
106
107 self.assertEqual(1.5e-101.__format__('e'), '1.500000e-101')
108 self.assertEqual('%e' % 1.5e-101, '1.500000e-101')
109
Eric Smith0923d1d2009-04-16 20:16:10 +0000110 self.assertEqual('%g' % 1.0, '1')
111 self.assertEqual('%#g' % 1.0, '1.00000')
112
Thomas Wouters89f507f2006-12-13 04:49:30 +0000113 def test_normal_integers(self):
114 # Ensure the first 256 integers are shared
115 a = 256
116 b = 128*2
117 if a is not b: self.fail('256 is not shared')
118 if 12 + 24 != 36: self.fail('int op')
119 if 12 + (-24) != -12: self.fail('int op')
120 if (-12) + 24 != 12: self.fail('int op')
121 if (-12) + (-24) != -36: self.fail('int op')
122 if not 12 < 24: self.fail('int op')
123 if not -24 < -12: self.fail('int op')
124 # Test for a particular bug in integer multiply
125 xsize, ysize, zsize = 238, 356, 4
126 if not (xsize*ysize*zsize == zsize*xsize*ysize == 338912):
127 self.fail('int mul commutativity')
128 # And another.
Christian Heimesa37d4c62007-12-04 23:02:19 +0000129 m = -sys.maxsize - 1
Thomas Wouters89f507f2006-12-13 04:49:30 +0000130 for divisor in 1, 2, 4, 8, 16, 32:
131 j = m // divisor
132 prod = divisor * j
133 if prod != m:
134 self.fail("%r * %r == %r != %r" % (divisor, j, prod, m))
135 if type(prod) is not int:
136 self.fail("expected type(prod) to be int, not %r" %
137 type(prod))
Mark Dickinson5c2db372009-12-05 20:28:34 +0000138 # Check for unified integral type
Thomas Wouters89f507f2006-12-13 04:49:30 +0000139 for divisor in 1, 2, 4, 8, 16, 32:
140 j = m // divisor - 1
141 prod = divisor * j
Guido van Rossume2a383d2007-01-15 16:59:06 +0000142 if type(prod) is not int:
Mark Dickinson5c2db372009-12-05 20:28:34 +0000143 self.fail("expected type(%r) to be int, not %r" %
Thomas Wouters89f507f2006-12-13 04:49:30 +0000144 (prod, type(prod)))
Mark Dickinson5c2db372009-12-05 20:28:34 +0000145 # Check for unified integral type
Christian Heimesa37d4c62007-12-04 23:02:19 +0000146 m = sys.maxsize
Thomas Wouters89f507f2006-12-13 04:49:30 +0000147 for divisor in 1, 2, 4, 8, 16, 32:
148 j = m // divisor + 1
149 prod = divisor * j
Guido van Rossume2a383d2007-01-15 16:59:06 +0000150 if type(prod) is not int:
Mark Dickinson5c2db372009-12-05 20:28:34 +0000151 self.fail("expected type(%r) to be int, not %r" %
Thomas Wouters89f507f2006-12-13 04:49:30 +0000152 (prod, type(prod)))
Neil Schemenauereff72442002-03-24 01:24:54 +0000153
Christian Heimesa37d4c62007-12-04 23:02:19 +0000154 x = sys.maxsize
Ezio Melottie9615932010-01-24 19:26:24 +0000155 self.assertIsInstance(x + 1, int,
156 "(sys.maxsize + 1) should have returned int")
157 self.assertIsInstance(-x - 1, int,
158 "(-sys.maxsize - 1) should have returned int")
159 self.assertIsInstance(-x - 2, int,
160 "(-sys.maxsize - 2) should have returned int")
Neil Schemenauereff72442002-03-24 01:24:54 +0000161
Thomas Wouters89f507f2006-12-13 04:49:30 +0000162 try: 5 << -5
163 except ValueError: pass
164 else: self.fail('int negative shift <<')
Neil Schemenauereff72442002-03-24 01:24:54 +0000165
Thomas Wouters89f507f2006-12-13 04:49:30 +0000166 try: 5 >> -5
167 except ValueError: pass
168 else: self.fail('int negative shift >>')
Guido van Rossum85f18201992-11-27 22:53:50 +0000169
Thomas Wouters89f507f2006-12-13 04:49:30 +0000170 def test_floats(self):
171 if 12.0 + 24.0 != 36.0: self.fail('float op')
172 if 12.0 + (-24.0) != -12.0: self.fail('float op')
173 if (-12.0) + 24.0 != 12.0: self.fail('float op')
174 if (-12.0) + (-24.0) != -36.0: self.fail('float op')
175 if not 12.0 < 24.0: self.fail('float op')
176 if not -24.0 < -12.0: self.fail('float op')
Guido van Rossum85f18201992-11-27 22:53:50 +0000177
Thomas Wouters89f507f2006-12-13 04:49:30 +0000178 def test_strings(self):
179 if len('') != 0: self.fail('len(\'\')')
180 if len('a') != 1: self.fail('len(\'a\')')
181 if len('abcdef') != 6: self.fail('len(\'abcdef\')')
182 if 'xyz' + 'abcde' != 'xyzabcde': self.fail('string concatenation')
183 if 'xyz'*3 != 'xyzxyzxyz': self.fail('string repetition *3')
184 if 0*'abcde' != '': self.fail('string repetition 0*')
185 if min('abc') != 'a' or max('abc') != 'c': self.fail('min/max string')
186 if 'a' in 'abc' and 'b' in 'abc' and 'c' in 'abc' and 'd' not in 'abc': pass
187 else: self.fail('in/not in string')
188 x = 'x'*103
189 if '%s!'%x != x+'!': self.fail('nasty string formatting bug')
Michael W. Hudson5efaf7e2002-06-11 10:55:12 +0000190
Thomas Wouters89f507f2006-12-13 04:49:30 +0000191 #extended slices for strings
192 a = '0123456789'
193 self.assertEqual(a[::], a)
194 self.assertEqual(a[::2], '02468')
195 self.assertEqual(a[1::2], '13579')
196 self.assertEqual(a[::-1],'9876543210')
197 self.assertEqual(a[::-2], '97531')
198 self.assertEqual(a[3::-2], '31')
199 self.assertEqual(a[-100:100:], a)
200 self.assertEqual(a[100:-100:-1], a[::-1])
Guido van Rossume2a383d2007-01-15 16:59:06 +0000201 self.assertEqual(a[-100:100:2], '02468')
Thomas Wouters89f507f2006-12-13 04:49:30 +0000202
Thomas Wouters89f507f2006-12-13 04:49:30 +0000203 def test_type_function(self):
204 self.assertRaises(TypeError, type, 1, 2)
205 self.assertRaises(TypeError, type, 1, 2, 3, 4)
Guido van Rossum85f18201992-11-27 22:53:50 +0000206
Christian Heimes7131fd92008-02-19 14:21:46 +0000207 def test_int__format__(self):
208 def test(i, format_spec, result):
Mark Dickinson5c2db372009-12-05 20:28:34 +0000209 # just make sure we have the unified type for integers
Christian Heimes7131fd92008-02-19 14:21:46 +0000210 assert type(i) == int
211 assert type(format_spec) == str
212 self.assertEqual(i.__format__(format_spec), result)
213
214 test(123456789, 'd', '123456789')
215 test(123456789, 'd', '123456789')
216
217 test(1, 'c', '\01')
218
219 # sign and aligning are interdependent
220 test(1, "-", '1')
221 test(-1, "-", '-1')
222 test(1, "-3", ' 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, " ", ' 1')
229 test(-1, " ", '-1')
230
231 # hex
232 test(3, "x", "3")
233 test(3, "X", "3")
234 test(1234, "x", "4d2")
235 test(-1234, "x", "-4d2")
236 test(1234, "8x", " 4d2")
237 test(-1234, "8x", " -4d2")
238 test(1234, "x", "4d2")
239 test(-1234, "x", "-4d2")
240 test(-3, "x", "-3")
241 test(-3, "X", "-3")
242 test(int('be', 16), "x", "be")
243 test(int('be', 16), "X", "BE")
244 test(-int('be', 16), "x", "-be")
245 test(-int('be', 16), "X", "-BE")
246
247 # octal
248 test(3, "o", "3")
249 test(-3, "o", "-3")
250 test(65, "o", "101")
251 test(-65, "o", "-101")
252 test(1234, "o", "2322")
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
261 # binary
262 test(3, "b", "11")
263 test(-3, "b", "-11")
264 test(1234, "b", "10011010010")
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
Eric Smithb1ebcc62008-07-15 13:02:41 +0000273 # alternate (#) formatting
274 test(0, "#b", '0b0')
275 test(0, "-#b", '0b0')
276 test(1, "-#b", '0b1')
277 test(-1, "-#b", '-0b1')
278 test(-1, "-#5b", ' -0b1')
279 test(1, "+#5b", ' +0b1')
280 test(100, "+#b", '+0b1100100')
Eric Smithd68af8f2008-07-16 00:15:35 +0000281 test(100, "#012b", '0b0001100100')
282 test(-100, "#012b", '-0b001100100')
Eric Smithb1ebcc62008-07-15 13:02:41 +0000283
284 test(0, "#o", '0o0')
285 test(0, "-#o", '0o0')
286 test(1, "-#o", '0o1')
287 test(-1, "-#o", '-0o1')
288 test(-1, "-#5o", ' -0o1')
289 test(1, "+#5o", ' +0o1')
290 test(100, "+#o", '+0o144')
Eric Smithd68af8f2008-07-16 00:15:35 +0000291 test(100, "#012o", '0o0000000144')
292 test(-100, "#012o", '-0o000000144')
Eric Smithb1ebcc62008-07-15 13:02:41 +0000293
294 test(0, "#x", '0x0')
295 test(0, "-#x", '0x0')
296 test(1, "-#x", '0x1')
297 test(-1, "-#x", '-0x1')
298 test(-1, "-#5x", ' -0x1')
299 test(1, "+#5x", ' +0x1')
300 test(100, "+#x", '+0x64')
Eric Smithd68af8f2008-07-16 00:15:35 +0000301 test(100, "#012x", '0x0000000064')
302 test(-100, "#012x", '-0x000000064')
303 test(123456, "#012x", '0x000001e240')
304 test(-123456, "#012x", '-0x00001e240')
Eric Smithb1ebcc62008-07-15 13:02:41 +0000305
306 test(0, "#X", '0X0')
307 test(0, "-#X", '0X0')
308 test(1, "-#X", '0X1')
309 test(-1, "-#X", '-0X1')
310 test(-1, "-#5X", ' -0X1')
311 test(1, "+#5X", ' +0X1')
312 test(100, "+#X", '+0X64')
Eric Smithd68af8f2008-07-16 00:15:35 +0000313 test(100, "#012X", '0X0000000064')
314 test(-100, "#012X", '-0X000000064')
315 test(123456, "#012X", '0X000001E240')
316 test(-123456, "#012X", '-0X00001E240')
Eric Smithb1ebcc62008-07-15 13:02:41 +0000317
Eric Smitha3b1ac82009-04-03 14:45:06 +0000318 test(123, ',', '123')
319 test(-123, ',', '-123')
320 test(1234, ',', '1,234')
321 test(-1234, ',', '-1,234')
322 test(123456, ',', '123,456')
323 test(-123456, ',', '-123,456')
324 test(1234567, ',', '1,234,567')
325 test(-1234567, ',', '-1,234,567')
326
Eric Smith937491d2009-04-22 17:04:27 +0000327 # issue 5782, commas with no specifier type
328 test(1234, '010,', '00,001,234')
329
Mark Dickinson5c2db372009-12-05 20:28:34 +0000330 # Unified type for integers
331 test(10**100, 'd', '1' + '0' * 100)
332 test(10**100+100, 'd', '1' + '0' * 97 + '100')
333
Christian Heimes7131fd92008-02-19 14:21:46 +0000334 # make sure these are errors
335
336 # precision disallowed
337 self.assertRaises(ValueError, 3 .__format__, "1.3")
338 # sign not allowed with 'c'
339 self.assertRaises(ValueError, 3 .__format__, "+c")
340 # format spec must be string
341 self.assertRaises(TypeError, 3 .__format__, None)
342 self.assertRaises(TypeError, 3 .__format__, 0)
Eric Smitha3b1ac82009-04-03 14:45:06 +0000343 # can't have ',' with 'n'
344 self.assertRaises(ValueError, 3 .__format__, ",n")
Eric Smith0923d1d2009-04-16 20:16:10 +0000345 # can't have ',' with 'c'
346 self.assertRaises(ValueError, 3 .__format__, ",c")
Eric V. Smitha12572f2014-04-15 22:37:55 -0400347 # can't have '#' with 'c'
348 self.assertRaises(ValueError, 3 .__format__, "#c")
Christian Heimes7131fd92008-02-19 14:21:46 +0000349
350 # ensure that only int and float type specifiers work
351 for format_spec in ([chr(x) for x in range(ord('a'), ord('z')+1)] +
352 [chr(x) for x in range(ord('A'), ord('Z')+1)]):
353 if not format_spec in 'bcdoxXeEfFgGn%':
354 self.assertRaises(ValueError, 0 .__format__, format_spec)
355 self.assertRaises(ValueError, 1 .__format__, format_spec)
356 self.assertRaises(ValueError, (-1) .__format__, format_spec)
357
358 # ensure that float type specifiers work; format converts
359 # the int to a float
Eric Smith5807c412008-05-11 21:00:57 +0000360 for format_spec in 'eEfFgG%':
Christian Heimes7131fd92008-02-19 14:21:46 +0000361 for value in [0, 1, -1, 100, -100, 1234567890, -1234567890]:
362 self.assertEqual(value.__format__(format_spec),
363 float(value).__format__(format_spec))
364
Eric Smithabb28c62010-02-23 00:22:24 +0000365 # Issue 6902
366 test(123456, "0<20", '12345600000000000000')
367 test(123456, "1<20", '12345611111111111111')
368 test(123456, "*<20", '123456**************')
369 test(123456, "0>20", '00000000000000123456')
370 test(123456, "1>20", '11111111111111123456')
371 test(123456, "*>20", '**************123456')
372 test(123456, "0=20", '00000000000000123456')
373 test(123456, "1=20", '11111111111111123456')
374 test(123456, "*=20", '**************123456')
375
Eric Smithb2c7af82008-04-30 02:12:09 +0000376 @run_with_locale('LC_NUMERIC', 'en_US.UTF8')
377 def test_float__format__locale(self):
378 # test locale support for __format__ code 'n'
379
380 for i in range(-10, 10):
381 x = 1234567890.0 * (10.0 ** i)
382 self.assertEqual(locale.format('%g', x, grouping=True), format(x, 'n'))
383 self.assertEqual(locale.format('%.10g', x, grouping=True), format(x, '.10n'))
384
Eric Smith5807c412008-05-11 21:00:57 +0000385 @run_with_locale('LC_NUMERIC', 'en_US.UTF8')
386 def test_int__format__locale(self):
387 # test locale support for __format__ code 'n' for integers
388
389 x = 123456789012345678901234567890
390 for i in range(0, 30):
391 self.assertEqual(locale.format('%d', x, grouping=True), format(x, 'n'))
392
393 # move to the next integer to test
394 x = x // 10
395
Eric Smithb151a452008-06-24 11:21:04 +0000396 rfmt = ">20n"
397 lfmt = "<20n"
398 cfmt = "^20n"
399 for x in (1234, 12345, 123456, 1234567, 12345678, 123456789, 1234567890, 12345678900):
400 self.assertEqual(len(format(0, rfmt)), len(format(x, rfmt)))
401 self.assertEqual(len(format(0, lfmt)), len(format(x, lfmt)))
402 self.assertEqual(len(format(0, cfmt)), len(format(x, cfmt)))
403
Christian Heimes7131fd92008-02-19 14:21:46 +0000404 def test_float__format__(self):
Christian Heimes7131fd92008-02-19 14:21:46 +0000405 def test(f, format_spec, result):
Christian Heimes7131fd92008-02-19 14:21:46 +0000406 self.assertEqual(f.__format__(format_spec), result)
Eric Smith984bb582010-11-25 16:08:06 +0000407 self.assertEqual(format(f, format_spec), result)
Christian Heimes7131fd92008-02-19 14:21:46 +0000408
409 test(0.0, 'f', '0.000000')
410
411 # the default is 'g', except for empty format spec
412 test(0.0, '', '0.0')
413 test(0.01, '', '0.01')
414 test(0.01, 'g', '0.01')
415
Eric Smith2ad79e82008-07-19 00:33:23 +0000416 # test for issue 3411
417 test(1.23, '1', '1.23')
418 test(-1.23, '1', '-1.23')
419 test(1.23, '1g', '1.23')
420 test(-1.23, '1g', '-1.23')
421
Christian Heimes7131fd92008-02-19 14:21:46 +0000422 test( 1.0, ' g', ' 1')
423 test(-1.0, ' g', '-1')
424 test( 1.0, '+g', '+1')
425 test(-1.0, '+g', '-1')
426 test(1.1234e200, 'g', '1.1234e+200')
427 test(1.1234e200, 'G', '1.1234E+200')
428
429
430 test(1.0, 'f', '1.000000')
431
432 test(-1.0, 'f', '-1.000000')
433
434 test( 1.0, ' f', ' 1.000000')
435 test(-1.0, ' f', '-1.000000')
436 test( 1.0, '+f', '+1.000000')
437 test(-1.0, '+f', '-1.000000')
Mark Dickinson33841c32009-05-01 15:37:04 +0000438
439 # Python versions <= 3.0 switched from 'f' to 'g' formatting for
440 # values larger than 1e50. No longer.
441 f = 1.1234e90
442 for fmt in 'f', 'F':
443 # don't do a direct equality check, since on some
444 # platforms only the first few digits of dtoa
445 # will be reliable
446 result = f.__format__(fmt)
447 self.assertEqual(len(result), 98)
448 self.assertEqual(result[-7], '.')
Benjamin Peterson577473f2010-01-19 00:09:57 +0000449 self.assertIn(result[:12], ('112340000000', '112339999999'))
Mark Dickinson33841c32009-05-01 15:37:04 +0000450 f = 1.1234e200
451 for fmt in 'f', 'F':
452 result = f.__format__(fmt)
453 self.assertEqual(len(result), 208)
454 self.assertEqual(result[-7], '.')
Benjamin Peterson577473f2010-01-19 00:09:57 +0000455 self.assertIn(result[:12], ('112340000000', '112339999999'))
Mark Dickinson33841c32009-05-01 15:37:04 +0000456
Christian Heimes7131fd92008-02-19 14:21:46 +0000457
Christian Heimesc3f30c42008-02-22 16:37:40 +0000458 test( 1.0, 'e', '1.000000e+00')
459 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.1234e20, 'e', '1.123400e+20')
463 test(1.1234e20, 'E', '1.123400E+20')
Christian Heimes7131fd92008-02-19 14:21:46 +0000464
Christian Heimesb186d002008-03-18 15:15:01 +0000465 # No format code means use g, but must have a decimal
466 # and a number after the decimal. This is tricky, because
467 # a totaly empty format specifier means something else.
468 # So, just use a sign flag
469 test(1e200, '+g', '+1e+200')
Eric Smith0923d1d2009-04-16 20:16:10 +0000470 test(1e200, '+', '+1e+200')
471
Christian Heimesb186d002008-03-18 15:15:01 +0000472 test(1.1e200, '+g', '+1.1e+200')
473 test(1.1e200, '+', '+1.1e+200')
474
Eric Smith0923d1d2009-04-16 20:16:10 +0000475 # 0 padding
476 test(1234., '010f', '1234.000000')
477 test(1234., '011f', '1234.000000')
478 test(1234., '012f', '01234.000000')
479 test(-1234., '011f', '-1234.000000')
480 test(-1234., '012f', '-1234.000000')
481 test(-1234., '013f', '-01234.000000')
482 test(-1234.12341234, '013f', '-01234.123412')
483 test(-123456.12341234, '011.2f', '-0123456.12')
484
Eric Smith937491d2009-04-22 17:04:27 +0000485 # issue 5782, commas with no specifier type
486 test(1.2, '010,.2', '0,000,001.2')
487
Eric Smith0923d1d2009-04-16 20:16:10 +0000488 # 0 padding with commas
489 test(1234., '011,f', '1,234.000000')
490 test(1234., '012,f', '1,234.000000')
491 test(1234., '013,f', '01,234.000000')
492 test(-1234., '012,f', '-1,234.000000')
493 test(-1234., '013,f', '-1,234.000000')
494 test(-1234., '014,f', '-01,234.000000')
495 test(-12345., '015,f', '-012,345.000000')
496 test(-123456., '016,f', '-0,123,456.000000')
497 test(-123456., '017,f', '-0,123,456.000000')
498 test(-123456.12341234, '017,f', '-0,123,456.123412')
499 test(-123456.12341234, '013,.2f', '-0,123,456.12')
500
Christian Heimes7131fd92008-02-19 14:21:46 +0000501 # % formatting
502 test(-1.0, '%', '-100.000000%')
503
504 # format spec must be string
505 self.assertRaises(TypeError, 3.0.__format__, None)
506 self.assertRaises(TypeError, 3.0.__format__, 0)
507
508 # other format specifiers shouldn't work on floats,
509 # in particular int specifiers
510 for format_spec in ([chr(x) for x in range(ord('a'), ord('z')+1)] +
511 [chr(x) for x in range(ord('A'), ord('Z')+1)]):
512 if not format_spec in 'eEfFgGn%':
513 self.assertRaises(ValueError, format, 0.0, format_spec)
514 self.assertRaises(ValueError, format, 1.0, format_spec)
515 self.assertRaises(ValueError, format, -1.0, format_spec)
516 self.assertRaises(ValueError, format, 1e100, format_spec)
517 self.assertRaises(ValueError, format, -1e100, format_spec)
518 self.assertRaises(ValueError, format, 1e-100, format_spec)
519 self.assertRaises(ValueError, format, -1e-100, format_spec)
520
Eric Smith984bb582010-11-25 16:08:06 +0000521 # Alternate float formatting
522 test(1.0, '.0e', '1e+00')
523 test(1.0, '#.0e', '1.e+00')
524 test(1.0, '.0f', '1')
525 test(1.0, '#.0f', '1.')
526 test(1.1, 'g', '1.1')
527 test(1.1, '#g', '1.10000')
528 test(1.0, '.0%', '100%')
529 test(1.0, '#.0%', '100.%')
530
531 # Issue 7094: Alternate formatting (specified by #)
532 test(1.0, '0e', '1.000000e+00')
533 test(1.0, '#0e', '1.000000e+00')
534 test(1.0, '0f', '1.000000' )
535 test(1.0, '#0f', '1.000000')
536 test(1.0, '.1e', '1.0e+00')
537 test(1.0, '#.1e', '1.0e+00')
538 test(1.0, '.1f', '1.0')
539 test(1.0, '#.1f', '1.0')
540 test(1.0, '.1%', '100.0%')
541 test(1.0, '#.1%', '100.0%')
Eric Smithb1ebcc62008-07-15 13:02:41 +0000542
Eric Smithabb28c62010-02-23 00:22:24 +0000543 # Issue 6902
544 test(12345.6, "0<20", '12345.60000000000000')
545 test(12345.6, "1<20", '12345.61111111111111')
546 test(12345.6, "*<20", '12345.6*************')
547 test(12345.6, "0>20", '000000000000012345.6')
548 test(12345.6, "1>20", '111111111111112345.6')
549 test(12345.6, "*>20", '*************12345.6')
550 test(12345.6, "0=20", '000000000000012345.6')
551 test(12345.6, "1=20", '111111111111112345.6')
552 test(12345.6, "*=20", '*************12345.6')
553
Eric Smith0923d1d2009-04-16 20:16:10 +0000554 def test_format_spec_errors(self):
555 # int, float, and string all share the same format spec
556 # mini-language parser.
557
558 # Check that we can't ask for too many digits. This is
559 # probably a CPython specific test. It tries to put the width
560 # into a C long.
561 self.assertRaises(ValueError, format, 0, '1'*10000 + 'd')
562
563 # Similar with the precision.
564 self.assertRaises(ValueError, format, 0, '.' + '1'*10000 + 'd')
565
566 # And may as well test both.
567 self.assertRaises(ValueError, format, 0, '1'*1000 + '.' + '1'*10000 + 'd')
568
569 # Make sure commas aren't allowed with various type codes
570 for code in 'xXobns':
571 self.assertRaises(ValueError, format, 0, ',' + code)
Christian Heimes7131fd92008-02-19 14:21:46 +0000572
Benjamin Peterson0e102062010-08-25 23:13:17 +0000573 def test_internal_sizes(self):
574 self.assertGreater(object.__basicsize__, 0)
575 self.assertGreater(tuple.__itemsize__, 0)
576
577
Victor Stinner0db176f2012-04-16 00:16:30 +0200578class MappingProxyTests(unittest.TestCase):
579 mappingproxy = types.MappingProxyType
580
581 def test_constructor(self):
582 class userdict(dict):
583 pass
584
585 mapping = {'x': 1, 'y': 2}
586 self.assertEqual(self.mappingproxy(mapping), mapping)
587 mapping = userdict(x=1, y=2)
588 self.assertEqual(self.mappingproxy(mapping), mapping)
589 mapping = collections.ChainMap({'x': 1}, {'y': 2})
590 self.assertEqual(self.mappingproxy(mapping), mapping)
591
592 self.assertRaises(TypeError, self.mappingproxy, 10)
593 self.assertRaises(TypeError, self.mappingproxy, ("a", "tuple"))
594 self.assertRaises(TypeError, self.mappingproxy, ["a", "list"])
595
596 def test_methods(self):
597 attrs = set(dir(self.mappingproxy({}))) - set(dir(object()))
598 self.assertEqual(attrs, {
599 '__contains__',
600 '__getitem__',
601 '__iter__',
602 '__len__',
603 'copy',
604 'get',
605 'items',
606 'keys',
607 'values',
608 })
609
610 def test_get(self):
611 view = self.mappingproxy({'a': 'A', 'b': 'B'})
612 self.assertEqual(view['a'], 'A')
613 self.assertEqual(view['b'], 'B')
614 self.assertRaises(KeyError, view.__getitem__, 'xxx')
615 self.assertEqual(view.get('a'), 'A')
616 self.assertIsNone(view.get('xxx'))
617 self.assertEqual(view.get('xxx', 42), 42)
618
619 def test_missing(self):
620 class dictmissing(dict):
621 def __missing__(self, key):
622 return "missing=%s" % key
623
624 view = self.mappingproxy(dictmissing(x=1))
625 self.assertEqual(view['x'], 1)
626 self.assertEqual(view['y'], 'missing=y')
627 self.assertEqual(view.get('x'), 1)
628 self.assertEqual(view.get('y'), None)
629 self.assertEqual(view.get('y', 42), 42)
630 self.assertTrue('x' in view)
631 self.assertFalse('y' in view)
632
633 def test_customdict(self):
634 class customdict(dict):
635 def __contains__(self, key):
636 if key == 'magic':
637 return True
638 else:
639 return dict.__contains__(self, key)
640
641 def __iter__(self):
642 return iter(('iter',))
643
644 def __len__(self):
645 return 500
646
647 def copy(self):
648 return 'copy'
649
650 def keys(self):
651 return 'keys'
652
653 def items(self):
654 return 'items'
655
656 def values(self):
657 return 'values'
658
659 def __getitem__(self, key):
660 return "getitem=%s" % dict.__getitem__(self, key)
661
662 def get(self, key, default=None):
663 return "get=%s" % dict.get(self, key, 'default=%r' % default)
664
665 custom = customdict({'key': 'value'})
666 view = self.mappingproxy(custom)
667 self.assertTrue('key' in view)
668 self.assertTrue('magic' in view)
669 self.assertFalse('xxx' in view)
670 self.assertEqual(view['key'], 'getitem=value')
671 self.assertRaises(KeyError, view.__getitem__, 'xxx')
672 self.assertEqual(tuple(view), ('iter',))
673 self.assertEqual(len(view), 500)
674 self.assertEqual(view.copy(), 'copy')
675 self.assertEqual(view.get('key'), 'get=value')
676 self.assertEqual(view.get('xxx'), 'get=default=None')
677 self.assertEqual(view.items(), 'items')
678 self.assertEqual(view.keys(), 'keys')
679 self.assertEqual(view.values(), 'values')
680
681 def test_chainmap(self):
682 d1 = {'x': 1}
683 d2 = {'y': 2}
684 mapping = collections.ChainMap(d1, d2)
685 view = self.mappingproxy(mapping)
686 self.assertTrue('x' in view)
687 self.assertTrue('y' in view)
688 self.assertFalse('z' in view)
689 self.assertEqual(view['x'], 1)
690 self.assertEqual(view['y'], 2)
691 self.assertRaises(KeyError, view.__getitem__, 'z')
692 self.assertEqual(tuple(sorted(view)), ('x', 'y'))
693 self.assertEqual(len(view), 2)
694 copy = view.copy()
695 self.assertIsNot(copy, mapping)
696 self.assertIsInstance(copy, collections.ChainMap)
697 self.assertEqual(copy, mapping)
698 self.assertEqual(view.get('x'), 1)
699 self.assertEqual(view.get('y'), 2)
700 self.assertIsNone(view.get('z'))
701 self.assertEqual(tuple(sorted(view.items())), (('x', 1), ('y', 2)))
702 self.assertEqual(tuple(sorted(view.keys())), ('x', 'y'))
703 self.assertEqual(tuple(sorted(view.values())), (1, 2))
704
705 def test_contains(self):
706 view = self.mappingproxy(dict.fromkeys('abc'))
707 self.assertTrue('a' in view)
708 self.assertTrue('b' in view)
709 self.assertTrue('c' in view)
710 self.assertFalse('xxx' in view)
711
712 def test_views(self):
713 mapping = {}
714 view = self.mappingproxy(mapping)
715 keys = view.keys()
716 values = view.values()
717 items = view.items()
718 self.assertEqual(list(keys), [])
719 self.assertEqual(list(values), [])
720 self.assertEqual(list(items), [])
721 mapping['key'] = 'value'
722 self.assertEqual(list(keys), ['key'])
723 self.assertEqual(list(values), ['value'])
724 self.assertEqual(list(items), [('key', 'value')])
725
726 def test_len(self):
727 for expected in range(6):
728 data = dict.fromkeys('abcde'[:expected])
729 self.assertEqual(len(data), expected)
730 view = self.mappingproxy(data)
731 self.assertEqual(len(view), expected)
732
733 def test_iterators(self):
734 keys = ('x', 'y')
735 values = (1, 2)
736 items = tuple(zip(keys, values))
737 view = self.mappingproxy(dict(items))
738 self.assertEqual(set(view), set(keys))
739 self.assertEqual(set(view.keys()), set(keys))
740 self.assertEqual(set(view.values()), set(values))
741 self.assertEqual(set(view.items()), set(items))
742
743 def test_copy(self):
744 original = {'key1': 27, 'key2': 51, 'key3': 93}
745 view = self.mappingproxy(original)
746 copy = view.copy()
747 self.assertEqual(type(copy), dict)
748 self.assertEqual(copy, original)
749 original['key1'] = 70
750 self.assertEqual(view['key1'], 70)
751 self.assertEqual(copy['key1'], 27)
752
753
Nick Coghlan7fc570a2012-05-20 02:34:13 +1000754class ClassCreationTests(unittest.TestCase):
755
756 class Meta(type):
757 def __init__(cls, name, bases, ns, **kw):
758 super().__init__(name, bases, ns)
759 @staticmethod
760 def __new__(mcls, name, bases, ns, **kw):
761 return super().__new__(mcls, name, bases, ns)
762 @classmethod
763 def __prepare__(mcls, name, bases, **kw):
764 ns = super().__prepare__(name, bases)
765 ns["y"] = 1
766 ns.update(kw)
767 return ns
768
769 def test_new_class_basics(self):
770 C = types.new_class("C")
771 self.assertEqual(C.__name__, "C")
772 self.assertEqual(C.__bases__, (object,))
773
774 def test_new_class_subclass(self):
775 C = types.new_class("C", (int,))
776 self.assertTrue(issubclass(C, int))
777
778 def test_new_class_meta(self):
779 Meta = self.Meta
780 settings = {"metaclass": Meta, "z": 2}
781 # We do this twice to make sure the passed in dict isn't mutated
782 for i in range(2):
783 C = types.new_class("C" + str(i), (), settings)
784 self.assertIsInstance(C, Meta)
785 self.assertEqual(C.y, 1)
786 self.assertEqual(C.z, 2)
787
788 def test_new_class_exec_body(self):
789 Meta = self.Meta
790 def func(ns):
791 ns["x"] = 0
792 C = types.new_class("C", (), {"metaclass": Meta, "z": 2}, func)
793 self.assertIsInstance(C, Meta)
794 self.assertEqual(C.x, 0)
795 self.assertEqual(C.y, 1)
796 self.assertEqual(C.z, 2)
797
Benjamin Peterson43f8f4c2012-09-27 18:10:17 -0400798 def test_new_class_metaclass_keywords(self):
Nick Coghlan7fc570a2012-05-20 02:34:13 +1000799 #Test that keywords are passed to the metaclass:
800 def meta_func(name, bases, ns, **kw):
801 return name, bases, ns, kw
802 res = types.new_class("X",
803 (int, object),
804 dict(metaclass=meta_func, x=0))
805 self.assertEqual(res, ("X", (int, object), {}, {"x": 0}))
806
807 def test_new_class_defaults(self):
808 # Test defaults/keywords:
809 C = types.new_class("C", (), {}, None)
810 self.assertEqual(C.__name__, "C")
811 self.assertEqual(C.__bases__, (object,))
812
813 def test_new_class_meta_with_base(self):
814 Meta = self.Meta
815 def func(ns):
816 ns["x"] = 0
817 C = types.new_class(name="C",
818 bases=(int,),
819 kwds=dict(metaclass=Meta, z=2),
820 exec_body=func)
821 self.assertTrue(issubclass(C, int))
822 self.assertIsInstance(C, Meta)
823 self.assertEqual(C.x, 0)
824 self.assertEqual(C.y, 1)
825 self.assertEqual(C.z, 2)
826
827 # Many of the following tests are derived from test_descr.py
828 def test_prepare_class(self):
829 # Basic test of metaclass derivation
830 expected_ns = {}
831 class A(type):
832 def __new__(*args, **kwargs):
833 return type.__new__(*args, **kwargs)
834
835 def __prepare__(*args):
836 return expected_ns
837
838 B = types.new_class("B", (object,))
839 C = types.new_class("C", (object,), {"metaclass": A})
840
841 # The most derived metaclass of D is A rather than type.
842 meta, ns, kwds = types.prepare_class("D", (B, C), {"metaclass": type})
843 self.assertIs(meta, A)
844 self.assertIs(ns, expected_ns)
845 self.assertEqual(len(kwds), 0)
846
847 def test_metaclass_derivation(self):
848 # issue1294232: correct metaclass calculation
849 new_calls = [] # to check the order of __new__ calls
850 class AMeta(type):
851 def __new__(mcls, name, bases, ns):
852 new_calls.append('AMeta')
853 return super().__new__(mcls, name, bases, ns)
854 @classmethod
855 def __prepare__(mcls, name, bases):
856 return {}
857
858 class BMeta(AMeta):
859 def __new__(mcls, name, bases, ns):
860 new_calls.append('BMeta')
861 return super().__new__(mcls, name, bases, ns)
862 @classmethod
863 def __prepare__(mcls, name, bases):
864 ns = super().__prepare__(name, bases)
865 ns['BMeta_was_here'] = True
866 return ns
867
868 A = types.new_class("A", (), {"metaclass": AMeta})
869 self.assertEqual(new_calls, ['AMeta'])
870 new_calls.clear()
871
872 B = types.new_class("B", (), {"metaclass": BMeta})
873 # BMeta.__new__ calls AMeta.__new__ with super:
874 self.assertEqual(new_calls, ['BMeta', 'AMeta'])
875 new_calls.clear()
876
877 C = types.new_class("C", (A, B))
878 # The most derived metaclass is BMeta:
879 self.assertEqual(new_calls, ['BMeta', 'AMeta'])
880 new_calls.clear()
881 # BMeta.__prepare__ should've been called:
882 self.assertIn('BMeta_was_here', C.__dict__)
883
884 # The order of the bases shouldn't matter:
885 C2 = types.new_class("C2", (B, A))
886 self.assertEqual(new_calls, ['BMeta', 'AMeta'])
887 new_calls.clear()
888 self.assertIn('BMeta_was_here', C2.__dict__)
889
890 # Check correct metaclass calculation when a metaclass is declared:
891 D = types.new_class("D", (C,), {"metaclass": type})
892 self.assertEqual(new_calls, ['BMeta', 'AMeta'])
893 new_calls.clear()
894 self.assertIn('BMeta_was_here', D.__dict__)
895
896 E = types.new_class("E", (C,), {"metaclass": AMeta})
897 self.assertEqual(new_calls, ['BMeta', 'AMeta'])
898 new_calls.clear()
899 self.assertIn('BMeta_was_here', E.__dict__)
900
901 def test_metaclass_override_function(self):
902 # Special case: the given metaclass isn't a class,
903 # so there is no metaclass calculation.
904 class A(metaclass=self.Meta):
905 pass
906
907 marker = object()
908 def func(*args, **kwargs):
909 return marker
910
911 X = types.new_class("X", (), {"metaclass": func})
912 Y = types.new_class("Y", (object,), {"metaclass": func})
913 Z = types.new_class("Z", (A,), {"metaclass": func})
914 self.assertIs(marker, X)
915 self.assertIs(marker, Y)
916 self.assertIs(marker, Z)
917
918 def test_metaclass_override_callable(self):
919 # The given metaclass is a class,
920 # but not a descendant of type.
921 new_calls = [] # to check the order of __new__ calls
922 prepare_calls = [] # to track __prepare__ calls
923 class ANotMeta:
924 def __new__(mcls, *args, **kwargs):
925 new_calls.append('ANotMeta')
926 return super().__new__(mcls)
927 @classmethod
928 def __prepare__(mcls, name, bases):
929 prepare_calls.append('ANotMeta')
930 return {}
931
932 class BNotMeta(ANotMeta):
933 def __new__(mcls, *args, **kwargs):
934 new_calls.append('BNotMeta')
935 return super().__new__(mcls)
936 @classmethod
937 def __prepare__(mcls, name, bases):
938 prepare_calls.append('BNotMeta')
939 return super().__prepare__(name, bases)
940
941 A = types.new_class("A", (), {"metaclass": ANotMeta})
942 self.assertIs(ANotMeta, type(A))
943 self.assertEqual(prepare_calls, ['ANotMeta'])
944 prepare_calls.clear()
945 self.assertEqual(new_calls, ['ANotMeta'])
946 new_calls.clear()
947
948 B = types.new_class("B", (), {"metaclass": BNotMeta})
949 self.assertIs(BNotMeta, type(B))
950 self.assertEqual(prepare_calls, ['BNotMeta', 'ANotMeta'])
951 prepare_calls.clear()
952 self.assertEqual(new_calls, ['BNotMeta', 'ANotMeta'])
953 new_calls.clear()
954
955 C = types.new_class("C", (A, B))
956 self.assertIs(BNotMeta, type(C))
957 self.assertEqual(prepare_calls, ['BNotMeta', 'ANotMeta'])
958 prepare_calls.clear()
959 self.assertEqual(new_calls, ['BNotMeta', 'ANotMeta'])
960 new_calls.clear()
961
962 C2 = types.new_class("C2", (B, A))
963 self.assertIs(BNotMeta, type(C2))
964 self.assertEqual(prepare_calls, ['BNotMeta', 'ANotMeta'])
965 prepare_calls.clear()
966 self.assertEqual(new_calls, ['BNotMeta', 'ANotMeta'])
967 new_calls.clear()
968
969 # This is a TypeError, because of a metaclass conflict:
970 # BNotMeta is neither a subclass, nor a superclass of type
971 with self.assertRaises(TypeError):
972 D = types.new_class("D", (C,), {"metaclass": type})
973
974 E = types.new_class("E", (C,), {"metaclass": ANotMeta})
975 self.assertIs(BNotMeta, type(E))
976 self.assertEqual(prepare_calls, ['BNotMeta', 'ANotMeta'])
977 prepare_calls.clear()
978 self.assertEqual(new_calls, ['BNotMeta', 'ANotMeta'])
979 new_calls.clear()
980
981 F = types.new_class("F", (object(), C))
982 self.assertIs(BNotMeta, type(F))
983 self.assertEqual(prepare_calls, ['BNotMeta', 'ANotMeta'])
984 prepare_calls.clear()
985 self.assertEqual(new_calls, ['BNotMeta', 'ANotMeta'])
986 new_calls.clear()
987
988 F2 = types.new_class("F2", (C, object()))
989 self.assertIs(BNotMeta, type(F2))
990 self.assertEqual(prepare_calls, ['BNotMeta', 'ANotMeta'])
991 prepare_calls.clear()
992 self.assertEqual(new_calls, ['BNotMeta', 'ANotMeta'])
993 new_calls.clear()
994
995 # TypeError: BNotMeta is neither a
996 # subclass, nor a superclass of int
997 with self.assertRaises(TypeError):
998 X = types.new_class("X", (C, int()))
999 with self.assertRaises(TypeError):
1000 X = types.new_class("X", (int(), C))
1001
1002
Barry Warsaw409da152012-06-03 16:18:47 -04001003class SimpleNamespaceTests(unittest.TestCase):
1004
1005 def test_constructor(self):
1006 ns1 = types.SimpleNamespace()
1007 ns2 = types.SimpleNamespace(x=1, y=2)
1008 ns3 = types.SimpleNamespace(**dict(x=1, y=2))
1009
1010 with self.assertRaises(TypeError):
1011 types.SimpleNamespace(1, 2, 3)
1012
1013 self.assertEqual(len(ns1.__dict__), 0)
1014 self.assertEqual(vars(ns1), {})
1015 self.assertEqual(len(ns2.__dict__), 2)
1016 self.assertEqual(vars(ns2), {'y': 2, 'x': 1})
1017 self.assertEqual(len(ns3.__dict__), 2)
1018 self.assertEqual(vars(ns3), {'y': 2, 'x': 1})
1019
1020 def test_unbound(self):
1021 ns1 = vars(types.SimpleNamespace())
1022 ns2 = vars(types.SimpleNamespace(x=1, y=2))
1023
1024 self.assertEqual(ns1, {})
1025 self.assertEqual(ns2, {'y': 2, 'x': 1})
1026
1027 def test_underlying_dict(self):
1028 ns1 = types.SimpleNamespace()
1029 ns2 = types.SimpleNamespace(x=1, y=2)
1030 ns3 = types.SimpleNamespace(a=True, b=False)
1031 mapping = ns3.__dict__
1032 del ns3
1033
1034 self.assertEqual(ns1.__dict__, {})
1035 self.assertEqual(ns2.__dict__, {'y': 2, 'x': 1})
1036 self.assertEqual(mapping, dict(a=True, b=False))
1037
1038 def test_attrget(self):
1039 ns = types.SimpleNamespace(x=1, y=2, w=3)
1040
1041 self.assertEqual(ns.x, 1)
1042 self.assertEqual(ns.y, 2)
1043 self.assertEqual(ns.w, 3)
1044 with self.assertRaises(AttributeError):
1045 ns.z
1046
1047 def test_attrset(self):
1048 ns1 = types.SimpleNamespace()
1049 ns2 = types.SimpleNamespace(x=1, y=2, w=3)
1050 ns1.a = 'spam'
1051 ns1.b = 'ham'
1052 ns2.z = 4
1053 ns2.theta = None
1054
1055 self.assertEqual(ns1.__dict__, dict(a='spam', b='ham'))
1056 self.assertEqual(ns2.__dict__, dict(x=1, y=2, w=3, z=4, theta=None))
1057
1058 def test_attrdel(self):
1059 ns1 = types.SimpleNamespace()
1060 ns2 = types.SimpleNamespace(x=1, y=2, w=3)
1061
1062 with self.assertRaises(AttributeError):
1063 del ns1.spam
1064 with self.assertRaises(AttributeError):
1065 del ns2.spam
1066
1067 del ns2.y
1068 self.assertEqual(vars(ns2), dict(w=3, x=1))
1069 ns2.y = 'spam'
1070 self.assertEqual(vars(ns2), dict(w=3, x=1, y='spam'))
1071 del ns2.y
1072 self.assertEqual(vars(ns2), dict(w=3, x=1))
1073
1074 ns1.spam = 5
1075 self.assertEqual(vars(ns1), dict(spam=5))
1076 del ns1.spam
1077 self.assertEqual(vars(ns1), {})
1078
1079 def test_repr(self):
1080 ns1 = types.SimpleNamespace(x=1, y=2, w=3)
1081 ns2 = types.SimpleNamespace()
1082 ns2.x = "spam"
1083 ns2._y = 5
Eric Snowb5c8f922013-02-16 16:32:39 -07001084 name = "namespace"
Barry Warsaw409da152012-06-03 16:18:47 -04001085
Eric Snowb5c8f922013-02-16 16:32:39 -07001086 self.assertEqual(repr(ns1), "{name}(w=3, x=1, y=2)".format(name=name))
1087 self.assertEqual(repr(ns2), "{name}(_y=5, x='spam')".format(name=name))
1088
1089 def test_equal(self):
1090 ns1 = types.SimpleNamespace(x=1)
1091 ns2 = types.SimpleNamespace()
1092 ns2.x = 1
1093
1094 self.assertEqual(types.SimpleNamespace(), types.SimpleNamespace())
1095 self.assertEqual(ns1, ns2)
1096 self.assertNotEqual(ns2, types.SimpleNamespace())
Barry Warsaw409da152012-06-03 16:18:47 -04001097
1098 def test_nested(self):
1099 ns1 = types.SimpleNamespace(a=1, b=2)
1100 ns2 = types.SimpleNamespace()
1101 ns3 = types.SimpleNamespace(x=ns1)
1102 ns2.spam = ns1
1103 ns2.ham = '?'
1104 ns2.spam = ns3
1105
1106 self.assertEqual(vars(ns1), dict(a=1, b=2))
1107 self.assertEqual(vars(ns2), dict(spam=ns3, ham='?'))
1108 self.assertEqual(ns2.spam, ns3)
1109 self.assertEqual(vars(ns3), dict(x=ns1))
1110 self.assertEqual(ns3.x.a, 1)
1111
1112 def test_recursive(self):
1113 ns1 = types.SimpleNamespace(c='cookie')
1114 ns2 = types.SimpleNamespace()
1115 ns3 = types.SimpleNamespace(x=1)
1116 ns1.spam = ns1
1117 ns2.spam = ns3
1118 ns3.spam = ns2
1119
1120 self.assertEqual(ns1.spam, ns1)
1121 self.assertEqual(ns1.spam.spam, ns1)
1122 self.assertEqual(ns1.spam.spam, ns1.spam)
1123 self.assertEqual(ns2.spam, ns3)
1124 self.assertEqual(ns3.spam, ns2)
1125 self.assertEqual(ns2.spam.spam, ns2)
1126
1127 def test_recursive_repr(self):
1128 ns1 = types.SimpleNamespace(c='cookie')
1129 ns2 = types.SimpleNamespace()
1130 ns3 = types.SimpleNamespace(x=1)
1131 ns1.spam = ns1
1132 ns2.spam = ns3
1133 ns3.spam = ns2
Eric Snowb5c8f922013-02-16 16:32:39 -07001134 name = "namespace"
1135 repr1 = "{name}(c='cookie', spam={name}(...))".format(name=name)
1136 repr2 = "{name}(spam={name}(spam={name}(...), x=1))".format(name=name)
Barry Warsaw409da152012-06-03 16:18:47 -04001137
Eric Snowb5c8f922013-02-16 16:32:39 -07001138 self.assertEqual(repr(ns1), repr1)
1139 self.assertEqual(repr(ns2), repr2)
Barry Warsaw409da152012-06-03 16:18:47 -04001140
1141 def test_as_dict(self):
1142 ns = types.SimpleNamespace(spam='spamspamspam')
1143
1144 with self.assertRaises(TypeError):
1145 len(ns)
1146 with self.assertRaises(TypeError):
1147 iter(ns)
1148 with self.assertRaises(TypeError):
1149 'spam' in ns
1150 with self.assertRaises(TypeError):
1151 ns['spam']
1152
Eric Snow547298c2012-10-16 22:35:38 -07001153 def test_subclass(self):
1154 class Spam(types.SimpleNamespace):
1155 pass
1156
1157 spam = Spam(ham=8, eggs=9)
1158
1159 self.assertIs(type(spam), Spam)
1160 self.assertEqual(vars(spam), {'ham': 8, 'eggs': 9})
1161
Eric Snowb5c8f922013-02-16 16:32:39 -07001162 def test_pickle(self):
1163 ns = types.SimpleNamespace(breakfast="spam", lunch="spam")
1164
Eric Snow9d05c8c2013-02-16 18:20:32 -07001165 for protocol in range(pickle.HIGHEST_PROTOCOL + 1):
1166 pname = "protocol {}".format(protocol)
1167 try:
1168 ns_pickled = pickle.dumps(ns, protocol)
1169 except TypeError as e:
1170 raise TypeError(pname) from e
1171 ns_roundtrip = pickle.loads(ns_pickled)
Eric Snowb5c8f922013-02-16 16:32:39 -07001172
Eric Snow9d05c8c2013-02-16 18:20:32 -07001173 self.assertEqual(ns, ns_roundtrip, pname)
Eric Snowb5c8f922013-02-16 16:32:39 -07001174
Serhiy Storchaka08d230a2015-05-22 11:02:49 +03001175 def test_fake_namespace_compare(self):
1176 # Issue #24257: Incorrect use of PyObject_IsInstance() caused
1177 # SystemError.
1178 class FakeSimpleNamespace(str):
1179 __class__ = types.SimpleNamespace
1180 self.assertFalse(types.SimpleNamespace() == FakeSimpleNamespace())
1181 self.assertTrue(types.SimpleNamespace() != FakeSimpleNamespace())
1182 with self.assertRaises(TypeError):
1183 types.SimpleNamespace() < FakeSimpleNamespace()
1184 with self.assertRaises(TypeError):
1185 types.SimpleNamespace() <= FakeSimpleNamespace()
1186 with self.assertRaises(TypeError):
1187 types.SimpleNamespace() > FakeSimpleNamespace()
1188 with self.assertRaises(TypeError):
1189 types.SimpleNamespace() >= FakeSimpleNamespace()
1190
Barry Warsaw409da152012-06-03 16:18:47 -04001191
Yury Selivanov75445082015-05-11 22:57:16 -04001192class CoroutineTests(unittest.TestCase):
1193 def test_wrong_args(self):
1194 class Foo:
1195 def __call__(self):
1196 pass
1197 def bar(): pass
1198
Yury Selivanovc565cd52015-05-29 09:06:05 -04001199 samples = [None, 1, object()]
Yury Selivanov75445082015-05-11 22:57:16 -04001200 for sample in samples:
Yury Selivanovc565cd52015-05-29 09:06:05 -04001201 with self.assertRaisesRegex(TypeError,
1202 'types.coroutine.*expects a callable'):
Yury Selivanov75445082015-05-11 22:57:16 -04001203 types.coroutine(sample)
1204
Yury Selivanovc565cd52015-05-29 09:06:05 -04001205 def test_wrong_func(self):
1206 @types.coroutine
1207 def foo():
1208 pass
Yury Selivanov13f77232015-05-29 16:19:18 -04001209 with self.assertRaisesRegex(TypeError,
1210 'callable wrapped .* non-coroutine'):
1211 foo()
Yury Selivanovc565cd52015-05-29 09:06:05 -04001212
1213 def test_duck_coro(self):
1214 class CoroLike:
1215 def send(self): pass
1216 def throw(self): pass
1217 def close(self): pass
Yury Selivanov13f77232015-05-29 16:19:18 -04001218 def __await__(self): return self
Yury Selivanovc565cd52015-05-29 09:06:05 -04001219
1220 coro = CoroLike()
1221 @types.coroutine
1222 def foo():
1223 return coro
Yury Selivanov13f77232015-05-29 16:19:18 -04001224 self.assertIs(foo().__await__(), coro)
1225
1226 def test_duck_gen(self):
1227 class GenLike:
1228 def send(self): pass
1229 def throw(self): pass
1230 def close(self): pass
1231 def __iter__(self): return self
1232 def __next__(self): pass
1233
1234 gen = GenLike()
1235 @types.coroutine
1236 def foo():
1237 return gen
1238 self.assertIs(foo().__await__(), gen)
1239
1240 with self.assertRaises(AttributeError):
1241 foo().gi_code
1242
1243 def test_gen(self):
1244 def gen(): yield
1245 gen = gen()
1246 @types.coroutine
1247 def foo(): return gen
1248 self.assertIs(foo().__await__(), gen)
1249
1250 for name in ('__name__', '__qualname__', 'gi_code',
1251 'gi_running', 'gi_frame'):
1252 self.assertIs(getattr(foo(), name),
1253 getattr(gen, name))
Yury Selivanovc565cd52015-05-29 09:06:05 -04001254
Yury Selivanov75445082015-05-11 22:57:16 -04001255 def test_genfunc(self):
1256 def gen():
1257 yield
1258
1259 self.assertFalse(isinstance(gen(), collections.abc.Coroutine))
1260 self.assertFalse(isinstance(gen(), collections.abc.Awaitable))
1261
1262 self.assertIs(types.coroutine(gen), gen)
1263
1264 self.assertTrue(gen.__code__.co_flags & inspect.CO_ITERABLE_COROUTINE)
1265 self.assertFalse(gen.__code__.co_flags & inspect.CO_COROUTINE)
1266
1267 g = gen()
1268 self.assertTrue(g.gi_code.co_flags & inspect.CO_ITERABLE_COROUTINE)
1269 self.assertFalse(g.gi_code.co_flags & inspect.CO_COROUTINE)
1270 self.assertTrue(isinstance(g, collections.abc.Coroutine))
1271 self.assertTrue(isinstance(g, collections.abc.Awaitable))
1272 g.close() # silence warning
1273
1274
Thomas Wouters89f507f2006-12-13 04:49:30 +00001275if __name__ == '__main__':
Zachary Ware38c707e2015-04-13 15:00:43 -05001276 unittest.main()