blob: ec2709dbd1c706b9a400b07016da962bdb31e3ad [file] [log] [blame]
Antoine Pitrouab4a6912014-05-23 11:46:03 +02001import math
Raymond Hettinger8a99b502003-06-23 13:36:57 +00002import unittest
Raymond Hettinger8a99b502003-06-23 13:36:57 +00003import sys
Georg Brandlfc8eef32008-03-28 12:11:56 +00004import _ast
Raymond Hettinger8a99b502003-06-23 13:36:57 +00005from test import test_support
Florent Xiclunaaf617192010-03-21 11:03:21 +00006import textwrap
Peter Schneider-Kampfdee0f02000-07-25 22:15:45 +00007
Raymond Hettinger8a99b502003-06-23 13:36:57 +00008class TestSpecifics(unittest.TestCase):
Jeremy Hylton778e2652001-11-09 19:50:08 +00009
Benjamin Petersone36199b2009-11-12 23:39:44 +000010 def test_no_ending_newline(self):
11 compile("hi", "<test>", "exec")
12 compile("hi\r", "<test>", "exec")
13
14 def test_empty(self):
15 compile("", "<test>", "exec")
16
17 def test_other_newlines(self):
18 compile("\r\n", "<test>", "exec")
19 compile("\r", "<test>", "exec")
20 compile("hi\r\nstuff\r\ndef f():\n pass\r", "<test>", "exec")
21 compile("this_is\rreally_old_mac\rdef f():\n pass", "<test>", "exec")
22
Raymond Hettinger8a99b502003-06-23 13:36:57 +000023 def test_debug_assignment(self):
24 # catch assignments to __debug__
25 self.assertRaises(SyntaxError, compile, '__debug__ = 1', '?', 'single')
26 import __builtin__
27 prev = __builtin__.__debug__
28 setattr(__builtin__, '__debug__', 'sure')
29 setattr(__builtin__, '__debug__', prev)
Jeremy Hylton778e2652001-11-09 19:50:08 +000030
Raymond Hettinger8a99b502003-06-23 13:36:57 +000031 def test_argument_handling(self):
32 # detect duplicate positional and keyword arguments
33 self.assertRaises(SyntaxError, eval, 'lambda a,a:0')
34 self.assertRaises(SyntaxError, eval, 'lambda a,a=1:0')
35 self.assertRaises(SyntaxError, eval, 'lambda a=1,a=1:0')
36 try:
37 exec 'def f(a, a): pass'
38 self.fail("duplicate arguments")
39 except SyntaxError:
40 pass
41 try:
42 exec 'def f(a = 0, a = 1): pass'
43 self.fail("duplicate keyword arguments")
44 except SyntaxError:
45 pass
46 try:
47 exec 'def f(a): global a; a = 1'
48 self.fail("variable is global and local")
49 except SyntaxError:
50 pass
Jeremy Hylton778e2652001-11-09 19:50:08 +000051
Raymond Hettinger8a99b502003-06-23 13:36:57 +000052 def test_syntax_error(self):
53 self.assertRaises(SyntaxError, compile, "1+*3", "filename", "exec")
Peter Schneider-Kampfdee0f02000-07-25 22:15:45 +000054
Georg Brandle06cf452007-06-07 13:23:24 +000055 def test_none_keyword_arg(self):
56 self.assertRaises(SyntaxError, compile, "f(None=1)", "<string>", "exec")
57
Raymond Hettinger8a99b502003-06-23 13:36:57 +000058 def test_duplicate_global_local(self):
59 try:
60 exec 'def f(a): global a; a = 1'
61 self.fail("variable is global and local")
62 except SyntaxError:
63 pass
Peter Schneider-Kampfdee0f02000-07-25 22:15:45 +000064
Mark Dickinson16587972012-11-25 13:25:57 +000065 def test_exec_functional_style(self):
66 # Exec'ing a tuple of length 2 works.
67 g = {'b': 2}
68 exec("a = b + 1", g)
69 self.assertEqual(g['a'], 3)
70
71 # As does exec'ing a tuple of length 3.
72 l = {'b': 3}
73 g = {'b': 5, 'c': 7}
74 exec("a = b + c", g, l)
75 self.assertNotIn('a', g)
76 self.assertEqual(l['a'], 10)
77
78 # Tuples not of length 2 or 3 are invalid.
79 with self.assertRaises(TypeError):
80 exec("a = b + 1",)
81
82 with self.assertRaises(TypeError):
83 exec("a = b + 1", {}, {}, {})
84
85 # Can't mix and match the two calling forms.
86 g = {'a': 3, 'b': 4}
87 l = {}
88 with self.assertRaises(TypeError):
89 exec("a = b + 1", g) in g
90 with self.assertRaises(TypeError):
91 exec("a = b + 1", g, l) in g, l
92
Raymond Hettinger66bd2332004-08-02 08:30:07 +000093 def test_exec_with_general_mapping_for_locals(self):
94
95 class M:
96 "Test mapping interface versus possible calls from eval()."
97 def __getitem__(self, key):
98 if key == 'a':
99 return 12
100 raise KeyError
101 def __setitem__(self, key, value):
102 self.results = (key, value)
103 def keys(self):
104 return list('xyz')
105
106 m = M()
107 g = globals()
108 exec 'z = a' in g, m
109 self.assertEqual(m.results, ('z', 12))
110 try:
111 exec 'z = b' in g, m
112 except NameError:
113 pass
114 else:
115 self.fail('Did not detect a KeyError')
116 exec 'z = dir()' in g, m
117 self.assertEqual(m.results, ('z', list('xyz')))
118 exec 'z = globals()' in g, m
119 self.assertEqual(m.results, ('z', g))
120 exec 'z = locals()' in g, m
121 self.assertEqual(m.results, ('z', m))
122 try:
123 exec 'z = b' in m
124 except TypeError:
125 pass
126 else:
127 self.fail('Did not validate globals as a real dict')
128
129 class A:
130 "Non-mapping"
131 pass
132 m = A()
133 try:
134 exec 'z = a' in g, m
135 except TypeError:
136 pass
137 else:
138 self.fail('Did not validate locals as a mapping')
139
140 # Verify that dict subclasses work as well
141 class D(dict):
142 def __getitem__(self, key):
143 if key == 'a':
144 return 12
145 return dict.__getitem__(self, key)
146 d = D()
147 exec 'z = a' in g, d
148 self.assertEqual(d['z'], 12)
149
Neal Norwitz6ab080c2005-10-24 00:08:10 +0000150 def test_extended_arg(self):
151 longexpr = 'x = x or ' + '-x' * 2500
152 code = '''
153def f(x):
154 %s
155 %s
156 %s
157 %s
158 %s
159 %s
160 %s
161 %s
162 %s
163 %s
164 # the expressions above have no effect, x == argument
165 while x:
166 x -= 1
167 # EXTENDED_ARG/JUMP_ABSOLUTE here
168 return x
169''' % ((longexpr,)*10)
170 exec code
171 self.assertEqual(f(5), 0)
172
Raymond Hettinger8a99b502003-06-23 13:36:57 +0000173 def test_complex_args(self):
Senthil Kumarance8e33a2010-01-08 19:04:16 +0000174
Florent Xiclunaaf617192010-03-21 11:03:21 +0000175 with test_support.check_py3k_warnings(
176 ("tuple parameter unpacking has been removed", SyntaxWarning)):
177 exec textwrap.dedent('''
Raymond Hettinger8a99b502003-06-23 13:36:57 +0000178 def comp_args((a, b)):
179 return a,b
180 self.assertEqual(comp_args((1, 2)), (1, 2))
Thomas Heller6b17abf2002-07-09 09:23:27 +0000181
Raymond Hettinger8a99b502003-06-23 13:36:57 +0000182 def comp_args((a, b)=(3, 4)):
183 return a, b
184 self.assertEqual(comp_args((1, 2)), (1, 2))
185 self.assertEqual(comp_args(), (3, 4))
Jeremy Hylton047e2c92001-01-19 03:25:56 +0000186
Raymond Hettinger8a99b502003-06-23 13:36:57 +0000187 def comp_args(a, (b, c)):
188 return a, b, c
189 self.assertEqual(comp_args(1, (2, 3)), (1, 2, 3))
Jeremy Hylton121b6eb2001-02-19 23:53:42 +0000190
Raymond Hettinger8a99b502003-06-23 13:36:57 +0000191 def comp_args(a=2, (b, c)=(3, 4)):
192 return a, b, c
193 self.assertEqual(comp_args(1, (2, 3)), (1, 2, 3))
194 self.assertEqual(comp_args(), (2, 3, 4))
Florent Xiclunaaf617192010-03-21 11:03:21 +0000195 ''')
Jeremy Hylton121b6eb2001-02-19 23:53:42 +0000196
Raymond Hettinger8a99b502003-06-23 13:36:57 +0000197 def test_argument_order(self):
198 try:
199 exec 'def f(a=1, (b, c)): pass'
200 self.fail("non-default args after default")
201 except SyntaxError:
202 pass
Jeremy Hylton121b6eb2001-02-19 23:53:42 +0000203
Raymond Hettinger8a99b502003-06-23 13:36:57 +0000204 def test_float_literals(self):
205 # testing bad float literals
206 self.assertRaises(SyntaxError, eval, "2e")
207 self.assertRaises(SyntaxError, eval, "2.0e+")
208 self.assertRaises(SyntaxError, eval, "1e-")
209 self.assertRaises(SyntaxError, eval, "3-4e/21")
Jeremy Hylton121b6eb2001-02-19 23:53:42 +0000210
Raymond Hettinger8a99b502003-06-23 13:36:57 +0000211 def test_indentation(self):
212 # testing compile() of indented block w/o trailing newline"
213 s = """
Guido van Rossum4b499dd32003-02-13 22:07:59 +0000214if 1:
215 if 2:
216 pass"""
Raymond Hettinger8a99b502003-06-23 13:36:57 +0000217 compile(s, "<string>", "exec")
218
Neal Norwitzed657552006-07-10 00:04:44 +0000219 # This test is probably specific to CPython and may not generalize
220 # to other implementations. We are trying to ensure that when
221 # the first line of code starts after 256, correct line numbers
222 # in tracebacks are still produced.
223 def test_leading_newlines(self):
224 s256 = "".join(["\n"] * 256 + ["spam"])
225 co = compile(s256, 'fn', 'exec')
226 self.assertEqual(co.co_firstlineno, 257)
227 self.assertEqual(co.co_lnotab, '')
228
Raymond Hettinger8a99b502003-06-23 13:36:57 +0000229 def test_literals_with_leading_zeroes(self):
230 for arg in ["077787", "0xj", "0x.", "0e", "090000000000000",
Eric Smith9ff19b52008-03-17 17:32:20 +0000231 "080000000000000", "000000000000009", "000000000000008",
232 "0b42", "0BADCAFE", "0o123456789", "0b1.1", "0o4.2",
Amaury Forgeot d'Arc52167212008-04-24 18:07:05 +0000233 "0b101j2", "0o153j2", "0b100e1", "0o777e1", "0o8", "0o78"]:
Raymond Hettinger8a99b502003-06-23 13:36:57 +0000234 self.assertRaises(SyntaxError, eval, arg)
235
236 self.assertEqual(eval("0777"), 511)
237 self.assertEqual(eval("0777L"), 511)
238 self.assertEqual(eval("000777"), 511)
239 self.assertEqual(eval("0xff"), 255)
240 self.assertEqual(eval("0xffL"), 255)
241 self.assertEqual(eval("0XfF"), 255)
242 self.assertEqual(eval("0777."), 777)
243 self.assertEqual(eval("0777.0"), 777)
244 self.assertEqual(eval("000000000000000000000000000000000000000000000000000777e0"), 777)
245 self.assertEqual(eval("0777e1"), 7770)
246 self.assertEqual(eval("0e0"), 0)
247 self.assertEqual(eval("0000E-012"), 0)
248 self.assertEqual(eval("09.5"), 9.5)
249 self.assertEqual(eval("0777j"), 777j)
250 self.assertEqual(eval("00j"), 0j)
251 self.assertEqual(eval("00.0"), 0)
252 self.assertEqual(eval("0e3"), 0)
253 self.assertEqual(eval("090000000000000."), 90000000000000.)
254 self.assertEqual(eval("090000000000000.0000000000000000000000"), 90000000000000.)
255 self.assertEqual(eval("090000000000000e0"), 90000000000000.)
256 self.assertEqual(eval("090000000000000e-0"), 90000000000000.)
257 self.assertEqual(eval("090000000000000j"), 90000000000000j)
258 self.assertEqual(eval("000000000000007"), 7)
259 self.assertEqual(eval("000000000000008."), 8.)
260 self.assertEqual(eval("000000000000009."), 9.)
Eric Smith9ff19b52008-03-17 17:32:20 +0000261 self.assertEqual(eval("0b101010"), 42)
262 self.assertEqual(eval("-0b000000000010"), -2)
263 self.assertEqual(eval("0o777"), 511)
264 self.assertEqual(eval("-0o0000010"), -8)
Mark Dickinson64b7e502008-07-16 09:40:03 +0000265 self.assertEqual(eval("020000000000.0"), 20000000000.0)
266 self.assertEqual(eval("037777777777e0"), 37777777777.0)
267 self.assertEqual(eval("01000000000000000000000.0"),
268 1000000000000000000000.0)
Raymond Hettinger8a99b502003-06-23 13:36:57 +0000269
270 def test_unary_minus(self):
271 # Verify treatment of unary minus on negative numbers SF bug #660455
Guido van Rossum6c9e1302003-11-29 23:52:13 +0000272 if sys.maxint == 2147483647:
273 # 32-bit machine
274 all_one_bits = '0xffffffff'
275 self.assertEqual(eval(all_one_bits), 4294967295L)
276 self.assertEqual(eval("-" + all_one_bits), -4294967295L)
277 elif sys.maxint == 9223372036854775807:
278 # 64-bit machine
Raymond Hettinger8a99b502003-06-23 13:36:57 +0000279 all_one_bits = '0xffffffffffffffff'
Guido van Rossum6c9e1302003-11-29 23:52:13 +0000280 self.assertEqual(eval(all_one_bits), 18446744073709551615L)
281 self.assertEqual(eval("-" + all_one_bits), -18446744073709551615L)
282 else:
283 self.fail("How many bits *does* this machine have???")
Ezio Melotti24b07bc2011-03-15 18:55:01 +0200284 # Verify treatment of constant folding on -(sys.maxint+1)
Neil Schemenauer6ec6ab02006-07-09 21:19:29 +0000285 # i.e. -2147483648 on 32 bit platforms. Should return int, not long.
Ezio Melottib0f5adc2010-01-24 16:58:36 +0000286 self.assertIsInstance(eval("%s" % (-sys.maxint - 1)), int)
287 self.assertIsInstance(eval("%s" % (-sys.maxint - 2)), long)
Raymond Hettinger8a99b502003-06-23 13:36:57 +0000288
Neal Norwitz28746ab2006-07-09 22:14:42 +0000289 if sys.maxint == 9223372036854775807:
290 def test_32_63_bit_values(self):
291 a = +4294967296 # 1 << 32
292 b = -4294967296 # 1 << 32
293 c = +281474976710656 # 1 << 48
294 d = -281474976710656 # 1 << 48
295 e = +4611686018427387904 # 1 << 62
296 f = -4611686018427387904 # 1 << 62
297 g = +9223372036854775807 # 1 << 63 - 1
298 h = -9223372036854775807 # 1 << 63 - 1
299
300 for variable in self.test_32_63_bit_values.func_code.co_consts:
301 if variable is not None:
Ezio Melottib0f5adc2010-01-24 16:58:36 +0000302 self.assertIsInstance(variable, int)
Neal Norwitz28746ab2006-07-09 22:14:42 +0000303
Raymond Hettinger8a99b502003-06-23 13:36:57 +0000304 def test_sequence_unpacking_error(self):
305 # Verify sequence packing/unpacking with "or". SF bug #757818
306 i,j = (1, -1) or (-1, 1)
307 self.assertEqual(i, 1)
308 self.assertEqual(j, -1)
Guido van Rossum4b499dd32003-02-13 22:07:59 +0000309
Raymond Hettinger11a70c72004-07-17 21:46:25 +0000310 def test_none_assignment(self):
311 stmts = [
312 'None = 0',
313 'None += 0',
314 '__builtins__.None = 0',
315 'def None(): pass',
316 'class None: pass',
317 '(a, None) = 0, 0',
318 'for None in range(10): pass',
319 'def f(None): pass',
Benjamin Peterson565e1b62009-06-13 03:46:30 +0000320 'import None',
321 'import x as None',
322 'from x import None',
323 'from x import y as None'
Raymond Hettinger11a70c72004-07-17 21:46:25 +0000324 ]
325 for stmt in stmts:
326 stmt += "\n"
327 self.assertRaises(SyntaxError, compile, stmt, 'tmp', 'single')
328 self.assertRaises(SyntaxError, compile, stmt, 'tmp', 'exec')
Benjamin Peterson565e1b62009-06-13 03:46:30 +0000329 # This is ok.
330 compile("from None import x", "tmp", "exec")
Benjamin Petersond1f5a592009-06-13 13:06:21 +0000331 compile("from x import None as y", "tmp", "exec")
332 compile("import None as x", "tmp", "exec")
Tim Petersd507dab2001-08-30 20:51:59 +0000333
Anthony Baxter1a4ddae2004-08-31 10:07:13 +0000334 def test_import(self):
335 succeed = [
336 'import sys',
337 'import os, sys',
Neal Norwitzfb48afa2006-07-08 05:31:37 +0000338 'import os as bar',
339 'import os.path as bar',
Anthony Baxter1a4ddae2004-08-31 10:07:13 +0000340 'from __future__ import nested_scopes, generators',
341 'from __future__ import (nested_scopes,\ngenerators)',
342 'from __future__ import (nested_scopes,\ngenerators,)',
343 'from sys import stdin, stderr, stdout',
344 'from sys import (stdin, stderr,\nstdout)',
345 'from sys import (stdin, stderr,\nstdout,)',
346 'from sys import (stdin\n, stderr, stdout)',
347 'from sys import (stdin\n, stderr, stdout,)',
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 'from sys import (stdin as si, stdout as so, stderr as se,)',
351 ]
352 fail = [
353 'import (os, sys)',
354 'import (os), (sys)',
355 'import ((os), (sys))',
356 'import (sys',
357 'import sys)',
358 'import (os,)',
Neal Norwitzfb48afa2006-07-08 05:31:37 +0000359 'import os As bar',
360 'import os.path a bar',
Georg Brandl9575fb22006-07-08 12:15:27 +0000361 'from sys import stdin As stdout',
362 'from sys import stdin a stdout',
Anthony Baxter1a4ddae2004-08-31 10:07:13 +0000363 'from (sys) import stdin',
364 'from __future__ import (nested_scopes',
365 'from __future__ import nested_scopes)',
366 'from __future__ import nested_scopes,\ngenerators',
367 'from sys import (stdin',
368 'from sys import stdin)',
369 'from sys import stdin, stdout,\nstderr',
370 'from sys import stdin si',
371 'from sys import stdin,'
372 'from sys import (*)',
373 'from sys import (stdin,, stdout, stderr)',
374 'from sys import (stdin, stdout),',
375 ]
376 for stmt in succeed:
377 compile(stmt, 'tmp', 'exec')
378 for stmt in fail:
379 self.assertRaises(SyntaxError, compile, stmt, 'tmp', 'exec')
380
Raymond Hettinger9047c8f2004-10-24 00:10:06 +0000381 def test_for_distinct_code_objects(self):
382 # SF bug 1048870
383 def f():
384 f1 = lambda x=1: x
385 f2 = lambda x=2: x
386 return f1, f2
387 f1, f2 = f()
388 self.assertNotEqual(id(f1.func_code), id(f2.func_code))
389
Benjamin Peterson0dee9c12010-03-17 20:41:42 +0000390 def test_lambda_doc(self):
391 l = lambda: "foo"
392 self.assertIsNone(l.__doc__)
393
Neal Norwitze98ccf62006-03-23 05:39:47 +0000394 def test_unicode_encoding(self):
395 code = u"# -*- coding: utf-8 -*-\npass\n"
396 self.assertRaises(SyntaxError, compile, code, "tmp", "exec")
397
Nick Coghlaneadee9a2006-03-13 12:31:58 +0000398 def test_subscripts(self):
399 # SF bug 1448804
400 # Class to make testing subscript results easy
401 class str_map(object):
402 def __init__(self):
403 self.data = {}
404 def __getitem__(self, key):
405 return self.data[str(key)]
406 def __setitem__(self, key, value):
407 self.data[str(key)] = value
408 def __delitem__(self, key):
409 del self.data[str(key)]
410 def __contains__(self, key):
411 return str(key) in self.data
412 d = str_map()
413 # Index
414 d[1] = 1
415 self.assertEqual(d[1], 1)
416 d[1] += 1
417 self.assertEqual(d[1], 2)
418 del d[1]
Ezio Melottiaa980582010-01-23 23:04:36 +0000419 self.assertNotIn(1, d)
Nick Coghlaneadee9a2006-03-13 12:31:58 +0000420 # Tuple of indices
421 d[1, 1] = 1
422 self.assertEqual(d[1, 1], 1)
423 d[1, 1] += 1
424 self.assertEqual(d[1, 1], 2)
425 del d[1, 1]
Ezio Melottiaa980582010-01-23 23:04:36 +0000426 self.assertNotIn((1, 1), d)
Nick Coghlaneadee9a2006-03-13 12:31:58 +0000427 # Simple slice
428 d[1:2] = 1
429 self.assertEqual(d[1:2], 1)
430 d[1:2] += 1
431 self.assertEqual(d[1:2], 2)
432 del d[1:2]
Ezio Melottiaa980582010-01-23 23:04:36 +0000433 self.assertNotIn(slice(1, 2), d)
Nick Coghlaneadee9a2006-03-13 12:31:58 +0000434 # Tuple of simple slices
435 d[1:2, 1:2] = 1
436 self.assertEqual(d[1:2, 1:2], 1)
437 d[1:2, 1:2] += 1
438 self.assertEqual(d[1:2, 1:2], 2)
439 del d[1:2, 1:2]
Ezio Melottiaa980582010-01-23 23:04:36 +0000440 self.assertNotIn((slice(1, 2), slice(1, 2)), d)
Nick Coghlaneadee9a2006-03-13 12:31:58 +0000441 # Extended slice
442 d[1:2:3] = 1
443 self.assertEqual(d[1:2:3], 1)
444 d[1:2:3] += 1
445 self.assertEqual(d[1:2:3], 2)
446 del d[1:2:3]
Ezio Melottiaa980582010-01-23 23:04:36 +0000447 self.assertNotIn(slice(1, 2, 3), d)
Nick Coghlaneadee9a2006-03-13 12:31:58 +0000448 # Tuple of extended slices
449 d[1:2:3, 1:2:3] = 1
450 self.assertEqual(d[1:2:3, 1:2:3], 1)
451 d[1:2:3, 1:2:3] += 1
452 self.assertEqual(d[1:2:3, 1:2:3], 2)
453 del d[1:2:3, 1:2:3]
Ezio Melottiaa980582010-01-23 23:04:36 +0000454 self.assertNotIn((slice(1, 2, 3), slice(1, 2, 3)), d)
Nick Coghlaneadee9a2006-03-13 12:31:58 +0000455 # Ellipsis
456 d[...] = 1
457 self.assertEqual(d[...], 1)
458 d[...] += 1
459 self.assertEqual(d[...], 2)
460 del d[...]
Ezio Melottiaa980582010-01-23 23:04:36 +0000461 self.assertNotIn(Ellipsis, d)
Nick Coghlaneadee9a2006-03-13 12:31:58 +0000462 # Tuple of Ellipses
463 d[..., ...] = 1
464 self.assertEqual(d[..., ...], 1)
465 d[..., ...] += 1
466 self.assertEqual(d[..., ...], 2)
467 del d[..., ...]
Ezio Melottiaa980582010-01-23 23:04:36 +0000468 self.assertNotIn((Ellipsis, Ellipsis), d)
Nick Coghlaneadee9a2006-03-13 12:31:58 +0000469
Jeremy Hylton37075c52007-02-27 01:01:59 +0000470 def test_mangling(self):
471 class A:
472 def f():
473 __mangled = 1
474 __not_mangled__ = 2
475 import __mangled_mod
476 import __package__.module
477
Ezio Melottiaa980582010-01-23 23:04:36 +0000478 self.assertIn("_A__mangled", A.f.func_code.co_varnames)
479 self.assertIn("__not_mangled__", A.f.func_code.co_varnames)
480 self.assertIn("_A__mangled_mod", A.f.func_code.co_varnames)
481 self.assertIn("__package__", A.f.func_code.co_varnames)
Jeremy Hylton37075c52007-02-27 01:01:59 +0000482
Georg Brandlfc8eef32008-03-28 12:11:56 +0000483 def test_compile_ast(self):
484 fname = __file__
485 if fname.lower().endswith(('pyc', 'pyo')):
486 fname = fname[:-1]
487 with open(fname, 'r') as f:
488 fcontents = f.read()
489 sample_code = [
490 ['<assign>', 'x = 5'],
491 ['<print1>', 'print 1'],
492 ['<printv>', 'print v'],
493 ['<printTrue>', 'print True'],
494 ['<printList>', 'print []'],
495 ['<ifblock>', """if True:\n pass\n"""],
496 ['<forblock>', """for n in [1, 2, 3]:\n print n\n"""],
497 ['<deffunc>', """def foo():\n pass\nfoo()\n"""],
498 [fname, fcontents],
499 ]
500
501 for fname, code in sample_code:
502 co1 = compile(code, '%s1' % fname, 'exec')
503 ast = compile(code, '%s2' % fname, 'exec', _ast.PyCF_ONLY_AST)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000504 self.assertTrue(type(ast) == _ast.Module)
Georg Brandlfc8eef32008-03-28 12:11:56 +0000505 co2 = compile(ast, '%s3' % fname, 'exec')
506 self.assertEqual(co1, co2)
Georg Brandlf2bfd542008-03-29 13:24:23 +0000507 # the code object's filename comes from the second compilation step
508 self.assertEqual(co2.co_filename, '%s3' % fname)
509
510 # raise exception when node type doesn't match with compile mode
511 co1 = compile('print 1', '<string>', 'exec', _ast.PyCF_ONLY_AST)
512 self.assertRaises(TypeError, compile, co1, '<ast>', 'eval')
513
514 # raise exception when node type is no start node
515 self.assertRaises(TypeError, compile, _ast.If(), '<ast>', 'exec')
516
517 # raise exception when node has invalid children
518 ast = _ast.Module()
519 ast.body = [_ast.BoolOp()]
520 self.assertRaises(TypeError, compile, ast, '<ast>', 'exec')
Georg Brandlfc8eef32008-03-28 12:11:56 +0000521
522
Antoine Pitrouab4a6912014-05-23 11:46:03 +0200523class TestStackSize(unittest.TestCase):
524 # These tests check that the computed stack size for a code object
525 # stays within reasonable bounds (see issue #21523 for an example
526 # dysfunction).
527 N = 100
528
529 def check_stack_size(self, code):
530 # To assert that the alleged stack size is not O(N), we
531 # check that it is smaller than log(N).
532 if isinstance(code, str):
533 code = compile(code, "<foo>", "single")
534 max_size = math.ceil(math.log(len(code.co_code)))
535 self.assertLessEqual(code.co_stacksize, max_size)
536
537 def test_and(self):
538 self.check_stack_size("x and " * self.N + "x")
539
540 def test_or(self):
541 self.check_stack_size("x or " * self.N + "x")
542
543 def test_and_or(self):
544 self.check_stack_size("x and x or " * self.N + "x")
545
546 def test_chained_comparison(self):
547 self.check_stack_size("x < " * self.N + "x")
548
549 def test_if_else(self):
550 self.check_stack_size("x if x else " * self.N + "x")
551
552 def test_binop(self):
553 self.check_stack_size("x + " * self.N + "x")
554
555 def test_func_and(self):
556 code = "def f(x):\n"
557 code += " x and x\n" * self.N
558 self.check_stack_size(code)
559
560
Raymond Hettinger8a99b502003-06-23 13:36:57 +0000561def test_main():
Antoine Pitrouab4a6912014-05-23 11:46:03 +0200562 test_support.run_unittest(__name__)
Tim Petersd507dab2001-08-30 20:51:59 +0000563
Raymond Hettinger8a99b502003-06-23 13:36:57 +0000564if __name__ == "__main__":
Antoine Pitrouab4a6912014-05-23 11:46:03 +0200565 unittest.main()