blob: 771fe9db96898dada6df679cc9a9148225630127 [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]")
54 self.check_expr("foo(*args)")
55 self.check_expr("foo(*args, **kw)")
56 self.check_expr("foo(**kw)")
57 self.check_expr("foo(key=value)")
58 self.check_expr("foo(key=value, *args)")
59 self.check_expr("foo(key=value, *args, **kw)")
60 self.check_expr("foo(key=value, **kw)")
61 self.check_expr("foo(a, b, c, *args)")
62 self.check_expr("foo(a, b, c, *args, **kw)")
63 self.check_expr("foo(a, b, c, **kw)")
64 self.check_expr("foo + bar")
Michael W. Hudson5e83b7a2003-01-29 14:20:23 +000065 self.check_expr("foo - bar")
66 self.check_expr("foo * bar")
67 self.check_expr("foo / bar")
68 self.check_expr("foo // bar")
Fred Drake58422e52001-06-04 03:56:24 +000069 self.check_expr("lambda: 0")
70 self.check_expr("lambda x: 0")
71 self.check_expr("lambda *y: 0")
72 self.check_expr("lambda *y, **z: 0")
73 self.check_expr("lambda **z: 0")
74 self.check_expr("lambda x, y: 0")
75 self.check_expr("lambda foo=bar: 0")
76 self.check_expr("lambda foo=bar, spaz=nifty+spit: 0")
77 self.check_expr("lambda foo=bar, **z: 0")
78 self.check_expr("lambda foo=bar, blaz=blat+2, **z: 0")
79 self.check_expr("lambda foo=bar, blaz=blat+2, *y, **z: 0")
80 self.check_expr("lambda x, *y, **z: 0")
Raymond Hettinger354433a2004-05-19 08:20:33 +000081 self.check_expr("(x for x in range(10))")
82 self.check_expr("foo(x for x in range(10))")
Fred Drake79ca79d2000-08-21 22:30:53 +000083
Fred Drake58422e52001-06-04 03:56:24 +000084 def test_print(self):
85 self.check_suite("print")
86 self.check_suite("print 1")
87 self.check_suite("print 1,")
88 self.check_suite("print >>fp")
89 self.check_suite("print >>fp, 1")
90 self.check_suite("print >>fp, 1,")
Fred Drake79ca79d2000-08-21 22:30:53 +000091
Fred Drake58422e52001-06-04 03:56:24 +000092 def test_simple_expression(self):
93 # expr_stmt
94 self.check_suite("a")
Fred Drake79ca79d2000-08-21 22:30:53 +000095
Fred Drake58422e52001-06-04 03:56:24 +000096 def test_simple_assignments(self):
97 self.check_suite("a = b")
98 self.check_suite("a = b = c = d = e")
Fred Drake28f739a2000-08-25 22:42:40 +000099
Fred Drake58422e52001-06-04 03:56:24 +0000100 def test_simple_augmented_assignments(self):
101 self.check_suite("a += b")
102 self.check_suite("a -= b")
103 self.check_suite("a *= b")
104 self.check_suite("a /= b")
Michael W. Hudson5e83b7a2003-01-29 14:20:23 +0000105 self.check_suite("a //= b")
Fred Drake58422e52001-06-04 03:56:24 +0000106 self.check_suite("a %= b")
107 self.check_suite("a &= b")
108 self.check_suite("a |= b")
109 self.check_suite("a ^= b")
110 self.check_suite("a <<= b")
111 self.check_suite("a >>= b")
112 self.check_suite("a **= b")
Fred Drakee3fb18c2001-01-07 06:02:19 +0000113
Fred Drake58422e52001-06-04 03:56:24 +0000114 def test_function_defs(self):
115 self.check_suite("def f(): pass")
116 self.check_suite("def f(*args): pass")
117 self.check_suite("def f(*args, **kw): pass")
118 self.check_suite("def f(**kw): pass")
119 self.check_suite("def f(foo=bar): pass")
120 self.check_suite("def f(foo=bar, *args): pass")
121 self.check_suite("def f(foo=bar, *args, **kw): pass")
122 self.check_suite("def f(foo=bar, **kw): pass")
Fred Drakee3fb18c2001-01-07 06:02:19 +0000123
Fred Drake58422e52001-06-04 03:56:24 +0000124 self.check_suite("def f(a, b): pass")
125 self.check_suite("def f(a, b, *args): pass")
126 self.check_suite("def f(a, b, *args, **kw): pass")
127 self.check_suite("def f(a, b, **kw): pass")
128 self.check_suite("def f(a, b, foo=bar): pass")
129 self.check_suite("def f(a, b, foo=bar, *args): pass")
130 self.check_suite("def f(a, b, foo=bar, *args, **kw): pass")
131 self.check_suite("def f(a, b, foo=bar, **kw): pass")
Fred Drakee3fb18c2001-01-07 06:02:19 +0000132
Anthony Baxterc2a5a632004-08-02 06:10:11 +0000133 self.check_suite("@staticmethod\n"
134 "def f(): pass")
135 self.check_suite("@staticmethod\n"
136 "@funcattrs(x, y)\n"
137 "def f(): pass")
138 self.check_suite("@funcattrs()\n"
139 "def f(): pass")
140
Brett Cannonf4189912005-04-09 02:30:16 +0000141 def test_class_defs(self):
142 self.check_suite("class foo():pass")
Tim Peterse8906822005-04-20 17:45:13 +0000143
Fred Drake58422e52001-06-04 03:56:24 +0000144 def test_import_from_statement(self):
145 self.check_suite("from sys.path import *")
146 self.check_suite("from sys.path import dirname")
Anthony Baxter1a4ddae2004-08-31 10:07:13 +0000147 self.check_suite("from sys.path import (dirname)")
148 self.check_suite("from sys.path import (dirname,)")
Fred Drake58422e52001-06-04 03:56:24 +0000149 self.check_suite("from sys.path import dirname as my_dirname")
Anthony Baxter1a4ddae2004-08-31 10:07:13 +0000150 self.check_suite("from sys.path import (dirname as my_dirname)")
151 self.check_suite("from sys.path import (dirname as my_dirname,)")
Fred Drake58422e52001-06-04 03:56:24 +0000152 self.check_suite("from sys.path import dirname, basename")
Anthony Baxter1a4ddae2004-08-31 10:07:13 +0000153 self.check_suite("from sys.path import (dirname, basename)")
154 self.check_suite("from sys.path import (dirname, basename,)")
Fred Drake58422e52001-06-04 03:56:24 +0000155 self.check_suite(
156 "from sys.path import dirname as my_dirname, basename")
157 self.check_suite(
Anthony Baxter1a4ddae2004-08-31 10:07:13 +0000158 "from sys.path import (dirname as my_dirname, basename)")
159 self.check_suite(
160 "from sys.path import (dirname as my_dirname, basename,)")
161 self.check_suite(
Fred Drake58422e52001-06-04 03:56:24 +0000162 "from sys.path import dirname, basename as my_basename")
Anthony Baxter1a4ddae2004-08-31 10:07:13 +0000163 self.check_suite(
164 "from sys.path import (dirname, basename as my_basename)")
165 self.check_suite(
166 "from sys.path import (dirname, basename as my_basename,)")
Fred Drakee3fb18c2001-01-07 06:02:19 +0000167
Fred Drake58422e52001-06-04 03:56:24 +0000168 def test_basic_import_statement(self):
169 self.check_suite("import sys")
170 self.check_suite("import sys as system")
171 self.check_suite("import sys, math")
172 self.check_suite("import sys as system, math")
173 self.check_suite("import sys, math as my_math")
Fred Drake79ca79d2000-08-21 22:30:53 +0000174
Neal Norwitz9caf9c02003-02-10 01:54:06 +0000175 def test_pep263(self):
176 self.check_suite("# -*- coding: iso-8859-1 -*-\n"
177 "pass\n")
178
179 def test_assert(self):
180 self.check_suite("assert alo < ahi and blo < bhi\n")
181
Fred Drake79ca79d2000-08-21 22:30:53 +0000182#
183# Second, we take *invalid* trees and make sure we get ParserError
184# rejections for them.
185#
186
Fred Drake58422e52001-06-04 03:56:24 +0000187class IllegalSyntaxTestCase(unittest.TestCase):
Guido van Rossum32c2ae72002-08-22 19:45:32 +0000188
Fred Drake58422e52001-06-04 03:56:24 +0000189 def check_bad_tree(self, tree, label):
190 try:
Fred Drake6e4f2c02001-07-17 19:33:25 +0000191 parser.sequence2st(tree)
Fred Drake58422e52001-06-04 03:56:24 +0000192 except parser.ParserError:
193 pass
194 else:
195 self.fail("did not detect invalid tree for %r" % label)
Fred Drake79ca79d2000-08-21 22:30:53 +0000196
Fred Drake58422e52001-06-04 03:56:24 +0000197 def test_junk(self):
198 # not even remotely valid:
199 self.check_bad_tree((1, 2, 3), "<junk>")
200
Fred Drakecf580c72001-07-17 03:01:29 +0000201 def test_illegal_yield_1(self):
Guido van Rossum32c2ae72002-08-22 19:45:32 +0000202 # Illegal yield statement: def f(): return 1; yield 1
Fred Drakecf580c72001-07-17 03:01:29 +0000203 tree = \
204 (257,
205 (264,
206 (285,
207 (259,
208 (1, 'def'),
209 (1, 'f'),
210 (260, (7, '('), (8, ')')),
211 (11, ':'),
212 (291,
213 (4, ''),
214 (5, ''),
215 (264,
216 (265,
217 (266,
218 (272,
219 (275,
220 (1, 'return'),
221 (313,
222 (292,
223 (293,
224 (294,
225 (295,
226 (297,
227 (298,
228 (299,
229 (300,
230 (301,
231 (302, (303, (304, (305, (2, '1')))))))))))))))))),
232 (264,
233 (265,
234 (266,
235 (272,
236 (276,
237 (1, 'yield'),
238 (313,
239 (292,
240 (293,
241 (294,
242 (295,
243 (297,
244 (298,
245 (299,
246 (300,
247 (301,
248 (302,
249 (303, (304, (305, (2, '1')))))))))))))))))),
250 (4, ''))),
251 (6, ''))))),
252 (4, ''),
253 (0, ''))))
254 self.check_bad_tree(tree, "def f():\n return 1\n yield 1")
255
256 def test_illegal_yield_2(self):
Guido van Rossum32c2ae72002-08-22 19:45:32 +0000257 # Illegal return in generator: def f(): return 1; yield 1
Fred Drakecf580c72001-07-17 03:01:29 +0000258 tree = \
259 (257,
260 (264,
261 (265,
262 (266,
263 (278,
264 (1, 'from'),
265 (281, (1, '__future__')),
266 (1, 'import'),
267 (279, (1, 'generators')))),
268 (4, ''))),
269 (264,
270 (285,
271 (259,
272 (1, 'def'),
273 (1, 'f'),
274 (260, (7, '('), (8, ')')),
275 (11, ':'),
276 (291,
277 (4, ''),
278 (5, ''),
279 (264,
280 (265,
281 (266,
282 (272,
283 (275,
284 (1, 'return'),
285 (313,
286 (292,
287 (293,
288 (294,
289 (295,
290 (297,
291 (298,
292 (299,
293 (300,
294 (301,
295 (302, (303, (304, (305, (2, '1')))))))))))))))))),
296 (264,
297 (265,
298 (266,
299 (272,
300 (276,
301 (1, 'yield'),
302 (313,
303 (292,
304 (293,
305 (294,
306 (295,
307 (297,
308 (298,
309 (299,
310 (300,
311 (301,
312 (302,
313 (303, (304, (305, (2, '1')))))))))))))))))),
314 (4, ''))),
315 (6, ''))))),
316 (4, ''),
317 (0, ''))))
318 self.check_bad_tree(tree, "def f():\n return 1\n yield 1")
319
Fred Drake58422e52001-06-04 03:56:24 +0000320 def test_print_chevron_comma(self):
Guido van Rossum32c2ae72002-08-22 19:45:32 +0000321 # Illegal input: print >>fp,
Fred Drake58422e52001-06-04 03:56:24 +0000322 tree = \
323 (257,
324 (264,
325 (265,
326 (266,
327 (268,
328 (1, 'print'),
329 (35, '>>'),
330 (290,
331 (291,
332 (292,
333 (293,
334 (295,
335 (296,
336 (297,
337 (298, (299, (300, (301, (302, (303, (1, 'fp')))))))))))))),
338 (12, ','))),
339 (4, ''))),
340 (0, ''))
341 self.check_bad_tree(tree, "print >>fp,")
342
343 def test_a_comma_comma_c(self):
Guido van Rossum32c2ae72002-08-22 19:45:32 +0000344 # Illegal input: a,,c
Fred Drake58422e52001-06-04 03:56:24 +0000345 tree = \
346 (258,
347 (311,
348 (290,
349 (291,
350 (292,
351 (293,
352 (295,
353 (296,
354 (297,
355 (298, (299, (300, (301, (302, (303, (1, 'a')))))))))))))),
356 (12, ','),
357 (12, ','),
358 (290,
359 (291,
360 (292,
361 (293,
362 (295,
363 (296,
364 (297,
365 (298, (299, (300, (301, (302, (303, (1, 'c'))))))))))))))),
366 (4, ''),
367 (0, ''))
368 self.check_bad_tree(tree, "a,,c")
369
370 def test_illegal_operator(self):
Guido van Rossum32c2ae72002-08-22 19:45:32 +0000371 # Illegal input: a $= b
Fred Drake58422e52001-06-04 03:56:24 +0000372 tree = \
373 (257,
374 (264,
375 (265,
376 (266,
377 (267,
378 (312,
379 (291,
380 (292,
381 (293,
382 (294,
383 (296,
384 (297,
385 (298,
386 (299,
387 (300, (301, (302, (303, (304, (1, 'a'))))))))))))))),
388 (268, (37, '$=')),
389 (312,
390 (291,
391 (292,
392 (293,
393 (294,
394 (296,
395 (297,
396 (298,
397 (299,
398 (300, (301, (302, (303, (304, (1, 'b'))))))))))))))))),
399 (4, ''))),
400 (0, ''))
401 self.check_bad_tree(tree, "a $= b")
Fred Drake79ca79d2000-08-21 22:30:53 +0000402
Neal Norwitz9caf9c02003-02-10 01:54:06 +0000403 def test_malformed_global(self):
404 #doesn't have global keyword in ast
405 tree = (257,
406 (264,
407 (265,
408 (266,
409 (282, (1, 'foo'))), (4, ''))),
410 (4, ''),
Tim Petersf2715e02003-02-19 02:35:07 +0000411 (0, ''))
Neal Norwitz9caf9c02003-02-10 01:54:06 +0000412 self.check_bad_tree(tree, "malformed global ast")
Fred Drake79ca79d2000-08-21 22:30:53 +0000413
Jeremy Hylton3e0055f2005-10-20 19:59:25 +0000414
415class CompileTestCase(unittest.TestCase):
416
417 # These tests are very minimal. :-(
418
419 def test_compile_expr(self):
420 st = parser.expr('2 + 3')
421 code = parser.compilest(st)
422 self.assertEquals(eval(code), 5)
423
424 def test_compile_suite(self):
425 st = parser.suite('x = 2; y = x + 3')
426 code = parser.compilest(st)
427 globs = {}
428 exec code in globs
429 self.assertEquals(globs['y'], 5)
430
431 def test_compile_error(self):
432 st = parser.suite('1 = 3 + 4')
433 self.assertRaises(SyntaxError, parser.compilest, st)
434
Fred Drake2e2be372001-09-20 21:33:42 +0000435def test_main():
Walter Dörwald21d3a322003-05-01 17:45:56 +0000436 test_support.run_unittest(
437 RoundtripLegalSyntaxTestCase,
Jeremy Hylton3e0055f2005-10-20 19:59:25 +0000438 IllegalSyntaxTestCase,
439 CompileTestCase,
Walter Dörwald21d3a322003-05-01 17:45:56 +0000440 )
Fred Drake2e2be372001-09-20 21:33:42 +0000441
442
443if __name__ == "__main__":
444 test_main()