blob: 3f5ac98a0e328fbcbd6c7a2e2199b062e1f3e433 [file] [log] [blame]
Guido van Rossum85f18201992-11-27 22:53:50 +00001# Python test set -- part 6, built-in types
2
Benjamin Petersonee8712c2008-05-20 21:35:26 +00003from test.support import run_unittest, run_with_locale
Victor Stinner0db176f2012-04-16 00:16:30 +02004import collections
Eric Smithb2c7af82008-04-30 02:12:09 +00005import locale
Victor Stinner0db176f2012-04-16 00:16:30 +02006import sys
7import types
8import unittest
Guido van Rossum85f18201992-11-27 22:53:50 +00009
Thomas Wouters89f507f2006-12-13 04:49:30 +000010class TypesTests(unittest.TestCase):
Guido van Rossum85f18201992-11-27 22:53:50 +000011
Thomas Wouters89f507f2006-12-13 04:49:30 +000012 def test_truth_values(self):
13 if None: self.fail('None is true instead of false')
14 if 0: self.fail('0 is true instead of false')
Thomas Wouters89f507f2006-12-13 04:49:30 +000015 if 0.0: self.fail('0.0 is true instead of false')
16 if '': self.fail('\'\' is true instead of false')
17 if not 1: self.fail('1 is false instead of true')
Thomas Wouters89f507f2006-12-13 04:49:30 +000018 if not 1.0: self.fail('1.0 is false instead of true')
19 if not 'x': self.fail('\'x\' is false instead of true')
20 if not {'x': 1}: self.fail('{\'x\': 1} is false instead of true')
21 def f(): pass
22 class C: pass
Thomas Wouters89f507f2006-12-13 04:49:30 +000023 x = C()
24 if not f: self.fail('f is false instead of true')
25 if not C: self.fail('C is false instead of true')
26 if not sys: self.fail('sys is false instead of true')
27 if not x: self.fail('x is false instead of true')
Guido van Rossum85f18201992-11-27 22:53:50 +000028
Thomas Wouters89f507f2006-12-13 04:49:30 +000029 def test_boolean_ops(self):
30 if 0 or 0: self.fail('0 or 0 is true instead of false')
31 if 1 and 1: pass
32 else: self.fail('1 and 1 is false instead of true')
33 if not 1: self.fail('not 1 is true instead of false')
Neil Schemenauereff72442002-03-24 01:24:54 +000034
Thomas Wouters89f507f2006-12-13 04:49:30 +000035 def test_comparisons(self):
36 if 0 < 1 <= 1 == 1 >= 1 > 0 != 1: pass
37 else: self.fail('int comparisons failed')
Thomas Wouters89f507f2006-12-13 04:49:30 +000038 if 0.0 < 1.0 <= 1.0 == 1.0 >= 1.0 > 0.0 != 1.0: pass
39 else: self.fail('float comparisons failed')
40 if '' < 'a' <= 'a' == 'a' < 'abc' < 'abd' < 'b': pass
41 else: self.fail('string comparisons failed')
42 if None is None: pass
43 else: self.fail('identity test failed')
Neil Schemenauereff72442002-03-24 01:24:54 +000044
Thomas Wouters89f507f2006-12-13 04:49:30 +000045 def test_float_constructor(self):
46 self.assertRaises(ValueError, float, '')
47 self.assertRaises(ValueError, float, '5\0')
Neil Schemenauereff72442002-03-24 01:24:54 +000048
Thomas Wouters89f507f2006-12-13 04:49:30 +000049 def test_zero_division(self):
50 try: 5.0 / 0.0
51 except ZeroDivisionError: pass
52 else: self.fail("5.0 / 0.0 didn't raise ZeroDivisionError")
Neil Schemenauereff72442002-03-24 01:24:54 +000053
Thomas Wouters89f507f2006-12-13 04:49:30 +000054 try: 5.0 // 0.0
55 except ZeroDivisionError: pass
56 else: self.fail("5.0 // 0.0 didn't raise ZeroDivisionError")
Neil Schemenauereff72442002-03-24 01:24:54 +000057
Thomas Wouters89f507f2006-12-13 04:49:30 +000058 try: 5.0 % 0.0
59 except ZeroDivisionError: pass
60 else: self.fail("5.0 % 0.0 didn't raise ZeroDivisionError")
Neil Schemenauereff72442002-03-24 01:24:54 +000061
Guido van Rossume2a383d2007-01-15 16:59:06 +000062 try: 5 / 0
Thomas Wouters89f507f2006-12-13 04:49:30 +000063 except ZeroDivisionError: pass
Christian Heimes7131fd92008-02-19 14:21:46 +000064 else: self.fail("5 / 0 didn't raise ZeroDivisionError")
Neil Schemenauereff72442002-03-24 01:24:54 +000065
Guido van Rossume2a383d2007-01-15 16:59:06 +000066 try: 5 // 0
Thomas Wouters89f507f2006-12-13 04:49:30 +000067 except ZeroDivisionError: pass
Christian Heimes7131fd92008-02-19 14:21:46 +000068 else: self.fail("5 // 0 didn't raise ZeroDivisionError")
Neil Schemenauereff72442002-03-24 01:24:54 +000069
Guido van Rossume2a383d2007-01-15 16:59:06 +000070 try: 5 % 0
Thomas Wouters89f507f2006-12-13 04:49:30 +000071 except ZeroDivisionError: pass
Christian Heimes7131fd92008-02-19 14:21:46 +000072 else: self.fail("5 % 0 didn't raise ZeroDivisionError")
Tim Petersa3c01ce2001-12-04 23:05:10 +000073
Thomas Wouters89f507f2006-12-13 04:49:30 +000074 def test_numeric_types(self):
Mark Dickinson5c2db372009-12-05 20:28:34 +000075 if 0 != 0.0 or 1 != 1.0 or -1 != -1.0:
76 self.fail('int/float value not equal')
Thomas Wouters89f507f2006-12-13 04:49:30 +000077 # calling built-in types without argument must return 0
78 if int() != 0: self.fail('int() does not return 0')
Thomas Wouters89f507f2006-12-13 04:49:30 +000079 if float() != 0.0: self.fail('float() does not return 0.0')
80 if int(1.9) == 1 == int(1.1) and int(-1.1) == -1 == int(-1.9): pass
81 else: self.fail('int() does not round properly')
Thomas Wouters89f507f2006-12-13 04:49:30 +000082 if float(1) == 1.0 and float(-1) == -1.0 and float(0) == 0.0: pass
83 else: self.fail('float() does not work properly')
Neil Schemenauereff72442002-03-24 01:24:54 +000084
Christian Heimesc3f30c42008-02-22 16:37:40 +000085 def test_float_to_string(self):
86 def test(f, result):
87 self.assertEqual(f.__format__('e'), result)
88 self.assertEqual('%e' % f, result)
89
90 # test all 2 digit exponents, both with __format__ and with
91 # '%' formatting
92 for i in range(-99, 100):
93 test(float('1.5e'+str(i)), '1.500000e{0:+03d}'.format(i))
94
95 # test some 3 digit exponents
96 self.assertEqual(1.5e100.__format__('e'), '1.500000e+100')
97 self.assertEqual('%e' % 1.5e100, '1.500000e+100')
98
99 self.assertEqual(1.5e101.__format__('e'), '1.500000e+101')
100 self.assertEqual('%e' % 1.5e101, '1.500000e+101')
101
102 self.assertEqual(1.5e-100.__format__('e'), '1.500000e-100')
103 self.assertEqual('%e' % 1.5e-100, '1.500000e-100')
104
105 self.assertEqual(1.5e-101.__format__('e'), '1.500000e-101')
106 self.assertEqual('%e' % 1.5e-101, '1.500000e-101')
107
Eric Smith0923d1d2009-04-16 20:16:10 +0000108 self.assertEqual('%g' % 1.0, '1')
109 self.assertEqual('%#g' % 1.0, '1.00000')
110
Thomas Wouters89f507f2006-12-13 04:49:30 +0000111 def test_normal_integers(self):
112 # Ensure the first 256 integers are shared
113 a = 256
114 b = 128*2
115 if a is not b: self.fail('256 is not shared')
116 if 12 + 24 != 36: self.fail('int op')
117 if 12 + (-24) != -12: self.fail('int op')
118 if (-12) + 24 != 12: self.fail('int op')
119 if (-12) + (-24) != -36: self.fail('int op')
120 if not 12 < 24: self.fail('int op')
121 if not -24 < -12: self.fail('int op')
122 # Test for a particular bug in integer multiply
123 xsize, ysize, zsize = 238, 356, 4
124 if not (xsize*ysize*zsize == zsize*xsize*ysize == 338912):
125 self.fail('int mul commutativity')
126 # And another.
Christian Heimesa37d4c62007-12-04 23:02:19 +0000127 m = -sys.maxsize - 1
Thomas Wouters89f507f2006-12-13 04:49:30 +0000128 for divisor in 1, 2, 4, 8, 16, 32:
129 j = m // divisor
130 prod = divisor * j
131 if prod != m:
132 self.fail("%r * %r == %r != %r" % (divisor, j, prod, m))
133 if type(prod) is not int:
134 self.fail("expected type(prod) to be int, not %r" %
135 type(prod))
Mark Dickinson5c2db372009-12-05 20:28:34 +0000136 # Check for unified integral type
Thomas Wouters89f507f2006-12-13 04:49:30 +0000137 for divisor in 1, 2, 4, 8, 16, 32:
138 j = m // divisor - 1
139 prod = divisor * j
Guido van Rossume2a383d2007-01-15 16:59:06 +0000140 if type(prod) is not int:
Mark Dickinson5c2db372009-12-05 20:28:34 +0000141 self.fail("expected type(%r) to be int, not %r" %
Thomas Wouters89f507f2006-12-13 04:49:30 +0000142 (prod, type(prod)))
Mark Dickinson5c2db372009-12-05 20:28:34 +0000143 # Check for unified integral type
Christian Heimesa37d4c62007-12-04 23:02:19 +0000144 m = sys.maxsize
Thomas Wouters89f507f2006-12-13 04:49:30 +0000145 for divisor in 1, 2, 4, 8, 16, 32:
146 j = m // divisor + 1
147 prod = divisor * j
Guido van Rossume2a383d2007-01-15 16:59:06 +0000148 if type(prod) is not int:
Mark Dickinson5c2db372009-12-05 20:28:34 +0000149 self.fail("expected type(%r) to be int, not %r" %
Thomas Wouters89f507f2006-12-13 04:49:30 +0000150 (prod, type(prod)))
Neil Schemenauereff72442002-03-24 01:24:54 +0000151
Christian Heimesa37d4c62007-12-04 23:02:19 +0000152 x = sys.maxsize
Ezio Melottie9615932010-01-24 19:26:24 +0000153 self.assertIsInstance(x + 1, int,
154 "(sys.maxsize + 1) should have returned int")
155 self.assertIsInstance(-x - 1, int,
156 "(-sys.maxsize - 1) should have returned int")
157 self.assertIsInstance(-x - 2, int,
158 "(-sys.maxsize - 2) should have returned int")
Neil Schemenauereff72442002-03-24 01:24:54 +0000159
Thomas Wouters89f507f2006-12-13 04:49:30 +0000160 try: 5 << -5
161 except ValueError: pass
162 else: self.fail('int negative shift <<')
Neil Schemenauereff72442002-03-24 01:24:54 +0000163
Thomas Wouters89f507f2006-12-13 04:49:30 +0000164 try: 5 >> -5
165 except ValueError: pass
166 else: self.fail('int negative shift >>')
Guido van Rossum85f18201992-11-27 22:53:50 +0000167
Thomas Wouters89f507f2006-12-13 04:49:30 +0000168 def test_floats(self):
169 if 12.0 + 24.0 != 36.0: self.fail('float op')
170 if 12.0 + (-24.0) != -12.0: self.fail('float op')
171 if (-12.0) + 24.0 != 12.0: self.fail('float op')
172 if (-12.0) + (-24.0) != -36.0: self.fail('float op')
173 if not 12.0 < 24.0: self.fail('float op')
174 if not -24.0 < -12.0: self.fail('float op')
Guido van Rossum85f18201992-11-27 22:53:50 +0000175
Thomas Wouters89f507f2006-12-13 04:49:30 +0000176 def test_strings(self):
177 if len('') != 0: self.fail('len(\'\')')
178 if len('a') != 1: self.fail('len(\'a\')')
179 if len('abcdef') != 6: self.fail('len(\'abcdef\')')
180 if 'xyz' + 'abcde' != 'xyzabcde': self.fail('string concatenation')
181 if 'xyz'*3 != 'xyzxyzxyz': self.fail('string repetition *3')
182 if 0*'abcde' != '': self.fail('string repetition 0*')
183 if min('abc') != 'a' or max('abc') != 'c': self.fail('min/max string')
184 if 'a' in 'abc' and 'b' in 'abc' and 'c' in 'abc' and 'd' not in 'abc': pass
185 else: self.fail('in/not in string')
186 x = 'x'*103
187 if '%s!'%x != x+'!': self.fail('nasty string formatting bug')
Michael W. Hudson5efaf7e2002-06-11 10:55:12 +0000188
Thomas Wouters89f507f2006-12-13 04:49:30 +0000189 #extended slices for strings
190 a = '0123456789'
191 self.assertEqual(a[::], a)
192 self.assertEqual(a[::2], '02468')
193 self.assertEqual(a[1::2], '13579')
194 self.assertEqual(a[::-1],'9876543210')
195 self.assertEqual(a[::-2], '97531')
196 self.assertEqual(a[3::-2], '31')
197 self.assertEqual(a[-100:100:], a)
198 self.assertEqual(a[100:-100:-1], a[::-1])
Guido van Rossume2a383d2007-01-15 16:59:06 +0000199 self.assertEqual(a[-100:100:2], '02468')
Thomas Wouters89f507f2006-12-13 04:49:30 +0000200
Thomas Wouters89f507f2006-12-13 04:49:30 +0000201 def test_type_function(self):
202 self.assertRaises(TypeError, type, 1, 2)
203 self.assertRaises(TypeError, type, 1, 2, 3, 4)
Guido van Rossum85f18201992-11-27 22:53:50 +0000204
Christian Heimes7131fd92008-02-19 14:21:46 +0000205 def test_int__format__(self):
206 def test(i, format_spec, result):
Mark Dickinson5c2db372009-12-05 20:28:34 +0000207 # just make sure we have the unified type for integers
Christian Heimes7131fd92008-02-19 14:21:46 +0000208 assert type(i) == int
209 assert type(format_spec) == str
210 self.assertEqual(i.__format__(format_spec), result)
211
212 test(123456789, 'd', '123456789')
213 test(123456789, 'd', '123456789')
214
215 test(1, 'c', '\01')
216
217 # sign and aligning are interdependent
218 test(1, "-", '1')
219 test(-1, "-", '-1')
220 test(1, "-3", ' 1')
221 test(-1, "-3", ' -1')
222 test(1, "+3", ' +1')
223 test(-1, "+3", ' -1')
224 test(1, " 3", ' 1')
225 test(-1, " 3", ' -1')
226 test(1, " ", ' 1')
227 test(-1, " ", '-1')
228
229 # hex
230 test(3, "x", "3")
231 test(3, "X", "3")
232 test(1234, "x", "4d2")
233 test(-1234, "x", "-4d2")
234 test(1234, "8x", " 4d2")
235 test(-1234, "8x", " -4d2")
236 test(1234, "x", "4d2")
237 test(-1234, "x", "-4d2")
238 test(-3, "x", "-3")
239 test(-3, "X", "-3")
240 test(int('be', 16), "x", "be")
241 test(int('be', 16), "X", "BE")
242 test(-int('be', 16), "x", "-be")
243 test(-int('be', 16), "X", "-BE")
244
245 # octal
246 test(3, "o", "3")
247 test(-3, "o", "-3")
248 test(65, "o", "101")
249 test(-65, "o", "-101")
250 test(1234, "o", "2322")
251 test(-1234, "o", "-2322")
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
259 # binary
260 test(3, "b", "11")
261 test(-3, "b", "-11")
262 test(1234, "b", "10011010010")
263 test(-1234, "b", "-10011010010")
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
Eric Smithb1ebcc62008-07-15 13:02:41 +0000271 # alternate (#) formatting
272 test(0, "#b", '0b0')
273 test(0, "-#b", '0b0')
274 test(1, "-#b", '0b1')
275 test(-1, "-#b", '-0b1')
276 test(-1, "-#5b", ' -0b1')
277 test(1, "+#5b", ' +0b1')
278 test(100, "+#b", '+0b1100100')
Eric Smithd68af8f2008-07-16 00:15:35 +0000279 test(100, "#012b", '0b0001100100')
280 test(-100, "#012b", '-0b001100100')
Eric Smithb1ebcc62008-07-15 13:02:41 +0000281
282 test(0, "#o", '0o0')
283 test(0, "-#o", '0o0')
284 test(1, "-#o", '0o1')
285 test(-1, "-#o", '-0o1')
286 test(-1, "-#5o", ' -0o1')
287 test(1, "+#5o", ' +0o1')
288 test(100, "+#o", '+0o144')
Eric Smithd68af8f2008-07-16 00:15:35 +0000289 test(100, "#012o", '0o0000000144')
290 test(-100, "#012o", '-0o000000144')
Eric Smithb1ebcc62008-07-15 13:02:41 +0000291
292 test(0, "#x", '0x0')
293 test(0, "-#x", '0x0')
294 test(1, "-#x", '0x1')
295 test(-1, "-#x", '-0x1')
296 test(-1, "-#5x", ' -0x1')
297 test(1, "+#5x", ' +0x1')
298 test(100, "+#x", '+0x64')
Eric Smithd68af8f2008-07-16 00:15:35 +0000299 test(100, "#012x", '0x0000000064')
300 test(-100, "#012x", '-0x000000064')
301 test(123456, "#012x", '0x000001e240')
302 test(-123456, "#012x", '-0x00001e240')
Eric Smithb1ebcc62008-07-15 13:02:41 +0000303
304 test(0, "#X", '0X0')
305 test(0, "-#X", '0X0')
306 test(1, "-#X", '0X1')
307 test(-1, "-#X", '-0X1')
308 test(-1, "-#5X", ' -0X1')
309 test(1, "+#5X", ' +0X1')
310 test(100, "+#X", '+0X64')
Eric Smithd68af8f2008-07-16 00:15:35 +0000311 test(100, "#012X", '0X0000000064')
312 test(-100, "#012X", '-0X000000064')
313 test(123456, "#012X", '0X000001E240')
314 test(-123456, "#012X", '-0X00001E240')
Eric Smithb1ebcc62008-07-15 13:02:41 +0000315
Eric Smitha3b1ac82009-04-03 14:45:06 +0000316 test(123, ',', '123')
317 test(-123, ',', '-123')
318 test(1234, ',', '1,234')
319 test(-1234, ',', '-1,234')
320 test(123456, ',', '123,456')
321 test(-123456, ',', '-123,456')
322 test(1234567, ',', '1,234,567')
323 test(-1234567, ',', '-1,234,567')
324
Eric Smith937491d2009-04-22 17:04:27 +0000325 # issue 5782, commas with no specifier type
326 test(1234, '010,', '00,001,234')
327
Mark Dickinson5c2db372009-12-05 20:28:34 +0000328 # Unified type for integers
329 test(10**100, 'd', '1' + '0' * 100)
330 test(10**100+100, 'd', '1' + '0' * 97 + '100')
331
Christian Heimes7131fd92008-02-19 14:21:46 +0000332 # make sure these are errors
333
334 # precision disallowed
335 self.assertRaises(ValueError, 3 .__format__, "1.3")
336 # sign not allowed with 'c'
337 self.assertRaises(ValueError, 3 .__format__, "+c")
338 # format spec must be string
339 self.assertRaises(TypeError, 3 .__format__, None)
340 self.assertRaises(TypeError, 3 .__format__, 0)
Eric Smitha3b1ac82009-04-03 14:45:06 +0000341 # can't have ',' with 'n'
342 self.assertRaises(ValueError, 3 .__format__, ",n")
Eric Smith0923d1d2009-04-16 20:16:10 +0000343 # can't have ',' with 'c'
344 self.assertRaises(ValueError, 3 .__format__, ",c")
Christian Heimes7131fd92008-02-19 14:21:46 +0000345
346 # ensure that only int and float type specifiers work
347 for format_spec in ([chr(x) for x in range(ord('a'), ord('z')+1)] +
348 [chr(x) for x in range(ord('A'), ord('Z')+1)]):
349 if not format_spec in 'bcdoxXeEfFgGn%':
350 self.assertRaises(ValueError, 0 .__format__, format_spec)
351 self.assertRaises(ValueError, 1 .__format__, format_spec)
352 self.assertRaises(ValueError, (-1) .__format__, format_spec)
353
354 # ensure that float type specifiers work; format converts
355 # the int to a float
Eric Smith5807c412008-05-11 21:00:57 +0000356 for format_spec in 'eEfFgG%':
Christian Heimes7131fd92008-02-19 14:21:46 +0000357 for value in [0, 1, -1, 100, -100, 1234567890, -1234567890]:
358 self.assertEqual(value.__format__(format_spec),
359 float(value).__format__(format_spec))
360
Eric Smithabb28c62010-02-23 00:22:24 +0000361 # Issue 6902
362 test(123456, "0<20", '12345600000000000000')
363 test(123456, "1<20", '12345611111111111111')
364 test(123456, "*<20", '123456**************')
365 test(123456, "0>20", '00000000000000123456')
366 test(123456, "1>20", '11111111111111123456')
367 test(123456, "*>20", '**************123456')
368 test(123456, "0=20", '00000000000000123456')
369 test(123456, "1=20", '11111111111111123456')
370 test(123456, "*=20", '**************123456')
371
Eric Smithb2c7af82008-04-30 02:12:09 +0000372 @run_with_locale('LC_NUMERIC', 'en_US.UTF8')
373 def test_float__format__locale(self):
374 # test locale support for __format__ code 'n'
375
376 for i in range(-10, 10):
377 x = 1234567890.0 * (10.0 ** i)
378 self.assertEqual(locale.format('%g', x, grouping=True), format(x, 'n'))
379 self.assertEqual(locale.format('%.10g', x, grouping=True), format(x, '.10n'))
380
Eric Smith5807c412008-05-11 21:00:57 +0000381 @run_with_locale('LC_NUMERIC', 'en_US.UTF8')
382 def test_int__format__locale(self):
383 # test locale support for __format__ code 'n' for integers
384
385 x = 123456789012345678901234567890
386 for i in range(0, 30):
387 self.assertEqual(locale.format('%d', x, grouping=True), format(x, 'n'))
388
389 # move to the next integer to test
390 x = x // 10
391
Eric Smithb151a452008-06-24 11:21:04 +0000392 rfmt = ">20n"
393 lfmt = "<20n"
394 cfmt = "^20n"
395 for x in (1234, 12345, 123456, 1234567, 12345678, 123456789, 1234567890, 12345678900):
396 self.assertEqual(len(format(0, rfmt)), len(format(x, rfmt)))
397 self.assertEqual(len(format(0, lfmt)), len(format(x, lfmt)))
398 self.assertEqual(len(format(0, cfmt)), len(format(x, cfmt)))
399
Christian Heimes7131fd92008-02-19 14:21:46 +0000400 def test_float__format__(self):
Christian Heimes7131fd92008-02-19 14:21:46 +0000401 def test(f, format_spec, result):
Christian Heimes7131fd92008-02-19 14:21:46 +0000402 self.assertEqual(f.__format__(format_spec), result)
Eric Smith984bb582010-11-25 16:08:06 +0000403 self.assertEqual(format(f, format_spec), result)
Christian Heimes7131fd92008-02-19 14:21:46 +0000404
405 test(0.0, 'f', '0.000000')
406
407 # the default is 'g', except for empty format spec
408 test(0.0, '', '0.0')
409 test(0.01, '', '0.01')
410 test(0.01, 'g', '0.01')
411
Eric Smith2ad79e82008-07-19 00:33:23 +0000412 # test for issue 3411
413 test(1.23, '1', '1.23')
414 test(-1.23, '1', '-1.23')
415 test(1.23, '1g', '1.23')
416 test(-1.23, '1g', '-1.23')
417
Christian Heimes7131fd92008-02-19 14:21:46 +0000418 test( 1.0, ' g', ' 1')
419 test(-1.0, ' g', '-1')
420 test( 1.0, '+g', '+1')
421 test(-1.0, '+g', '-1')
422 test(1.1234e200, 'g', '1.1234e+200')
423 test(1.1234e200, 'G', '1.1234E+200')
424
425
426 test(1.0, 'f', '1.000000')
427
428 test(-1.0, 'f', '-1.000000')
429
430 test( 1.0, ' f', ' 1.000000')
431 test(-1.0, ' f', '-1.000000')
432 test( 1.0, '+f', '+1.000000')
433 test(-1.0, '+f', '-1.000000')
Mark Dickinson33841c32009-05-01 15:37:04 +0000434
435 # Python versions <= 3.0 switched from 'f' to 'g' formatting for
436 # values larger than 1e50. No longer.
437 f = 1.1234e90
438 for fmt in 'f', 'F':
439 # don't do a direct equality check, since on some
440 # platforms only the first few digits of dtoa
441 # will be reliable
442 result = f.__format__(fmt)
443 self.assertEqual(len(result), 98)
444 self.assertEqual(result[-7], '.')
Benjamin Peterson577473f2010-01-19 00:09:57 +0000445 self.assertIn(result[:12], ('112340000000', '112339999999'))
Mark Dickinson33841c32009-05-01 15:37:04 +0000446 f = 1.1234e200
447 for fmt in 'f', 'F':
448 result = f.__format__(fmt)
449 self.assertEqual(len(result), 208)
450 self.assertEqual(result[-7], '.')
Benjamin Peterson577473f2010-01-19 00:09:57 +0000451 self.assertIn(result[:12], ('112340000000', '112339999999'))
Mark Dickinson33841c32009-05-01 15:37:04 +0000452
Christian Heimes7131fd92008-02-19 14:21:46 +0000453
Christian Heimesc3f30c42008-02-22 16:37:40 +0000454 test( 1.0, 'e', '1.000000e+00')
455 test(-1.0, 'e', '-1.000000e+00')
456 test( 1.0, 'E', '1.000000E+00')
457 test(-1.0, 'E', '-1.000000E+00')
458 test(1.1234e20, 'e', '1.123400e+20')
459 test(1.1234e20, 'E', '1.123400E+20')
Christian Heimes7131fd92008-02-19 14:21:46 +0000460
Christian Heimesb186d002008-03-18 15:15:01 +0000461 # No format code means use g, but must have a decimal
462 # and a number after the decimal. This is tricky, because
463 # a totaly empty format specifier means something else.
464 # So, just use a sign flag
465 test(1e200, '+g', '+1e+200')
Eric Smith0923d1d2009-04-16 20:16:10 +0000466 test(1e200, '+', '+1e+200')
467
Christian Heimesb186d002008-03-18 15:15:01 +0000468 test(1.1e200, '+g', '+1.1e+200')
469 test(1.1e200, '+', '+1.1e+200')
470
Eric Smith0923d1d2009-04-16 20:16:10 +0000471 # 0 padding
472 test(1234., '010f', '1234.000000')
473 test(1234., '011f', '1234.000000')
474 test(1234., '012f', '01234.000000')
475 test(-1234., '011f', '-1234.000000')
476 test(-1234., '012f', '-1234.000000')
477 test(-1234., '013f', '-01234.000000')
478 test(-1234.12341234, '013f', '-01234.123412')
479 test(-123456.12341234, '011.2f', '-0123456.12')
480
Eric Smith937491d2009-04-22 17:04:27 +0000481 # issue 5782, commas with no specifier type
482 test(1.2, '010,.2', '0,000,001.2')
483
Eric Smith0923d1d2009-04-16 20:16:10 +0000484 # 0 padding with commas
485 test(1234., '011,f', '1,234.000000')
486 test(1234., '012,f', '1,234.000000')
487 test(1234., '013,f', '01,234.000000')
488 test(-1234., '012,f', '-1,234.000000')
489 test(-1234., '013,f', '-1,234.000000')
490 test(-1234., '014,f', '-01,234.000000')
491 test(-12345., '015,f', '-012,345.000000')
492 test(-123456., '016,f', '-0,123,456.000000')
493 test(-123456., '017,f', '-0,123,456.000000')
494 test(-123456.12341234, '017,f', '-0,123,456.123412')
495 test(-123456.12341234, '013,.2f', '-0,123,456.12')
496
Christian Heimes7131fd92008-02-19 14:21:46 +0000497 # % formatting
498 test(-1.0, '%', '-100.000000%')
499
500 # format spec must be string
501 self.assertRaises(TypeError, 3.0.__format__, None)
502 self.assertRaises(TypeError, 3.0.__format__, 0)
503
504 # other format specifiers shouldn't work on floats,
505 # in particular int specifiers
506 for format_spec in ([chr(x) for x in range(ord('a'), ord('z')+1)] +
507 [chr(x) for x in range(ord('A'), ord('Z')+1)]):
508 if not format_spec in 'eEfFgGn%':
509 self.assertRaises(ValueError, format, 0.0, format_spec)
510 self.assertRaises(ValueError, format, 1.0, format_spec)
511 self.assertRaises(ValueError, format, -1.0, format_spec)
512 self.assertRaises(ValueError, format, 1e100, format_spec)
513 self.assertRaises(ValueError, format, -1e100, format_spec)
514 self.assertRaises(ValueError, format, 1e-100, format_spec)
515 self.assertRaises(ValueError, format, -1e-100, format_spec)
516
Eric Smith984bb582010-11-25 16:08:06 +0000517 # Alternate float formatting
518 test(1.0, '.0e', '1e+00')
519 test(1.0, '#.0e', '1.e+00')
520 test(1.0, '.0f', '1')
521 test(1.0, '#.0f', '1.')
522 test(1.1, 'g', '1.1')
523 test(1.1, '#g', '1.10000')
524 test(1.0, '.0%', '100%')
525 test(1.0, '#.0%', '100.%')
526
527 # Issue 7094: Alternate formatting (specified by #)
528 test(1.0, '0e', '1.000000e+00')
529 test(1.0, '#0e', '1.000000e+00')
530 test(1.0, '0f', '1.000000' )
531 test(1.0, '#0f', '1.000000')
532 test(1.0, '.1e', '1.0e+00')
533 test(1.0, '#.1e', '1.0e+00')
534 test(1.0, '.1f', '1.0')
535 test(1.0, '#.1f', '1.0')
536 test(1.0, '.1%', '100.0%')
537 test(1.0, '#.1%', '100.0%')
Eric Smithb1ebcc62008-07-15 13:02:41 +0000538
Eric Smithabb28c62010-02-23 00:22:24 +0000539 # Issue 6902
540 test(12345.6, "0<20", '12345.60000000000000')
541 test(12345.6, "1<20", '12345.61111111111111')
542 test(12345.6, "*<20", '12345.6*************')
543 test(12345.6, "0>20", '000000000000012345.6')
544 test(12345.6, "1>20", '111111111111112345.6')
545 test(12345.6, "*>20", '*************12345.6')
546 test(12345.6, "0=20", '000000000000012345.6')
547 test(12345.6, "1=20", '111111111111112345.6')
548 test(12345.6, "*=20", '*************12345.6')
549
Eric Smith0923d1d2009-04-16 20:16:10 +0000550 def test_format_spec_errors(self):
551 # int, float, and string all share the same format spec
552 # mini-language parser.
553
554 # Check that we can't ask for too many digits. This is
555 # probably a CPython specific test. It tries to put the width
556 # into a C long.
557 self.assertRaises(ValueError, format, 0, '1'*10000 + 'd')
558
559 # Similar with the precision.
560 self.assertRaises(ValueError, format, 0, '.' + '1'*10000 + 'd')
561
562 # And may as well test both.
563 self.assertRaises(ValueError, format, 0, '1'*1000 + '.' + '1'*10000 + 'd')
564
565 # Make sure commas aren't allowed with various type codes
566 for code in 'xXobns':
567 self.assertRaises(ValueError, format, 0, ',' + code)
Christian Heimes7131fd92008-02-19 14:21:46 +0000568
Benjamin Peterson0e102062010-08-25 23:13:17 +0000569 def test_internal_sizes(self):
570 self.assertGreater(object.__basicsize__, 0)
571 self.assertGreater(tuple.__itemsize__, 0)
572
573
Victor Stinner0db176f2012-04-16 00:16:30 +0200574class MappingProxyTests(unittest.TestCase):
575 mappingproxy = types.MappingProxyType
576
577 def test_constructor(self):
578 class userdict(dict):
579 pass
580
581 mapping = {'x': 1, 'y': 2}
582 self.assertEqual(self.mappingproxy(mapping), mapping)
583 mapping = userdict(x=1, y=2)
584 self.assertEqual(self.mappingproxy(mapping), mapping)
585 mapping = collections.ChainMap({'x': 1}, {'y': 2})
586 self.assertEqual(self.mappingproxy(mapping), mapping)
587
588 self.assertRaises(TypeError, self.mappingproxy, 10)
589 self.assertRaises(TypeError, self.mappingproxy, ("a", "tuple"))
590 self.assertRaises(TypeError, self.mappingproxy, ["a", "list"])
591
592 def test_methods(self):
593 attrs = set(dir(self.mappingproxy({}))) - set(dir(object()))
594 self.assertEqual(attrs, {
595 '__contains__',
596 '__getitem__',
597 '__iter__',
598 '__len__',
599 'copy',
600 'get',
601 'items',
602 'keys',
603 'values',
604 })
605
606 def test_get(self):
607 view = self.mappingproxy({'a': 'A', 'b': 'B'})
608 self.assertEqual(view['a'], 'A')
609 self.assertEqual(view['b'], 'B')
610 self.assertRaises(KeyError, view.__getitem__, 'xxx')
611 self.assertEqual(view.get('a'), 'A')
612 self.assertIsNone(view.get('xxx'))
613 self.assertEqual(view.get('xxx', 42), 42)
614
615 def test_missing(self):
616 class dictmissing(dict):
617 def __missing__(self, key):
618 return "missing=%s" % key
619
620 view = self.mappingproxy(dictmissing(x=1))
621 self.assertEqual(view['x'], 1)
622 self.assertEqual(view['y'], 'missing=y')
623 self.assertEqual(view.get('x'), 1)
624 self.assertEqual(view.get('y'), None)
625 self.assertEqual(view.get('y', 42), 42)
626 self.assertTrue('x' in view)
627 self.assertFalse('y' in view)
628
629 def test_customdict(self):
630 class customdict(dict):
631 def __contains__(self, key):
632 if key == 'magic':
633 return True
634 else:
635 return dict.__contains__(self, key)
636
637 def __iter__(self):
638 return iter(('iter',))
639
640 def __len__(self):
641 return 500
642
643 def copy(self):
644 return 'copy'
645
646 def keys(self):
647 return 'keys'
648
649 def items(self):
650 return 'items'
651
652 def values(self):
653 return 'values'
654
655 def __getitem__(self, key):
656 return "getitem=%s" % dict.__getitem__(self, key)
657
658 def get(self, key, default=None):
659 return "get=%s" % dict.get(self, key, 'default=%r' % default)
660
661 custom = customdict({'key': 'value'})
662 view = self.mappingproxy(custom)
663 self.assertTrue('key' in view)
664 self.assertTrue('magic' in view)
665 self.assertFalse('xxx' in view)
666 self.assertEqual(view['key'], 'getitem=value')
667 self.assertRaises(KeyError, view.__getitem__, 'xxx')
668 self.assertEqual(tuple(view), ('iter',))
669 self.assertEqual(len(view), 500)
670 self.assertEqual(view.copy(), 'copy')
671 self.assertEqual(view.get('key'), 'get=value')
672 self.assertEqual(view.get('xxx'), 'get=default=None')
673 self.assertEqual(view.items(), 'items')
674 self.assertEqual(view.keys(), 'keys')
675 self.assertEqual(view.values(), 'values')
676
677 def test_chainmap(self):
678 d1 = {'x': 1}
679 d2 = {'y': 2}
680 mapping = collections.ChainMap(d1, d2)
681 view = self.mappingproxy(mapping)
682 self.assertTrue('x' in view)
683 self.assertTrue('y' in view)
684 self.assertFalse('z' in view)
685 self.assertEqual(view['x'], 1)
686 self.assertEqual(view['y'], 2)
687 self.assertRaises(KeyError, view.__getitem__, 'z')
688 self.assertEqual(tuple(sorted(view)), ('x', 'y'))
689 self.assertEqual(len(view), 2)
690 copy = view.copy()
691 self.assertIsNot(copy, mapping)
692 self.assertIsInstance(copy, collections.ChainMap)
693 self.assertEqual(copy, mapping)
694 self.assertEqual(view.get('x'), 1)
695 self.assertEqual(view.get('y'), 2)
696 self.assertIsNone(view.get('z'))
697 self.assertEqual(tuple(sorted(view.items())), (('x', 1), ('y', 2)))
698 self.assertEqual(tuple(sorted(view.keys())), ('x', 'y'))
699 self.assertEqual(tuple(sorted(view.values())), (1, 2))
700
701 def test_contains(self):
702 view = self.mappingproxy(dict.fromkeys('abc'))
703 self.assertTrue('a' in view)
704 self.assertTrue('b' in view)
705 self.assertTrue('c' in view)
706 self.assertFalse('xxx' in view)
707
708 def test_views(self):
709 mapping = {}
710 view = self.mappingproxy(mapping)
711 keys = view.keys()
712 values = view.values()
713 items = view.items()
714 self.assertEqual(list(keys), [])
715 self.assertEqual(list(values), [])
716 self.assertEqual(list(items), [])
717 mapping['key'] = 'value'
718 self.assertEqual(list(keys), ['key'])
719 self.assertEqual(list(values), ['value'])
720 self.assertEqual(list(items), [('key', 'value')])
721
722 def test_len(self):
723 for expected in range(6):
724 data = dict.fromkeys('abcde'[:expected])
725 self.assertEqual(len(data), expected)
726 view = self.mappingproxy(data)
727 self.assertEqual(len(view), expected)
728
729 def test_iterators(self):
730 keys = ('x', 'y')
731 values = (1, 2)
732 items = tuple(zip(keys, values))
733 view = self.mappingproxy(dict(items))
734 self.assertEqual(set(view), set(keys))
735 self.assertEqual(set(view.keys()), set(keys))
736 self.assertEqual(set(view.values()), set(values))
737 self.assertEqual(set(view.items()), set(items))
738
739 def test_copy(self):
740 original = {'key1': 27, 'key2': 51, 'key3': 93}
741 view = self.mappingproxy(original)
742 copy = view.copy()
743 self.assertEqual(type(copy), dict)
744 self.assertEqual(copy, original)
745 original['key1'] = 70
746 self.assertEqual(view['key1'], 70)
747 self.assertEqual(copy['key1'], 27)
748
749
Nick Coghlan7fc570a2012-05-20 02:34:13 +1000750class ClassCreationTests(unittest.TestCase):
751
752 class Meta(type):
753 def __init__(cls, name, bases, ns, **kw):
754 super().__init__(name, bases, ns)
755 @staticmethod
756 def __new__(mcls, name, bases, ns, **kw):
757 return super().__new__(mcls, name, bases, ns)
758 @classmethod
759 def __prepare__(mcls, name, bases, **kw):
760 ns = super().__prepare__(name, bases)
761 ns["y"] = 1
762 ns.update(kw)
763 return ns
764
765 def test_new_class_basics(self):
766 C = types.new_class("C")
767 self.assertEqual(C.__name__, "C")
768 self.assertEqual(C.__bases__, (object,))
769
770 def test_new_class_subclass(self):
771 C = types.new_class("C", (int,))
772 self.assertTrue(issubclass(C, int))
773
774 def test_new_class_meta(self):
775 Meta = self.Meta
776 settings = {"metaclass": Meta, "z": 2}
777 # We do this twice to make sure the passed in dict isn't mutated
778 for i in range(2):
779 C = types.new_class("C" + str(i), (), settings)
780 self.assertIsInstance(C, Meta)
781 self.assertEqual(C.y, 1)
782 self.assertEqual(C.z, 2)
783
784 def test_new_class_exec_body(self):
785 Meta = self.Meta
786 def func(ns):
787 ns["x"] = 0
788 C = types.new_class("C", (), {"metaclass": Meta, "z": 2}, func)
789 self.assertIsInstance(C, Meta)
790 self.assertEqual(C.x, 0)
791 self.assertEqual(C.y, 1)
792 self.assertEqual(C.z, 2)
793
Benjamin Peterson43f8f4c2012-09-27 18:10:17 -0400794 def test_new_class_metaclass_keywords(self):
Nick Coghlan7fc570a2012-05-20 02:34:13 +1000795 #Test that keywords are passed to the metaclass:
796 def meta_func(name, bases, ns, **kw):
797 return name, bases, ns, kw
798 res = types.new_class("X",
799 (int, object),
800 dict(metaclass=meta_func, x=0))
801 self.assertEqual(res, ("X", (int, object), {}, {"x": 0}))
802
803 def test_new_class_defaults(self):
804 # Test defaults/keywords:
805 C = types.new_class("C", (), {}, None)
806 self.assertEqual(C.__name__, "C")
807 self.assertEqual(C.__bases__, (object,))
808
809 def test_new_class_meta_with_base(self):
810 Meta = self.Meta
811 def func(ns):
812 ns["x"] = 0
813 C = types.new_class(name="C",
814 bases=(int,),
815 kwds=dict(metaclass=Meta, z=2),
816 exec_body=func)
817 self.assertTrue(issubclass(C, int))
818 self.assertIsInstance(C, Meta)
819 self.assertEqual(C.x, 0)
820 self.assertEqual(C.y, 1)
821 self.assertEqual(C.z, 2)
822
823 # Many of the following tests are derived from test_descr.py
824 def test_prepare_class(self):
825 # Basic test of metaclass derivation
826 expected_ns = {}
827 class A(type):
828 def __new__(*args, **kwargs):
829 return type.__new__(*args, **kwargs)
830
831 def __prepare__(*args):
832 return expected_ns
833
834 B = types.new_class("B", (object,))
835 C = types.new_class("C", (object,), {"metaclass": A})
836
837 # The most derived metaclass of D is A rather than type.
838 meta, ns, kwds = types.prepare_class("D", (B, C), {"metaclass": type})
839 self.assertIs(meta, A)
840 self.assertIs(ns, expected_ns)
841 self.assertEqual(len(kwds), 0)
842
843 def test_metaclass_derivation(self):
844 # issue1294232: correct metaclass calculation
845 new_calls = [] # to check the order of __new__ calls
846 class AMeta(type):
847 def __new__(mcls, name, bases, ns):
848 new_calls.append('AMeta')
849 return super().__new__(mcls, name, bases, ns)
850 @classmethod
851 def __prepare__(mcls, name, bases):
852 return {}
853
854 class BMeta(AMeta):
855 def __new__(mcls, name, bases, ns):
856 new_calls.append('BMeta')
857 return super().__new__(mcls, name, bases, ns)
858 @classmethod
859 def __prepare__(mcls, name, bases):
860 ns = super().__prepare__(name, bases)
861 ns['BMeta_was_here'] = True
862 return ns
863
864 A = types.new_class("A", (), {"metaclass": AMeta})
865 self.assertEqual(new_calls, ['AMeta'])
866 new_calls.clear()
867
868 B = types.new_class("B", (), {"metaclass": BMeta})
869 # BMeta.__new__ calls AMeta.__new__ with super:
870 self.assertEqual(new_calls, ['BMeta', 'AMeta'])
871 new_calls.clear()
872
873 C = types.new_class("C", (A, B))
874 # The most derived metaclass is BMeta:
875 self.assertEqual(new_calls, ['BMeta', 'AMeta'])
876 new_calls.clear()
877 # BMeta.__prepare__ should've been called:
878 self.assertIn('BMeta_was_here', C.__dict__)
879
880 # The order of the bases shouldn't matter:
881 C2 = types.new_class("C2", (B, A))
882 self.assertEqual(new_calls, ['BMeta', 'AMeta'])
883 new_calls.clear()
884 self.assertIn('BMeta_was_here', C2.__dict__)
885
886 # Check correct metaclass calculation when a metaclass is declared:
887 D = types.new_class("D", (C,), {"metaclass": type})
888 self.assertEqual(new_calls, ['BMeta', 'AMeta'])
889 new_calls.clear()
890 self.assertIn('BMeta_was_here', D.__dict__)
891
892 E = types.new_class("E", (C,), {"metaclass": AMeta})
893 self.assertEqual(new_calls, ['BMeta', 'AMeta'])
894 new_calls.clear()
895 self.assertIn('BMeta_was_here', E.__dict__)
896
897 def test_metaclass_override_function(self):
898 # Special case: the given metaclass isn't a class,
899 # so there is no metaclass calculation.
900 class A(metaclass=self.Meta):
901 pass
902
903 marker = object()
904 def func(*args, **kwargs):
905 return marker
906
907 X = types.new_class("X", (), {"metaclass": func})
908 Y = types.new_class("Y", (object,), {"metaclass": func})
909 Z = types.new_class("Z", (A,), {"metaclass": func})
910 self.assertIs(marker, X)
911 self.assertIs(marker, Y)
912 self.assertIs(marker, Z)
913
914 def test_metaclass_override_callable(self):
915 # The given metaclass is a class,
916 # but not a descendant of type.
917 new_calls = [] # to check the order of __new__ calls
918 prepare_calls = [] # to track __prepare__ calls
919 class ANotMeta:
920 def __new__(mcls, *args, **kwargs):
921 new_calls.append('ANotMeta')
922 return super().__new__(mcls)
923 @classmethod
924 def __prepare__(mcls, name, bases):
925 prepare_calls.append('ANotMeta')
926 return {}
927
928 class BNotMeta(ANotMeta):
929 def __new__(mcls, *args, **kwargs):
930 new_calls.append('BNotMeta')
931 return super().__new__(mcls)
932 @classmethod
933 def __prepare__(mcls, name, bases):
934 prepare_calls.append('BNotMeta')
935 return super().__prepare__(name, bases)
936
937 A = types.new_class("A", (), {"metaclass": ANotMeta})
938 self.assertIs(ANotMeta, type(A))
939 self.assertEqual(prepare_calls, ['ANotMeta'])
940 prepare_calls.clear()
941 self.assertEqual(new_calls, ['ANotMeta'])
942 new_calls.clear()
943
944 B = types.new_class("B", (), {"metaclass": BNotMeta})
945 self.assertIs(BNotMeta, type(B))
946 self.assertEqual(prepare_calls, ['BNotMeta', 'ANotMeta'])
947 prepare_calls.clear()
948 self.assertEqual(new_calls, ['BNotMeta', 'ANotMeta'])
949 new_calls.clear()
950
951 C = types.new_class("C", (A, B))
952 self.assertIs(BNotMeta, type(C))
953 self.assertEqual(prepare_calls, ['BNotMeta', 'ANotMeta'])
954 prepare_calls.clear()
955 self.assertEqual(new_calls, ['BNotMeta', 'ANotMeta'])
956 new_calls.clear()
957
958 C2 = types.new_class("C2", (B, A))
959 self.assertIs(BNotMeta, type(C2))
960 self.assertEqual(prepare_calls, ['BNotMeta', 'ANotMeta'])
961 prepare_calls.clear()
962 self.assertEqual(new_calls, ['BNotMeta', 'ANotMeta'])
963 new_calls.clear()
964
965 # This is a TypeError, because of a metaclass conflict:
966 # BNotMeta is neither a subclass, nor a superclass of type
967 with self.assertRaises(TypeError):
968 D = types.new_class("D", (C,), {"metaclass": type})
969
970 E = types.new_class("E", (C,), {"metaclass": ANotMeta})
971 self.assertIs(BNotMeta, type(E))
972 self.assertEqual(prepare_calls, ['BNotMeta', 'ANotMeta'])
973 prepare_calls.clear()
974 self.assertEqual(new_calls, ['BNotMeta', 'ANotMeta'])
975 new_calls.clear()
976
977 F = types.new_class("F", (object(), C))
978 self.assertIs(BNotMeta, type(F))
979 self.assertEqual(prepare_calls, ['BNotMeta', 'ANotMeta'])
980 prepare_calls.clear()
981 self.assertEqual(new_calls, ['BNotMeta', 'ANotMeta'])
982 new_calls.clear()
983
984 F2 = types.new_class("F2", (C, object()))
985 self.assertIs(BNotMeta, type(F2))
986 self.assertEqual(prepare_calls, ['BNotMeta', 'ANotMeta'])
987 prepare_calls.clear()
988 self.assertEqual(new_calls, ['BNotMeta', 'ANotMeta'])
989 new_calls.clear()
990
991 # TypeError: BNotMeta is neither a
992 # subclass, nor a superclass of int
993 with self.assertRaises(TypeError):
994 X = types.new_class("X", (C, int()))
995 with self.assertRaises(TypeError):
996 X = types.new_class("X", (int(), C))
997
998
Barry Warsaw409da152012-06-03 16:18:47 -0400999class SimpleNamespaceTests(unittest.TestCase):
1000
1001 def test_constructor(self):
1002 ns1 = types.SimpleNamespace()
1003 ns2 = types.SimpleNamespace(x=1, y=2)
1004 ns3 = types.SimpleNamespace(**dict(x=1, y=2))
1005
1006 with self.assertRaises(TypeError):
1007 types.SimpleNamespace(1, 2, 3)
1008
1009 self.assertEqual(len(ns1.__dict__), 0)
1010 self.assertEqual(vars(ns1), {})
1011 self.assertEqual(len(ns2.__dict__), 2)
1012 self.assertEqual(vars(ns2), {'y': 2, 'x': 1})
1013 self.assertEqual(len(ns3.__dict__), 2)
1014 self.assertEqual(vars(ns3), {'y': 2, 'x': 1})
1015
1016 def test_unbound(self):
1017 ns1 = vars(types.SimpleNamespace())
1018 ns2 = vars(types.SimpleNamespace(x=1, y=2))
1019
1020 self.assertEqual(ns1, {})
1021 self.assertEqual(ns2, {'y': 2, 'x': 1})
1022
1023 def test_underlying_dict(self):
1024 ns1 = types.SimpleNamespace()
1025 ns2 = types.SimpleNamespace(x=1, y=2)
1026 ns3 = types.SimpleNamespace(a=True, b=False)
1027 mapping = ns3.__dict__
1028 del ns3
1029
1030 self.assertEqual(ns1.__dict__, {})
1031 self.assertEqual(ns2.__dict__, {'y': 2, 'x': 1})
1032 self.assertEqual(mapping, dict(a=True, b=False))
1033
1034 def test_attrget(self):
1035 ns = types.SimpleNamespace(x=1, y=2, w=3)
1036
1037 self.assertEqual(ns.x, 1)
1038 self.assertEqual(ns.y, 2)
1039 self.assertEqual(ns.w, 3)
1040 with self.assertRaises(AttributeError):
1041 ns.z
1042
1043 def test_attrset(self):
1044 ns1 = types.SimpleNamespace()
1045 ns2 = types.SimpleNamespace(x=1, y=2, w=3)
1046 ns1.a = 'spam'
1047 ns1.b = 'ham'
1048 ns2.z = 4
1049 ns2.theta = None
1050
1051 self.assertEqual(ns1.__dict__, dict(a='spam', b='ham'))
1052 self.assertEqual(ns2.__dict__, dict(x=1, y=2, w=3, z=4, theta=None))
1053
1054 def test_attrdel(self):
1055 ns1 = types.SimpleNamespace()
1056 ns2 = types.SimpleNamespace(x=1, y=2, w=3)
1057
1058 with self.assertRaises(AttributeError):
1059 del ns1.spam
1060 with self.assertRaises(AttributeError):
1061 del ns2.spam
1062
1063 del ns2.y
1064 self.assertEqual(vars(ns2), dict(w=3, x=1))
1065 ns2.y = 'spam'
1066 self.assertEqual(vars(ns2), dict(w=3, x=1, y='spam'))
1067 del ns2.y
1068 self.assertEqual(vars(ns2), dict(w=3, x=1))
1069
1070 ns1.spam = 5
1071 self.assertEqual(vars(ns1), dict(spam=5))
1072 del ns1.spam
1073 self.assertEqual(vars(ns1), {})
1074
1075 def test_repr(self):
1076 ns1 = types.SimpleNamespace(x=1, y=2, w=3)
1077 ns2 = types.SimpleNamespace()
1078 ns2.x = "spam"
1079 ns2._y = 5
1080
1081 self.assertEqual(repr(ns1), "namespace(w=3, x=1, y=2)")
1082 self.assertEqual(repr(ns2), "namespace(_y=5, x='spam')")
1083
1084 def test_nested(self):
1085 ns1 = types.SimpleNamespace(a=1, b=2)
1086 ns2 = types.SimpleNamespace()
1087 ns3 = types.SimpleNamespace(x=ns1)
1088 ns2.spam = ns1
1089 ns2.ham = '?'
1090 ns2.spam = ns3
1091
1092 self.assertEqual(vars(ns1), dict(a=1, b=2))
1093 self.assertEqual(vars(ns2), dict(spam=ns3, ham='?'))
1094 self.assertEqual(ns2.spam, ns3)
1095 self.assertEqual(vars(ns3), dict(x=ns1))
1096 self.assertEqual(ns3.x.a, 1)
1097
1098 def test_recursive(self):
1099 ns1 = types.SimpleNamespace(c='cookie')
1100 ns2 = types.SimpleNamespace()
1101 ns3 = types.SimpleNamespace(x=1)
1102 ns1.spam = ns1
1103 ns2.spam = ns3
1104 ns3.spam = ns2
1105
1106 self.assertEqual(ns1.spam, ns1)
1107 self.assertEqual(ns1.spam.spam, ns1)
1108 self.assertEqual(ns1.spam.spam, ns1.spam)
1109 self.assertEqual(ns2.spam, ns3)
1110 self.assertEqual(ns3.spam, ns2)
1111 self.assertEqual(ns2.spam.spam, ns2)
1112
1113 def test_recursive_repr(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(repr(ns1),
1122 "namespace(c='cookie', spam=namespace(...))")
1123 self.assertEqual(repr(ns2),
1124 "namespace(spam=namespace(spam=namespace(...), x=1))")
1125
1126 def test_as_dict(self):
1127 ns = types.SimpleNamespace(spam='spamspamspam')
1128
1129 with self.assertRaises(TypeError):
1130 len(ns)
1131 with self.assertRaises(TypeError):
1132 iter(ns)
1133 with self.assertRaises(TypeError):
1134 'spam' in ns
1135 with self.assertRaises(TypeError):
1136 ns['spam']
1137
1138
Thomas Wouters89f507f2006-12-13 04:49:30 +00001139def test_main():
Barry Warsaw409da152012-06-03 16:18:47 -04001140 run_unittest(TypesTests, MappingProxyTests, ClassCreationTests,
1141 SimpleNamespaceTests)
Neil Schemenauereff72442002-03-24 01:24:54 +00001142
Thomas Wouters89f507f2006-12-13 04:49:30 +00001143if __name__ == '__main__':
1144 test_main()