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