source: python/trunk/Lib/test/test_compile.py

Last change on this file was 391, checked in by dmik, 11 years ago

python: Merge vendor 2.7.6 to trunk.

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