blob: 020acd500fe2b73f8628037403997c7f4f395469 [file] [log] [blame]
Fred Drake79ca79d2000-08-21 22:30:53 +00001import parser
Fred Drake58422e52001-06-04 03:56:24 +00002import unittest
Christian Heimesb186d002008-03-18 15:15:01 +00003import sys
Mark Dickinson211c6252009-02-01 10:28:51 +00004import operator
Benjamin Petersonee8712c2008-05-20 21:35:26 +00005from test import support
Fred Drake79ca79d2000-08-21 22:30:53 +00006
7#
8# First, we test that we can generate trees from valid source fragments,
9# and that these valid trees are indeed allowed by the tree-loading side
10# of the parser module.
11#
12
Fred Drake58422e52001-06-04 03:56:24 +000013class RoundtripLegalSyntaxTestCase(unittest.TestCase):
Guido van Rossum32c2ae72002-08-22 19:45:32 +000014
Fred Drake58422e52001-06-04 03:56:24 +000015 def roundtrip(self, f, s):
16 st1 = f(s)
17 t = st1.totuple()
18 try:
Fred Drake6e4f2c02001-07-17 19:33:25 +000019 st2 = parser.sequence2st(t)
Guido van Rossumb940e112007-01-10 16:19:56 +000020 except parser.ParserError as why:
Anthony Baxterc2a5a632004-08-02 06:10:11 +000021 self.fail("could not roundtrip %r: %s" % (s, why))
Fred Drake79ca79d2000-08-21 22:30:53 +000022
Ezio Melottib3aedd42010-11-20 19:04:17 +000023 self.assertEqual(t, st2.totuple(),
24 "could not re-generate syntax tree")
Fred Drake28f739a2000-08-25 22:42:40 +000025
Fred Drake58422e52001-06-04 03:56:24 +000026 def check_expr(self, s):
27 self.roundtrip(parser.expr, s)
Fred Drake28f739a2000-08-25 22:42:40 +000028
Benjamin Petersonf216c942008-10-31 02:28:05 +000029 def test_flags_passed(self):
30 # The unicode literals flags has to be passed from the paser to AST
31 # generation.
32 suite = parser.suite("from __future__ import unicode_literals; x = ''")
33 code = suite.compile()
34 scope = {}
35 exec(code, {}, scope)
Ezio Melottie9615932010-01-24 19:26:24 +000036 self.assertIsInstance(scope["x"], str)
Benjamin Petersonf216c942008-10-31 02:28:05 +000037
Fred Drake58422e52001-06-04 03:56:24 +000038 def check_suite(self, s):
39 self.roundtrip(parser.suite, s)
Fred Drake28f739a2000-08-25 22:42:40 +000040
Fred Drakecf580c72001-07-17 03:01:29 +000041 def test_yield_statement(self):
Tim Peters496563a2002-04-01 00:28:59 +000042 self.check_suite("def f(): yield 1")
Phillip J. Eby0d6615f2005-08-02 00:46:46 +000043 self.check_suite("def f(): yield")
44 self.check_suite("def f(): x += yield")
45 self.check_suite("def f(): x = yield 1")
46 self.check_suite("def f(): x = y = yield 1")
47 self.check_suite("def f(): x = yield")
48 self.check_suite("def f(): x = y = yield")
49 self.check_suite("def f(): 1 + (yield)*2")
50 self.check_suite("def f(): (yield 1)*2")
Tim Peters496563a2002-04-01 00:28:59 +000051 self.check_suite("def f(): return; yield 1")
52 self.check_suite("def f(): yield 1; return")
53 self.check_suite("def f():\n"
Fred Drakecf580c72001-07-17 03:01:29 +000054 " for x in range(30):\n"
55 " yield x\n")
Phillip J. Eby0d6615f2005-08-02 00:46:46 +000056 self.check_suite("def f():\n"
57 " if (yield):\n"
58 " yield x\n")
Fred Drakecf580c72001-07-17 03:01:29 +000059
Fred Drake58422e52001-06-04 03:56:24 +000060 def test_expressions(self):
61 self.check_expr("foo(1)")
62 self.check_expr("[1, 2, 3]")
63 self.check_expr("[x**3 for x in range(20)]")
64 self.check_expr("[x**3 for x in range(20) if x % 3]")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000065 self.check_expr("[x**3 for x in range(20) if x % 2 if x % 3]")
66 self.check_expr("list(x**3 for x in range(20))")
67 self.check_expr("list(x**3 for x in range(20) if x % 3)")
68 self.check_expr("list(x**3 for x in range(20) if x % 2 if x % 3)")
Fred Drake58422e52001-06-04 03:56:24 +000069 self.check_expr("foo(*args)")
70 self.check_expr("foo(*args, **kw)")
71 self.check_expr("foo(**kw)")
72 self.check_expr("foo(key=value)")
73 self.check_expr("foo(key=value, *args)")
74 self.check_expr("foo(key=value, *args, **kw)")
75 self.check_expr("foo(key=value, **kw)")
76 self.check_expr("foo(a, b, c, *args)")
77 self.check_expr("foo(a, b, c, *args, **kw)")
78 self.check_expr("foo(a, b, c, **kw)")
Benjamin Peterson3938a902008-08-20 02:33:00 +000079 self.check_expr("foo(a, *args, keyword=23)")
Fred Drake58422e52001-06-04 03:56:24 +000080 self.check_expr("foo + bar")
Michael W. Hudson5e83b7a2003-01-29 14:20:23 +000081 self.check_expr("foo - bar")
82 self.check_expr("foo * bar")
83 self.check_expr("foo / bar")
84 self.check_expr("foo // bar")
Fred Drake58422e52001-06-04 03:56:24 +000085 self.check_expr("lambda: 0")
86 self.check_expr("lambda x: 0")
87 self.check_expr("lambda *y: 0")
88 self.check_expr("lambda *y, **z: 0")
89 self.check_expr("lambda **z: 0")
90 self.check_expr("lambda x, y: 0")
91 self.check_expr("lambda foo=bar: 0")
92 self.check_expr("lambda foo=bar, spaz=nifty+spit: 0")
93 self.check_expr("lambda foo=bar, **z: 0")
94 self.check_expr("lambda foo=bar, blaz=blat+2, **z: 0")
95 self.check_expr("lambda foo=bar, blaz=blat+2, *y, **z: 0")
96 self.check_expr("lambda x, *y, **z: 0")
Raymond Hettinger354433a2004-05-19 08:20:33 +000097 self.check_expr("(x for x in range(10))")
98 self.check_expr("foo(x for x in range(10))")
Fred Drake79ca79d2000-08-21 22:30:53 +000099
Fred Drake58422e52001-06-04 03:56:24 +0000100 def test_simple_expression(self):
101 # expr_stmt
102 self.check_suite("a")
Fred Drake79ca79d2000-08-21 22:30:53 +0000103
Fred Drake58422e52001-06-04 03:56:24 +0000104 def test_simple_assignments(self):
105 self.check_suite("a = b")
106 self.check_suite("a = b = c = d = e")
Fred Drake28f739a2000-08-25 22:42:40 +0000107
Fred Drake58422e52001-06-04 03:56:24 +0000108 def test_simple_augmented_assignments(self):
109 self.check_suite("a += b")
110 self.check_suite("a -= b")
111 self.check_suite("a *= b")
112 self.check_suite("a /= b")
Michael W. Hudson5e83b7a2003-01-29 14:20:23 +0000113 self.check_suite("a //= b")
Fred Drake58422e52001-06-04 03:56:24 +0000114 self.check_suite("a %= b")
115 self.check_suite("a &= b")
116 self.check_suite("a |= b")
117 self.check_suite("a ^= b")
118 self.check_suite("a <<= b")
119 self.check_suite("a >>= b")
120 self.check_suite("a **= b")
Fred Drakee3fb18c2001-01-07 06:02:19 +0000121
Fred Drake58422e52001-06-04 03:56:24 +0000122 def test_function_defs(self):
123 self.check_suite("def f(): pass")
124 self.check_suite("def f(*args): pass")
125 self.check_suite("def f(*args, **kw): pass")
126 self.check_suite("def f(**kw): pass")
127 self.check_suite("def f(foo=bar): pass")
128 self.check_suite("def f(foo=bar, *args): pass")
129 self.check_suite("def f(foo=bar, *args, **kw): pass")
130 self.check_suite("def f(foo=bar, **kw): pass")
Fred Drakee3fb18c2001-01-07 06:02:19 +0000131
Fred Drake58422e52001-06-04 03:56:24 +0000132 self.check_suite("def f(a, b): pass")
133 self.check_suite("def f(a, b, *args): pass")
134 self.check_suite("def f(a, b, *args, **kw): pass")
135 self.check_suite("def f(a, b, **kw): pass")
136 self.check_suite("def f(a, b, foo=bar): pass")
137 self.check_suite("def f(a, b, foo=bar, *args): pass")
138 self.check_suite("def f(a, b, foo=bar, *args, **kw): pass")
139 self.check_suite("def f(a, b, foo=bar, **kw): pass")
Fred Drakee3fb18c2001-01-07 06:02:19 +0000140
Anthony Baxterc2a5a632004-08-02 06:10:11 +0000141 self.check_suite("@staticmethod\n"
142 "def f(): pass")
143 self.check_suite("@staticmethod\n"
144 "@funcattrs(x, y)\n"
145 "def f(): pass")
146 self.check_suite("@funcattrs()\n"
147 "def f(): pass")
148
Brett Cannonf4189912005-04-09 02:30:16 +0000149 def test_class_defs(self):
150 self.check_suite("class foo():pass")
Guido van Rossumfc158e22007-11-15 19:17:28 +0000151 self.check_suite("class foo(object):pass")
Mark Dickinson2bd61a92010-07-04 16:37:31 +0000152 self.check_suite("@class_decorator\n"
153 "class foo():pass")
154 self.check_suite("@class_decorator(arg)\n"
155 "class foo():pass")
156 self.check_suite("@decorator1\n"
157 "@decorator2\n"
158 "class foo():pass")
Tim Peterse8906822005-04-20 17:45:13 +0000159
Fred Drake58422e52001-06-04 03:56:24 +0000160 def test_import_from_statement(self):
161 self.check_suite("from sys.path import *")
162 self.check_suite("from sys.path import dirname")
Anthony Baxter1a4ddae2004-08-31 10:07:13 +0000163 self.check_suite("from sys.path import (dirname)")
164 self.check_suite("from sys.path import (dirname,)")
Fred Drake58422e52001-06-04 03:56:24 +0000165 self.check_suite("from sys.path import dirname as my_dirname")
Anthony Baxter1a4ddae2004-08-31 10:07:13 +0000166 self.check_suite("from sys.path import (dirname as my_dirname)")
167 self.check_suite("from sys.path import (dirname as my_dirname,)")
Fred Drake58422e52001-06-04 03:56:24 +0000168 self.check_suite("from sys.path import dirname, basename")
Anthony Baxter1a4ddae2004-08-31 10:07:13 +0000169 self.check_suite("from sys.path import (dirname, basename)")
170 self.check_suite("from sys.path import (dirname, basename,)")
Fred Drake58422e52001-06-04 03:56:24 +0000171 self.check_suite(
172 "from sys.path import dirname as my_dirname, basename")
173 self.check_suite(
Anthony Baxter1a4ddae2004-08-31 10:07:13 +0000174 "from sys.path import (dirname as my_dirname, basename)")
175 self.check_suite(
176 "from sys.path import (dirname as my_dirname, basename,)")
177 self.check_suite(
Fred Drake58422e52001-06-04 03:56:24 +0000178 "from sys.path import dirname, basename as my_basename")
Anthony Baxter1a4ddae2004-08-31 10:07:13 +0000179 self.check_suite(
180 "from sys.path import (dirname, basename as my_basename)")
181 self.check_suite(
182 "from sys.path import (dirname, basename as my_basename,)")
Benjamin Petersonc0747cf2008-11-03 20:31:38 +0000183 self.check_suite("from .bogus import x")
Fred Drakee3fb18c2001-01-07 06:02:19 +0000184
Fred Drake58422e52001-06-04 03:56:24 +0000185 def test_basic_import_statement(self):
186 self.check_suite("import sys")
187 self.check_suite("import sys as system")
188 self.check_suite("import sys, math")
189 self.check_suite("import sys as system, math")
190 self.check_suite("import sys, math as my_math")
Fred Drake79ca79d2000-08-21 22:30:53 +0000191
Mark Dickinson2cc8a5e2010-07-04 18:11:51 +0000192 def test_relative_imports(self):
193 self.check_suite("from . import name")
194 self.check_suite("from .. import name")
Mark Dickinsonfeb3b752010-07-04 18:38:57 +0000195 # check all the way up to '....', since '...' is tokenized
196 # differently from '.' (it's an ellipsis token).
197 self.check_suite("from ... import name")
198 self.check_suite("from .... import name")
Mark Dickinson2cc8a5e2010-07-04 18:11:51 +0000199 self.check_suite("from .pkg import name")
200 self.check_suite("from ..pkg import name")
Mark Dickinsonfeb3b752010-07-04 18:38:57 +0000201 self.check_suite("from ...pkg import name")
202 self.check_suite("from ....pkg import name")
Mark Dickinson2cc8a5e2010-07-04 18:11:51 +0000203
Neal Norwitz9caf9c02003-02-10 01:54:06 +0000204 def test_pep263(self):
205 self.check_suite("# -*- coding: iso-8859-1 -*-\n"
206 "pass\n")
207
208 def test_assert(self):
209 self.check_suite("assert alo < ahi and blo < bhi\n")
210
Benjamin Peterson4469d0c2008-11-30 22:46:23 +0000211 def test_with(self):
212 self.check_suite("with open('x'): pass\n")
213 self.check_suite("with open('x') as f: pass\n")
Georg Brandl0c315622009-05-25 21:10:36 +0000214 self.check_suite("with open('x') as f, open('y') as g: pass\n")
Benjamin Peterson4469d0c2008-11-30 22:46:23 +0000215
Georg Brandleee31162008-12-07 15:15:22 +0000216 def test_try_stmt(self):
217 self.check_suite("try: pass\nexcept: pass\n")
218 self.check_suite("try: pass\nfinally: pass\n")
219 self.check_suite("try: pass\nexcept A: pass\nfinally: pass\n")
220 self.check_suite("try: pass\nexcept A: pass\nexcept: pass\n"
221 "finally: pass\n")
222 self.check_suite("try: pass\nexcept: pass\nelse: pass\n")
223 self.check_suite("try: pass\nexcept: pass\nelse: pass\n"
224 "finally: pass\n")
225
Thomas Wouters89f507f2006-12-13 04:49:30 +0000226 def test_position(self):
227 # An absolutely minimal test of position information. Better
228 # tests would be a big project.
Benjamin Peterson8f326b22009-12-13 02:10:36 +0000229 code = "def f(x):\n return x + 1"
Thomas Wouters89f507f2006-12-13 04:49:30 +0000230 st1 = parser.suite(code)
231 st2 = st1.totuple(line_info=1, col_info=1)
232
233 def walk(tree):
234 node_type = tree[0]
235 next = tree[1]
236 if isinstance(next, tuple):
237 for elt in tree[1:]:
238 for x in walk(elt):
239 yield x
240 else:
241 yield tree
242
243 terminals = list(walk(st2))
244 self.assertEqual([
245 (1, 'def', 1, 0),
246 (1, 'f', 1, 4),
247 (7, '(', 1, 5),
248 (1, 'x', 1, 6),
249 (8, ')', 1, 7),
250 (11, ':', 1, 8),
251 (4, '', 1, 9),
252 (5, '', 2, -1),
253 (1, 'return', 2, 4),
254 (1, 'x', 2, 11),
255 (14, '+', 2, 13),
256 (2, '1', 2, 15),
257 (4, '', 2, 16),
Benjamin Peterson8f326b22009-12-13 02:10:36 +0000258 (6, '', 2, -1),
259 (4, '', 2, -1),
260 (0, '', 2, -1)],
Thomas Wouters89f507f2006-12-13 04:49:30 +0000261 terminals)
262
Benjamin Peterson4905e802009-09-27 02:43:28 +0000263 def test_extended_unpacking(self):
264 self.check_suite("*a = y")
265 self.check_suite("x, *b, = m")
266 self.check_suite("[*a, *b] = y")
267 self.check_suite("for [*x, b] in x: pass")
268
Thomas Wouters89f507f2006-12-13 04:49:30 +0000269
Fred Drake79ca79d2000-08-21 22:30:53 +0000270#
271# Second, we take *invalid* trees and make sure we get ParserError
272# rejections for them.
273#
274
Fred Drake58422e52001-06-04 03:56:24 +0000275class IllegalSyntaxTestCase(unittest.TestCase):
Guido van Rossum32c2ae72002-08-22 19:45:32 +0000276
Fred Drake58422e52001-06-04 03:56:24 +0000277 def check_bad_tree(self, tree, label):
278 try:
Fred Drake6e4f2c02001-07-17 19:33:25 +0000279 parser.sequence2st(tree)
Fred Drake58422e52001-06-04 03:56:24 +0000280 except parser.ParserError:
281 pass
282 else:
283 self.fail("did not detect invalid tree for %r" % label)
Fred Drake79ca79d2000-08-21 22:30:53 +0000284
Fred Drake58422e52001-06-04 03:56:24 +0000285 def test_junk(self):
286 # not even remotely valid:
287 self.check_bad_tree((1, 2, 3), "<junk>")
288
Fred Drakecf580c72001-07-17 03:01:29 +0000289 def test_illegal_yield_1(self):
Guido van Rossum32c2ae72002-08-22 19:45:32 +0000290 # Illegal yield statement: def f(): return 1; yield 1
Fred Drakecf580c72001-07-17 03:01:29 +0000291 tree = \
292 (257,
293 (264,
294 (285,
295 (259,
296 (1, 'def'),
297 (1, 'f'),
298 (260, (7, '('), (8, ')')),
299 (11, ':'),
300 (291,
301 (4, ''),
302 (5, ''),
303 (264,
304 (265,
305 (266,
306 (272,
307 (275,
308 (1, 'return'),
309 (313,
310 (292,
311 (293,
312 (294,
313 (295,
314 (297,
315 (298,
316 (299,
317 (300,
318 (301,
319 (302, (303, (304, (305, (2, '1')))))))))))))))))),
320 (264,
321 (265,
322 (266,
323 (272,
324 (276,
325 (1, 'yield'),
326 (313,
327 (292,
328 (293,
329 (294,
330 (295,
331 (297,
332 (298,
333 (299,
334 (300,
335 (301,
336 (302,
337 (303, (304, (305, (2, '1')))))))))))))))))),
338 (4, ''))),
339 (6, ''))))),
340 (4, ''),
341 (0, ''))))
342 self.check_bad_tree(tree, "def f():\n return 1\n yield 1")
343
344 def test_illegal_yield_2(self):
Guido van Rossum32c2ae72002-08-22 19:45:32 +0000345 # Illegal return in generator: def f(): return 1; yield 1
Fred Drakecf580c72001-07-17 03:01:29 +0000346 tree = \
347 (257,
348 (264,
349 (265,
350 (266,
351 (278,
352 (1, 'from'),
353 (281, (1, '__future__')),
354 (1, 'import'),
355 (279, (1, 'generators')))),
356 (4, ''))),
357 (264,
358 (285,
359 (259,
360 (1, 'def'),
361 (1, 'f'),
362 (260, (7, '('), (8, ')')),
363 (11, ':'),
364 (291,
365 (4, ''),
366 (5, ''),
367 (264,
368 (265,
369 (266,
370 (272,
371 (275,
372 (1, 'return'),
373 (313,
374 (292,
375 (293,
376 (294,
377 (295,
378 (297,
379 (298,
380 (299,
381 (300,
382 (301,
383 (302, (303, (304, (305, (2, '1')))))))))))))))))),
384 (264,
385 (265,
386 (266,
387 (272,
388 (276,
389 (1, 'yield'),
390 (313,
391 (292,
392 (293,
393 (294,
394 (295,
395 (297,
396 (298,
397 (299,
398 (300,
399 (301,
400 (302,
401 (303, (304, (305, (2, '1')))))))))))))))))),
402 (4, ''))),
403 (6, ''))))),
404 (4, ''),
405 (0, ''))))
406 self.check_bad_tree(tree, "def f():\n return 1\n yield 1")
407
Fred Drake58422e52001-06-04 03:56:24 +0000408 def test_a_comma_comma_c(self):
Guido van Rossum32c2ae72002-08-22 19:45:32 +0000409 # Illegal input: a,,c
Fred Drake58422e52001-06-04 03:56:24 +0000410 tree = \
411 (258,
412 (311,
413 (290,
414 (291,
415 (292,
416 (293,
417 (295,
418 (296,
419 (297,
420 (298, (299, (300, (301, (302, (303, (1, 'a')))))))))))))),
421 (12, ','),
422 (12, ','),
423 (290,
424 (291,
425 (292,
426 (293,
427 (295,
428 (296,
429 (297,
430 (298, (299, (300, (301, (302, (303, (1, 'c'))))))))))))))),
431 (4, ''),
432 (0, ''))
433 self.check_bad_tree(tree, "a,,c")
434
435 def test_illegal_operator(self):
Guido van Rossum32c2ae72002-08-22 19:45:32 +0000436 # Illegal input: a $= b
Fred Drake58422e52001-06-04 03:56:24 +0000437 tree = \
438 (257,
439 (264,
440 (265,
441 (266,
442 (267,
443 (312,
444 (291,
445 (292,
446 (293,
447 (294,
448 (296,
449 (297,
450 (298,
451 (299,
452 (300, (301, (302, (303, (304, (1, 'a'))))))))))))))),
453 (268, (37, '$=')),
454 (312,
455 (291,
456 (292,
457 (293,
458 (294,
459 (296,
460 (297,
461 (298,
462 (299,
463 (300, (301, (302, (303, (304, (1, 'b'))))))))))))))))),
464 (4, ''))),
465 (0, ''))
466 self.check_bad_tree(tree, "a $= b")
Fred Drake79ca79d2000-08-21 22:30:53 +0000467
Neal Norwitz9caf9c02003-02-10 01:54:06 +0000468 def test_malformed_global(self):
469 #doesn't have global keyword in ast
470 tree = (257,
471 (264,
472 (265,
473 (266,
474 (282, (1, 'foo'))), (4, ''))),
475 (4, ''),
Tim Petersf2715e02003-02-19 02:35:07 +0000476 (0, ''))
Neal Norwitz9caf9c02003-02-10 01:54:06 +0000477 self.check_bad_tree(tree, "malformed global ast")
Fred Drake79ca79d2000-08-21 22:30:53 +0000478
Mark Dickinson2cc8a5e2010-07-04 18:11:51 +0000479 def test_missing_import_source(self):
Mark Dickinson3445b482010-07-04 18:15:26 +0000480 # from import fred
Mark Dickinson2cc8a5e2010-07-04 18:11:51 +0000481 tree = \
482 (257,
Mark Dickinson3445b482010-07-04 18:15:26 +0000483 (268,
484 (269,
485 (270,
486 (282,
487 (284, (1, 'from'), (1, 'import'),
488 (287, (285, (1, 'fred')))))),
Mark Dickinson2cc8a5e2010-07-04 18:11:51 +0000489 (4, ''))),
490 (4, ''), (0, ''))
Mark Dickinson3445b482010-07-04 18:15:26 +0000491 self.check_bad_tree(tree, "from import fred")
Mark Dickinson2cc8a5e2010-07-04 18:11:51 +0000492
Jeremy Hylton3e0055f2005-10-20 19:59:25 +0000493
494class CompileTestCase(unittest.TestCase):
495
496 # These tests are very minimal. :-(
497
498 def test_compile_expr(self):
499 st = parser.expr('2 + 3')
500 code = parser.compilest(st)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000501 self.assertEqual(eval(code), 5)
Jeremy Hylton3e0055f2005-10-20 19:59:25 +0000502
503 def test_compile_suite(self):
504 st = parser.suite('x = 2; y = x + 3')
505 code = parser.compilest(st)
506 globs = {}
Georg Brandl7cae87c2006-09-06 06:51:57 +0000507 exec(code, globs)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000508 self.assertEqual(globs['y'], 5)
Jeremy Hylton3e0055f2005-10-20 19:59:25 +0000509
510 def test_compile_error(self):
511 st = parser.suite('1 = 3 + 4')
512 self.assertRaises(SyntaxError, parser.compilest, st)
513
Guido van Rossumb5a755e2007-07-18 18:15:48 +0000514 def test_compile_badunicode(self):
Guido van Rossum7eb6ca52007-07-18 21:00:22 +0000515 st = parser.suite('a = "\\U12345678"')
Guido van Rossumb5a755e2007-07-18 18:15:48 +0000516 self.assertRaises(SyntaxError, parser.compilest, st)
Guido van Rossum7eb6ca52007-07-18 21:00:22 +0000517 st = parser.suite('a = "\\u1"')
Guido van Rossumb5a755e2007-07-18 18:15:48 +0000518 self.assertRaises(SyntaxError, parser.compilest, st)
519
Mark Dickinsond35a32e2010-06-17 12:33:22 +0000520 def test_issue_9011(self):
521 # Issue 9011: compilation of an unary minus expression changed
522 # the meaning of the ST, so that a second compilation produced
523 # incorrect results.
524 st = parser.expr('-3')
525 code1 = parser.compilest(st)
526 self.assertEqual(eval(code1), -3)
527 code2 = parser.compilest(st)
528 self.assertEqual(eval(code2), -3)
529
Christian Heimes90c3d9b2008-02-23 13:18:03 +0000530class ParserStackLimitTestCase(unittest.TestCase):
Mark Dickinsond35a32e2010-06-17 12:33:22 +0000531 """try to push the parser to/over its limits.
Christian Heimes90c3d9b2008-02-23 13:18:03 +0000532 see http://bugs.python.org/issue1881 for a discussion
533 """
534 def _nested_expression(self, level):
535 return "["*level+"]"*level
536
537 def test_deeply_nested_list(self):
538 # XXX used to be 99 levels in 2.x
539 e = self._nested_expression(93)
540 st = parser.expr(e)
541 st.compile()
542
543 def test_trigger_memory_error(self):
544 e = self._nested_expression(100)
Christian Heimesb186d002008-03-18 15:15:01 +0000545 print("Expecting 's_push: parser stack overflow' in next line",
546 file=sys.stderr)
Antoine Pitrou88909542009-06-29 13:54:42 +0000547 sys.stderr.flush()
Christian Heimes90c3d9b2008-02-23 13:18:03 +0000548 self.assertRaises(MemoryError, parser.expr, e)
549
Mark Dickinson211c6252009-02-01 10:28:51 +0000550class STObjectTestCase(unittest.TestCase):
551 """Test operations on ST objects themselves"""
552
553 def test_comparisons(self):
554 # ST objects should support order and equality comparisons
555 st1 = parser.expr('2 + 3')
556 st2 = parser.suite('x = 2; y = x + 3')
557 st3 = parser.expr('list(x**3 for x in range(20))')
558 st1_copy = parser.expr('2 + 3')
559 st2_copy = parser.suite('x = 2; y = x + 3')
560 st3_copy = parser.expr('list(x**3 for x in range(20))')
561
562 # exercise fast path for object identity
Ezio Melottib3aedd42010-11-20 19:04:17 +0000563 self.assertEqual(st1 == st1, True)
564 self.assertEqual(st2 == st2, True)
565 self.assertEqual(st3 == st3, True)
Mark Dickinson211c6252009-02-01 10:28:51 +0000566 # slow path equality
567 self.assertEqual(st1, st1_copy)
568 self.assertEqual(st2, st2_copy)
569 self.assertEqual(st3, st3_copy)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000570 self.assertEqual(st1 == st2, False)
571 self.assertEqual(st1 == st3, False)
572 self.assertEqual(st2 == st3, False)
573 self.assertEqual(st1 != st1, False)
574 self.assertEqual(st2 != st2, False)
575 self.assertEqual(st3 != st3, False)
576 self.assertEqual(st1 != st1_copy, False)
577 self.assertEqual(st2 != st2_copy, False)
578 self.assertEqual(st3 != st3_copy, False)
579 self.assertEqual(st2 != st1, True)
580 self.assertEqual(st1 != st3, True)
581 self.assertEqual(st3 != st2, True)
Mark Dickinson211c6252009-02-01 10:28:51 +0000582 # we don't particularly care what the ordering is; just that
583 # it's usable and self-consistent
Ezio Melottib3aedd42010-11-20 19:04:17 +0000584 self.assertEqual(st1 < st2, not (st2 <= st1))
585 self.assertEqual(st1 < st3, not (st3 <= st1))
586 self.assertEqual(st2 < st3, not (st3 <= st2))
587 self.assertEqual(st1 < st2, st2 > st1)
588 self.assertEqual(st1 < st3, st3 > st1)
589 self.assertEqual(st2 < st3, st3 > st2)
590 self.assertEqual(st1 <= st2, st2 >= st1)
591 self.assertEqual(st3 <= st1, st1 >= st3)
592 self.assertEqual(st2 <= st3, st3 >= st2)
Mark Dickinson211c6252009-02-01 10:28:51 +0000593 # transitivity
594 bottom = min(st1, st2, st3)
595 top = max(st1, st2, st3)
596 mid = sorted([st1, st2, st3])[1]
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000597 self.assertTrue(bottom < mid)
598 self.assertTrue(bottom < top)
599 self.assertTrue(mid < top)
600 self.assertTrue(bottom <= mid)
601 self.assertTrue(bottom <= top)
602 self.assertTrue(mid <= top)
603 self.assertTrue(bottom <= bottom)
604 self.assertTrue(mid <= mid)
605 self.assertTrue(top <= top)
Mark Dickinson211c6252009-02-01 10:28:51 +0000606 # interaction with other types
Ezio Melottib3aedd42010-11-20 19:04:17 +0000607 self.assertEqual(st1 == 1588.602459, False)
608 self.assertEqual('spanish armada' != st2, True)
Mark Dickinson211c6252009-02-01 10:28:51 +0000609 self.assertRaises(TypeError, operator.ge, st3, None)
610 self.assertRaises(TypeError, operator.le, False, st1)
611 self.assertRaises(TypeError, operator.lt, st1, 1815)
612 self.assertRaises(TypeError, operator.gt, b'waterloo', st2)
613
614
615 # XXX tests for pickling and unpickling of ST objects should go here
616
617
Fred Drake2e2be372001-09-20 21:33:42 +0000618def test_main():
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000619 support.run_unittest(
Walter Dörwald21d3a322003-05-01 17:45:56 +0000620 RoundtripLegalSyntaxTestCase,
Jeremy Hylton3e0055f2005-10-20 19:59:25 +0000621 IllegalSyntaxTestCase,
622 CompileTestCase,
Christian Heimes90c3d9b2008-02-23 13:18:03 +0000623 ParserStackLimitTestCase,
Mark Dickinson211c6252009-02-01 10:28:51 +0000624 STObjectTestCase,
Walter Dörwald21d3a322003-05-01 17:45:56 +0000625 )
Fred Drake2e2be372001-09-20 21:33:42 +0000626
627
628if __name__ == "__main__":
629 test_main()