blob: 4bd2943b11333ac2e945c8887b8b623e3b6f1eb8 [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)
Anthony Baxterc2a5a632004-08-02 06:10:11 +000018 except parser.ParserError, why:
19 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]")
Neal Norwitzd3a91622006-04-12 05:27:46 +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_print(self):
89 self.check_suite("print")
90 self.check_suite("print 1")
91 self.check_suite("print 1,")
92 self.check_suite("print >>fp")
93 self.check_suite("print >>fp, 1")
94 self.check_suite("print >>fp, 1,")
Fred Drake79ca79d2000-08-21 22:30:53 +000095
Fred Drake58422e52001-06-04 03:56:24 +000096 def test_simple_expression(self):
97 # expr_stmt
98 self.check_suite("a")
Fred Drake79ca79d2000-08-21 22:30:53 +000099
Fred Drake58422e52001-06-04 03:56:24 +0000100 def test_simple_assignments(self):
101 self.check_suite("a = b")
102 self.check_suite("a = b = c = d = e")
Fred Drake28f739a2000-08-25 22:42:40 +0000103
Fred Drake58422e52001-06-04 03:56:24 +0000104 def test_simple_augmented_assignments(self):
105 self.check_suite("a += b")
106 self.check_suite("a -= b")
107 self.check_suite("a *= b")
108 self.check_suite("a /= b")
Michael W. Hudson5e83b7a2003-01-29 14:20:23 +0000109 self.check_suite("a //= b")
Fred Drake58422e52001-06-04 03:56:24 +0000110 self.check_suite("a %= b")
111 self.check_suite("a &= b")
112 self.check_suite("a |= b")
113 self.check_suite("a ^= b")
114 self.check_suite("a <<= b")
115 self.check_suite("a >>= b")
116 self.check_suite("a **= b")
Fred Drakee3fb18c2001-01-07 06:02:19 +0000117
Fred Drake58422e52001-06-04 03:56:24 +0000118 def test_function_defs(self):
119 self.check_suite("def f(): pass")
120 self.check_suite("def f(*args): pass")
121 self.check_suite("def f(*args, **kw): pass")
122 self.check_suite("def f(**kw): pass")
123 self.check_suite("def f(foo=bar): pass")
124 self.check_suite("def f(foo=bar, *args): pass")
125 self.check_suite("def f(foo=bar, *args, **kw): pass")
126 self.check_suite("def f(foo=bar, **kw): pass")
Fred Drakee3fb18c2001-01-07 06:02:19 +0000127
Fred Drake58422e52001-06-04 03:56:24 +0000128 self.check_suite("def f(a, b): pass")
129 self.check_suite("def f(a, b, *args): pass")
130 self.check_suite("def f(a, b, *args, **kw): pass")
131 self.check_suite("def f(a, b, **kw): pass")
132 self.check_suite("def f(a, b, foo=bar): pass")
133 self.check_suite("def f(a, b, foo=bar, *args): pass")
134 self.check_suite("def f(a, b, foo=bar, *args, **kw): pass")
135 self.check_suite("def f(a, b, foo=bar, **kw): pass")
Fred Drakee3fb18c2001-01-07 06:02:19 +0000136
Anthony Baxterc2a5a632004-08-02 06:10:11 +0000137 self.check_suite("@staticmethod\n"
138 "def f(): pass")
139 self.check_suite("@staticmethod\n"
140 "@funcattrs(x, y)\n"
141 "def f(): pass")
142 self.check_suite("@funcattrs()\n"
143 "def f(): pass")
144
Brett Cannonf4189912005-04-09 02:30:16 +0000145 def test_class_defs(self):
146 self.check_suite("class foo():pass")
Tim Peterse8906822005-04-20 17:45:13 +0000147
Fred Drake58422e52001-06-04 03:56:24 +0000148 def test_import_from_statement(self):
149 self.check_suite("from sys.path import *")
150 self.check_suite("from sys.path import dirname")
Anthony Baxter1a4ddae2004-08-31 10:07:13 +0000151 self.check_suite("from sys.path import (dirname)")
152 self.check_suite("from sys.path import (dirname,)")
Fred Drake58422e52001-06-04 03:56:24 +0000153 self.check_suite("from sys.path import dirname as my_dirname")
Anthony Baxter1a4ddae2004-08-31 10:07:13 +0000154 self.check_suite("from sys.path import (dirname as my_dirname)")
155 self.check_suite("from sys.path import (dirname as my_dirname,)")
Fred Drake58422e52001-06-04 03:56:24 +0000156 self.check_suite("from sys.path import dirname, basename")
Anthony Baxter1a4ddae2004-08-31 10:07:13 +0000157 self.check_suite("from sys.path import (dirname, basename)")
158 self.check_suite("from sys.path import (dirname, basename,)")
Fred Drake58422e52001-06-04 03:56:24 +0000159 self.check_suite(
160 "from sys.path import dirname as my_dirname, basename")
161 self.check_suite(
Anthony Baxter1a4ddae2004-08-31 10:07:13 +0000162 "from sys.path import (dirname as my_dirname, basename)")
163 self.check_suite(
164 "from sys.path import (dirname as my_dirname, basename,)")
165 self.check_suite(
Fred Drake58422e52001-06-04 03:56:24 +0000166 "from sys.path import dirname, basename as my_basename")
Anthony Baxter1a4ddae2004-08-31 10:07:13 +0000167 self.check_suite(
168 "from sys.path import (dirname, basename as my_basename)")
169 self.check_suite(
170 "from sys.path import (dirname, basename as my_basename,)")
Fred Drakee3fb18c2001-01-07 06:02:19 +0000171
Fred Drake58422e52001-06-04 03:56:24 +0000172 def test_basic_import_statement(self):
173 self.check_suite("import sys")
174 self.check_suite("import sys as system")
175 self.check_suite("import sys, math")
176 self.check_suite("import sys as system, math")
177 self.check_suite("import sys, math as my_math")
Fred Drake79ca79d2000-08-21 22:30:53 +0000178
Neal Norwitz9caf9c02003-02-10 01:54:06 +0000179 def test_pep263(self):
180 self.check_suite("# -*- coding: iso-8859-1 -*-\n"
181 "pass\n")
182
183 def test_assert(self):
184 self.check_suite("assert alo < ahi and blo < bhi\n")
185
Jeremy Hylton60e96f62006-08-22 20:46:00 +0000186 def test_position(self):
187 # An absolutely minimal test of position information. Better
188 # tests would be a big project.
189 code = "def f(x):\n return x + 1\n"
190 st1 = parser.suite(code)
191 st2 = st1.totuple(line_info=1, col_info=1)
192
193 def walk(tree):
194 node_type = tree[0]
195 next = tree[1]
196 if isinstance(next, tuple):
197 for elt in tree[1:]:
198 for x in walk(elt):
199 yield x
200 else:
201 yield tree
Tim Peters147f9ae2006-08-25 22:05:39 +0000202
Jeremy Hylton60e96f62006-08-22 20:46:00 +0000203 terminals = list(walk(st2))
204 self.assertEqual([
205 (1, 'def', 1, 0),
206 (1, 'f', 1, 4),
207 (7, '(', 1, 5),
208 (1, 'x', 1, 6),
209 (8, ')', 1, 7),
210 (11, ':', 1, 8),
211 (4, '', 1, 9),
212 (5, '', 2, -1),
213 (1, 'return', 2, 4),
214 (1, 'x', 2, 11),
215 (14, '+', 2, 13),
216 (2, '1', 2, 15),
217 (4, '', 2, 16),
218 (6, '', 2, -1),
219 (4, '', 2, -1),
220 (0, '', 2, -1)],
221 terminals)
222
223
Fred Drake79ca79d2000-08-21 22:30:53 +0000224#
225# Second, we take *invalid* trees and make sure we get ParserError
226# rejections for them.
227#
228
Fred Drake58422e52001-06-04 03:56:24 +0000229class IllegalSyntaxTestCase(unittest.TestCase):
Guido van Rossum32c2ae72002-08-22 19:45:32 +0000230
Fred Drake58422e52001-06-04 03:56:24 +0000231 def check_bad_tree(self, tree, label):
232 try:
Fred Drake6e4f2c02001-07-17 19:33:25 +0000233 parser.sequence2st(tree)
Fred Drake58422e52001-06-04 03:56:24 +0000234 except parser.ParserError:
235 pass
236 else:
237 self.fail("did not detect invalid tree for %r" % label)
Fred Drake79ca79d2000-08-21 22:30:53 +0000238
Fred Drake58422e52001-06-04 03:56:24 +0000239 def test_junk(self):
240 # not even remotely valid:
241 self.check_bad_tree((1, 2, 3), "<junk>")
242
Fred Drakecf580c72001-07-17 03:01:29 +0000243 def test_illegal_yield_1(self):
Guido van Rossum32c2ae72002-08-22 19:45:32 +0000244 # Illegal yield statement: def f(): return 1; yield 1
Fred Drakecf580c72001-07-17 03:01:29 +0000245 tree = \
246 (257,
247 (264,
248 (285,
249 (259,
250 (1, 'def'),
251 (1, 'f'),
252 (260, (7, '('), (8, ')')),
253 (11, ':'),
254 (291,
255 (4, ''),
256 (5, ''),
257 (264,
258 (265,
259 (266,
260 (272,
261 (275,
262 (1, 'return'),
263 (313,
264 (292,
265 (293,
266 (294,
267 (295,
268 (297,
269 (298,
270 (299,
271 (300,
272 (301,
273 (302, (303, (304, (305, (2, '1')))))))))))))))))),
274 (264,
275 (265,
276 (266,
277 (272,
278 (276,
279 (1, 'yield'),
280 (313,
281 (292,
282 (293,
283 (294,
284 (295,
285 (297,
286 (298,
287 (299,
288 (300,
289 (301,
290 (302,
291 (303, (304, (305, (2, '1')))))))))))))))))),
292 (4, ''))),
293 (6, ''))))),
294 (4, ''),
295 (0, ''))))
296 self.check_bad_tree(tree, "def f():\n return 1\n yield 1")
297
298 def test_illegal_yield_2(self):
Guido van Rossum32c2ae72002-08-22 19:45:32 +0000299 # Illegal return in generator: def f(): return 1; yield 1
Fred Drakecf580c72001-07-17 03:01:29 +0000300 tree = \
301 (257,
302 (264,
303 (265,
304 (266,
305 (278,
306 (1, 'from'),
307 (281, (1, '__future__')),
308 (1, 'import'),
309 (279, (1, 'generators')))),
310 (4, ''))),
311 (264,
312 (285,
313 (259,
314 (1, 'def'),
315 (1, 'f'),
316 (260, (7, '('), (8, ')')),
317 (11, ':'),
318 (291,
319 (4, ''),
320 (5, ''),
321 (264,
322 (265,
323 (266,
324 (272,
325 (275,
326 (1, 'return'),
327 (313,
328 (292,
329 (293,
330 (294,
331 (295,
332 (297,
333 (298,
334 (299,
335 (300,
336 (301,
337 (302, (303, (304, (305, (2, '1')))))))))))))))))),
338 (264,
339 (265,
340 (266,
341 (272,
342 (276,
343 (1, 'yield'),
344 (313,
345 (292,
346 (293,
347 (294,
348 (295,
349 (297,
350 (298,
351 (299,
352 (300,
353 (301,
354 (302,
355 (303, (304, (305, (2, '1')))))))))))))))))),
356 (4, ''))),
357 (6, ''))))),
358 (4, ''),
359 (0, ''))))
360 self.check_bad_tree(tree, "def f():\n return 1\n yield 1")
361
Fred Drake58422e52001-06-04 03:56:24 +0000362 def test_print_chevron_comma(self):
Guido van Rossum32c2ae72002-08-22 19:45:32 +0000363 # Illegal input: print >>fp,
Fred Drake58422e52001-06-04 03:56:24 +0000364 tree = \
365 (257,
366 (264,
367 (265,
368 (266,
369 (268,
370 (1, 'print'),
371 (35, '>>'),
372 (290,
373 (291,
374 (292,
375 (293,
376 (295,
377 (296,
378 (297,
379 (298, (299, (300, (301, (302, (303, (1, 'fp')))))))))))))),
380 (12, ','))),
381 (4, ''))),
382 (0, ''))
383 self.check_bad_tree(tree, "print >>fp,")
384
385 def test_a_comma_comma_c(self):
Guido van Rossum32c2ae72002-08-22 19:45:32 +0000386 # Illegal input: a,,c
Fred Drake58422e52001-06-04 03:56:24 +0000387 tree = \
388 (258,
389 (311,
390 (290,
391 (291,
392 (292,
393 (293,
394 (295,
395 (296,
396 (297,
397 (298, (299, (300, (301, (302, (303, (1, 'a')))))))))))))),
398 (12, ','),
399 (12, ','),
400 (290,
401 (291,
402 (292,
403 (293,
404 (295,
405 (296,
406 (297,
407 (298, (299, (300, (301, (302, (303, (1, 'c'))))))))))))))),
408 (4, ''),
409 (0, ''))
410 self.check_bad_tree(tree, "a,,c")
411
412 def test_illegal_operator(self):
Guido van Rossum32c2ae72002-08-22 19:45:32 +0000413 # Illegal input: a $= b
Fred Drake58422e52001-06-04 03:56:24 +0000414 tree = \
415 (257,
416 (264,
417 (265,
418 (266,
419 (267,
420 (312,
421 (291,
422 (292,
423 (293,
424 (294,
425 (296,
426 (297,
427 (298,
428 (299,
429 (300, (301, (302, (303, (304, (1, 'a'))))))))))))))),
430 (268, (37, '$=')),
431 (312,
432 (291,
433 (292,
434 (293,
435 (294,
436 (296,
437 (297,
438 (298,
439 (299,
440 (300, (301, (302, (303, (304, (1, 'b'))))))))))))))))),
441 (4, ''))),
442 (0, ''))
443 self.check_bad_tree(tree, "a $= b")
Fred Drake79ca79d2000-08-21 22:30:53 +0000444
Neal Norwitz9caf9c02003-02-10 01:54:06 +0000445 def test_malformed_global(self):
446 #doesn't have global keyword in ast
447 tree = (257,
448 (264,
449 (265,
450 (266,
451 (282, (1, 'foo'))), (4, ''))),
452 (4, ''),
Tim Petersf2715e02003-02-19 02:35:07 +0000453 (0, ''))
Neal Norwitz9caf9c02003-02-10 01:54:06 +0000454 self.check_bad_tree(tree, "malformed global ast")
Fred Drake79ca79d2000-08-21 22:30:53 +0000455
Jeremy Hylton3e0055f2005-10-20 19:59:25 +0000456
457class CompileTestCase(unittest.TestCase):
458
459 # These tests are very minimal. :-(
460
461 def test_compile_expr(self):
462 st = parser.expr('2 + 3')
463 code = parser.compilest(st)
464 self.assertEquals(eval(code), 5)
465
466 def test_compile_suite(self):
467 st = parser.suite('x = 2; y = x + 3')
468 code = parser.compilest(st)
469 globs = {}
470 exec code in globs
471 self.assertEquals(globs['y'], 5)
472
473 def test_compile_error(self):
474 st = parser.suite('1 = 3 + 4')
475 self.assertRaises(SyntaxError, parser.compilest, st)
476
Fred Drake2e2be372001-09-20 21:33:42 +0000477def test_main():
Walter Dörwald21d3a322003-05-01 17:45:56 +0000478 test_support.run_unittest(
479 RoundtripLegalSyntaxTestCase,
Jeremy Hylton3e0055f2005-10-20 19:59:25 +0000480 IllegalSyntaxTestCase,
481 CompileTestCase,
Walter Dörwald21d3a322003-05-01 17:45:56 +0000482 )
Fred Drake2e2be372001-09-20 21:33:42 +0000483
484
485if __name__ == "__main__":
486 test_main()