Add better error reporting for MemoryErrors caused by str->float conversions.
[python.git] / Lib / test / test_compile.py
blob28b73325d8dd320d71a1d3b850e33167ab86779d
1 import unittest
2 import sys
3 import _ast
4 from test import test_support
6 class TestSpecifics(unittest.TestCase):
8 def test_no_ending_newline(self):
9 compile("hi", "<test>", "exec")
10 compile("hi\r", "<test>", "exec")
12 def test_empty(self):
13 compile("", "<test>", "exec")
15 def test_other_newlines(self):
16 compile("\r\n", "<test>", "exec")
17 compile("\r", "<test>", "exec")
18 compile("hi\r\nstuff\r\ndef f():\n pass\r", "<test>", "exec")
19 compile("this_is\rreally_old_mac\rdef f():\n pass", "<test>", "exec")
21 def test_debug_assignment(self):
22 # catch assignments to __debug__
23 self.assertRaises(SyntaxError, compile, '__debug__ = 1', '?', 'single')
24 import __builtin__
25 prev = __builtin__.__debug__
26 setattr(__builtin__, '__debug__', 'sure')
27 setattr(__builtin__, '__debug__', prev)
29 def test_argument_handling(self):
30 # detect duplicate positional and keyword arguments
31 self.assertRaises(SyntaxError, eval, 'lambda a,a:0')
32 self.assertRaises(SyntaxError, eval, 'lambda a,a=1:0')
33 self.assertRaises(SyntaxError, eval, 'lambda a=1,a=1:0')
34 try:
35 exec 'def f(a, a): pass'
36 self.fail("duplicate arguments")
37 except SyntaxError:
38 pass
39 try:
40 exec 'def f(a = 0, a = 1): pass'
41 self.fail("duplicate keyword arguments")
42 except SyntaxError:
43 pass
44 try:
45 exec 'def f(a): global a; a = 1'
46 self.fail("variable is global and local")
47 except SyntaxError:
48 pass
50 def test_syntax_error(self):
51 self.assertRaises(SyntaxError, compile, "1+*3", "filename", "exec")
53 def test_none_keyword_arg(self):
54 self.assertRaises(SyntaxError, compile, "f(None=1)", "<string>", "exec")
56 def test_duplicate_global_local(self):
57 try:
58 exec 'def f(a): global a; a = 1'
59 self.fail("variable is global and local")
60 except SyntaxError:
61 pass
63 def test_exec_with_general_mapping_for_locals(self):
65 class M:
66 "Test mapping interface versus possible calls from eval()."
67 def __getitem__(self, key):
68 if key == 'a':
69 return 12
70 raise KeyError
71 def __setitem__(self, key, value):
72 self.results = (key, value)
73 def keys(self):
74 return list('xyz')
76 m = M()
77 g = globals()
78 exec 'z = a' in g, m
79 self.assertEqual(m.results, ('z', 12))
80 try:
81 exec 'z = b' in g, m
82 except NameError:
83 pass
84 else:
85 self.fail('Did not detect a KeyError')
86 exec 'z = dir()' in g, m
87 self.assertEqual(m.results, ('z', list('xyz')))
88 exec 'z = globals()' in g, m
89 self.assertEqual(m.results, ('z', g))
90 exec 'z = locals()' in g, m
91 self.assertEqual(m.results, ('z', m))
92 try:
93 exec 'z = b' in m
94 except TypeError:
95 pass
96 else:
97 self.fail('Did not validate globals as a real dict')
99 class A:
100 "Non-mapping"
101 pass
102 m = A()
103 try:
104 exec 'z = a' in g, m
105 except TypeError:
106 pass
107 else:
108 self.fail('Did not validate locals as a mapping')
110 # Verify that dict subclasses work as well
111 class D(dict):
112 def __getitem__(self, key):
113 if key == 'a':
114 return 12
115 return dict.__getitem__(self, key)
116 d = D()
117 exec 'z = a' in g, d
118 self.assertEqual(d['z'], 12)
120 def test_extended_arg(self):
121 longexpr = 'x = x or ' + '-x' * 2500
122 code = '''
123 def f(x):
134 # the expressions above have no effect, x == argument
135 while x:
136 x -= 1
137 # EXTENDED_ARG/JUMP_ABSOLUTE here
138 return x
139 ''' % ((longexpr,)*10)
140 exec code
141 self.assertEqual(f(5), 0)
143 def test_complex_args(self):
145 def comp_args((a, b)):
146 return a,b
147 self.assertEqual(comp_args((1, 2)), (1, 2))
149 def comp_args((a, b)=(3, 4)):
150 return a, b
151 self.assertEqual(comp_args((1, 2)), (1, 2))
152 self.assertEqual(comp_args(), (3, 4))
154 def comp_args(a, (b, c)):
155 return a, b, c
156 self.assertEqual(comp_args(1, (2, 3)), (1, 2, 3))
158 def comp_args(a=2, (b, c)=(3, 4)):
159 return a, b, c
160 self.assertEqual(comp_args(1, (2, 3)), (1, 2, 3))
161 self.assertEqual(comp_args(), (2, 3, 4))
163 def test_argument_order(self):
164 try:
165 exec 'def f(a=1, (b, c)): pass'
166 self.fail("non-default args after default")
167 except SyntaxError:
168 pass
170 def test_float_literals(self):
171 # testing bad float literals
172 self.assertRaises(SyntaxError, eval, "2e")
173 self.assertRaises(SyntaxError, eval, "2.0e+")
174 self.assertRaises(SyntaxError, eval, "1e-")
175 self.assertRaises(SyntaxError, eval, "3-4e/21")
177 def test_indentation(self):
178 # testing compile() of indented block w/o trailing newline"
179 s = """
180 if 1:
181 if 2:
182 pass"""
183 compile(s, "<string>", "exec")
185 # This test is probably specific to CPython and may not generalize
186 # to other implementations. We are trying to ensure that when
187 # the first line of code starts after 256, correct line numbers
188 # in tracebacks are still produced.
189 def test_leading_newlines(self):
190 s256 = "".join(["\n"] * 256 + ["spam"])
191 co = compile(s256, 'fn', 'exec')
192 self.assertEqual(co.co_firstlineno, 257)
193 self.assertEqual(co.co_lnotab, '')
195 def test_literals_with_leading_zeroes(self):
196 for arg in ["077787", "0xj", "0x.", "0e", "090000000000000",
197 "080000000000000", "000000000000009", "000000000000008",
198 "0b42", "0BADCAFE", "0o123456789", "0b1.1", "0o4.2",
199 "0b101j2", "0o153j2", "0b100e1", "0o777e1", "0o8", "0o78"]:
200 self.assertRaises(SyntaxError, eval, arg)
202 self.assertEqual(eval("0777"), 511)
203 self.assertEqual(eval("0777L"), 511)
204 self.assertEqual(eval("000777"), 511)
205 self.assertEqual(eval("0xff"), 255)
206 self.assertEqual(eval("0xffL"), 255)
207 self.assertEqual(eval("0XfF"), 255)
208 self.assertEqual(eval("0777."), 777)
209 self.assertEqual(eval("0777.0"), 777)
210 self.assertEqual(eval("000000000000000000000000000000000000000000000000000777e0"), 777)
211 self.assertEqual(eval("0777e1"), 7770)
212 self.assertEqual(eval("0e0"), 0)
213 self.assertEqual(eval("0000E-012"), 0)
214 self.assertEqual(eval("09.5"), 9.5)
215 self.assertEqual(eval("0777j"), 777j)
216 self.assertEqual(eval("00j"), 0j)
217 self.assertEqual(eval("00.0"), 0)
218 self.assertEqual(eval("0e3"), 0)
219 self.assertEqual(eval("090000000000000."), 90000000000000.)
220 self.assertEqual(eval("090000000000000.0000000000000000000000"), 90000000000000.)
221 self.assertEqual(eval("090000000000000e0"), 90000000000000.)
222 self.assertEqual(eval("090000000000000e-0"), 90000000000000.)
223 self.assertEqual(eval("090000000000000j"), 90000000000000j)
224 self.assertEqual(eval("000000000000007"), 7)
225 self.assertEqual(eval("000000000000008."), 8.)
226 self.assertEqual(eval("000000000000009."), 9.)
227 self.assertEqual(eval("0b101010"), 42)
228 self.assertEqual(eval("-0b000000000010"), -2)
229 self.assertEqual(eval("0o777"), 511)
230 self.assertEqual(eval("-0o0000010"), -8)
231 self.assertEqual(eval("020000000000.0"), 20000000000.0)
232 self.assertEqual(eval("037777777777e0"), 37777777777.0)
233 self.assertEqual(eval("01000000000000000000000.0"),
234 1000000000000000000000.0)
236 def test_unary_minus(self):
237 # Verify treatment of unary minus on negative numbers SF bug #660455
238 if sys.maxint == 2147483647:
239 # 32-bit machine
240 all_one_bits = '0xffffffff'
241 self.assertEqual(eval(all_one_bits), 4294967295L)
242 self.assertEqual(eval("-" + all_one_bits), -4294967295L)
243 elif sys.maxint == 9223372036854775807:
244 # 64-bit machine
245 all_one_bits = '0xffffffffffffffff'
246 self.assertEqual(eval(all_one_bits), 18446744073709551615L)
247 self.assertEqual(eval("-" + all_one_bits), -18446744073709551615L)
248 else:
249 self.fail("How many bits *does* this machine have???")
250 # Verify treatment of contant folding on -(sys.maxint+1)
251 # i.e. -2147483648 on 32 bit platforms. Should return int, not long.
252 self.assertTrue(isinstance(eval("%s" % (-sys.maxint - 1)), int))
253 self.assertTrue(isinstance(eval("%s" % (-sys.maxint - 2)), long))
255 if sys.maxint == 9223372036854775807:
256 def test_32_63_bit_values(self):
257 a = +4294967296 # 1 << 32
258 b = -4294967296 # 1 << 32
259 c = +281474976710656 # 1 << 48
260 d = -281474976710656 # 1 << 48
261 e = +4611686018427387904 # 1 << 62
262 f = -4611686018427387904 # 1 << 62
263 g = +9223372036854775807 # 1 << 63 - 1
264 h = -9223372036854775807 # 1 << 63 - 1
266 for variable in self.test_32_63_bit_values.func_code.co_consts:
267 if variable is not None:
268 self.assertTrue(isinstance(variable, int))
270 def test_sequence_unpacking_error(self):
271 # Verify sequence packing/unpacking with "or". SF bug #757818
272 i,j = (1, -1) or (-1, 1)
273 self.assertEqual(i, 1)
274 self.assertEqual(j, -1)
276 def test_none_assignment(self):
277 stmts = [
278 'None = 0',
279 'None += 0',
280 '__builtins__.None = 0',
281 'def None(): pass',
282 'class None: pass',
283 '(a, None) = 0, 0',
284 'for None in range(10): pass',
285 'def f(None): pass',
286 'import None',
287 'import x as None',
288 'from x import None',
289 'from x import y as None'
291 for stmt in stmts:
292 stmt += "\n"
293 self.assertRaises(SyntaxError, compile, stmt, 'tmp', 'single')
294 self.assertRaises(SyntaxError, compile, stmt, 'tmp', 'exec')
295 # This is ok.
296 compile("from None import x", "tmp", "exec")
297 compile("from x import None as y", "tmp", "exec")
298 compile("import None as x", "tmp", "exec")
300 def test_import(self):
301 succeed = [
302 'import sys',
303 'import os, sys',
304 'import os as bar',
305 'import os.path as bar',
306 'from __future__ import nested_scopes, generators',
307 'from __future__ import (nested_scopes,\ngenerators)',
308 'from __future__ import (nested_scopes,\ngenerators,)',
309 'from sys import stdin, stderr, stdout',
310 'from sys import (stdin, stderr,\nstdout)',
311 'from sys import (stdin, stderr,\nstdout,)',
312 'from sys import (stdin\n, stderr, stdout)',
313 'from sys import (stdin\n, stderr, stdout,)',
314 'from sys import stdin as si, stdout as so, stderr as se',
315 'from sys import (stdin as si, stdout as so, stderr as se)',
316 'from sys import (stdin as si, stdout as so, stderr as se,)',
318 fail = [
319 'import (os, sys)',
320 'import (os), (sys)',
321 'import ((os), (sys))',
322 'import (sys',
323 'import sys)',
324 'import (os,)',
325 'import os As bar',
326 'import os.path a bar',
327 'from sys import stdin As stdout',
328 'from sys import stdin a stdout',
329 'from (sys) import stdin',
330 'from __future__ import (nested_scopes',
331 'from __future__ import nested_scopes)',
332 'from __future__ import nested_scopes,\ngenerators',
333 'from sys import (stdin',
334 'from sys import stdin)',
335 'from sys import stdin, stdout,\nstderr',
336 'from sys import stdin si',
337 'from sys import stdin,'
338 'from sys import (*)',
339 'from sys import (stdin,, stdout, stderr)',
340 'from sys import (stdin, stdout),',
342 for stmt in succeed:
343 compile(stmt, 'tmp', 'exec')
344 for stmt in fail:
345 self.assertRaises(SyntaxError, compile, stmt, 'tmp', 'exec')
347 def test_for_distinct_code_objects(self):
348 # SF bug 1048870
349 def f():
350 f1 = lambda x=1: x
351 f2 = lambda x=2: x
352 return f1, f2
353 f1, f2 = f()
354 self.assertNotEqual(id(f1.func_code), id(f2.func_code))
356 def test_unicode_encoding(self):
357 code = u"# -*- coding: utf-8 -*-\npass\n"
358 self.assertRaises(SyntaxError, compile, code, "tmp", "exec")
360 def test_subscripts(self):
361 # SF bug 1448804
362 # Class to make testing subscript results easy
363 class str_map(object):
364 def __init__(self):
365 self.data = {}
366 def __getitem__(self, key):
367 return self.data[str(key)]
368 def __setitem__(self, key, value):
369 self.data[str(key)] = value
370 def __delitem__(self, key):
371 del self.data[str(key)]
372 def __contains__(self, key):
373 return str(key) in self.data
374 d = str_map()
375 # Index
376 d[1] = 1
377 self.assertEqual(d[1], 1)
378 d[1] += 1
379 self.assertEqual(d[1], 2)
380 del d[1]
381 self.assertEqual(1 in d, False)
382 # Tuple of indices
383 d[1, 1] = 1
384 self.assertEqual(d[1, 1], 1)
385 d[1, 1] += 1
386 self.assertEqual(d[1, 1], 2)
387 del d[1, 1]
388 self.assertEqual((1, 1) in d, False)
389 # Simple slice
390 d[1:2] = 1
391 self.assertEqual(d[1:2], 1)
392 d[1:2] += 1
393 self.assertEqual(d[1:2], 2)
394 del d[1:2]
395 self.assertEqual(slice(1, 2) in d, False)
396 # Tuple of simple slices
397 d[1:2, 1:2] = 1
398 self.assertEqual(d[1:2, 1:2], 1)
399 d[1:2, 1:2] += 1
400 self.assertEqual(d[1:2, 1:2], 2)
401 del d[1:2, 1:2]
402 self.assertEqual((slice(1, 2), slice(1, 2)) in d, False)
403 # Extended slice
404 d[1:2:3] = 1
405 self.assertEqual(d[1:2:3], 1)
406 d[1:2:3] += 1
407 self.assertEqual(d[1:2:3], 2)
408 del d[1:2:3]
409 self.assertEqual(slice(1, 2, 3) in d, False)
410 # Tuple of extended slices
411 d[1:2:3, 1:2:3] = 1
412 self.assertEqual(d[1:2:3, 1:2:3], 1)
413 d[1:2:3, 1:2:3] += 1
414 self.assertEqual(d[1:2:3, 1:2:3], 2)
415 del d[1:2:3, 1:2:3]
416 self.assertEqual((slice(1, 2, 3), slice(1, 2, 3)) in d, False)
417 # Ellipsis
418 d[...] = 1
419 self.assertEqual(d[...], 1)
420 d[...] += 1
421 self.assertEqual(d[...], 2)
422 del d[...]
423 self.assertEqual(Ellipsis in d, False)
424 # Tuple of Ellipses
425 d[..., ...] = 1
426 self.assertEqual(d[..., ...], 1)
427 d[..., ...] += 1
428 self.assertEqual(d[..., ...], 2)
429 del d[..., ...]
430 self.assertEqual((Ellipsis, Ellipsis) in d, False)
432 def test_mangling(self):
433 class A:
434 def f():
435 __mangled = 1
436 __not_mangled__ = 2
437 import __mangled_mod
438 import __package__.module
440 self.assertTrue("_A__mangled" in A.f.func_code.co_varnames)
441 self.assertTrue("__not_mangled__" in A.f.func_code.co_varnames)
442 self.assertTrue("_A__mangled_mod" in A.f.func_code.co_varnames)
443 self.assertTrue("__package__" in A.f.func_code.co_varnames)
445 def test_compile_ast(self):
446 fname = __file__
447 if fname.lower().endswith(('pyc', 'pyo')):
448 fname = fname[:-1]
449 with open(fname, 'r') as f:
450 fcontents = f.read()
451 sample_code = [
452 ['<assign>', 'x = 5'],
453 ['<print1>', 'print 1'],
454 ['<printv>', 'print v'],
455 ['<printTrue>', 'print True'],
456 ['<printList>', 'print []'],
457 ['<ifblock>', """if True:\n pass\n"""],
458 ['<forblock>', """for n in [1, 2, 3]:\n print n\n"""],
459 ['<deffunc>', """def foo():\n pass\nfoo()\n"""],
460 [fname, fcontents],
463 for fname, code in sample_code:
464 co1 = compile(code, '%s1' % fname, 'exec')
465 ast = compile(code, '%s2' % fname, 'exec', _ast.PyCF_ONLY_AST)
466 self.assertTrue(type(ast) == _ast.Module)
467 co2 = compile(ast, '%s3' % fname, 'exec')
468 self.assertEqual(co1, co2)
469 # the code object's filename comes from the second compilation step
470 self.assertEqual(co2.co_filename, '%s3' % fname)
472 # raise exception when node type doesn't match with compile mode
473 co1 = compile('print 1', '<string>', 'exec', _ast.PyCF_ONLY_AST)
474 self.assertRaises(TypeError, compile, co1, '<ast>', 'eval')
476 # raise exception when node type is no start node
477 self.assertRaises(TypeError, compile, _ast.If(), '<ast>', 'exec')
479 # raise exception when node has invalid children
480 ast = _ast.Module()
481 ast.body = [_ast.BoolOp()]
482 self.assertRaises(TypeError, compile, ast, '<ast>', 'exec')
485 def test_main():
486 test_support.run_unittest(TestSpecifics)
488 if __name__ == "__main__":
489 test_main()