blob: 6ffd64ab576715c4c2083efcff19c31ddc188f58 [file] [log] [blame]
Raymond Hettinger8a99b502003-06-23 13:36:57 +00001import unittest
Raymond Hettinger8a99b502003-06-23 13:36:57 +00002import sys
Georg Brandlfc8eef32008-03-28 12:11:56 +00003import _ast
Raymond Hettinger8a99b502003-06-23 13:36:57 +00004from test import test_support
Peter Schneider-Kampfdee0f02000-07-25 22:15:45 +00005
Raymond Hettinger8a99b502003-06-23 13:36:57 +00006class TestSpecifics(unittest.TestCase):
Jeremy Hylton778e2652001-11-09 19:50:08 +00007
Raymond Hettinger8a99b502003-06-23 13:36:57 +00008 def test_debug_assignment(self):
9 # catch assignments to __debug__
10 self.assertRaises(SyntaxError, compile, '__debug__ = 1', '?', 'single')
11 import __builtin__
12 prev = __builtin__.__debug__
13 setattr(__builtin__, '__debug__', 'sure')
14 setattr(__builtin__, '__debug__', prev)
Jeremy Hylton778e2652001-11-09 19:50:08 +000015
Raymond Hettinger8a99b502003-06-23 13:36:57 +000016 def test_argument_handling(self):
17 # detect duplicate positional and keyword arguments
18 self.assertRaises(SyntaxError, eval, 'lambda a,a:0')
19 self.assertRaises(SyntaxError, eval, 'lambda a,a=1:0')
20 self.assertRaises(SyntaxError, eval, 'lambda a=1,a=1:0')
21 try:
22 exec 'def f(a, a): pass'
23 self.fail("duplicate arguments")
24 except SyntaxError:
25 pass
26 try:
27 exec 'def f(a = 0, a = 1): pass'
28 self.fail("duplicate keyword arguments")
29 except SyntaxError:
30 pass
31 try:
32 exec 'def f(a): global a; a = 1'
33 self.fail("variable is global and local")
34 except SyntaxError:
35 pass
Jeremy Hylton778e2652001-11-09 19:50:08 +000036
Raymond Hettinger8a99b502003-06-23 13:36:57 +000037 def test_syntax_error(self):
38 self.assertRaises(SyntaxError, compile, "1+*3", "filename", "exec")
Peter Schneider-Kampfdee0f02000-07-25 22:15:45 +000039
Georg Brandle06cf452007-06-07 13:23:24 +000040 def test_none_keyword_arg(self):
41 self.assertRaises(SyntaxError, compile, "f(None=1)", "<string>", "exec")
42
Raymond Hettinger8a99b502003-06-23 13:36:57 +000043 def test_duplicate_global_local(self):
44 try:
45 exec 'def f(a): global a; a = 1'
46 self.fail("variable is global and local")
47 except SyntaxError:
48 pass
Peter Schneider-Kampfdee0f02000-07-25 22:15:45 +000049
Raymond Hettinger66bd2332004-08-02 08:30:07 +000050 def test_exec_with_general_mapping_for_locals(self):
51
52 class M:
53 "Test mapping interface versus possible calls from eval()."
54 def __getitem__(self, key):
55 if key == 'a':
56 return 12
57 raise KeyError
58 def __setitem__(self, key, value):
59 self.results = (key, value)
60 def keys(self):
61 return list('xyz')
62
63 m = M()
64 g = globals()
65 exec 'z = a' in g, m
66 self.assertEqual(m.results, ('z', 12))
67 try:
68 exec 'z = b' in g, m
69 except NameError:
70 pass
71 else:
72 self.fail('Did not detect a KeyError')
73 exec 'z = dir()' in g, m
74 self.assertEqual(m.results, ('z', list('xyz')))
75 exec 'z = globals()' in g, m
76 self.assertEqual(m.results, ('z', g))
77 exec 'z = locals()' in g, m
78 self.assertEqual(m.results, ('z', m))
79 try:
80 exec 'z = b' in m
81 except TypeError:
82 pass
83 else:
84 self.fail('Did not validate globals as a real dict')
85
86 class A:
87 "Non-mapping"
88 pass
89 m = A()
90 try:
91 exec 'z = a' in g, m
92 except TypeError:
93 pass
94 else:
95 self.fail('Did not validate locals as a mapping')
96
97 # Verify that dict subclasses work as well
98 class D(dict):
99 def __getitem__(self, key):
100 if key == 'a':
101 return 12
102 return dict.__getitem__(self, key)
103 d = D()
104 exec 'z = a' in g, d
105 self.assertEqual(d['z'], 12)
106
Neal Norwitz6ab080c2005-10-24 00:08:10 +0000107 def test_extended_arg(self):
108 longexpr = 'x = x or ' + '-x' * 2500
109 code = '''
110def f(x):
111 %s
112 %s
113 %s
114 %s
115 %s
116 %s
117 %s
118 %s
119 %s
120 %s
121 # the expressions above have no effect, x == argument
122 while x:
123 x -= 1
124 # EXTENDED_ARG/JUMP_ABSOLUTE here
125 return x
126''' % ((longexpr,)*10)
127 exec code
128 self.assertEqual(f(5), 0)
129
Raymond Hettinger8a99b502003-06-23 13:36:57 +0000130 def test_complex_args(self):
Thomas Heller6b17abf2002-07-09 09:23:27 +0000131
Raymond Hettinger8a99b502003-06-23 13:36:57 +0000132 def comp_args((a, b)):
133 return a,b
134 self.assertEqual(comp_args((1, 2)), (1, 2))
Thomas Heller6b17abf2002-07-09 09:23:27 +0000135
Raymond Hettinger8a99b502003-06-23 13:36:57 +0000136 def comp_args((a, b)=(3, 4)):
137 return a, b
138 self.assertEqual(comp_args((1, 2)), (1, 2))
139 self.assertEqual(comp_args(), (3, 4))
Jeremy Hylton047e2c92001-01-19 03:25:56 +0000140
Raymond Hettinger8a99b502003-06-23 13:36:57 +0000141 def comp_args(a, (b, c)):
142 return a, b, c
143 self.assertEqual(comp_args(1, (2, 3)), (1, 2, 3))
Jeremy Hylton121b6eb2001-02-19 23:53:42 +0000144
Raymond Hettinger8a99b502003-06-23 13:36:57 +0000145 def comp_args(a=2, (b, c)=(3, 4)):
146 return a, b, c
147 self.assertEqual(comp_args(1, (2, 3)), (1, 2, 3))
148 self.assertEqual(comp_args(), (2, 3, 4))
Jeremy Hylton121b6eb2001-02-19 23:53:42 +0000149
Raymond Hettinger8a99b502003-06-23 13:36:57 +0000150 def test_argument_order(self):
151 try:
152 exec 'def f(a=1, (b, c)): pass'
153 self.fail("non-default args after default")
154 except SyntaxError:
155 pass
Jeremy Hylton121b6eb2001-02-19 23:53:42 +0000156
Raymond Hettinger8a99b502003-06-23 13:36:57 +0000157 def test_float_literals(self):
158 # testing bad float literals
159 self.assertRaises(SyntaxError, eval, "2e")
160 self.assertRaises(SyntaxError, eval, "2.0e+")
161 self.assertRaises(SyntaxError, eval, "1e-")
162 self.assertRaises(SyntaxError, eval, "3-4e/21")
Jeremy Hylton121b6eb2001-02-19 23:53:42 +0000163
Raymond Hettinger8a99b502003-06-23 13:36:57 +0000164 def test_indentation(self):
165 # testing compile() of indented block w/o trailing newline"
166 s = """
Guido van Rossum4b499dd32003-02-13 22:07:59 +0000167if 1:
168 if 2:
169 pass"""
Raymond Hettinger8a99b502003-06-23 13:36:57 +0000170 compile(s, "<string>", "exec")
171
Neal Norwitzed657552006-07-10 00:04:44 +0000172 # This test is probably specific to CPython and may not generalize
173 # to other implementations. We are trying to ensure that when
174 # the first line of code starts after 256, correct line numbers
175 # in tracebacks are still produced.
176 def test_leading_newlines(self):
177 s256 = "".join(["\n"] * 256 + ["spam"])
178 co = compile(s256, 'fn', 'exec')
179 self.assertEqual(co.co_firstlineno, 257)
180 self.assertEqual(co.co_lnotab, '')
181
Raymond Hettinger8a99b502003-06-23 13:36:57 +0000182 def test_literals_with_leading_zeroes(self):
183 for arg in ["077787", "0xj", "0x.", "0e", "090000000000000",
Eric Smith9ff19b52008-03-17 17:32:20 +0000184 "080000000000000", "000000000000009", "000000000000008",
185 "0b42", "0BADCAFE", "0o123456789", "0b1.1", "0o4.2",
Amaury Forgeot d'Arc52167212008-04-24 18:07:05 +0000186 "0b101j2", "0o153j2", "0b100e1", "0o777e1", "0o8", "0o78"]:
Raymond Hettinger8a99b502003-06-23 13:36:57 +0000187 self.assertRaises(SyntaxError, eval, arg)
188
189 self.assertEqual(eval("0777"), 511)
190 self.assertEqual(eval("0777L"), 511)
191 self.assertEqual(eval("000777"), 511)
192 self.assertEqual(eval("0xff"), 255)
193 self.assertEqual(eval("0xffL"), 255)
194 self.assertEqual(eval("0XfF"), 255)
195 self.assertEqual(eval("0777."), 777)
196 self.assertEqual(eval("0777.0"), 777)
197 self.assertEqual(eval("000000000000000000000000000000000000000000000000000777e0"), 777)
198 self.assertEqual(eval("0777e1"), 7770)
199 self.assertEqual(eval("0e0"), 0)
200 self.assertEqual(eval("0000E-012"), 0)
201 self.assertEqual(eval("09.5"), 9.5)
202 self.assertEqual(eval("0777j"), 777j)
203 self.assertEqual(eval("00j"), 0j)
204 self.assertEqual(eval("00.0"), 0)
205 self.assertEqual(eval("0e3"), 0)
206 self.assertEqual(eval("090000000000000."), 90000000000000.)
207 self.assertEqual(eval("090000000000000.0000000000000000000000"), 90000000000000.)
208 self.assertEqual(eval("090000000000000e0"), 90000000000000.)
209 self.assertEqual(eval("090000000000000e-0"), 90000000000000.)
210 self.assertEqual(eval("090000000000000j"), 90000000000000j)
211 self.assertEqual(eval("000000000000007"), 7)
212 self.assertEqual(eval("000000000000008."), 8.)
213 self.assertEqual(eval("000000000000009."), 9.)
Eric Smith9ff19b52008-03-17 17:32:20 +0000214 self.assertEqual(eval("0b101010"), 42)
215 self.assertEqual(eval("-0b000000000010"), -2)
216 self.assertEqual(eval("0o777"), 511)
217 self.assertEqual(eval("-0o0000010"), -8)
Mark Dickinson64b7e502008-07-16 09:40:03 +0000218 self.assertEqual(eval("020000000000.0"), 20000000000.0)
219 self.assertEqual(eval("037777777777e0"), 37777777777.0)
220 self.assertEqual(eval("01000000000000000000000.0"),
221 1000000000000000000000.0)
Raymond Hettinger8a99b502003-06-23 13:36:57 +0000222
223 def test_unary_minus(self):
224 # Verify treatment of unary minus on negative numbers SF bug #660455
Guido van Rossum6c9e1302003-11-29 23:52:13 +0000225 if sys.maxint == 2147483647:
226 # 32-bit machine
227 all_one_bits = '0xffffffff'
228 self.assertEqual(eval(all_one_bits), 4294967295L)
229 self.assertEqual(eval("-" + all_one_bits), -4294967295L)
230 elif sys.maxint == 9223372036854775807:
231 # 64-bit machine
Raymond Hettinger8a99b502003-06-23 13:36:57 +0000232 all_one_bits = '0xffffffffffffffff'
Guido van Rossum6c9e1302003-11-29 23:52:13 +0000233 self.assertEqual(eval(all_one_bits), 18446744073709551615L)
234 self.assertEqual(eval("-" + all_one_bits), -18446744073709551615L)
235 else:
236 self.fail("How many bits *does* this machine have???")
Neil Schemenauer6ec6ab02006-07-09 21:19:29 +0000237 # Verify treatment of contant folding on -(sys.maxint+1)
238 # i.e. -2147483648 on 32 bit platforms. Should return int, not long.
239 self.assertTrue(isinstance(eval("%s" % (-sys.maxint - 1)), int))
240 self.assertTrue(isinstance(eval("%s" % (-sys.maxint - 2)), long))
Raymond Hettinger8a99b502003-06-23 13:36:57 +0000241
Neal Norwitz28746ab2006-07-09 22:14:42 +0000242 if sys.maxint == 9223372036854775807:
243 def test_32_63_bit_values(self):
244 a = +4294967296 # 1 << 32
245 b = -4294967296 # 1 << 32
246 c = +281474976710656 # 1 << 48
247 d = -281474976710656 # 1 << 48
248 e = +4611686018427387904 # 1 << 62
249 f = -4611686018427387904 # 1 << 62
250 g = +9223372036854775807 # 1 << 63 - 1
251 h = -9223372036854775807 # 1 << 63 - 1
252
253 for variable in self.test_32_63_bit_values.func_code.co_consts:
254 if variable is not None:
255 self.assertTrue(isinstance(variable, int))
256
Raymond Hettinger8a99b502003-06-23 13:36:57 +0000257 def test_sequence_unpacking_error(self):
258 # Verify sequence packing/unpacking with "or". SF bug #757818
259 i,j = (1, -1) or (-1, 1)
260 self.assertEqual(i, 1)
261 self.assertEqual(j, -1)
Guido van Rossum4b499dd32003-02-13 22:07:59 +0000262
Raymond Hettinger11a70c72004-07-17 21:46:25 +0000263 def test_none_assignment(self):
264 stmts = [
265 'None = 0',
266 'None += 0',
267 '__builtins__.None = 0',
268 'def None(): pass',
269 'class None: pass',
270 '(a, None) = 0, 0',
271 'for None in range(10): pass',
272 'def f(None): pass',
Benjamin Peterson565e1b62009-06-13 03:46:30 +0000273 'import None',
274 'import x as None',
275 'from x import None',
276 'from x import y as None'
Raymond Hettinger11a70c72004-07-17 21:46:25 +0000277 ]
278 for stmt in stmts:
279 stmt += "\n"
280 self.assertRaises(SyntaxError, compile, stmt, 'tmp', 'single')
281 self.assertRaises(SyntaxError, compile, stmt, 'tmp', 'exec')
Benjamin Peterson565e1b62009-06-13 03:46:30 +0000282 # This is ok.
283 compile("from None import x", "tmp", "exec")
Benjamin Petersond1f5a592009-06-13 13:06:21 +0000284 compile("from x import None as y", "tmp", "exec")
285 compile("import None as x", "tmp", "exec")
Tim Petersd507dab2001-08-30 20:51:59 +0000286
Anthony Baxter1a4ddae2004-08-31 10:07:13 +0000287 def test_import(self):
288 succeed = [
289 'import sys',
290 'import os, sys',
Neal Norwitzfb48afa2006-07-08 05:31:37 +0000291 'import os as bar',
292 'import os.path as bar',
Anthony Baxter1a4ddae2004-08-31 10:07:13 +0000293 'from __future__ import nested_scopes, generators',
294 'from __future__ import (nested_scopes,\ngenerators)',
295 'from __future__ import (nested_scopes,\ngenerators,)',
296 'from sys import stdin, stderr, stdout',
297 'from sys import (stdin, stderr,\nstdout)',
298 'from sys import (stdin, stderr,\nstdout,)',
299 'from sys import (stdin\n, stderr, stdout)',
300 'from sys import (stdin\n, stderr, stdout,)',
301 'from sys import stdin as si, stdout as so, stderr as se',
302 'from sys import (stdin as si, stdout as so, stderr as se)',
303 'from sys import (stdin as si, stdout as so, stderr as se,)',
304 ]
305 fail = [
306 'import (os, sys)',
307 'import (os), (sys)',
308 'import ((os), (sys))',
309 'import (sys',
310 'import sys)',
311 'import (os,)',
Neal Norwitzfb48afa2006-07-08 05:31:37 +0000312 'import os As bar',
313 'import os.path a bar',
Georg Brandl9575fb22006-07-08 12:15:27 +0000314 'from sys import stdin As stdout',
315 'from sys import stdin a stdout',
Anthony Baxter1a4ddae2004-08-31 10:07:13 +0000316 'from (sys) import stdin',
317 'from __future__ import (nested_scopes',
318 'from __future__ import nested_scopes)',
319 'from __future__ import nested_scopes,\ngenerators',
320 'from sys import (stdin',
321 'from sys import stdin)',
322 'from sys import stdin, stdout,\nstderr',
323 'from sys import stdin si',
324 'from sys import stdin,'
325 'from sys import (*)',
326 'from sys import (stdin,, stdout, stderr)',
327 'from sys import (stdin, stdout),',
328 ]
329 for stmt in succeed:
330 compile(stmt, 'tmp', 'exec')
331 for stmt in fail:
332 self.assertRaises(SyntaxError, compile, stmt, 'tmp', 'exec')
333
Raymond Hettinger9047c8f2004-10-24 00:10:06 +0000334 def test_for_distinct_code_objects(self):
335 # SF bug 1048870
336 def f():
337 f1 = lambda x=1: x
338 f2 = lambda x=2: x
339 return f1, f2
340 f1, f2 = f()
341 self.assertNotEqual(id(f1.func_code), id(f2.func_code))
342
Neal Norwitze98ccf62006-03-23 05:39:47 +0000343 def test_unicode_encoding(self):
344 code = u"# -*- coding: utf-8 -*-\npass\n"
345 self.assertRaises(SyntaxError, compile, code, "tmp", "exec")
346
Nick Coghlaneadee9a2006-03-13 12:31:58 +0000347 def test_subscripts(self):
348 # SF bug 1448804
349 # Class to make testing subscript results easy
350 class str_map(object):
351 def __init__(self):
352 self.data = {}
353 def __getitem__(self, key):
354 return self.data[str(key)]
355 def __setitem__(self, key, value):
356 self.data[str(key)] = value
357 def __delitem__(self, key):
358 del self.data[str(key)]
359 def __contains__(self, key):
360 return str(key) in self.data
361 d = str_map()
362 # Index
363 d[1] = 1
364 self.assertEqual(d[1], 1)
365 d[1] += 1
366 self.assertEqual(d[1], 2)
367 del d[1]
368 self.assertEqual(1 in d, False)
369 # Tuple of indices
370 d[1, 1] = 1
371 self.assertEqual(d[1, 1], 1)
372 d[1, 1] += 1
373 self.assertEqual(d[1, 1], 2)
374 del d[1, 1]
375 self.assertEqual((1, 1) in d, False)
376 # Simple slice
377 d[1:2] = 1
378 self.assertEqual(d[1:2], 1)
379 d[1:2] += 1
380 self.assertEqual(d[1:2], 2)
381 del d[1:2]
382 self.assertEqual(slice(1, 2) in d, False)
383 # Tuple of simple slices
384 d[1:2, 1:2] = 1
385 self.assertEqual(d[1:2, 1:2], 1)
386 d[1:2, 1:2] += 1
387 self.assertEqual(d[1:2, 1:2], 2)
388 del d[1:2, 1:2]
389 self.assertEqual((slice(1, 2), slice(1, 2)) in d, False)
390 # Extended slice
391 d[1:2:3] = 1
392 self.assertEqual(d[1:2:3], 1)
393 d[1:2:3] += 1
394 self.assertEqual(d[1:2:3], 2)
395 del d[1:2:3]
396 self.assertEqual(slice(1, 2, 3) in d, False)
397 # Tuple of extended slices
398 d[1:2:3, 1:2:3] = 1
399 self.assertEqual(d[1:2:3, 1:2:3], 1)
400 d[1:2:3, 1:2:3] += 1
401 self.assertEqual(d[1:2:3, 1:2:3], 2)
402 del d[1:2:3, 1:2:3]
403 self.assertEqual((slice(1, 2, 3), slice(1, 2, 3)) in d, False)
404 # Ellipsis
405 d[...] = 1
406 self.assertEqual(d[...], 1)
407 d[...] += 1
408 self.assertEqual(d[...], 2)
409 del d[...]
410 self.assertEqual(Ellipsis in d, False)
411 # Tuple of Ellipses
412 d[..., ...] = 1
413 self.assertEqual(d[..., ...], 1)
414 d[..., ...] += 1
415 self.assertEqual(d[..., ...], 2)
416 del d[..., ...]
417 self.assertEqual((Ellipsis, Ellipsis) in d, False)
418
Jeremy Hylton37075c52007-02-27 01:01:59 +0000419 def test_mangling(self):
420 class A:
421 def f():
422 __mangled = 1
423 __not_mangled__ = 2
424 import __mangled_mod
425 import __package__.module
426
427 self.assert_("_A__mangled" in A.f.func_code.co_varnames)
428 self.assert_("__not_mangled__" in A.f.func_code.co_varnames)
429 self.assert_("_A__mangled_mod" in A.f.func_code.co_varnames)
430 self.assert_("__package__" in A.f.func_code.co_varnames)
431
Georg Brandlfc8eef32008-03-28 12:11:56 +0000432 def test_compile_ast(self):
433 fname = __file__
434 if fname.lower().endswith(('pyc', 'pyo')):
435 fname = fname[:-1]
436 with open(fname, 'r') as f:
437 fcontents = f.read()
438 sample_code = [
439 ['<assign>', 'x = 5'],
440 ['<print1>', 'print 1'],
441 ['<printv>', 'print v'],
442 ['<printTrue>', 'print True'],
443 ['<printList>', 'print []'],
444 ['<ifblock>', """if True:\n pass\n"""],
445 ['<forblock>', """for n in [1, 2, 3]:\n print n\n"""],
446 ['<deffunc>', """def foo():\n pass\nfoo()\n"""],
447 [fname, fcontents],
448 ]
449
450 for fname, code in sample_code:
451 co1 = compile(code, '%s1' % fname, 'exec')
452 ast = compile(code, '%s2' % fname, 'exec', _ast.PyCF_ONLY_AST)
453 self.assert_(type(ast) == _ast.Module)
454 co2 = compile(ast, '%s3' % fname, 'exec')
455 self.assertEqual(co1, co2)
Georg Brandlf2bfd542008-03-29 13:24:23 +0000456 # the code object's filename comes from the second compilation step
457 self.assertEqual(co2.co_filename, '%s3' % fname)
458
459 # raise exception when node type doesn't match with compile mode
460 co1 = compile('print 1', '<string>', 'exec', _ast.PyCF_ONLY_AST)
461 self.assertRaises(TypeError, compile, co1, '<ast>', 'eval')
462
463 # raise exception when node type is no start node
464 self.assertRaises(TypeError, compile, _ast.If(), '<ast>', 'exec')
465
466 # raise exception when node has invalid children
467 ast = _ast.Module()
468 ast.body = [_ast.BoolOp()]
469 self.assertRaises(TypeError, compile, ast, '<ast>', 'exec')
Georg Brandlfc8eef32008-03-28 12:11:56 +0000470
471
Raymond Hettinger8a99b502003-06-23 13:36:57 +0000472def test_main():
473 test_support.run_unittest(TestSpecifics)
Tim Petersd507dab2001-08-30 20:51:59 +0000474
Raymond Hettinger8a99b502003-06-23 13:36:57 +0000475if __name__ == "__main__":
476 test_main()