blob: 3bebe7e6ee1f1274a08ebb3480658474874fa977 [file] [log] [blame]
Fred Drake79ca79d2000-08-21 22:30:53 +00001import parser
Fred Drake58422e52001-06-04 03:56:24 +00002import unittest
Barry Warsaw04f357c2002-07-23 19:04:11 +00003from test import test_support
Fred Drake79ca79d2000-08-21 22:30:53 +00004
5#
6# First, we test that we can generate trees from valid source fragments,
7# and that these valid trees are indeed allowed by the tree-loading side
8# of the parser module.
9#
10
Fred Drake58422e52001-06-04 03:56:24 +000011class RoundtripLegalSyntaxTestCase(unittest.TestCase):
Guido van Rossum32c2ae72002-08-22 19:45:32 +000012
Fred Drake58422e52001-06-04 03:56:24 +000013 def roundtrip(self, f, s):
14 st1 = f(s)
15 t = st1.totuple()
16 try:
Fred Drake6e4f2c02001-07-17 19:33:25 +000017 st2 = parser.sequence2st(t)
Guido van Rossumb940e112007-01-10 16:19:56 +000018 except parser.ParserError as why:
Anthony Baxterc2a5a632004-08-02 06:10:11 +000019 self.fail("could not roundtrip %r: %s" % (s, why))
Fred Drake79ca79d2000-08-21 22:30:53 +000020
Fred Drake58422e52001-06-04 03:56:24 +000021 self.assertEquals(t, st2.totuple(),
22 "could not re-generate syntax tree")
Fred Drake28f739a2000-08-25 22:42:40 +000023
Fred Drake58422e52001-06-04 03:56:24 +000024 def check_expr(self, s):
25 self.roundtrip(parser.expr, s)
Fred Drake28f739a2000-08-25 22:42:40 +000026
Fred Drake58422e52001-06-04 03:56:24 +000027 def check_suite(self, s):
28 self.roundtrip(parser.suite, s)
Fred Drake28f739a2000-08-25 22:42:40 +000029
Fred Drakecf580c72001-07-17 03:01:29 +000030 def test_yield_statement(self):
Tim Peters496563a2002-04-01 00:28:59 +000031 self.check_suite("def f(): yield 1")
Phillip J. Eby0d6615f2005-08-02 00:46:46 +000032 self.check_suite("def f(): yield")
33 self.check_suite("def f(): x += yield")
34 self.check_suite("def f(): x = yield 1")
35 self.check_suite("def f(): x = y = yield 1")
36 self.check_suite("def f(): x = yield")
37 self.check_suite("def f(): x = y = yield")
38 self.check_suite("def f(): 1 + (yield)*2")
39 self.check_suite("def f(): (yield 1)*2")
Tim Peters496563a2002-04-01 00:28:59 +000040 self.check_suite("def f(): return; yield 1")
41 self.check_suite("def f(): yield 1; return")
42 self.check_suite("def f():\n"
Fred Drakecf580c72001-07-17 03:01:29 +000043 " for x in range(30):\n"
44 " yield x\n")
Phillip J. Eby0d6615f2005-08-02 00:46:46 +000045 self.check_suite("def f():\n"
46 " if (yield):\n"
47 " yield x\n")
Fred Drakecf580c72001-07-17 03:01:29 +000048
Fred Drake58422e52001-06-04 03:56:24 +000049 def test_expressions(self):
50 self.check_expr("foo(1)")
51 self.check_expr("[1, 2, 3]")
52 self.check_expr("[x**3 for x in range(20)]")
53 self.check_expr("[x**3 for x in range(20) if x % 3]")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000054 self.check_expr("[x**3 for x in range(20) if x % 2 if x % 3]")
55 self.check_expr("list(x**3 for x in range(20))")
56 self.check_expr("list(x**3 for x in range(20) if x % 3)")
57 self.check_expr("list(x**3 for x in range(20) if x % 2 if x % 3)")
Fred Drake58422e52001-06-04 03:56:24 +000058 self.check_expr("foo(*args)")
59 self.check_expr("foo(*args, **kw)")
60 self.check_expr("foo(**kw)")
61 self.check_expr("foo(key=value)")
62 self.check_expr("foo(key=value, *args)")
63 self.check_expr("foo(key=value, *args, **kw)")
64 self.check_expr("foo(key=value, **kw)")
65 self.check_expr("foo(a, b, c, *args)")
66 self.check_expr("foo(a, b, c, *args, **kw)")
67 self.check_expr("foo(a, b, c, **kw)")
68 self.check_expr("foo + bar")
Michael W. Hudson5e83b7a2003-01-29 14:20:23 +000069 self.check_expr("foo - bar")
70 self.check_expr("foo * bar")
71 self.check_expr("foo / bar")
72 self.check_expr("foo // bar")
Fred Drake58422e52001-06-04 03:56:24 +000073 self.check_expr("lambda: 0")
74 self.check_expr("lambda x: 0")
75 self.check_expr("lambda *y: 0")
76 self.check_expr("lambda *y, **z: 0")
77 self.check_expr("lambda **z: 0")
78 self.check_expr("lambda x, y: 0")
79 self.check_expr("lambda foo=bar: 0")
80 self.check_expr("lambda foo=bar, spaz=nifty+spit: 0")
81 self.check_expr("lambda foo=bar, **z: 0")
82 self.check_expr("lambda foo=bar, blaz=blat+2, **z: 0")
83 self.check_expr("lambda foo=bar, blaz=blat+2, *y, **z: 0")
84 self.check_expr("lambda x, *y, **z: 0")
Raymond Hettinger354433a2004-05-19 08:20:33 +000085 self.check_expr("(x for x in range(10))")
86 self.check_expr("foo(x for x in range(10))")
Fred Drake79ca79d2000-08-21 22:30:53 +000087
Fred Drake58422e52001-06-04 03:56:24 +000088 def test_simple_expression(self):
89 # expr_stmt
90 self.check_suite("a")
Fred Drake79ca79d2000-08-21 22:30:53 +000091
Fred Drake58422e52001-06-04 03:56:24 +000092 def test_simple_assignments(self):
93 self.check_suite("a = b")
94 self.check_suite("a = b = c = d = e")
Fred Drake28f739a2000-08-25 22:42:40 +000095
Fred Drake58422e52001-06-04 03:56:24 +000096 def test_simple_augmented_assignments(self):
97 self.check_suite("a += b")
98 self.check_suite("a -= b")
99 self.check_suite("a *= b")
100 self.check_suite("a /= b")
Michael W. Hudson5e83b7a2003-01-29 14:20:23 +0000101 self.check_suite("a //= b")
Fred Drake58422e52001-06-04 03:56:24 +0000102 self.check_suite("a %= b")
103 self.check_suite("a &= b")
104 self.check_suite("a |= b")
105 self.check_suite("a ^= b")
106 self.check_suite("a <<= b")
107 self.check_suite("a >>= b")
108 self.check_suite("a **= b")
Fred Drakee3fb18c2001-01-07 06:02:19 +0000109
Fred Drake58422e52001-06-04 03:56:24 +0000110 def test_function_defs(self):
111 self.check_suite("def f(): pass")
112 self.check_suite("def f(*args): pass")
113 self.check_suite("def f(*args, **kw): pass")
114 self.check_suite("def f(**kw): pass")
115 self.check_suite("def f(foo=bar): pass")
116 self.check_suite("def f(foo=bar, *args): pass")
117 self.check_suite("def f(foo=bar, *args, **kw): pass")
118 self.check_suite("def f(foo=bar, **kw): pass")
Fred Drakee3fb18c2001-01-07 06:02:19 +0000119
Fred Drake58422e52001-06-04 03:56:24 +0000120 self.check_suite("def f(a, b): pass")
121 self.check_suite("def f(a, b, *args): pass")
122 self.check_suite("def f(a, b, *args, **kw): pass")
123 self.check_suite("def f(a, b, **kw): pass")
124 self.check_suite("def f(a, b, foo=bar): pass")
125 self.check_suite("def f(a, b, foo=bar, *args): pass")
126 self.check_suite("def f(a, b, foo=bar, *args, **kw): pass")
127 self.check_suite("def f(a, b, foo=bar, **kw): pass")
Fred Drakee3fb18c2001-01-07 06:02:19 +0000128
Anthony Baxterc2a5a632004-08-02 06:10:11 +0000129 self.check_suite("@staticmethod\n"
130 "def f(): pass")
131 self.check_suite("@staticmethod\n"
132 "@funcattrs(x, y)\n"
133 "def f(): pass")
134 self.check_suite("@funcattrs()\n"
135 "def f(): pass")
136
Brett Cannonf4189912005-04-09 02:30:16 +0000137 def test_class_defs(self):
138 self.check_suite("class foo():pass")
Guido van Rossumfc158e22007-11-15 19:17:28 +0000139 self.check_suite("class foo(object):pass")
Tim Peterse8906822005-04-20 17:45:13 +0000140
Fred Drake58422e52001-06-04 03:56:24 +0000141 def test_import_from_statement(self):
142 self.check_suite("from sys.path import *")
143 self.check_suite("from sys.path import dirname")
Anthony Baxter1a4ddae2004-08-31 10:07:13 +0000144 self.check_suite("from sys.path import (dirname)")
145 self.check_suite("from sys.path import (dirname,)")
Fred Drake58422e52001-06-04 03:56:24 +0000146 self.check_suite("from sys.path import dirname as my_dirname")
Anthony Baxter1a4ddae2004-08-31 10:07:13 +0000147 self.check_suite("from sys.path import (dirname as my_dirname)")
148 self.check_suite("from sys.path import (dirname as my_dirname,)")
Fred Drake58422e52001-06-04 03:56:24 +0000149 self.check_suite("from sys.path import dirname, basename")
Anthony Baxter1a4ddae2004-08-31 10:07:13 +0000150 self.check_suite("from sys.path import (dirname, basename)")
151 self.check_suite("from sys.path import (dirname, basename,)")
Fred Drake58422e52001-06-04 03:56:24 +0000152 self.check_suite(
153 "from sys.path import dirname as my_dirname, basename")
154 self.check_suite(
Anthony Baxter1a4ddae2004-08-31 10:07:13 +0000155 "from sys.path import (dirname as my_dirname, basename)")
156 self.check_suite(
157 "from sys.path import (dirname as my_dirname, basename,)")
158 self.check_suite(
Fred Drake58422e52001-06-04 03:56:24 +0000159 "from sys.path import dirname, basename as my_basename")
Anthony Baxter1a4ddae2004-08-31 10:07:13 +0000160 self.check_suite(
161 "from sys.path import (dirname, basename as my_basename)")
162 self.check_suite(
163 "from sys.path import (dirname, basename as my_basename,)")
Fred Drakee3fb18c2001-01-07 06:02:19 +0000164
Fred Drake58422e52001-06-04 03:56:24 +0000165 def test_basic_import_statement(self):
166 self.check_suite("import sys")
167 self.check_suite("import sys as system")
168 self.check_suite("import sys, math")
169 self.check_suite("import sys as system, math")
170 self.check_suite("import sys, math as my_math")
Fred Drake79ca79d2000-08-21 22:30:53 +0000171
Neal Norwitz9caf9c02003-02-10 01:54:06 +0000172 def test_pep263(self):
173 self.check_suite("# -*- coding: iso-8859-1 -*-\n"
174 "pass\n")
175
176 def test_assert(self):
177 self.check_suite("assert alo < ahi and blo < bhi\n")
178
Thomas Wouters89f507f2006-12-13 04:49:30 +0000179 def test_position(self):
180 # An absolutely minimal test of position information. Better
181 # tests would be a big project.
182 code = "def f(x):\n return x + 1\n"
183 st1 = parser.suite(code)
184 st2 = st1.totuple(line_info=1, col_info=1)
185
186 def walk(tree):
187 node_type = tree[0]
188 next = tree[1]
189 if isinstance(next, tuple):
190 for elt in tree[1:]:
191 for x in walk(elt):
192 yield x
193 else:
194 yield tree
195
196 terminals = list(walk(st2))
197 self.assertEqual([
198 (1, 'def', 1, 0),
199 (1, 'f', 1, 4),
200 (7, '(', 1, 5),
201 (1, 'x', 1, 6),
202 (8, ')', 1, 7),
203 (11, ':', 1, 8),
204 (4, '', 1, 9),
205 (5, '', 2, -1),
206 (1, 'return', 2, 4),
207 (1, 'x', 2, 11),
208 (14, '+', 2, 13),
209 (2, '1', 2, 15),
210 (4, '', 2, 16),
211 (6, '', 2, -1),
212 (4, '', 2, -1),
213 (0, '', 2, -1)],
214 terminals)
215
216
Fred Drake79ca79d2000-08-21 22:30:53 +0000217#
218# Second, we take *invalid* trees and make sure we get ParserError
219# rejections for them.
220#
221
Fred Drake58422e52001-06-04 03:56:24 +0000222class IllegalSyntaxTestCase(unittest.TestCase):
Guido van Rossum32c2ae72002-08-22 19:45:32 +0000223
Fred Drake58422e52001-06-04 03:56:24 +0000224 def check_bad_tree(self, tree, label):
225 try:
Fred Drake6e4f2c02001-07-17 19:33:25 +0000226 parser.sequence2st(tree)
Fred Drake58422e52001-06-04 03:56:24 +0000227 except parser.ParserError:
228 pass
229 else:
230 self.fail("did not detect invalid tree for %r" % label)
Fred Drake79ca79d2000-08-21 22:30:53 +0000231
Fred Drake58422e52001-06-04 03:56:24 +0000232 def test_junk(self):
233 # not even remotely valid:
234 self.check_bad_tree((1, 2, 3), "<junk>")
235
Fred Drakecf580c72001-07-17 03:01:29 +0000236 def test_illegal_yield_1(self):
Guido van Rossum32c2ae72002-08-22 19:45:32 +0000237 # Illegal yield statement: def f(): return 1; yield 1
Fred Drakecf580c72001-07-17 03:01:29 +0000238 tree = \
239 (257,
240 (264,
241 (285,
242 (259,
243 (1, 'def'),
244 (1, 'f'),
245 (260, (7, '('), (8, ')')),
246 (11, ':'),
247 (291,
248 (4, ''),
249 (5, ''),
250 (264,
251 (265,
252 (266,
253 (272,
254 (275,
255 (1, 'return'),
256 (313,
257 (292,
258 (293,
259 (294,
260 (295,
261 (297,
262 (298,
263 (299,
264 (300,
265 (301,
266 (302, (303, (304, (305, (2, '1')))))))))))))))))),
267 (264,
268 (265,
269 (266,
270 (272,
271 (276,
272 (1, 'yield'),
273 (313,
274 (292,
275 (293,
276 (294,
277 (295,
278 (297,
279 (298,
280 (299,
281 (300,
282 (301,
283 (302,
284 (303, (304, (305, (2, '1')))))))))))))))))),
285 (4, ''))),
286 (6, ''))))),
287 (4, ''),
288 (0, ''))))
289 self.check_bad_tree(tree, "def f():\n return 1\n yield 1")
290
291 def test_illegal_yield_2(self):
Guido van Rossum32c2ae72002-08-22 19:45:32 +0000292 # Illegal return in generator: def f(): return 1; yield 1
Fred Drakecf580c72001-07-17 03:01:29 +0000293 tree = \
294 (257,
295 (264,
296 (265,
297 (266,
298 (278,
299 (1, 'from'),
300 (281, (1, '__future__')),
301 (1, 'import'),
302 (279, (1, 'generators')))),
303 (4, ''))),
304 (264,
305 (285,
306 (259,
307 (1, 'def'),
308 (1, 'f'),
309 (260, (7, '('), (8, ')')),
310 (11, ':'),
311 (291,
312 (4, ''),
313 (5, ''),
314 (264,
315 (265,
316 (266,
317 (272,
318 (275,
319 (1, 'return'),
320 (313,
321 (292,
322 (293,
323 (294,
324 (295,
325 (297,
326 (298,
327 (299,
328 (300,
329 (301,
330 (302, (303, (304, (305, (2, '1')))))))))))))))))),
331 (264,
332 (265,
333 (266,
334 (272,
335 (276,
336 (1, 'yield'),
337 (313,
338 (292,
339 (293,
340 (294,
341 (295,
342 (297,
343 (298,
344 (299,
345 (300,
346 (301,
347 (302,
348 (303, (304, (305, (2, '1')))))))))))))))))),
349 (4, ''))),
350 (6, ''))))),
351 (4, ''),
352 (0, ''))))
353 self.check_bad_tree(tree, "def f():\n return 1\n yield 1")
354
Fred Drake58422e52001-06-04 03:56:24 +0000355 def test_a_comma_comma_c(self):
Guido van Rossum32c2ae72002-08-22 19:45:32 +0000356 # Illegal input: a,,c
Fred Drake58422e52001-06-04 03:56:24 +0000357 tree = \
358 (258,
359 (311,
360 (290,
361 (291,
362 (292,
363 (293,
364 (295,
365 (296,
366 (297,
367 (298, (299, (300, (301, (302, (303, (1, 'a')))))))))))))),
368 (12, ','),
369 (12, ','),
370 (290,
371 (291,
372 (292,
373 (293,
374 (295,
375 (296,
376 (297,
377 (298, (299, (300, (301, (302, (303, (1, 'c'))))))))))))))),
378 (4, ''),
379 (0, ''))
380 self.check_bad_tree(tree, "a,,c")
381
382 def test_illegal_operator(self):
Guido van Rossum32c2ae72002-08-22 19:45:32 +0000383 # Illegal input: a $= b
Fred Drake58422e52001-06-04 03:56:24 +0000384 tree = \
385 (257,
386 (264,
387 (265,
388 (266,
389 (267,
390 (312,
391 (291,
392 (292,
393 (293,
394 (294,
395 (296,
396 (297,
397 (298,
398 (299,
399 (300, (301, (302, (303, (304, (1, 'a'))))))))))))))),
400 (268, (37, '$=')),
401 (312,
402 (291,
403 (292,
404 (293,
405 (294,
406 (296,
407 (297,
408 (298,
409 (299,
410 (300, (301, (302, (303, (304, (1, 'b'))))))))))))))))),
411 (4, ''))),
412 (0, ''))
413 self.check_bad_tree(tree, "a $= b")
Fred Drake79ca79d2000-08-21 22:30:53 +0000414
Neal Norwitz9caf9c02003-02-10 01:54:06 +0000415 def test_malformed_global(self):
416 #doesn't have global keyword in ast
417 tree = (257,
418 (264,
419 (265,
420 (266,
421 (282, (1, 'foo'))), (4, ''))),
422 (4, ''),
Tim Petersf2715e02003-02-19 02:35:07 +0000423 (0, ''))
Neal Norwitz9caf9c02003-02-10 01:54:06 +0000424 self.check_bad_tree(tree, "malformed global ast")
Fred Drake79ca79d2000-08-21 22:30:53 +0000425
Jeremy Hylton3e0055f2005-10-20 19:59:25 +0000426
427class CompileTestCase(unittest.TestCase):
428
429 # These tests are very minimal. :-(
430
431 def test_compile_expr(self):
432 st = parser.expr('2 + 3')
433 code = parser.compilest(st)
434 self.assertEquals(eval(code), 5)
435
436 def test_compile_suite(self):
437 st = parser.suite('x = 2; y = x + 3')
438 code = parser.compilest(st)
439 globs = {}
Georg Brandl7cae87c2006-09-06 06:51:57 +0000440 exec(code, globs)
Jeremy Hylton3e0055f2005-10-20 19:59:25 +0000441 self.assertEquals(globs['y'], 5)
442
443 def test_compile_error(self):
444 st = parser.suite('1 = 3 + 4')
445 self.assertRaises(SyntaxError, parser.compilest, st)
446
Guido van Rossumb5a755e2007-07-18 18:15:48 +0000447 def test_compile_badunicode(self):
Guido van Rossum7eb6ca52007-07-18 21:00:22 +0000448 st = parser.suite('a = "\\U12345678"')
Guido van Rossumb5a755e2007-07-18 18:15:48 +0000449 self.assertRaises(SyntaxError, parser.compilest, st)
Guido van Rossum7eb6ca52007-07-18 21:00:22 +0000450 st = parser.suite('a = "\\u1"')
Guido van Rossumb5a755e2007-07-18 18:15:48 +0000451 self.assertRaises(SyntaxError, parser.compilest, st)
452
Fred Drake2e2be372001-09-20 21:33:42 +0000453def test_main():
Walter Dörwald21d3a322003-05-01 17:45:56 +0000454 test_support.run_unittest(
455 RoundtripLegalSyntaxTestCase,
Jeremy Hylton3e0055f2005-10-20 19:59:25 +0000456 IllegalSyntaxTestCase,
457 CompileTestCase,
Walter Dörwald21d3a322003-05-01 17:45:56 +0000458 )
Fred Drake2e2be372001-09-20 21:33:42 +0000459
460
461if __name__ == "__main__":
462 test_main()