blob: ec1845d7fe9ae0315aa18344ad64ca757baf679a [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
Pablo Galindo9211e2f2019-07-30 12:04:01 +01009from test.support.script_helper import assert_python_ok
Fred Drake79ca79d2000-08-21 22:30:53 +000010
11#
12# First, we test that we can generate trees from valid source fragments,
13# and that these valid trees are indeed allowed by the tree-loading side
14# of the parser module.
15#
16
Fred Drake58422e52001-06-04 03:56:24 +000017class RoundtripLegalSyntaxTestCase(unittest.TestCase):
Guido van Rossum32c2ae72002-08-22 19:45:32 +000018
Fred Drake58422e52001-06-04 03:56:24 +000019 def roundtrip(self, f, s):
20 st1 = f(s)
21 t = st1.totuple()
22 try:
Fred Drake6e4f2c02001-07-17 19:33:25 +000023 st2 = parser.sequence2st(t)
Guido van Rossumb940e112007-01-10 16:19:56 +000024 except parser.ParserError as why:
Anthony Baxterc2a5a632004-08-02 06:10:11 +000025 self.fail("could not roundtrip %r: %s" % (s, why))
Fred Drake79ca79d2000-08-21 22:30:53 +000026
Ezio Melottib3aedd42010-11-20 19:04:17 +000027 self.assertEqual(t, st2.totuple(),
28 "could not re-generate syntax tree")
Fred Drake28f739a2000-08-25 22:42:40 +000029
Fred Drake58422e52001-06-04 03:56:24 +000030 def check_expr(self, s):
31 self.roundtrip(parser.expr, s)
Fred Drake28f739a2000-08-25 22:42:40 +000032
Benjamin Petersonf216c942008-10-31 02:28:05 +000033 def test_flags_passed(self):
Mike53f7a7c2017-12-14 14:04:53 +030034 # The unicode literals flags has to be passed from the parser to AST
Benjamin Petersonf216c942008-10-31 02:28:05 +000035 # generation.
36 suite = parser.suite("from __future__ import unicode_literals; x = ''")
37 code = suite.compile()
38 scope = {}
39 exec(code, {}, scope)
Ezio Melottie9615932010-01-24 19:26:24 +000040 self.assertIsInstance(scope["x"], str)
Benjamin Petersonf216c942008-10-31 02:28:05 +000041
Fred Drake58422e52001-06-04 03:56:24 +000042 def check_suite(self, s):
43 self.roundtrip(parser.suite, s)
Fred Drake28f739a2000-08-25 22:42:40 +000044
Fred Drakecf580c72001-07-17 03:01:29 +000045 def test_yield_statement(self):
Tim Peters496563a2002-04-01 00:28:59 +000046 self.check_suite("def f(): yield 1")
Phillip J. Eby0d6615f2005-08-02 00:46:46 +000047 self.check_suite("def f(): yield")
48 self.check_suite("def f(): x += yield")
49 self.check_suite("def f(): x = yield 1")
50 self.check_suite("def f(): x = y = yield 1")
51 self.check_suite("def f(): x = yield")
52 self.check_suite("def f(): x = y = yield")
53 self.check_suite("def f(): 1 + (yield)*2")
54 self.check_suite("def f(): (yield 1)*2")
Tim Peters496563a2002-04-01 00:28:59 +000055 self.check_suite("def f(): return; yield 1")
56 self.check_suite("def f(): yield 1; return")
Nick Coghlan1f7ce622012-01-13 21:43:40 +100057 self.check_suite("def f(): yield from 1")
58 self.check_suite("def f(): x = yield from 1")
59 self.check_suite("def f(): f((yield from 1))")
60 self.check_suite("def f(): yield 1; return 1")
Tim Peters496563a2002-04-01 00:28:59 +000061 self.check_suite("def f():\n"
Fred Drakecf580c72001-07-17 03:01:29 +000062 " for x in range(30):\n"
63 " yield x\n")
Phillip J. Eby0d6615f2005-08-02 00:46:46 +000064 self.check_suite("def f():\n"
65 " if (yield):\n"
66 " yield x\n")
Fred Drakecf580c72001-07-17 03:01:29 +000067
Yury Selivanov75445082015-05-11 22:57:16 -040068 def test_await_statement(self):
69 self.check_suite("async def f():\n await smth()")
70 self.check_suite("async def f():\n foo = await smth()")
71 self.check_suite("async def f():\n foo, bar = await smth()")
72 self.check_suite("async def f():\n (await smth())")
73 self.check_suite("async def f():\n foo((await smth()))")
74 self.check_suite("async def f():\n await foo(); return 42")
75
76 def test_async_with_statement(self):
77 self.check_suite("async def f():\n async with 1: pass")
78 self.check_suite("async def f():\n async with a as b, c as d: pass")
79
80 def test_async_for_statement(self):
81 self.check_suite("async def f():\n async for i in (): pass")
82 self.check_suite("async def f():\n async for i, b in (): pass")
83
Mark Dickinson407b3bd2012-04-29 22:18:31 +010084 def test_nonlocal_statement(self):
85 self.check_suite("def f():\n"
86 " x = 0\n"
87 " def g():\n"
88 " nonlocal x\n")
89 self.check_suite("def f():\n"
90 " x = y = 0\n"
91 " def g():\n"
92 " nonlocal x, y\n")
93
Fred Drake58422e52001-06-04 03:56:24 +000094 def test_expressions(self):
95 self.check_expr("foo(1)")
96 self.check_expr("[1, 2, 3]")
97 self.check_expr("[x**3 for x in range(20)]")
98 self.check_expr("[x**3 for x in range(20) if x % 3]")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000099 self.check_expr("[x**3 for x in range(20) if x % 2 if x % 3]")
100 self.check_expr("list(x**3 for x in range(20))")
101 self.check_expr("list(x**3 for x in range(20) if x % 3)")
102 self.check_expr("list(x**3 for x in range(20) if x % 2 if x % 3)")
Fred Drake58422e52001-06-04 03:56:24 +0000103 self.check_expr("foo(*args)")
104 self.check_expr("foo(*args, **kw)")
105 self.check_expr("foo(**kw)")
106 self.check_expr("foo(key=value)")
107 self.check_expr("foo(key=value, *args)")
108 self.check_expr("foo(key=value, *args, **kw)")
109 self.check_expr("foo(key=value, **kw)")
110 self.check_expr("foo(a, b, c, *args)")
111 self.check_expr("foo(a, b, c, *args, **kw)")
112 self.check_expr("foo(a, b, c, **kw)")
Benjamin Peterson3938a902008-08-20 02:33:00 +0000113 self.check_expr("foo(a, *args, keyword=23)")
Fred Drake58422e52001-06-04 03:56:24 +0000114 self.check_expr("foo + bar")
Michael W. Hudson5e83b7a2003-01-29 14:20:23 +0000115 self.check_expr("foo - bar")
116 self.check_expr("foo * bar")
117 self.check_expr("foo / bar")
118 self.check_expr("foo // bar")
Emily Morehouse8f59ee02019-01-24 16:49:56 -0700119 self.check_expr("(foo := 1)")
Fred Drake58422e52001-06-04 03:56:24 +0000120 self.check_expr("lambda: 0")
121 self.check_expr("lambda x: 0")
122 self.check_expr("lambda *y: 0")
123 self.check_expr("lambda *y, **z: 0")
124 self.check_expr("lambda **z: 0")
125 self.check_expr("lambda x, y: 0")
126 self.check_expr("lambda foo=bar: 0")
127 self.check_expr("lambda foo=bar, spaz=nifty+spit: 0")
128 self.check_expr("lambda foo=bar, **z: 0")
129 self.check_expr("lambda foo=bar, blaz=blat+2, **z: 0")
130 self.check_expr("lambda foo=bar, blaz=blat+2, *y, **z: 0")
131 self.check_expr("lambda x, *y, **z: 0")
Raymond Hettinger354433a2004-05-19 08:20:33 +0000132 self.check_expr("(x for x in range(10))")
133 self.check_expr("foo(x for x in range(10))")
Mark Dickinsonda029fb2012-05-07 17:24:04 +0100134 self.check_expr("...")
135 self.check_expr("a[...]")
Fred Drake79ca79d2000-08-21 22:30:53 +0000136
Fred Drake58422e52001-06-04 03:56:24 +0000137 def test_simple_expression(self):
138 # expr_stmt
139 self.check_suite("a")
Fred Drake79ca79d2000-08-21 22:30:53 +0000140
Fred Drake58422e52001-06-04 03:56:24 +0000141 def test_simple_assignments(self):
142 self.check_suite("a = b")
143 self.check_suite("a = b = c = d = e")
Fred Drake28f739a2000-08-25 22:42:40 +0000144
Yury Selivanovf8cb8a12016-09-08 20:50:03 -0700145 def test_var_annot(self):
146 self.check_suite("x: int = 5")
147 self.check_suite("y: List[T] = []; z: [list] = fun()")
148 self.check_suite("x: tuple = (1, 2)")
149 self.check_suite("d[f()]: int = 42")
150 self.check_suite("f(d[x]): str = 'abc'")
151 self.check_suite("x.y.z.w: complex = 42j")
152 self.check_suite("x: int")
153 self.check_suite("def f():\n"
154 " x: str\n"
155 " y: int = 5\n")
156 self.check_suite("class C:\n"
157 " x: str\n"
158 " y: int = 5\n")
159 self.check_suite("class C:\n"
160 " def __init__(self, x: int) -> None:\n"
161 " self.x: int = x\n")
162 # double check for nonsense
163 with self.assertRaises(SyntaxError):
164 exec("2+2: int", {}, {})
165 with self.assertRaises(SyntaxError):
166 exec("[]: int = 5", {}, {})
167 with self.assertRaises(SyntaxError):
168 exec("x, *y, z: int = range(5)", {}, {})
169 with self.assertRaises(SyntaxError):
Ivan Levkivskyi62c35a82019-01-25 01:39:19 +0000170 exec("x: int = 1, y = 2", {}, {})
Yury Selivanovf8cb8a12016-09-08 20:50:03 -0700171 with self.assertRaises(SyntaxError):
172 exec("u = v: int", {}, {})
173 with self.assertRaises(SyntaxError):
174 exec("False: int", {}, {})
175 with self.assertRaises(SyntaxError):
176 exec("x.False: int", {}, {})
177 with self.assertRaises(SyntaxError):
178 exec("x.y,: int", {}, {})
179 with self.assertRaises(SyntaxError):
180 exec("[0]: int", {}, {})
181 with self.assertRaises(SyntaxError):
182 exec("f(): int", {}, {})
183
Fred Drake58422e52001-06-04 03:56:24 +0000184 def test_simple_augmented_assignments(self):
185 self.check_suite("a += b")
186 self.check_suite("a -= b")
187 self.check_suite("a *= b")
188 self.check_suite("a /= b")
Michael W. Hudson5e83b7a2003-01-29 14:20:23 +0000189 self.check_suite("a //= b")
Fred Drake58422e52001-06-04 03:56:24 +0000190 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")
196 self.check_suite("a **= b")
Fred Drakee3fb18c2001-01-07 06:02:19 +0000197
Fred Drake58422e52001-06-04 03:56:24 +0000198 def test_function_defs(self):
199 self.check_suite("def f(): pass")
200 self.check_suite("def f(*args): pass")
201 self.check_suite("def f(*args, **kw): pass")
202 self.check_suite("def f(**kw): pass")
203 self.check_suite("def f(foo=bar): pass")
204 self.check_suite("def f(foo=bar, *args): pass")
205 self.check_suite("def f(foo=bar, *args, **kw): pass")
206 self.check_suite("def f(foo=bar, **kw): pass")
Fred Drakee3fb18c2001-01-07 06:02:19 +0000207
Fred Drake58422e52001-06-04 03:56:24 +0000208 self.check_suite("def f(a, b): pass")
209 self.check_suite("def f(a, b, *args): pass")
210 self.check_suite("def f(a, b, *args, **kw): pass")
211 self.check_suite("def f(a, b, **kw): pass")
212 self.check_suite("def f(a, b, foo=bar): pass")
213 self.check_suite("def f(a, b, foo=bar, *args): pass")
214 self.check_suite("def f(a, b, foo=bar, *args, **kw): pass")
215 self.check_suite("def f(a, b, foo=bar, **kw): pass")
Fred Drakee3fb18c2001-01-07 06:02:19 +0000216
Anthony Baxterc2a5a632004-08-02 06:10:11 +0000217 self.check_suite("@staticmethod\n"
218 "def f(): pass")
219 self.check_suite("@staticmethod\n"
220 "@funcattrs(x, y)\n"
221 "def f(): pass")
222 self.check_suite("@funcattrs()\n"
223 "def f(): pass")
224
Mark Dickinsonea7e9f92012-04-29 18:34:40 +0100225 # keyword-only arguments
226 self.check_suite("def f(*, a): pass")
227 self.check_suite("def f(*, a = 5): pass")
228 self.check_suite("def f(*, a = 5, b): pass")
229 self.check_suite("def f(*, a, b = 5): pass")
230 self.check_suite("def f(*, a, b = 5, **kwds): pass")
231 self.check_suite("def f(*args, a): pass")
232 self.check_suite("def f(*args, a = 5): pass")
233 self.check_suite("def f(*args, a = 5, b): pass")
234 self.check_suite("def f(*args, a, b = 5): pass")
235 self.check_suite("def f(*args, a, b = 5, **kwds): pass")
236
Pablo Galindo8c77b8c2019-04-29 13:36:57 +0100237 # positional-only arguments
238 self.check_suite("def f(a, /): pass")
239 self.check_suite("def f(a, /,): pass")
240 self.check_suite("def f(a, b, /): pass")
241 self.check_suite("def f(a, b, /, c): pass")
242 self.check_suite("def f(a, b, /, c = 6): pass")
243 self.check_suite("def f(a, b, /, c, *, d): pass")
244 self.check_suite("def f(a, b, /, c = 1, *, d): pass")
245 self.check_suite("def f(a, b, /, c, *, d = 1): pass")
246 self.check_suite("def f(a, b=1, /, c=2, *, d = 3): pass")
247 self.check_suite("def f(a=0, b=1, /, c=2, *, d = 3): pass")
248
Mark Dickinsonea7e9f92012-04-29 18:34:40 +0100249 # function annotations
250 self.check_suite("def f(a: int): pass")
251 self.check_suite("def f(a: int = 5): pass")
252 self.check_suite("def f(*args: list): pass")
253 self.check_suite("def f(**kwds: dict): pass")
254 self.check_suite("def f(*, a: int): pass")
255 self.check_suite("def f(*, a: int = 5): pass")
256 self.check_suite("def f() -> int: pass")
257
Brett Cannonf4189912005-04-09 02:30:16 +0000258 def test_class_defs(self):
259 self.check_suite("class foo():pass")
Guido van Rossumfc158e22007-11-15 19:17:28 +0000260 self.check_suite("class foo(object):pass")
Mark Dickinson2bd61a92010-07-04 16:37:31 +0000261 self.check_suite("@class_decorator\n"
262 "class foo():pass")
263 self.check_suite("@class_decorator(arg)\n"
264 "class foo():pass")
265 self.check_suite("@decorator1\n"
266 "@decorator2\n"
267 "class foo():pass")
Tim Peterse8906822005-04-20 17:45:13 +0000268
Fred Drake58422e52001-06-04 03:56:24 +0000269 def test_import_from_statement(self):
270 self.check_suite("from sys.path import *")
271 self.check_suite("from sys.path import dirname")
Anthony Baxter1a4ddae2004-08-31 10:07:13 +0000272 self.check_suite("from sys.path import (dirname)")
273 self.check_suite("from sys.path import (dirname,)")
Fred Drake58422e52001-06-04 03:56:24 +0000274 self.check_suite("from sys.path import dirname as my_dirname")
Anthony Baxter1a4ddae2004-08-31 10:07:13 +0000275 self.check_suite("from sys.path import (dirname as my_dirname)")
276 self.check_suite("from sys.path import (dirname as my_dirname,)")
Fred Drake58422e52001-06-04 03:56:24 +0000277 self.check_suite("from sys.path import dirname, basename")
Anthony Baxter1a4ddae2004-08-31 10:07:13 +0000278 self.check_suite("from sys.path import (dirname, basename)")
279 self.check_suite("from sys.path import (dirname, basename,)")
Fred Drake58422e52001-06-04 03:56:24 +0000280 self.check_suite(
281 "from sys.path import dirname as my_dirname, basename")
282 self.check_suite(
Anthony Baxter1a4ddae2004-08-31 10:07:13 +0000283 "from sys.path import (dirname as my_dirname, basename)")
284 self.check_suite(
285 "from sys.path import (dirname as my_dirname, basename,)")
286 self.check_suite(
Fred Drake58422e52001-06-04 03:56:24 +0000287 "from sys.path import dirname, basename as my_basename")
Anthony Baxter1a4ddae2004-08-31 10:07:13 +0000288 self.check_suite(
289 "from sys.path import (dirname, basename as my_basename)")
290 self.check_suite(
291 "from sys.path import (dirname, basename as my_basename,)")
Benjamin Petersonc0747cf2008-11-03 20:31:38 +0000292 self.check_suite("from .bogus import x")
Fred Drakee3fb18c2001-01-07 06:02:19 +0000293
Fred Drake58422e52001-06-04 03:56:24 +0000294 def test_basic_import_statement(self):
295 self.check_suite("import sys")
296 self.check_suite("import sys as system")
297 self.check_suite("import sys, math")
298 self.check_suite("import sys as system, math")
299 self.check_suite("import sys, math as my_math")
Fred Drake79ca79d2000-08-21 22:30:53 +0000300
Mark Dickinson2cc8a5e2010-07-04 18:11:51 +0000301 def test_relative_imports(self):
302 self.check_suite("from . import name")
303 self.check_suite("from .. import name")
Mark Dickinsonfeb3b752010-07-04 18:38:57 +0000304 # check all the way up to '....', since '...' is tokenized
305 # differently from '.' (it's an ellipsis token).
306 self.check_suite("from ... import name")
307 self.check_suite("from .... import name")
Mark Dickinson2cc8a5e2010-07-04 18:11:51 +0000308 self.check_suite("from .pkg import name")
309 self.check_suite("from ..pkg import name")
Mark Dickinsonfeb3b752010-07-04 18:38:57 +0000310 self.check_suite("from ...pkg import name")
311 self.check_suite("from ....pkg import name")
Mark Dickinson2cc8a5e2010-07-04 18:11:51 +0000312
Neal Norwitz9caf9c02003-02-10 01:54:06 +0000313 def test_pep263(self):
314 self.check_suite("# -*- coding: iso-8859-1 -*-\n"
315 "pass\n")
316
317 def test_assert(self):
318 self.check_suite("assert alo < ahi and blo < bhi\n")
319
Benjamin Peterson4469d0c2008-11-30 22:46:23 +0000320 def test_with(self):
321 self.check_suite("with open('x'): pass\n")
322 self.check_suite("with open('x') as f: pass\n")
Georg Brandl0c315622009-05-25 21:10:36 +0000323 self.check_suite("with open('x') as f, open('y') as g: pass\n")
Benjamin Peterson4469d0c2008-11-30 22:46:23 +0000324
Georg Brandleee31162008-12-07 15:15:22 +0000325 def test_try_stmt(self):
326 self.check_suite("try: pass\nexcept: pass\n")
327 self.check_suite("try: pass\nfinally: pass\n")
328 self.check_suite("try: pass\nexcept A: pass\nfinally: pass\n")
329 self.check_suite("try: pass\nexcept A: pass\nexcept: pass\n"
330 "finally: pass\n")
331 self.check_suite("try: pass\nexcept: pass\nelse: pass\n")
332 self.check_suite("try: pass\nexcept: pass\nelse: pass\n"
333 "finally: pass\n")
334
Pablo Galindo9a0000d2019-03-21 23:33:02 +0000335 def test_if_stmt(self):
336 self.check_suite("if True:\n pass\nelse:\n pass\n")
337 self.check_suite("if True:\n pass\nelif True:\n pass\nelse:\n pass\n")
338
Thomas Wouters89f507f2006-12-13 04:49:30 +0000339 def test_position(self):
340 # An absolutely minimal test of position information. Better
341 # tests would be a big project.
Benjamin Peterson8f326b22009-12-13 02:10:36 +0000342 code = "def f(x):\n return x + 1"
Serhiy Storchakae5362ea2018-04-19 01:55:37 +0300343 st = parser.suite(code)
Thomas Wouters89f507f2006-12-13 04:49:30 +0000344
345 def walk(tree):
346 node_type = tree[0]
347 next = tree[1]
Serhiy Storchakae5362ea2018-04-19 01:55:37 +0300348 if isinstance(next, (tuple, list)):
Thomas Wouters89f507f2006-12-13 04:49:30 +0000349 for elt in tree[1:]:
350 for x in walk(elt):
351 yield x
352 else:
353 yield tree
354
Serhiy Storchakae5362ea2018-04-19 01:55:37 +0300355 expected = [
Thomas Wouters89f507f2006-12-13 04:49:30 +0000356 (1, 'def', 1, 0),
357 (1, 'f', 1, 4),
358 (7, '(', 1, 5),
359 (1, 'x', 1, 6),
360 (8, ')', 1, 7),
361 (11, ':', 1, 8),
362 (4, '', 1, 9),
363 (5, '', 2, -1),
364 (1, 'return', 2, 4),
365 (1, 'x', 2, 11),
366 (14, '+', 2, 13),
367 (2, '1', 2, 15),
368 (4, '', 2, 16),
Benjamin Peterson8f326b22009-12-13 02:10:36 +0000369 (6, '', 2, -1),
370 (4, '', 2, -1),
Serhiy Storchakae5362ea2018-04-19 01:55:37 +0300371 (0, '', 2, -1),
372 ]
373
374 self.assertEqual(list(walk(st.totuple(line_info=True, col_info=True))),
375 expected)
376 self.assertEqual(list(walk(st.totuple())),
377 [(t, n) for t, n, l, c in expected])
378 self.assertEqual(list(walk(st.totuple(line_info=True))),
379 [(t, n, l) for t, n, l, c in expected])
380 self.assertEqual(list(walk(st.totuple(col_info=True))),
381 [(t, n, c) for t, n, l, c in expected])
382 self.assertEqual(list(walk(st.tolist(line_info=True, col_info=True))),
383 [list(x) for x in expected])
384 self.assertEqual(list(walk(parser.st2tuple(st, line_info=True,
385 col_info=True))),
386 expected)
387 self.assertEqual(list(walk(parser.st2list(st, line_info=True,
388 col_info=True))),
389 [list(x) for x in expected])
Thomas Wouters89f507f2006-12-13 04:49:30 +0000390
Benjamin Peterson4905e802009-09-27 02:43:28 +0000391 def test_extended_unpacking(self):
392 self.check_suite("*a = y")
393 self.check_suite("x, *b, = m")
394 self.check_suite("[*a, *b] = y")
395 self.check_suite("for [*x, b] in x: pass")
396
Mark Dickinsoncf360b92012-05-07 12:01:27 +0100397 def test_raise_statement(self):
398 self.check_suite("raise\n")
399 self.check_suite("raise e\n")
400 self.check_suite("try:\n"
401 " suite\n"
402 "except Exception as e:\n"
403 " raise ValueError from e\n")
404
Benjamin Peterson025e9eb2015-05-05 20:16:41 -0400405 def test_list_displays(self):
406 self.check_expr('[]')
407 self.check_expr('[*{2}, 3, *[4]]')
408
Mark Dickinson11c1dee2012-05-07 16:34:34 +0100409 def test_set_displays(self):
Benjamin Peterson025e9eb2015-05-05 20:16:41 -0400410 self.check_expr('{*{2}, 3, *[4]}')
Mark Dickinson11c1dee2012-05-07 16:34:34 +0100411 self.check_expr('{2}')
412 self.check_expr('{2,}')
413 self.check_expr('{2, 3}')
414 self.check_expr('{2, 3,}')
415
416 def test_dict_displays(self):
417 self.check_expr('{}')
418 self.check_expr('{a:b}')
419 self.check_expr('{a:b,}')
420 self.check_expr('{a:b, c:d}')
421 self.check_expr('{a:b, c:d,}')
Benjamin Peterson025e9eb2015-05-05 20:16:41 -0400422 self.check_expr('{**{}}')
423 self.check_expr('{**{}, 3:4, **{5:6, 7:8}}')
424
425 def test_argument_unpacking(self):
Yury Selivanov50a26142015-08-05 17:59:45 -0400426 self.check_expr("f(*a, **b)")
Benjamin Peterson025e9eb2015-05-05 20:16:41 -0400427 self.check_expr('f(a, *b, *c, *d)')
428 self.check_expr('f(**a, **b)')
429 self.check_expr('f(2, *a, *b, **b, **c, **d)')
Yury Selivanov50a26142015-08-05 17:59:45 -0400430 self.check_expr("f(*b, *() or () and (), **{} and {}, **() or {})")
Mark Dickinson11c1dee2012-05-07 16:34:34 +0100431
432 def test_set_comprehensions(self):
433 self.check_expr('{x for x in seq}')
434 self.check_expr('{f(x) for x in seq}')
435 self.check_expr('{f(x) for x in seq if condition(x)}')
436
437 def test_dict_comprehensions(self):
438 self.check_expr('{x:x for x in seq}')
439 self.check_expr('{x**2:x[3] for x in seq if condition(x)}')
440 self.check_expr('{x:x for x in seq1 for y in seq2 if condition(x, y)}')
441
Emily Morehouse8f59ee02019-01-24 16:49:56 -0700442 def test_named_expressions(self):
443 self.check_suite("(a := 1)")
444 self.check_suite("(a := a)")
445 self.check_suite("if (match := pattern.search(data)) is None: pass")
Xtreakd4fceaa2019-02-02 03:10:16 +0530446 self.check_suite("while match := pattern.search(f.read()): pass")
Emily Morehouse8f59ee02019-01-24 16:49:56 -0700447 self.check_suite("[y := f(x), y**2, y**3]")
448 self.check_suite("filtered_data = [y for x in data if (y := f(x)) is None]")
449 self.check_suite("(y := f(x))")
450 self.check_suite("y0 = (y1 := f(x))")
451 self.check_suite("foo(x=(y := f(x)))")
452 self.check_suite("def foo(answer=(p := 42)): pass")
453 self.check_suite("def foo(answer: (p := 42) = 5): pass")
454 self.check_suite("lambda: (x := 1)")
455 self.check_suite("(x := lambda: 1)")
456 self.check_suite("(x := lambda: (y := 1))") # not in PEP
457 self.check_suite("lambda line: (m := re.match(pattern, line)) and m.group(1)")
458 self.check_suite("x = (y := 0)")
459 self.check_suite("(z:=(y:=(x:=0)))")
460 self.check_suite("(info := (name, phone, *rest))")
461 self.check_suite("(x:=1,2)")
462 self.check_suite("(total := total + tax)")
463 self.check_suite("len(lines := f.readlines())")
464 self.check_suite("foo(x := 3, cat='vector')")
465 self.check_suite("foo(cat=(category := 'vector'))")
466 self.check_suite("if any(len(longline := l) >= 100 for l in lines): print(longline)")
467 self.check_suite(
468 "if env_base := os.environ.get('PYTHONUSERBASE', None): return env_base"
469 )
470 self.check_suite(
471 "if self._is_special and (ans := self._check_nans(context=context)): return ans"
472 )
473 self.check_suite("foo(b := 2, a=1)")
474 self.check_suite("foo(b := 2, a=1)")
475 self.check_suite("foo((b := 2), a=1)")
476 self.check_suite("foo(c=(b := 2), a=1)")
Jörn Heisslerc8a35412019-06-22 16:40:55 +0200477 self.check_suite("{(x := C(i)).q: x for i in y}")
478
Thomas Wouters89f507f2006-12-13 04:49:30 +0000479
Fred Drake79ca79d2000-08-21 22:30:53 +0000480#
481# Second, we take *invalid* trees and make sure we get ParserError
482# rejections for them.
483#
484
Fred Drake58422e52001-06-04 03:56:24 +0000485class IllegalSyntaxTestCase(unittest.TestCase):
Guido van Rossum32c2ae72002-08-22 19:45:32 +0000486
Fred Drake58422e52001-06-04 03:56:24 +0000487 def check_bad_tree(self, tree, label):
488 try:
Fred Drake6e4f2c02001-07-17 19:33:25 +0000489 parser.sequence2st(tree)
Fred Drake58422e52001-06-04 03:56:24 +0000490 except parser.ParserError:
491 pass
492 else:
493 self.fail("did not detect invalid tree for %r" % label)
Fred Drake79ca79d2000-08-21 22:30:53 +0000494
Fred Drake58422e52001-06-04 03:56:24 +0000495 def test_junk(self):
496 # not even remotely valid:
497 self.check_bad_tree((1, 2, 3), "<junk>")
498
Serhiy Storchakaa79f4c22017-04-19 21:09:21 +0300499 def test_illegal_terminal(self):
500 tree = \
501 (257,
502 (269,
503 (270,
504 (271,
505 (277,
506 (1,))),
507 (4, ''))),
508 (4, ''),
509 (0, ''))
510 self.check_bad_tree(tree, "too small items in terminal node")
511 tree = \
512 (257,
513 (269,
514 (270,
515 (271,
516 (277,
517 (1, b'pass'))),
518 (4, ''))),
519 (4, ''),
520 (0, ''))
521 self.check_bad_tree(tree, "non-string second item in terminal node")
522 tree = \
523 (257,
524 (269,
525 (270,
526 (271,
527 (277,
528 (1, 'pass', '0', 0))),
529 (4, ''))),
530 (4, ''),
531 (0, ''))
532 self.check_bad_tree(tree, "non-integer third item in terminal node")
533 tree = \
534 (257,
535 (269,
536 (270,
537 (271,
538 (277,
539 (1, 'pass', 0, 0))),
540 (4, ''))),
541 (4, ''),
542 (0, ''))
543 self.check_bad_tree(tree, "too many items in terminal node")
544
Fred Drakecf580c72001-07-17 03:01:29 +0000545 def test_illegal_yield_1(self):
Guido van Rossum32c2ae72002-08-22 19:45:32 +0000546 # Illegal yield statement: def f(): return 1; yield 1
Fred Drakecf580c72001-07-17 03:01:29 +0000547 tree = \
548 (257,
549 (264,
550 (285,
551 (259,
552 (1, 'def'),
553 (1, 'f'),
554 (260, (7, '('), (8, ')')),
555 (11, ':'),
556 (291,
557 (4, ''),
558 (5, ''),
559 (264,
560 (265,
561 (266,
562 (272,
563 (275,
564 (1, 'return'),
565 (313,
566 (292,
567 (293,
568 (294,
569 (295,
570 (297,
571 (298,
572 (299,
573 (300,
574 (301,
575 (302, (303, (304, (305, (2, '1')))))))))))))))))),
576 (264,
577 (265,
578 (266,
579 (272,
580 (276,
581 (1, 'yield'),
582 (313,
583 (292,
584 (293,
585 (294,
586 (295,
587 (297,
588 (298,
589 (299,
590 (300,
591 (301,
592 (302,
593 (303, (304, (305, (2, '1')))))))))))))))))),
594 (4, ''))),
595 (6, ''))))),
596 (4, ''),
597 (0, ''))))
598 self.check_bad_tree(tree, "def f():\n return 1\n yield 1")
599
600 def test_illegal_yield_2(self):
Guido van Rossum32c2ae72002-08-22 19:45:32 +0000601 # Illegal return in generator: def f(): return 1; yield 1
Fred Drakecf580c72001-07-17 03:01:29 +0000602 tree = \
603 (257,
604 (264,
605 (265,
606 (266,
607 (278,
608 (1, 'from'),
609 (281, (1, '__future__')),
610 (1, 'import'),
611 (279, (1, 'generators')))),
612 (4, ''))),
613 (264,
614 (285,
615 (259,
616 (1, 'def'),
617 (1, 'f'),
618 (260, (7, '('), (8, ')')),
619 (11, ':'),
620 (291,
621 (4, ''),
622 (5, ''),
623 (264,
624 (265,
625 (266,
626 (272,
627 (275,
628 (1, 'return'),
629 (313,
630 (292,
631 (293,
632 (294,
633 (295,
634 (297,
635 (298,
636 (299,
637 (300,
638 (301,
639 (302, (303, (304, (305, (2, '1')))))))))))))))))),
640 (264,
641 (265,
642 (266,
643 (272,
644 (276,
645 (1, 'yield'),
646 (313,
647 (292,
648 (293,
649 (294,
650 (295,
651 (297,
652 (298,
653 (299,
654 (300,
655 (301,
656 (302,
657 (303, (304, (305, (2, '1')))))))))))))))))),
658 (4, ''))),
659 (6, ''))))),
660 (4, ''),
661 (0, ''))))
662 self.check_bad_tree(tree, "def f():\n return 1\n yield 1")
663
Fred Drake58422e52001-06-04 03:56:24 +0000664 def test_a_comma_comma_c(self):
Guido van Rossum32c2ae72002-08-22 19:45:32 +0000665 # Illegal input: a,,c
Fred Drake58422e52001-06-04 03:56:24 +0000666 tree = \
667 (258,
668 (311,
669 (290,
670 (291,
671 (292,
672 (293,
673 (295,
674 (296,
675 (297,
676 (298, (299, (300, (301, (302, (303, (1, 'a')))))))))))))),
677 (12, ','),
678 (12, ','),
679 (290,
680 (291,
681 (292,
682 (293,
683 (295,
684 (296,
685 (297,
686 (298, (299, (300, (301, (302, (303, (1, 'c'))))))))))))))),
687 (4, ''),
688 (0, ''))
689 self.check_bad_tree(tree, "a,,c")
690
691 def test_illegal_operator(self):
Guido van Rossum32c2ae72002-08-22 19:45:32 +0000692 # Illegal input: a $= b
Fred Drake58422e52001-06-04 03:56:24 +0000693 tree = \
694 (257,
695 (264,
696 (265,
697 (266,
698 (267,
699 (312,
700 (291,
701 (292,
702 (293,
703 (294,
704 (296,
705 (297,
706 (298,
707 (299,
708 (300, (301, (302, (303, (304, (1, 'a'))))))))))))))),
709 (268, (37, '$=')),
710 (312,
711 (291,
712 (292,
713 (293,
714 (294,
715 (296,
716 (297,
717 (298,
718 (299,
719 (300, (301, (302, (303, (304, (1, 'b'))))))))))))))))),
720 (4, ''))),
721 (0, ''))
722 self.check_bad_tree(tree, "a $= b")
Fred Drake79ca79d2000-08-21 22:30:53 +0000723
Neal Norwitz9caf9c02003-02-10 01:54:06 +0000724 def test_malformed_global(self):
725 #doesn't have global keyword in ast
726 tree = (257,
727 (264,
728 (265,
729 (266,
730 (282, (1, 'foo'))), (4, ''))),
731 (4, ''),
Tim Petersf2715e02003-02-19 02:35:07 +0000732 (0, ''))
Neal Norwitz9caf9c02003-02-10 01:54:06 +0000733 self.check_bad_tree(tree, "malformed global ast")
Fred Drake79ca79d2000-08-21 22:30:53 +0000734
Mark Dickinson2cc8a5e2010-07-04 18:11:51 +0000735 def test_missing_import_source(self):
Mark Dickinson3445b482010-07-04 18:15:26 +0000736 # from import fred
Mark Dickinson2cc8a5e2010-07-04 18:11:51 +0000737 tree = \
738 (257,
Mark Dickinson3445b482010-07-04 18:15:26 +0000739 (268,
740 (269,
741 (270,
742 (282,
743 (284, (1, 'from'), (1, 'import'),
744 (287, (285, (1, 'fred')))))),
Mark Dickinson2cc8a5e2010-07-04 18:11:51 +0000745 (4, ''))),
746 (4, ''), (0, ''))
Mark Dickinson3445b482010-07-04 18:15:26 +0000747 self.check_bad_tree(tree, "from import fred")
Mark Dickinson2cc8a5e2010-07-04 18:11:51 +0000748
Serhiy Storchakaa79f4c22017-04-19 21:09:21 +0300749 def test_illegal_encoding(self):
750 # Illegal encoding declaration
751 tree = \
Emily Morehouse8f59ee02019-01-24 16:49:56 -0700752 (341,
Serhiy Storchakaa79f4c22017-04-19 21:09:21 +0300753 (257, (0, '')))
754 self.check_bad_tree(tree, "missed encoding")
755 tree = \
Emily Morehouse8f59ee02019-01-24 16:49:56 -0700756 (341,
Serhiy Storchakaa79f4c22017-04-19 21:09:21 +0300757 (257, (0, '')),
758 b'iso-8859-1')
759 self.check_bad_tree(tree, "non-string encoding")
760 tree = \
Emily Morehouse8f59ee02019-01-24 16:49:56 -0700761 (341,
Serhiy Storchakaa79f4c22017-04-19 21:09:21 +0300762 (257, (0, '')),
763 '\udcff')
764 with self.assertRaises(UnicodeEncodeError):
765 parser.sequence2st(tree)
766
tyomitchcb0748d2019-04-03 08:12:07 +0300767 def test_invalid_node_id(self):
768 tree = (257, (269, (-7, '')))
769 self.check_bad_tree(tree, "negative node id")
770 tree = (257, (269, (99, '')))
771 self.check_bad_tree(tree, "invalid token id")
772 tree = (257, (269, (9999, (0, ''))))
773 self.check_bad_tree(tree, "invalid symbol id")
774
775 def test_ParserError_message(self):
776 try:
777 parser.sequence2st((257,(269,(257,(0,'')))))
778 except parser.ParserError as why:
779 self.assertIn("compound_stmt", str(why)) # Expected
780 self.assertIn("file_input", str(why)) # Got
781
782
Jeremy Hylton3e0055f2005-10-20 19:59:25 +0000783
784class CompileTestCase(unittest.TestCase):
785
786 # These tests are very minimal. :-(
787
788 def test_compile_expr(self):
789 st = parser.expr('2 + 3')
790 code = parser.compilest(st)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000791 self.assertEqual(eval(code), 5)
Jeremy Hylton3e0055f2005-10-20 19:59:25 +0000792
793 def test_compile_suite(self):
794 st = parser.suite('x = 2; y = x + 3')
795 code = parser.compilest(st)
796 globs = {}
Georg Brandl7cae87c2006-09-06 06:51:57 +0000797 exec(code, globs)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000798 self.assertEqual(globs['y'], 5)
Jeremy Hylton3e0055f2005-10-20 19:59:25 +0000799
800 def test_compile_error(self):
801 st = parser.suite('1 = 3 + 4')
802 self.assertRaises(SyntaxError, parser.compilest, st)
803
Guido van Rossumb5a755e2007-07-18 18:15:48 +0000804 def test_compile_badunicode(self):
Guido van Rossum7eb6ca52007-07-18 21:00:22 +0000805 st = parser.suite('a = "\\U12345678"')
Guido van Rossumb5a755e2007-07-18 18:15:48 +0000806 self.assertRaises(SyntaxError, parser.compilest, st)
Guido van Rossum7eb6ca52007-07-18 21:00:22 +0000807 st = parser.suite('a = "\\u1"')
Guido van Rossumb5a755e2007-07-18 18:15:48 +0000808 self.assertRaises(SyntaxError, parser.compilest, st)
809
Mark Dickinsond35a32e2010-06-17 12:33:22 +0000810 def test_issue_9011(self):
811 # Issue 9011: compilation of an unary minus expression changed
812 # the meaning of the ST, so that a second compilation produced
813 # incorrect results.
814 st = parser.expr('-3')
815 code1 = parser.compilest(st)
816 self.assertEqual(eval(code1), -3)
817 code2 = parser.compilest(st)
818 self.assertEqual(eval(code2), -3)
819
Serhiy Storchaka9305d832016-06-18 13:53:36 +0300820 def test_compile_filename(self):
821 st = parser.expr('a + 5')
822 code = parser.compilest(st)
823 self.assertEqual(code.co_filename, '<syntax-tree>')
824 code = st.compile()
825 self.assertEqual(code.co_filename, '<syntax-tree>')
Serhiy Storchakafebc3322016-08-06 23:29:29 +0300826 for filename in 'file.py', b'file.py':
Serhiy Storchaka9305d832016-06-18 13:53:36 +0300827 code = parser.compilest(st, filename)
828 self.assertEqual(code.co_filename, 'file.py')
829 code = st.compile(filename)
830 self.assertEqual(code.co_filename, 'file.py')
Serhiy Storchakafebc3322016-08-06 23:29:29 +0300831 for filename in bytearray(b'file.py'), memoryview(b'file.py'):
832 with self.assertWarns(DeprecationWarning):
833 code = parser.compilest(st, filename)
834 self.assertEqual(code.co_filename, 'file.py')
835 with self.assertWarns(DeprecationWarning):
836 code = st.compile(filename)
837 self.assertEqual(code.co_filename, 'file.py')
Serhiy Storchaka9305d832016-06-18 13:53:36 +0300838 self.assertRaises(TypeError, parser.compilest, st, list(b'file.py'))
839 self.assertRaises(TypeError, st.compile, list(b'file.py'))
840
841
Christian Heimes90c3d9b2008-02-23 13:18:03 +0000842class ParserStackLimitTestCase(unittest.TestCase):
Mark Dickinsond35a32e2010-06-17 12:33:22 +0000843 """try to push the parser to/over its limits.
Christian Heimes90c3d9b2008-02-23 13:18:03 +0000844 see http://bugs.python.org/issue1881 for a discussion
845 """
846 def _nested_expression(self, level):
847 return "["*level+"]"*level
848
849 def test_deeply_nested_list(self):
Emily Morehouse8f59ee02019-01-24 16:49:56 -0700850 # This has fluctuated between 99 levels in 2.x, down to 93 levels in
851 # 3.7.X and back up to 99 in 3.8.X. Related to MAXSTACK size in Parser.h
852 e = self._nested_expression(99)
Christian Heimes90c3d9b2008-02-23 13:18:03 +0000853 st = parser.expr(e)
854 st.compile()
855
856 def test_trigger_memory_error(self):
857 e = self._nested_expression(100)
Ezio Melotti39191842013-03-09 22:17:33 +0200858 rc, out, err = assert_python_failure('-c', e)
859 # parsing the expression will result in an error message
860 # followed by a MemoryError (see #11963)
Ezio Melottie7c32992013-03-10 03:25:45 +0200861 self.assertIn(b's_push: parser stack overflow', err)
862 self.assertIn(b'MemoryError', err)
Christian Heimes90c3d9b2008-02-23 13:18:03 +0000863
Mark Dickinson211c6252009-02-01 10:28:51 +0000864class STObjectTestCase(unittest.TestCase):
865 """Test operations on ST objects themselves"""
866
867 def test_comparisons(self):
868 # ST objects should support order and equality comparisons
869 st1 = parser.expr('2 + 3')
870 st2 = parser.suite('x = 2; y = x + 3')
871 st3 = parser.expr('list(x**3 for x in range(20))')
872 st1_copy = parser.expr('2 + 3')
873 st2_copy = parser.suite('x = 2; y = x + 3')
874 st3_copy = parser.expr('list(x**3 for x in range(20))')
875
876 # exercise fast path for object identity
Ezio Melottib3aedd42010-11-20 19:04:17 +0000877 self.assertEqual(st1 == st1, True)
878 self.assertEqual(st2 == st2, True)
879 self.assertEqual(st3 == st3, True)
Mark Dickinson211c6252009-02-01 10:28:51 +0000880 # slow path equality
881 self.assertEqual(st1, st1_copy)
882 self.assertEqual(st2, st2_copy)
883 self.assertEqual(st3, st3_copy)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000884 self.assertEqual(st1 == st2, False)
885 self.assertEqual(st1 == st3, False)
886 self.assertEqual(st2 == st3, False)
887 self.assertEqual(st1 != st1, False)
888 self.assertEqual(st2 != st2, False)
889 self.assertEqual(st3 != st3, False)
890 self.assertEqual(st1 != st1_copy, False)
891 self.assertEqual(st2 != st2_copy, False)
892 self.assertEqual(st3 != st3_copy, False)
893 self.assertEqual(st2 != st1, True)
894 self.assertEqual(st1 != st3, True)
895 self.assertEqual(st3 != st2, True)
Mark Dickinson211c6252009-02-01 10:28:51 +0000896 # we don't particularly care what the ordering is; just that
897 # it's usable and self-consistent
Ezio Melottib3aedd42010-11-20 19:04:17 +0000898 self.assertEqual(st1 < st2, not (st2 <= st1))
899 self.assertEqual(st1 < st3, not (st3 <= st1))
900 self.assertEqual(st2 < st3, not (st3 <= st2))
901 self.assertEqual(st1 < st2, st2 > st1)
902 self.assertEqual(st1 < st3, st3 > st1)
903 self.assertEqual(st2 < st3, st3 > st2)
904 self.assertEqual(st1 <= st2, st2 >= st1)
905 self.assertEqual(st3 <= st1, st1 >= st3)
906 self.assertEqual(st2 <= st3, st3 >= st2)
Mark Dickinson211c6252009-02-01 10:28:51 +0000907 # transitivity
908 bottom = min(st1, st2, st3)
909 top = max(st1, st2, st3)
910 mid = sorted([st1, st2, st3])[1]
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000911 self.assertTrue(bottom < mid)
912 self.assertTrue(bottom < top)
913 self.assertTrue(mid < top)
914 self.assertTrue(bottom <= mid)
915 self.assertTrue(bottom <= top)
916 self.assertTrue(mid <= top)
917 self.assertTrue(bottom <= bottom)
918 self.assertTrue(mid <= mid)
919 self.assertTrue(top <= top)
Mark Dickinson211c6252009-02-01 10:28:51 +0000920 # interaction with other types
Ezio Melottib3aedd42010-11-20 19:04:17 +0000921 self.assertEqual(st1 == 1588.602459, False)
922 self.assertEqual('spanish armada' != st2, True)
Mark Dickinson211c6252009-02-01 10:28:51 +0000923 self.assertRaises(TypeError, operator.ge, st3, None)
924 self.assertRaises(TypeError, operator.le, False, st1)
925 self.assertRaises(TypeError, operator.lt, st1, 1815)
926 self.assertRaises(TypeError, operator.gt, b'waterloo', st2)
927
Serhiy Storchakaa79f4c22017-04-19 21:09:21 +0300928 def test_copy_pickle(self):
929 sts = [
930 parser.expr('2 + 3'),
931 parser.suite('x = 2; y = x + 3'),
932 parser.expr('list(x**3 for x in range(20))')
933 ]
934 for st in sts:
935 st_copy = copy.copy(st)
936 self.assertEqual(st_copy.totuple(), st.totuple())
937 st_copy = copy.deepcopy(st)
938 self.assertEqual(st_copy.totuple(), st.totuple())
939 for proto in range(pickle.HIGHEST_PROTOCOL+1):
940 st_copy = pickle.loads(pickle.dumps(st, proto))
941 self.assertEqual(st_copy.totuple(), st.totuple())
942
Jesus Ceae9c53182012-08-03 14:28:37 +0200943 check_sizeof = support.check_sizeof
944
945 @support.cpython_only
946 def test_sizeof(self):
947 def XXXROUNDUP(n):
948 if n <= 1:
949 return n
950 if n <= 128:
951 return (n + 3) & ~3
952 return 1 << (n - 1).bit_length()
953
Guido van Rossum495da292019-03-07 12:38:08 -0800954 basesize = support.calcobjsize('Piii')
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000955 nodesize = struct.calcsize('hP3iP0h2i')
Jesus Ceae9c53182012-08-03 14:28:37 +0200956 def sizeofchildren(node):
957 if node is None:
958 return 0
959 res = 0
960 hasstr = len(node) > 1 and isinstance(node[-1], str)
961 if hasstr:
962 res += len(node[-1]) + 1
963 children = node[1:-1] if hasstr else node[1:]
964 if children:
965 res += XXXROUNDUP(len(children)) * nodesize
Jesus Ceae9c53182012-08-03 14:28:37 +0200966 for child in children:
967 res += sizeofchildren(child)
968 return res
969
970 def check_st_sizeof(st):
971 self.check_sizeof(st, basesize + nodesize +
972 sizeofchildren(st.totuple()))
973
974 check_st_sizeof(parser.expr('2 + 3'))
975 check_st_sizeof(parser.expr('2 + 3 + 4'))
976 check_st_sizeof(parser.suite('x = 2 + 3'))
977 check_st_sizeof(parser.suite(''))
978 check_st_sizeof(parser.suite('# -*- coding: utf-8 -*-'))
979 check_st_sizeof(parser.expr('[' + '2,' * 1000 + ']'))
980
Mark Dickinson211c6252009-02-01 10:28:51 +0000981
982 # XXX tests for pickling and unpickling of ST objects should go here
983
Benjamin Petersonf719957d2011-06-04 22:06:42 -0500984class OtherParserCase(unittest.TestCase):
985
986 def test_two_args_to_expr(self):
987 # See bug #12264
988 with self.assertRaises(TypeError):
989 parser.expr("a", "b")
990
Pablo Galindo9211e2f2019-07-30 12:04:01 +0100991
992class TestDeprecation(unittest.TestCase):
993 def test_deprecation_message(self):
994 code = "def f():\n import parser\n\nf()"
995 rc, out, err = assert_python_ok('-c', code)
996 self.assertIn(b'<string>:2: DeprecationWarning', err)
997
998
Fred Drake2e2be372001-09-20 21:33:42 +0000999if __name__ == "__main__":
Zachary Ware38c707e2015-04-13 15:00:43 -05001000 unittest.main()