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