blob: e5285c6360229d7434460e99c85edc2d037bcf61 [file] [log] [blame]
Serhiy Storchakaa79f4c22017-04-19 21:09:21 +03001import copy
Fred Drake79ca79d2000-08-21 22:30:53 +00002import parser
Serhiy Storchakaa79f4c22017-04-19 21:09:21 +03003import pickle
Fred Drake58422e52001-06-04 03:56:24 +00004import unittest
Mark Dickinson211c6252009-02-01 10:28:51 +00005import operator
Jesus Ceae9c53182012-08-03 14:28:37 +02006import struct
Benjamin Petersonee8712c2008-05-20 21:35:26 +00007from test import support
Berker Peksagce643912015-05-06 06:33:17 +03008from test.support.script_helper import assert_python_failure
Fred Drake79ca79d2000-08-21 22:30:53 +00009
10#
11# First, we test that we can generate trees from valid source fragments,
12# and that these valid trees are indeed allowed by the tree-loading side
13# of the parser module.
14#
15
Fred Drake58422e52001-06-04 03:56:24 +000016class RoundtripLegalSyntaxTestCase(unittest.TestCase):
Guido van Rossum32c2ae72002-08-22 19:45:32 +000017
Fred Drake58422e52001-06-04 03:56:24 +000018 def roundtrip(self, f, s):
19 st1 = f(s)
20 t = st1.totuple()
21 try:
Fred Drake6e4f2c02001-07-17 19:33:25 +000022 st2 = parser.sequence2st(t)
Guido van Rossumb940e112007-01-10 16:19:56 +000023 except parser.ParserError as why:
Anthony Baxterc2a5a632004-08-02 06:10:11 +000024 self.fail("could not roundtrip %r: %s" % (s, why))
Fred Drake79ca79d2000-08-21 22:30:53 +000025
Ezio Melottib3aedd42010-11-20 19:04:17 +000026 self.assertEqual(t, st2.totuple(),
27 "could not re-generate syntax tree")
Fred Drake28f739a2000-08-25 22:42:40 +000028
Fred Drake58422e52001-06-04 03:56:24 +000029 def check_expr(self, s):
30 self.roundtrip(parser.expr, s)
Fred Drake28f739a2000-08-25 22:42:40 +000031
Benjamin Petersonf216c942008-10-31 02:28:05 +000032 def test_flags_passed(self):
Mike53f7a7c2017-12-14 14:04:53 +030033 # The unicode literals flags has to be passed from the parser to AST
Benjamin Petersonf216c942008-10-31 02:28:05 +000034 # generation.
35 suite = parser.suite("from __future__ import unicode_literals; x = ''")
36 code = suite.compile()
37 scope = {}
38 exec(code, {}, scope)
Ezio Melottie9615932010-01-24 19:26:24 +000039 self.assertIsInstance(scope["x"], str)
Benjamin Petersonf216c942008-10-31 02:28:05 +000040
Fred Drake58422e52001-06-04 03:56:24 +000041 def check_suite(self, s):
42 self.roundtrip(parser.suite, s)
Fred Drake28f739a2000-08-25 22:42:40 +000043
Fred Drakecf580c72001-07-17 03:01:29 +000044 def test_yield_statement(self):
Tim Peters496563a2002-04-01 00:28:59 +000045 self.check_suite("def f(): yield 1")
Phillip J. Eby0d6615f2005-08-02 00:46:46 +000046 self.check_suite("def f(): yield")
47 self.check_suite("def f(): x += yield")
48 self.check_suite("def f(): x = yield 1")
49 self.check_suite("def f(): x = y = yield 1")
50 self.check_suite("def f(): x = yield")
51 self.check_suite("def f(): x = y = yield")
52 self.check_suite("def f(): 1 + (yield)*2")
53 self.check_suite("def f(): (yield 1)*2")
Tim Peters496563a2002-04-01 00:28:59 +000054 self.check_suite("def f(): return; yield 1")
55 self.check_suite("def f(): yield 1; return")
Nick Coghlan1f7ce622012-01-13 21:43:40 +100056 self.check_suite("def f(): yield from 1")
57 self.check_suite("def f(): x = yield from 1")
58 self.check_suite("def f(): f((yield from 1))")
59 self.check_suite("def f(): yield 1; return 1")
Tim Peters496563a2002-04-01 00:28:59 +000060 self.check_suite("def f():\n"
Fred Drakecf580c72001-07-17 03:01:29 +000061 " for x in range(30):\n"
62 " yield x\n")
Phillip J. Eby0d6615f2005-08-02 00:46:46 +000063 self.check_suite("def f():\n"
64 " if (yield):\n"
65 " yield x\n")
Fred Drakecf580c72001-07-17 03:01:29 +000066
Yury Selivanov75445082015-05-11 22:57:16 -040067 def test_await_statement(self):
68 self.check_suite("async def f():\n await smth()")
69 self.check_suite("async def f():\n foo = await smth()")
70 self.check_suite("async def f():\n foo, bar = await smth()")
71 self.check_suite("async def f():\n (await smth())")
72 self.check_suite("async def f():\n foo((await smth()))")
73 self.check_suite("async def f():\n await foo(); return 42")
74
75 def test_async_with_statement(self):
76 self.check_suite("async def f():\n async with 1: pass")
77 self.check_suite("async def f():\n async with a as b, c as d: pass")
78
79 def test_async_for_statement(self):
80 self.check_suite("async def f():\n async for i in (): pass")
81 self.check_suite("async def f():\n async for i, b in (): pass")
82
Mark Dickinson407b3bd2012-04-29 22:18:31 +010083 def test_nonlocal_statement(self):
84 self.check_suite("def f():\n"
85 " x = 0\n"
86 " def g():\n"
87 " nonlocal x\n")
88 self.check_suite("def f():\n"
89 " x = y = 0\n"
90 " def g():\n"
91 " nonlocal x, y\n")
92
Fred Drake58422e52001-06-04 03:56:24 +000093 def test_expressions(self):
94 self.check_expr("foo(1)")
95 self.check_expr("[1, 2, 3]")
96 self.check_expr("[x**3 for x in range(20)]")
97 self.check_expr("[x**3 for x in range(20) if x % 3]")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000098 self.check_expr("[x**3 for x in range(20) if x % 2 if x % 3]")
99 self.check_expr("list(x**3 for x in range(20))")
100 self.check_expr("list(x**3 for x in range(20) if x % 3)")
101 self.check_expr("list(x**3 for x in range(20) if x % 2 if x % 3)")
Fred Drake58422e52001-06-04 03:56:24 +0000102 self.check_expr("foo(*args)")
103 self.check_expr("foo(*args, **kw)")
104 self.check_expr("foo(**kw)")
105 self.check_expr("foo(key=value)")
106 self.check_expr("foo(key=value, *args)")
107 self.check_expr("foo(key=value, *args, **kw)")
108 self.check_expr("foo(key=value, **kw)")
109 self.check_expr("foo(a, b, c, *args)")
110 self.check_expr("foo(a, b, c, *args, **kw)")
111 self.check_expr("foo(a, b, c, **kw)")
Benjamin Peterson3938a902008-08-20 02:33:00 +0000112 self.check_expr("foo(a, *args, keyword=23)")
Fred Drake58422e52001-06-04 03:56:24 +0000113 self.check_expr("foo + bar")
Michael W. Hudson5e83b7a2003-01-29 14:20:23 +0000114 self.check_expr("foo - bar")
115 self.check_expr("foo * bar")
116 self.check_expr("foo / bar")
117 self.check_expr("foo // bar")
Emily Morehouse8f59ee02019-01-24 16:49:56 -0700118 self.check_expr("(foo := 1)")
Fred Drake58422e52001-06-04 03:56:24 +0000119 self.check_expr("lambda: 0")
120 self.check_expr("lambda x: 0")
121 self.check_expr("lambda *y: 0")
122 self.check_expr("lambda *y, **z: 0")
123 self.check_expr("lambda **z: 0")
124 self.check_expr("lambda x, y: 0")
125 self.check_expr("lambda foo=bar: 0")
126 self.check_expr("lambda foo=bar, spaz=nifty+spit: 0")
127 self.check_expr("lambda foo=bar, **z: 0")
128 self.check_expr("lambda foo=bar, blaz=blat+2, **z: 0")
129 self.check_expr("lambda foo=bar, blaz=blat+2, *y, **z: 0")
130 self.check_expr("lambda x, *y, **z: 0")
Raymond Hettinger354433a2004-05-19 08:20:33 +0000131 self.check_expr("(x for x in range(10))")
132 self.check_expr("foo(x for x in range(10))")
Mark Dickinsonda029fb2012-05-07 17:24:04 +0100133 self.check_expr("...")
134 self.check_expr("a[...]")
Fred Drake79ca79d2000-08-21 22:30:53 +0000135
Fred Drake58422e52001-06-04 03:56:24 +0000136 def test_simple_expression(self):
137 # expr_stmt
138 self.check_suite("a")
Fred Drake79ca79d2000-08-21 22:30:53 +0000139
Fred Drake58422e52001-06-04 03:56:24 +0000140 def test_simple_assignments(self):
141 self.check_suite("a = b")
142 self.check_suite("a = b = c = d = e")
Fred Drake28f739a2000-08-25 22:42:40 +0000143
Yury Selivanovf8cb8a12016-09-08 20:50:03 -0700144 def test_var_annot(self):
145 self.check_suite("x: int = 5")
146 self.check_suite("y: List[T] = []; z: [list] = fun()")
147 self.check_suite("x: tuple = (1, 2)")
148 self.check_suite("d[f()]: int = 42")
149 self.check_suite("f(d[x]): str = 'abc'")
150 self.check_suite("x.y.z.w: complex = 42j")
151 self.check_suite("x: int")
152 self.check_suite("def f():\n"
153 " x: str\n"
154 " y: int = 5\n")
155 self.check_suite("class C:\n"
156 " x: str\n"
157 " y: int = 5\n")
158 self.check_suite("class C:\n"
159 " def __init__(self, x: int) -> None:\n"
160 " self.x: int = x\n")
161 # double check for nonsense
162 with self.assertRaises(SyntaxError):
163 exec("2+2: int", {}, {})
164 with self.assertRaises(SyntaxError):
165 exec("[]: int = 5", {}, {})
166 with self.assertRaises(SyntaxError):
167 exec("x, *y, z: int = range(5)", {}, {})
168 with self.assertRaises(SyntaxError):
Ivan Levkivskyi62c35a82019-01-25 01:39:19 +0000169 exec("x: int = 1, y = 2", {}, {})
Yury Selivanovf8cb8a12016-09-08 20:50:03 -0700170 with self.assertRaises(SyntaxError):
171 exec("u = v: int", {}, {})
172 with self.assertRaises(SyntaxError):
173 exec("False: int", {}, {})
174 with self.assertRaises(SyntaxError):
175 exec("x.False: int", {}, {})
176 with self.assertRaises(SyntaxError):
177 exec("x.y,: int", {}, {})
178 with self.assertRaises(SyntaxError):
179 exec("[0]: int", {}, {})
180 with self.assertRaises(SyntaxError):
181 exec("f(): int", {}, {})
182
Fred Drake58422e52001-06-04 03:56:24 +0000183 def test_simple_augmented_assignments(self):
184 self.check_suite("a += b")
185 self.check_suite("a -= b")
186 self.check_suite("a *= b")
187 self.check_suite("a /= b")
Michael W. Hudson5e83b7a2003-01-29 14:20:23 +0000188 self.check_suite("a //= b")
Fred Drake58422e52001-06-04 03:56:24 +0000189 self.check_suite("a %= b")
190 self.check_suite("a &= b")
191 self.check_suite("a |= b")
192 self.check_suite("a ^= b")
193 self.check_suite("a <<= b")
194 self.check_suite("a >>= b")
195 self.check_suite("a **= b")
Fred Drakee3fb18c2001-01-07 06:02:19 +0000196
Fred Drake58422e52001-06-04 03:56:24 +0000197 def test_function_defs(self):
198 self.check_suite("def f(): pass")
199 self.check_suite("def f(*args): pass")
200 self.check_suite("def f(*args, **kw): pass")
201 self.check_suite("def f(**kw): pass")
202 self.check_suite("def f(foo=bar): pass")
203 self.check_suite("def f(foo=bar, *args): pass")
204 self.check_suite("def f(foo=bar, *args, **kw): pass")
205 self.check_suite("def f(foo=bar, **kw): pass")
Fred Drakee3fb18c2001-01-07 06:02:19 +0000206
Fred Drake58422e52001-06-04 03:56:24 +0000207 self.check_suite("def f(a, b): pass")
208 self.check_suite("def f(a, b, *args): pass")
209 self.check_suite("def f(a, b, *args, **kw): pass")
210 self.check_suite("def f(a, b, **kw): pass")
211 self.check_suite("def f(a, b, foo=bar): pass")
212 self.check_suite("def f(a, b, foo=bar, *args): pass")
213 self.check_suite("def f(a, b, foo=bar, *args, **kw): pass")
214 self.check_suite("def f(a, b, foo=bar, **kw): pass")
Fred Drakee3fb18c2001-01-07 06:02:19 +0000215
Anthony Baxterc2a5a632004-08-02 06:10:11 +0000216 self.check_suite("@staticmethod\n"
217 "def f(): pass")
218 self.check_suite("@staticmethod\n"
219 "@funcattrs(x, y)\n"
220 "def f(): pass")
221 self.check_suite("@funcattrs()\n"
222 "def f(): pass")
223
Mark Dickinsonea7e9f92012-04-29 18:34:40 +0100224 # keyword-only arguments
225 self.check_suite("def f(*, a): pass")
226 self.check_suite("def f(*, a = 5): pass")
227 self.check_suite("def f(*, a = 5, b): pass")
228 self.check_suite("def f(*, a, b = 5): pass")
229 self.check_suite("def f(*, a, b = 5, **kwds): pass")
230 self.check_suite("def f(*args, a): pass")
231 self.check_suite("def f(*args, a = 5): pass")
232 self.check_suite("def f(*args, a = 5, b): pass")
233 self.check_suite("def f(*args, a, b = 5): pass")
234 self.check_suite("def f(*args, a, b = 5, **kwds): pass")
235
Pablo Galindo8c77b8c2019-04-29 13:36:57 +0100236 # positional-only arguments
237 self.check_suite("def f(a, /): pass")
238 self.check_suite("def f(a, /,): pass")
239 self.check_suite("def f(a, b, /): pass")
240 self.check_suite("def f(a, b, /, c): pass")
241 self.check_suite("def f(a, b, /, c = 6): pass")
242 self.check_suite("def f(a, b, /, c, *, d): pass")
243 self.check_suite("def f(a, b, /, c = 1, *, d): pass")
244 self.check_suite("def f(a, b, /, c, *, d = 1): pass")
245 self.check_suite("def f(a, b=1, /, c=2, *, d = 3): pass")
246 self.check_suite("def f(a=0, b=1, /, c=2, *, d = 3): pass")
247
Mark Dickinsonea7e9f92012-04-29 18:34:40 +0100248 # function annotations
249 self.check_suite("def f(a: int): pass")
250 self.check_suite("def f(a: int = 5): pass")
251 self.check_suite("def f(*args: list): pass")
252 self.check_suite("def f(**kwds: dict): pass")
253 self.check_suite("def f(*, a: int): pass")
254 self.check_suite("def f(*, a: int = 5): pass")
255 self.check_suite("def f() -> int: pass")
256
Brett Cannonf4189912005-04-09 02:30:16 +0000257 def test_class_defs(self):
258 self.check_suite("class foo():pass")
Guido van Rossumfc158e22007-11-15 19:17:28 +0000259 self.check_suite("class foo(object):pass")
Mark Dickinson2bd61a92010-07-04 16:37:31 +0000260 self.check_suite("@class_decorator\n"
261 "class foo():pass")
262 self.check_suite("@class_decorator(arg)\n"
263 "class foo():pass")
264 self.check_suite("@decorator1\n"
265 "@decorator2\n"
266 "class foo():pass")
Tim Peterse8906822005-04-20 17:45:13 +0000267
Fred Drake58422e52001-06-04 03:56:24 +0000268 def test_import_from_statement(self):
269 self.check_suite("from sys.path import *")
270 self.check_suite("from sys.path import dirname")
Anthony Baxter1a4ddae2004-08-31 10:07:13 +0000271 self.check_suite("from sys.path import (dirname)")
272 self.check_suite("from sys.path import (dirname,)")
Fred Drake58422e52001-06-04 03:56:24 +0000273 self.check_suite("from sys.path import dirname as my_dirname")
Anthony Baxter1a4ddae2004-08-31 10:07:13 +0000274 self.check_suite("from sys.path import (dirname as my_dirname)")
275 self.check_suite("from sys.path import (dirname as my_dirname,)")
Fred Drake58422e52001-06-04 03:56:24 +0000276 self.check_suite("from sys.path import dirname, basename")
Anthony Baxter1a4ddae2004-08-31 10:07:13 +0000277 self.check_suite("from sys.path import (dirname, basename)")
278 self.check_suite("from sys.path import (dirname, basename,)")
Fred Drake58422e52001-06-04 03:56:24 +0000279 self.check_suite(
280 "from sys.path import dirname as my_dirname, basename")
281 self.check_suite(
Anthony Baxter1a4ddae2004-08-31 10:07:13 +0000282 "from sys.path import (dirname as my_dirname, basename)")
283 self.check_suite(
284 "from sys.path import (dirname as my_dirname, basename,)")
285 self.check_suite(
Fred Drake58422e52001-06-04 03:56:24 +0000286 "from sys.path import dirname, basename as my_basename")
Anthony Baxter1a4ddae2004-08-31 10:07:13 +0000287 self.check_suite(
288 "from sys.path import (dirname, basename as my_basename)")
289 self.check_suite(
290 "from sys.path import (dirname, basename as my_basename,)")
Benjamin Petersonc0747cf2008-11-03 20:31:38 +0000291 self.check_suite("from .bogus import x")
Fred Drakee3fb18c2001-01-07 06:02:19 +0000292
Fred Drake58422e52001-06-04 03:56:24 +0000293 def test_basic_import_statement(self):
294 self.check_suite("import sys")
295 self.check_suite("import sys as system")
296 self.check_suite("import sys, math")
297 self.check_suite("import sys as system, math")
298 self.check_suite("import sys, math as my_math")
Fred Drake79ca79d2000-08-21 22:30:53 +0000299
Mark Dickinson2cc8a5e2010-07-04 18:11:51 +0000300 def test_relative_imports(self):
301 self.check_suite("from . import name")
302 self.check_suite("from .. import name")
Mark Dickinsonfeb3b752010-07-04 18:38:57 +0000303 # check all the way up to '....', since '...' is tokenized
304 # differently from '.' (it's an ellipsis token).
305 self.check_suite("from ... import name")
306 self.check_suite("from .... import name")
Mark Dickinson2cc8a5e2010-07-04 18:11:51 +0000307 self.check_suite("from .pkg import name")
308 self.check_suite("from ..pkg import name")
Mark Dickinsonfeb3b752010-07-04 18:38:57 +0000309 self.check_suite("from ...pkg import name")
310 self.check_suite("from ....pkg import name")
Mark Dickinson2cc8a5e2010-07-04 18:11:51 +0000311
Neal Norwitz9caf9c02003-02-10 01:54:06 +0000312 def test_pep263(self):
313 self.check_suite("# -*- coding: iso-8859-1 -*-\n"
314 "pass\n")
315
316 def test_assert(self):
317 self.check_suite("assert alo < ahi and blo < bhi\n")
318
Benjamin Peterson4469d0c2008-11-30 22:46:23 +0000319 def test_with(self):
320 self.check_suite("with open('x'): pass\n")
321 self.check_suite("with open('x') as f: pass\n")
Georg Brandl0c315622009-05-25 21:10:36 +0000322 self.check_suite("with open('x') as f, open('y') as g: pass\n")
Benjamin Peterson4469d0c2008-11-30 22:46:23 +0000323
Georg Brandleee31162008-12-07 15:15:22 +0000324 def test_try_stmt(self):
325 self.check_suite("try: pass\nexcept: pass\n")
326 self.check_suite("try: pass\nfinally: pass\n")
327 self.check_suite("try: pass\nexcept A: pass\nfinally: pass\n")
328 self.check_suite("try: pass\nexcept A: pass\nexcept: pass\n"
329 "finally: pass\n")
330 self.check_suite("try: pass\nexcept: pass\nelse: pass\n")
331 self.check_suite("try: pass\nexcept: pass\nelse: pass\n"
332 "finally: pass\n")
333
Pablo Galindo9a0000d2019-03-21 23:33:02 +0000334 def test_if_stmt(self):
335 self.check_suite("if True:\n pass\nelse:\n pass\n")
336 self.check_suite("if True:\n pass\nelif True:\n pass\nelse:\n pass\n")
337
Thomas Wouters89f507f2006-12-13 04:49:30 +0000338 def test_position(self):
339 # An absolutely minimal test of position information. Better
340 # tests would be a big project.
Benjamin Peterson8f326b22009-12-13 02:10:36 +0000341 code = "def f(x):\n return x + 1"
Serhiy Storchakae5362ea2018-04-19 01:55:37 +0300342 st = parser.suite(code)
Thomas Wouters89f507f2006-12-13 04:49:30 +0000343
344 def walk(tree):
345 node_type = tree[0]
346 next = tree[1]
Serhiy Storchakae5362ea2018-04-19 01:55:37 +0300347 if isinstance(next, (tuple, list)):
Thomas Wouters89f507f2006-12-13 04:49:30 +0000348 for elt in tree[1:]:
349 for x in walk(elt):
350 yield x
351 else:
352 yield tree
353
Serhiy Storchakae5362ea2018-04-19 01:55:37 +0300354 expected = [
Thomas Wouters89f507f2006-12-13 04:49:30 +0000355 (1, 'def', 1, 0),
356 (1, 'f', 1, 4),
357 (7, '(', 1, 5),
358 (1, 'x', 1, 6),
359 (8, ')', 1, 7),
360 (11, ':', 1, 8),
361 (4, '', 1, 9),
362 (5, '', 2, -1),
363 (1, 'return', 2, 4),
364 (1, 'x', 2, 11),
365 (14, '+', 2, 13),
366 (2, '1', 2, 15),
367 (4, '', 2, 16),
Benjamin Peterson8f326b22009-12-13 02:10:36 +0000368 (6, '', 2, -1),
369 (4, '', 2, -1),
Serhiy Storchakae5362ea2018-04-19 01:55:37 +0300370 (0, '', 2, -1),
371 ]
372
373 self.assertEqual(list(walk(st.totuple(line_info=True, col_info=True))),
374 expected)
375 self.assertEqual(list(walk(st.totuple())),
376 [(t, n) for t, n, l, c in expected])
377 self.assertEqual(list(walk(st.totuple(line_info=True))),
378 [(t, n, l) for t, n, l, c in expected])
379 self.assertEqual(list(walk(st.totuple(col_info=True))),
380 [(t, n, c) for t, n, l, c in expected])
381 self.assertEqual(list(walk(st.tolist(line_info=True, col_info=True))),
382 [list(x) for x in expected])
383 self.assertEqual(list(walk(parser.st2tuple(st, line_info=True,
384 col_info=True))),
385 expected)
386 self.assertEqual(list(walk(parser.st2list(st, line_info=True,
387 col_info=True))),
388 [list(x) for x in expected])
Thomas Wouters89f507f2006-12-13 04:49:30 +0000389
Benjamin Peterson4905e802009-09-27 02:43:28 +0000390 def test_extended_unpacking(self):
391 self.check_suite("*a = y")
392 self.check_suite("x, *b, = m")
393 self.check_suite("[*a, *b] = y")
394 self.check_suite("for [*x, b] in x: pass")
395
Mark Dickinsoncf360b92012-05-07 12:01:27 +0100396 def test_raise_statement(self):
397 self.check_suite("raise\n")
398 self.check_suite("raise e\n")
399 self.check_suite("try:\n"
400 " suite\n"
401 "except Exception as e:\n"
402 " raise ValueError from e\n")
403
Benjamin Peterson025e9eb2015-05-05 20:16:41 -0400404 def test_list_displays(self):
405 self.check_expr('[]')
406 self.check_expr('[*{2}, 3, *[4]]')
407
Mark Dickinson11c1dee2012-05-07 16:34:34 +0100408 def test_set_displays(self):
Benjamin Peterson025e9eb2015-05-05 20:16:41 -0400409 self.check_expr('{*{2}, 3, *[4]}')
Mark Dickinson11c1dee2012-05-07 16:34:34 +0100410 self.check_expr('{2}')
411 self.check_expr('{2,}')
412 self.check_expr('{2, 3}')
413 self.check_expr('{2, 3,}')
414
415 def test_dict_displays(self):
416 self.check_expr('{}')
417 self.check_expr('{a:b}')
418 self.check_expr('{a:b,}')
419 self.check_expr('{a:b, c:d}')
420 self.check_expr('{a:b, c:d,}')
Benjamin Peterson025e9eb2015-05-05 20:16:41 -0400421 self.check_expr('{**{}}')
422 self.check_expr('{**{}, 3:4, **{5:6, 7:8}}')
423
424 def test_argument_unpacking(self):
Yury Selivanov50a26142015-08-05 17:59:45 -0400425 self.check_expr("f(*a, **b)")
Benjamin Peterson025e9eb2015-05-05 20:16:41 -0400426 self.check_expr('f(a, *b, *c, *d)')
427 self.check_expr('f(**a, **b)')
428 self.check_expr('f(2, *a, *b, **b, **c, **d)')
Yury Selivanov50a26142015-08-05 17:59:45 -0400429 self.check_expr("f(*b, *() or () and (), **{} and {}, **() or {})")
Mark Dickinson11c1dee2012-05-07 16:34:34 +0100430
431 def test_set_comprehensions(self):
432 self.check_expr('{x for x in seq}')
433 self.check_expr('{f(x) for x in seq}')
434 self.check_expr('{f(x) for x in seq if condition(x)}')
435
436 def test_dict_comprehensions(self):
437 self.check_expr('{x:x for x in seq}')
438 self.check_expr('{x**2:x[3] for x in seq if condition(x)}')
439 self.check_expr('{x:x for x in seq1 for y in seq2 if condition(x, y)}')
440
Emily Morehouse8f59ee02019-01-24 16:49:56 -0700441 def test_named_expressions(self):
442 self.check_suite("(a := 1)")
443 self.check_suite("(a := a)")
444 self.check_suite("if (match := pattern.search(data)) is None: pass")
Xtreakd4fceaa2019-02-02 03:10:16 +0530445 self.check_suite("while match := pattern.search(f.read()): pass")
Emily Morehouse8f59ee02019-01-24 16:49:56 -0700446 self.check_suite("[y := f(x), y**2, y**3]")
447 self.check_suite("filtered_data = [y for x in data if (y := f(x)) is None]")
448 self.check_suite("(y := f(x))")
449 self.check_suite("y0 = (y1 := f(x))")
450 self.check_suite("foo(x=(y := f(x)))")
451 self.check_suite("def foo(answer=(p := 42)): pass")
452 self.check_suite("def foo(answer: (p := 42) = 5): pass")
453 self.check_suite("lambda: (x := 1)")
454 self.check_suite("(x := lambda: 1)")
455 self.check_suite("(x := lambda: (y := 1))") # not in PEP
456 self.check_suite("lambda line: (m := re.match(pattern, line)) and m.group(1)")
457 self.check_suite("x = (y := 0)")
458 self.check_suite("(z:=(y:=(x:=0)))")
459 self.check_suite("(info := (name, phone, *rest))")
460 self.check_suite("(x:=1,2)")
461 self.check_suite("(total := total + tax)")
462 self.check_suite("len(lines := f.readlines())")
463 self.check_suite("foo(x := 3, cat='vector')")
464 self.check_suite("foo(cat=(category := 'vector'))")
465 self.check_suite("if any(len(longline := l) >= 100 for l in lines): print(longline)")
466 self.check_suite(
467 "if env_base := os.environ.get('PYTHONUSERBASE', None): return env_base"
468 )
469 self.check_suite(
470 "if self._is_special and (ans := self._check_nans(context=context)): return ans"
471 )
472 self.check_suite("foo(b := 2, a=1)")
473 self.check_suite("foo(b := 2, a=1)")
474 self.check_suite("foo((b := 2), a=1)")
475 self.check_suite("foo(c=(b := 2), a=1)")
Miss Islington (bot)874ff652019-06-22 15:34:03 -0700476 self.check_suite("{(x := C(i)).q: x for i in y}")
477
Thomas Wouters89f507f2006-12-13 04:49:30 +0000478
Fred Drake79ca79d2000-08-21 22:30:53 +0000479#
480# Second, we take *invalid* trees and make sure we get ParserError
481# rejections for them.
482#
483
Fred Drake58422e52001-06-04 03:56:24 +0000484class IllegalSyntaxTestCase(unittest.TestCase):
Guido van Rossum32c2ae72002-08-22 19:45:32 +0000485
Fred Drake58422e52001-06-04 03:56:24 +0000486 def check_bad_tree(self, tree, label):
487 try:
Fred Drake6e4f2c02001-07-17 19:33:25 +0000488 parser.sequence2st(tree)
Fred Drake58422e52001-06-04 03:56:24 +0000489 except parser.ParserError:
490 pass
491 else:
492 self.fail("did not detect invalid tree for %r" % label)
Fred Drake79ca79d2000-08-21 22:30:53 +0000493
Fred Drake58422e52001-06-04 03:56:24 +0000494 def test_junk(self):
495 # not even remotely valid:
496 self.check_bad_tree((1, 2, 3), "<junk>")
497
Serhiy Storchakaa79f4c22017-04-19 21:09:21 +0300498 def test_illegal_terminal(self):
499 tree = \
500 (257,
501 (269,
502 (270,
503 (271,
504 (277,
505 (1,))),
506 (4, ''))),
507 (4, ''),
508 (0, ''))
509 self.check_bad_tree(tree, "too small items in terminal node")
510 tree = \
511 (257,
512 (269,
513 (270,
514 (271,
515 (277,
516 (1, b'pass'))),
517 (4, ''))),
518 (4, ''),
519 (0, ''))
520 self.check_bad_tree(tree, "non-string second item in terminal node")
521 tree = \
522 (257,
523 (269,
524 (270,
525 (271,
526 (277,
527 (1, 'pass', '0', 0))),
528 (4, ''))),
529 (4, ''),
530 (0, ''))
531 self.check_bad_tree(tree, "non-integer third item in terminal node")
532 tree = \
533 (257,
534 (269,
535 (270,
536 (271,
537 (277,
538 (1, 'pass', 0, 0))),
539 (4, ''))),
540 (4, ''),
541 (0, ''))
542 self.check_bad_tree(tree, "too many items in terminal node")
543
Fred Drakecf580c72001-07-17 03:01:29 +0000544 def test_illegal_yield_1(self):
Guido van Rossum32c2ae72002-08-22 19:45:32 +0000545 # Illegal yield statement: def f(): return 1; yield 1
Fred Drakecf580c72001-07-17 03:01:29 +0000546 tree = \
547 (257,
548 (264,
549 (285,
550 (259,
551 (1, 'def'),
552 (1, 'f'),
553 (260, (7, '('), (8, ')')),
554 (11, ':'),
555 (291,
556 (4, ''),
557 (5, ''),
558 (264,
559 (265,
560 (266,
561 (272,
562 (275,
563 (1, 'return'),
564 (313,
565 (292,
566 (293,
567 (294,
568 (295,
569 (297,
570 (298,
571 (299,
572 (300,
573 (301,
574 (302, (303, (304, (305, (2, '1')))))))))))))))))),
575 (264,
576 (265,
577 (266,
578 (272,
579 (276,
580 (1, 'yield'),
581 (313,
582 (292,
583 (293,
584 (294,
585 (295,
586 (297,
587 (298,
588 (299,
589 (300,
590 (301,
591 (302,
592 (303, (304, (305, (2, '1')))))))))))))))))),
593 (4, ''))),
594 (6, ''))))),
595 (4, ''),
596 (0, ''))))
597 self.check_bad_tree(tree, "def f():\n return 1\n yield 1")
598
599 def test_illegal_yield_2(self):
Guido van Rossum32c2ae72002-08-22 19:45:32 +0000600 # Illegal return in generator: def f(): return 1; yield 1
Fred Drakecf580c72001-07-17 03:01:29 +0000601 tree = \
602 (257,
603 (264,
604 (265,
605 (266,
606 (278,
607 (1, 'from'),
608 (281, (1, '__future__')),
609 (1, 'import'),
610 (279, (1, 'generators')))),
611 (4, ''))),
612 (264,
613 (285,
614 (259,
615 (1, 'def'),
616 (1, 'f'),
617 (260, (7, '('), (8, ')')),
618 (11, ':'),
619 (291,
620 (4, ''),
621 (5, ''),
622 (264,
623 (265,
624 (266,
625 (272,
626 (275,
627 (1, 'return'),
628 (313,
629 (292,
630 (293,
631 (294,
632 (295,
633 (297,
634 (298,
635 (299,
636 (300,
637 (301,
638 (302, (303, (304, (305, (2, '1')))))))))))))))))),
639 (264,
640 (265,
641 (266,
642 (272,
643 (276,
644 (1, 'yield'),
645 (313,
646 (292,
647 (293,
648 (294,
649 (295,
650 (297,
651 (298,
652 (299,
653 (300,
654 (301,
655 (302,
656 (303, (304, (305, (2, '1')))))))))))))))))),
657 (4, ''))),
658 (6, ''))))),
659 (4, ''),
660 (0, ''))))
661 self.check_bad_tree(tree, "def f():\n return 1\n yield 1")
662
Fred Drake58422e52001-06-04 03:56:24 +0000663 def test_a_comma_comma_c(self):
Guido van Rossum32c2ae72002-08-22 19:45:32 +0000664 # Illegal input: a,,c
Fred Drake58422e52001-06-04 03:56:24 +0000665 tree = \
666 (258,
667 (311,
668 (290,
669 (291,
670 (292,
671 (293,
672 (295,
673 (296,
674 (297,
675 (298, (299, (300, (301, (302, (303, (1, 'a')))))))))))))),
676 (12, ','),
677 (12, ','),
678 (290,
679 (291,
680 (292,
681 (293,
682 (295,
683 (296,
684 (297,
685 (298, (299, (300, (301, (302, (303, (1, 'c'))))))))))))))),
686 (4, ''),
687 (0, ''))
688 self.check_bad_tree(tree, "a,,c")
689
690 def test_illegal_operator(self):
Guido van Rossum32c2ae72002-08-22 19:45:32 +0000691 # Illegal input: a $= b
Fred Drake58422e52001-06-04 03:56:24 +0000692 tree = \
693 (257,
694 (264,
695 (265,
696 (266,
697 (267,
698 (312,
699 (291,
700 (292,
701 (293,
702 (294,
703 (296,
704 (297,
705 (298,
706 (299,
707 (300, (301, (302, (303, (304, (1, 'a'))))))))))))))),
708 (268, (37, '$=')),
709 (312,
710 (291,
711 (292,
712 (293,
713 (294,
714 (296,
715 (297,
716 (298,
717 (299,
718 (300, (301, (302, (303, (304, (1, 'b'))))))))))))))))),
719 (4, ''))),
720 (0, ''))
721 self.check_bad_tree(tree, "a $= b")
Fred Drake79ca79d2000-08-21 22:30:53 +0000722
Neal Norwitz9caf9c02003-02-10 01:54:06 +0000723 def test_malformed_global(self):
724 #doesn't have global keyword in ast
725 tree = (257,
726 (264,
727 (265,
728 (266,
729 (282, (1, 'foo'))), (4, ''))),
730 (4, ''),
Tim Petersf2715e02003-02-19 02:35:07 +0000731 (0, ''))
Neal Norwitz9caf9c02003-02-10 01:54:06 +0000732 self.check_bad_tree(tree, "malformed global ast")
Fred Drake79ca79d2000-08-21 22:30:53 +0000733
Mark Dickinson2cc8a5e2010-07-04 18:11:51 +0000734 def test_missing_import_source(self):
Mark Dickinson3445b482010-07-04 18:15:26 +0000735 # from import fred
Mark Dickinson2cc8a5e2010-07-04 18:11:51 +0000736 tree = \
737 (257,
Mark Dickinson3445b482010-07-04 18:15:26 +0000738 (268,
739 (269,
740 (270,
741 (282,
742 (284, (1, 'from'), (1, 'import'),
743 (287, (285, (1, 'fred')))))),
Mark Dickinson2cc8a5e2010-07-04 18:11:51 +0000744 (4, ''))),
745 (4, ''), (0, ''))
Mark Dickinson3445b482010-07-04 18:15:26 +0000746 self.check_bad_tree(tree, "from import fred")
Mark Dickinson2cc8a5e2010-07-04 18:11:51 +0000747
Serhiy Storchakaa79f4c22017-04-19 21:09:21 +0300748 def test_illegal_encoding(self):
749 # Illegal encoding declaration
750 tree = \
Emily Morehouse8f59ee02019-01-24 16:49:56 -0700751 (341,
Serhiy Storchakaa79f4c22017-04-19 21:09:21 +0300752 (257, (0, '')))
753 self.check_bad_tree(tree, "missed encoding")
754 tree = \
Emily Morehouse8f59ee02019-01-24 16:49:56 -0700755 (341,
Serhiy Storchakaa79f4c22017-04-19 21:09:21 +0300756 (257, (0, '')),
757 b'iso-8859-1')
758 self.check_bad_tree(tree, "non-string encoding")
759 tree = \
Emily Morehouse8f59ee02019-01-24 16:49:56 -0700760 (341,
Serhiy Storchakaa79f4c22017-04-19 21:09:21 +0300761 (257, (0, '')),
762 '\udcff')
763 with self.assertRaises(UnicodeEncodeError):
764 parser.sequence2st(tree)
765
tyomitchcb0748d2019-04-03 08:12:07 +0300766 def test_invalid_node_id(self):
767 tree = (257, (269, (-7, '')))
768 self.check_bad_tree(tree, "negative node id")
769 tree = (257, (269, (99, '')))
770 self.check_bad_tree(tree, "invalid token id")
771 tree = (257, (269, (9999, (0, ''))))
772 self.check_bad_tree(tree, "invalid symbol id")
773
774 def test_ParserError_message(self):
775 try:
776 parser.sequence2st((257,(269,(257,(0,'')))))
777 except parser.ParserError as why:
778 self.assertIn("compound_stmt", str(why)) # Expected
779 self.assertIn("file_input", str(why)) # Got
780
781
Jeremy Hylton3e0055f2005-10-20 19:59:25 +0000782
783class CompileTestCase(unittest.TestCase):
784
785 # These tests are very minimal. :-(
786
787 def test_compile_expr(self):
788 st = parser.expr('2 + 3')
789 code = parser.compilest(st)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000790 self.assertEqual(eval(code), 5)
Jeremy Hylton3e0055f2005-10-20 19:59:25 +0000791
792 def test_compile_suite(self):
793 st = parser.suite('x = 2; y = x + 3')
794 code = parser.compilest(st)
795 globs = {}
Georg Brandl7cae87c2006-09-06 06:51:57 +0000796 exec(code, globs)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000797 self.assertEqual(globs['y'], 5)
Jeremy Hylton3e0055f2005-10-20 19:59:25 +0000798
799 def test_compile_error(self):
800 st = parser.suite('1 = 3 + 4')
801 self.assertRaises(SyntaxError, parser.compilest, st)
802
Guido van Rossumb5a755e2007-07-18 18:15:48 +0000803 def test_compile_badunicode(self):
Guido van Rossum7eb6ca52007-07-18 21:00:22 +0000804 st = parser.suite('a = "\\U12345678"')
Guido van Rossumb5a755e2007-07-18 18:15:48 +0000805 self.assertRaises(SyntaxError, parser.compilest, st)
Guido van Rossum7eb6ca52007-07-18 21:00:22 +0000806 st = parser.suite('a = "\\u1"')
Guido van Rossumb5a755e2007-07-18 18:15:48 +0000807 self.assertRaises(SyntaxError, parser.compilest, st)
808
Mark Dickinsond35a32e2010-06-17 12:33:22 +0000809 def test_issue_9011(self):
810 # Issue 9011: compilation of an unary minus expression changed
811 # the meaning of the ST, so that a second compilation produced
812 # incorrect results.
813 st = parser.expr('-3')
814 code1 = parser.compilest(st)
815 self.assertEqual(eval(code1), -3)
816 code2 = parser.compilest(st)
817 self.assertEqual(eval(code2), -3)
818
Serhiy Storchaka9305d832016-06-18 13:53:36 +0300819 def test_compile_filename(self):
820 st = parser.expr('a + 5')
821 code = parser.compilest(st)
822 self.assertEqual(code.co_filename, '<syntax-tree>')
823 code = st.compile()
824 self.assertEqual(code.co_filename, '<syntax-tree>')
Serhiy Storchakafebc3322016-08-06 23:29:29 +0300825 for filename in 'file.py', b'file.py':
Serhiy Storchaka9305d832016-06-18 13:53:36 +0300826 code = parser.compilest(st, filename)
827 self.assertEqual(code.co_filename, 'file.py')
828 code = st.compile(filename)
829 self.assertEqual(code.co_filename, 'file.py')
Serhiy Storchakafebc3322016-08-06 23:29:29 +0300830 for filename in bytearray(b'file.py'), memoryview(b'file.py'):
831 with self.assertWarns(DeprecationWarning):
832 code = parser.compilest(st, filename)
833 self.assertEqual(code.co_filename, 'file.py')
834 with self.assertWarns(DeprecationWarning):
835 code = st.compile(filename)
836 self.assertEqual(code.co_filename, 'file.py')
Serhiy Storchaka9305d832016-06-18 13:53:36 +0300837 self.assertRaises(TypeError, parser.compilest, st, list(b'file.py'))
838 self.assertRaises(TypeError, st.compile, list(b'file.py'))
839
840
Christian Heimes90c3d9b2008-02-23 13:18:03 +0000841class ParserStackLimitTestCase(unittest.TestCase):
Mark Dickinsond35a32e2010-06-17 12:33:22 +0000842 """try to push the parser to/over its limits.
Christian Heimes90c3d9b2008-02-23 13:18:03 +0000843 see http://bugs.python.org/issue1881 for a discussion
844 """
845 def _nested_expression(self, level):
846 return "["*level+"]"*level
847
848 def test_deeply_nested_list(self):
Emily Morehouse8f59ee02019-01-24 16:49:56 -0700849 # This has fluctuated between 99 levels in 2.x, down to 93 levels in
850 # 3.7.X and back up to 99 in 3.8.X. Related to MAXSTACK size in Parser.h
851 e = self._nested_expression(99)
Christian Heimes90c3d9b2008-02-23 13:18:03 +0000852 st = parser.expr(e)
853 st.compile()
854
855 def test_trigger_memory_error(self):
856 e = self._nested_expression(100)
Ezio Melotti39191842013-03-09 22:17:33 +0200857 rc, out, err = assert_python_failure('-c', e)
858 # parsing the expression will result in an error message
859 # followed by a MemoryError (see #11963)
Ezio Melottie7c32992013-03-10 03:25:45 +0200860 self.assertIn(b's_push: parser stack overflow', err)
861 self.assertIn(b'MemoryError', err)
Christian Heimes90c3d9b2008-02-23 13:18:03 +0000862
Mark Dickinson211c6252009-02-01 10:28:51 +0000863class STObjectTestCase(unittest.TestCase):
864 """Test operations on ST objects themselves"""
865
866 def test_comparisons(self):
867 # ST objects should support order and equality comparisons
868 st1 = parser.expr('2 + 3')
869 st2 = parser.suite('x = 2; y = x + 3')
870 st3 = parser.expr('list(x**3 for x in range(20))')
871 st1_copy = parser.expr('2 + 3')
872 st2_copy = parser.suite('x = 2; y = x + 3')
873 st3_copy = parser.expr('list(x**3 for x in range(20))')
874
875 # exercise fast path for object identity
Ezio Melottib3aedd42010-11-20 19:04:17 +0000876 self.assertEqual(st1 == st1, True)
877 self.assertEqual(st2 == st2, True)
878 self.assertEqual(st3 == st3, True)
Mark Dickinson211c6252009-02-01 10:28:51 +0000879 # slow path equality
880 self.assertEqual(st1, st1_copy)
881 self.assertEqual(st2, st2_copy)
882 self.assertEqual(st3, st3_copy)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000883 self.assertEqual(st1 == st2, False)
884 self.assertEqual(st1 == st3, False)
885 self.assertEqual(st2 == st3, False)
886 self.assertEqual(st1 != st1, False)
887 self.assertEqual(st2 != st2, False)
888 self.assertEqual(st3 != st3, False)
889 self.assertEqual(st1 != st1_copy, False)
890 self.assertEqual(st2 != st2_copy, False)
891 self.assertEqual(st3 != st3_copy, False)
892 self.assertEqual(st2 != st1, True)
893 self.assertEqual(st1 != st3, True)
894 self.assertEqual(st3 != st2, True)
Mark Dickinson211c6252009-02-01 10:28:51 +0000895 # we don't particularly care what the ordering is; just that
896 # it's usable and self-consistent
Ezio Melottib3aedd42010-11-20 19:04:17 +0000897 self.assertEqual(st1 < st2, not (st2 <= st1))
898 self.assertEqual(st1 < st3, not (st3 <= st1))
899 self.assertEqual(st2 < st3, not (st3 <= st2))
900 self.assertEqual(st1 < st2, st2 > st1)
901 self.assertEqual(st1 < st3, st3 > st1)
902 self.assertEqual(st2 < st3, st3 > st2)
903 self.assertEqual(st1 <= st2, st2 >= st1)
904 self.assertEqual(st3 <= st1, st1 >= st3)
905 self.assertEqual(st2 <= st3, st3 >= st2)
Mark Dickinson211c6252009-02-01 10:28:51 +0000906 # transitivity
907 bottom = min(st1, st2, st3)
908 top = max(st1, st2, st3)
909 mid = sorted([st1, st2, st3])[1]
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000910 self.assertTrue(bottom < mid)
911 self.assertTrue(bottom < top)
912 self.assertTrue(mid < top)
913 self.assertTrue(bottom <= mid)
914 self.assertTrue(bottom <= top)
915 self.assertTrue(mid <= top)
916 self.assertTrue(bottom <= bottom)
917 self.assertTrue(mid <= mid)
918 self.assertTrue(top <= top)
Mark Dickinson211c6252009-02-01 10:28:51 +0000919 # interaction with other types
Ezio Melottib3aedd42010-11-20 19:04:17 +0000920 self.assertEqual(st1 == 1588.602459, False)
921 self.assertEqual('spanish armada' != st2, True)
Mark Dickinson211c6252009-02-01 10:28:51 +0000922 self.assertRaises(TypeError, operator.ge, st3, None)
923 self.assertRaises(TypeError, operator.le, False, st1)
924 self.assertRaises(TypeError, operator.lt, st1, 1815)
925 self.assertRaises(TypeError, operator.gt, b'waterloo', st2)
926
Serhiy Storchakaa79f4c22017-04-19 21:09:21 +0300927 def test_copy_pickle(self):
928 sts = [
929 parser.expr('2 + 3'),
930 parser.suite('x = 2; y = x + 3'),
931 parser.expr('list(x**3 for x in range(20))')
932 ]
933 for st in sts:
934 st_copy = copy.copy(st)
935 self.assertEqual(st_copy.totuple(), st.totuple())
936 st_copy = copy.deepcopy(st)
937 self.assertEqual(st_copy.totuple(), st.totuple())
938 for proto in range(pickle.HIGHEST_PROTOCOL+1):
939 st_copy = pickle.loads(pickle.dumps(st, proto))
940 self.assertEqual(st_copy.totuple(), st.totuple())
941
Jesus Ceae9c53182012-08-03 14:28:37 +0200942 check_sizeof = support.check_sizeof
943
944 @support.cpython_only
945 def test_sizeof(self):
946 def XXXROUNDUP(n):
947 if n <= 1:
948 return n
949 if n <= 128:
950 return (n + 3) & ~3
951 return 1 << (n - 1).bit_length()
952
Guido van Rossum495da292019-03-07 12:38:08 -0800953 basesize = support.calcobjsize('Piii')
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000954 nodesize = struct.calcsize('hP3iP0h2i')
Jesus Ceae9c53182012-08-03 14:28:37 +0200955 def sizeofchildren(node):
956 if node is None:
957 return 0
958 res = 0
959 hasstr = len(node) > 1 and isinstance(node[-1], str)
960 if hasstr:
961 res += len(node[-1]) + 1
962 children = node[1:-1] if hasstr else node[1:]
963 if children:
964 res += XXXROUNDUP(len(children)) * nodesize
Jesus Ceae9c53182012-08-03 14:28:37 +0200965 for child in children:
966 res += sizeofchildren(child)
967 return res
968
969 def check_st_sizeof(st):
970 self.check_sizeof(st, basesize + nodesize +
971 sizeofchildren(st.totuple()))
972
973 check_st_sizeof(parser.expr('2 + 3'))
974 check_st_sizeof(parser.expr('2 + 3 + 4'))
975 check_st_sizeof(parser.suite('x = 2 + 3'))
976 check_st_sizeof(parser.suite(''))
977 check_st_sizeof(parser.suite('# -*- coding: utf-8 -*-'))
978 check_st_sizeof(parser.expr('[' + '2,' * 1000 + ']'))
979
Mark Dickinson211c6252009-02-01 10:28:51 +0000980
981 # XXX tests for pickling and unpickling of ST objects should go here
982
Benjamin Petersonf719957d2011-06-04 22:06:42 -0500983class OtherParserCase(unittest.TestCase):
984
985 def test_two_args_to_expr(self):
986 # See bug #12264
987 with self.assertRaises(TypeError):
988 parser.expr("a", "b")
989
Fred Drake2e2be372001-09-20 21:33:42 +0000990if __name__ == "__main__":
Zachary Ware38c707e2015-04-13 15:00:43 -0500991 unittest.main()