blob: 7295f66d393a446a82ceecd03db67f0a31e5f49c [file] [log] [blame]
Serhiy Storchakaa79f4c22017-04-19 21:09:21 +03001import copy
Zackery Spytz10a0a092019-08-08 15:48:00 -06002import warnings
3with warnings.catch_warnings():
4 warnings.filterwarnings('ignore', 'The parser module is deprecated',
5 DeprecationWarning)
6 import parser
Serhiy Storchakaa79f4c22017-04-19 21:09:21 +03007import pickle
Fred Drake58422e52001-06-04 03:56:24 +00008import unittest
Mark Dickinson211c6252009-02-01 10:28:51 +00009import operator
Jesus Ceae9c53182012-08-03 14:28:37 +020010import struct
Benjamin Petersonee8712c2008-05-20 21:35:26 +000011from test import support
Berker Peksagce643912015-05-06 06:33:17 +030012from test.support.script_helper import assert_python_failure
Pablo Galindo9211e2f2019-07-30 12:04:01 +010013from test.support.script_helper import assert_python_ok
Fred Drake79ca79d2000-08-21 22:30:53 +000014
15#
16# First, we test that we can generate trees from valid source fragments,
17# and that these valid trees are indeed allowed by the tree-loading side
18# of the parser module.
19#
20
Fred Drake58422e52001-06-04 03:56:24 +000021class RoundtripLegalSyntaxTestCase(unittest.TestCase):
Guido van Rossum32c2ae72002-08-22 19:45:32 +000022
Fred Drake58422e52001-06-04 03:56:24 +000023 def roundtrip(self, f, s):
24 st1 = f(s)
25 t = st1.totuple()
26 try:
Fred Drake6e4f2c02001-07-17 19:33:25 +000027 st2 = parser.sequence2st(t)
Guido van Rossumb940e112007-01-10 16:19:56 +000028 except parser.ParserError as why:
Anthony Baxterc2a5a632004-08-02 06:10:11 +000029 self.fail("could not roundtrip %r: %s" % (s, why))
Fred Drake79ca79d2000-08-21 22:30:53 +000030
Ezio Melottib3aedd42010-11-20 19:04:17 +000031 self.assertEqual(t, st2.totuple(),
32 "could not re-generate syntax tree")
Fred Drake28f739a2000-08-25 22:42:40 +000033
Fred Drake58422e52001-06-04 03:56:24 +000034 def check_expr(self, s):
35 self.roundtrip(parser.expr, s)
Fred Drake28f739a2000-08-25 22:42:40 +000036
Benjamin Petersonf216c942008-10-31 02:28:05 +000037 def test_flags_passed(self):
Mike53f7a7c2017-12-14 14:04:53 +030038 # The unicode literals flags has to be passed from the parser to AST
Benjamin Petersonf216c942008-10-31 02:28:05 +000039 # generation.
40 suite = parser.suite("from __future__ import unicode_literals; x = ''")
41 code = suite.compile()
42 scope = {}
43 exec(code, {}, scope)
Ezio Melottie9615932010-01-24 19:26:24 +000044 self.assertIsInstance(scope["x"], str)
Benjamin Petersonf216c942008-10-31 02:28:05 +000045
Fred Drake58422e52001-06-04 03:56:24 +000046 def check_suite(self, s):
47 self.roundtrip(parser.suite, s)
Fred Drake28f739a2000-08-25 22:42:40 +000048
Fred Drakecf580c72001-07-17 03:01:29 +000049 def test_yield_statement(self):
Tim Peters496563a2002-04-01 00:28:59 +000050 self.check_suite("def f(): yield 1")
Phillip J. Eby0d6615f2005-08-02 00:46:46 +000051 self.check_suite("def f(): yield")
52 self.check_suite("def f(): x += yield")
53 self.check_suite("def f(): x = yield 1")
54 self.check_suite("def f(): x = y = yield 1")
55 self.check_suite("def f(): x = yield")
56 self.check_suite("def f(): x = y = yield")
57 self.check_suite("def f(): 1 + (yield)*2")
58 self.check_suite("def f(): (yield 1)*2")
Tim Peters496563a2002-04-01 00:28:59 +000059 self.check_suite("def f(): return; yield 1")
60 self.check_suite("def f(): yield 1; return")
Nick Coghlan1f7ce622012-01-13 21:43:40 +100061 self.check_suite("def f(): yield from 1")
62 self.check_suite("def f(): x = yield from 1")
63 self.check_suite("def f(): f((yield from 1))")
64 self.check_suite("def f(): yield 1; return 1")
Tim Peters496563a2002-04-01 00:28:59 +000065 self.check_suite("def f():\n"
Fred Drakecf580c72001-07-17 03:01:29 +000066 " for x in range(30):\n"
67 " yield x\n")
Phillip J. Eby0d6615f2005-08-02 00:46:46 +000068 self.check_suite("def f():\n"
69 " if (yield):\n"
70 " yield x\n")
Fred Drakecf580c72001-07-17 03:01:29 +000071
Yury Selivanov75445082015-05-11 22:57:16 -040072 def test_await_statement(self):
73 self.check_suite("async def f():\n await smth()")
74 self.check_suite("async def f():\n foo = await smth()")
75 self.check_suite("async def f():\n foo, bar = await smth()")
76 self.check_suite("async def f():\n (await smth())")
77 self.check_suite("async def f():\n foo((await smth()))")
78 self.check_suite("async def f():\n await foo(); return 42")
79
80 def test_async_with_statement(self):
81 self.check_suite("async def f():\n async with 1: pass")
82 self.check_suite("async def f():\n async with a as b, c as d: pass")
83
84 def test_async_for_statement(self):
85 self.check_suite("async def f():\n async for i in (): pass")
86 self.check_suite("async def f():\n async for i, b in (): pass")
87
Mark Dickinson407b3bd2012-04-29 22:18:31 +010088 def test_nonlocal_statement(self):
89 self.check_suite("def f():\n"
90 " x = 0\n"
91 " def g():\n"
92 " nonlocal x\n")
93 self.check_suite("def f():\n"
94 " x = y = 0\n"
95 " def g():\n"
96 " nonlocal x, y\n")
97
Fred Drake58422e52001-06-04 03:56:24 +000098 def test_expressions(self):
99 self.check_expr("foo(1)")
100 self.check_expr("[1, 2, 3]")
101 self.check_expr("[x**3 for x in range(20)]")
102 self.check_expr("[x**3 for x in range(20) if x % 3]")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000103 self.check_expr("[x**3 for x in range(20) if x % 2 if x % 3]")
104 self.check_expr("list(x**3 for x in range(20))")
105 self.check_expr("list(x**3 for x in range(20) if x % 3)")
106 self.check_expr("list(x**3 for x in range(20) if x % 2 if x % 3)")
Fred Drake58422e52001-06-04 03:56:24 +0000107 self.check_expr("foo(*args)")
108 self.check_expr("foo(*args, **kw)")
109 self.check_expr("foo(**kw)")
110 self.check_expr("foo(key=value)")
111 self.check_expr("foo(key=value, *args)")
112 self.check_expr("foo(key=value, *args, **kw)")
113 self.check_expr("foo(key=value, **kw)")
114 self.check_expr("foo(a, b, c, *args)")
115 self.check_expr("foo(a, b, c, *args, **kw)")
116 self.check_expr("foo(a, b, c, **kw)")
Benjamin Peterson3938a902008-08-20 02:33:00 +0000117 self.check_expr("foo(a, *args, keyword=23)")
Fred Drake58422e52001-06-04 03:56:24 +0000118 self.check_expr("foo + bar")
Michael W. Hudson5e83b7a2003-01-29 14:20:23 +0000119 self.check_expr("foo - bar")
120 self.check_expr("foo * bar")
121 self.check_expr("foo / bar")
122 self.check_expr("foo // bar")
Emily Morehouse8f59ee02019-01-24 16:49:56 -0700123 self.check_expr("(foo := 1)")
Fred Drake58422e52001-06-04 03:56:24 +0000124 self.check_expr("lambda: 0")
125 self.check_expr("lambda x: 0")
126 self.check_expr("lambda *y: 0")
127 self.check_expr("lambda *y, **z: 0")
128 self.check_expr("lambda **z: 0")
129 self.check_expr("lambda x, y: 0")
130 self.check_expr("lambda foo=bar: 0")
131 self.check_expr("lambda foo=bar, spaz=nifty+spit: 0")
132 self.check_expr("lambda foo=bar, **z: 0")
133 self.check_expr("lambda foo=bar, blaz=blat+2, **z: 0")
134 self.check_expr("lambda foo=bar, blaz=blat+2, *y, **z: 0")
135 self.check_expr("lambda x, *y, **z: 0")
Raymond Hettinger354433a2004-05-19 08:20:33 +0000136 self.check_expr("(x for x in range(10))")
137 self.check_expr("foo(x for x in range(10))")
Mark Dickinsonda029fb2012-05-07 17:24:04 +0100138 self.check_expr("...")
139 self.check_expr("a[...]")
Fred Drake79ca79d2000-08-21 22:30:53 +0000140
Fred Drake58422e52001-06-04 03:56:24 +0000141 def test_simple_expression(self):
142 # expr_stmt
143 self.check_suite("a")
Fred Drake79ca79d2000-08-21 22:30:53 +0000144
Fred Drake58422e52001-06-04 03:56:24 +0000145 def test_simple_assignments(self):
146 self.check_suite("a = b")
147 self.check_suite("a = b = c = d = e")
Fred Drake28f739a2000-08-25 22:42:40 +0000148
Yury Selivanovf8cb8a12016-09-08 20:50:03 -0700149 def test_var_annot(self):
150 self.check_suite("x: int = 5")
151 self.check_suite("y: List[T] = []; z: [list] = fun()")
152 self.check_suite("x: tuple = (1, 2)")
153 self.check_suite("d[f()]: int = 42")
154 self.check_suite("f(d[x]): str = 'abc'")
155 self.check_suite("x.y.z.w: complex = 42j")
156 self.check_suite("x: int")
157 self.check_suite("def f():\n"
158 " x: str\n"
159 " y: int = 5\n")
160 self.check_suite("class C:\n"
161 " x: str\n"
162 " y: int = 5\n")
163 self.check_suite("class C:\n"
164 " def __init__(self, x: int) -> None:\n"
165 " self.x: int = x\n")
166 # double check for nonsense
167 with self.assertRaises(SyntaxError):
168 exec("2+2: int", {}, {})
169 with self.assertRaises(SyntaxError):
170 exec("[]: int = 5", {}, {})
171 with self.assertRaises(SyntaxError):
172 exec("x, *y, z: int = range(5)", {}, {})
173 with self.assertRaises(SyntaxError):
Ivan Levkivskyi62c35a82019-01-25 01:39:19 +0000174 exec("x: int = 1, y = 2", {}, {})
Yury Selivanovf8cb8a12016-09-08 20:50:03 -0700175 with self.assertRaises(SyntaxError):
176 exec("u = v: int", {}, {})
177 with self.assertRaises(SyntaxError):
178 exec("False: int", {}, {})
179 with self.assertRaises(SyntaxError):
180 exec("x.False: int", {}, {})
181 with self.assertRaises(SyntaxError):
182 exec("x.y,: int", {}, {})
183 with self.assertRaises(SyntaxError):
184 exec("[0]: int", {}, {})
185 with self.assertRaises(SyntaxError):
186 exec("f(): int", {}, {})
187
Fred Drake58422e52001-06-04 03:56:24 +0000188 def test_simple_augmented_assignments(self):
189 self.check_suite("a += b")
190 self.check_suite("a -= b")
191 self.check_suite("a *= b")
192 self.check_suite("a /= b")
Michael W. Hudson5e83b7a2003-01-29 14:20:23 +0000193 self.check_suite("a //= b")
Fred Drake58422e52001-06-04 03:56:24 +0000194 self.check_suite("a %= b")
195 self.check_suite("a &= b")
196 self.check_suite("a |= b")
197 self.check_suite("a ^= b")
198 self.check_suite("a <<= b")
199 self.check_suite("a >>= b")
200 self.check_suite("a **= b")
Fred Drakee3fb18c2001-01-07 06:02:19 +0000201
Fred Drake58422e52001-06-04 03:56:24 +0000202 def test_function_defs(self):
203 self.check_suite("def f(): pass")
204 self.check_suite("def f(*args): pass")
205 self.check_suite("def f(*args, **kw): pass")
206 self.check_suite("def f(**kw): pass")
207 self.check_suite("def f(foo=bar): pass")
208 self.check_suite("def f(foo=bar, *args): pass")
209 self.check_suite("def f(foo=bar, *args, **kw): pass")
210 self.check_suite("def f(foo=bar, **kw): pass")
Fred Drakee3fb18c2001-01-07 06:02:19 +0000211
Fred Drake58422e52001-06-04 03:56:24 +0000212 self.check_suite("def f(a, b): pass")
213 self.check_suite("def f(a, b, *args): pass")
214 self.check_suite("def f(a, b, *args, **kw): pass")
215 self.check_suite("def f(a, b, **kw): pass")
216 self.check_suite("def f(a, b, foo=bar): pass")
217 self.check_suite("def f(a, b, foo=bar, *args): pass")
218 self.check_suite("def f(a, b, foo=bar, *args, **kw): pass")
219 self.check_suite("def f(a, b, foo=bar, **kw): pass")
Fred Drakee3fb18c2001-01-07 06:02:19 +0000220
Anthony Baxterc2a5a632004-08-02 06:10:11 +0000221 self.check_suite("@staticmethod\n"
222 "def f(): pass")
223 self.check_suite("@staticmethod\n"
224 "@funcattrs(x, y)\n"
225 "def f(): pass")
226 self.check_suite("@funcattrs()\n"
227 "def f(): pass")
228
Mark Dickinsonea7e9f92012-04-29 18:34:40 +0100229 # keyword-only arguments
230 self.check_suite("def f(*, a): pass")
231 self.check_suite("def f(*, a = 5): pass")
232 self.check_suite("def f(*, a = 5, b): pass")
233 self.check_suite("def f(*, a, b = 5): pass")
234 self.check_suite("def f(*, a, b = 5, **kwds): pass")
235 self.check_suite("def f(*args, a): pass")
236 self.check_suite("def f(*args, a = 5): pass")
237 self.check_suite("def f(*args, a = 5, b): pass")
238 self.check_suite("def f(*args, a, b = 5): pass")
239 self.check_suite("def f(*args, a, b = 5, **kwds): pass")
240
Pablo Galindo8c77b8c2019-04-29 13:36:57 +0100241 # positional-only arguments
242 self.check_suite("def f(a, /): pass")
243 self.check_suite("def f(a, /,): pass")
244 self.check_suite("def f(a, b, /): pass")
245 self.check_suite("def f(a, b, /, c): pass")
246 self.check_suite("def f(a, b, /, c = 6): pass")
247 self.check_suite("def f(a, b, /, c, *, d): pass")
248 self.check_suite("def f(a, b, /, c = 1, *, d): pass")
249 self.check_suite("def f(a, b, /, c, *, d = 1): pass")
250 self.check_suite("def f(a, b=1, /, c=2, *, d = 3): pass")
251 self.check_suite("def f(a=0, b=1, /, c=2, *, d = 3): pass")
252
Mark Dickinsonea7e9f92012-04-29 18:34:40 +0100253 # function annotations
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(*args: list): pass")
257 self.check_suite("def f(**kwds: dict): pass")
258 self.check_suite("def f(*, a: int): pass")
259 self.check_suite("def f(*, a: int = 5): pass")
260 self.check_suite("def f() -> int: pass")
261
Brett Cannonf4189912005-04-09 02:30:16 +0000262 def test_class_defs(self):
263 self.check_suite("class foo():pass")
Guido van Rossumfc158e22007-11-15 19:17:28 +0000264 self.check_suite("class foo(object):pass")
Mark Dickinson2bd61a92010-07-04 16:37:31 +0000265 self.check_suite("@class_decorator\n"
266 "class foo():pass")
267 self.check_suite("@class_decorator(arg)\n"
268 "class foo():pass")
269 self.check_suite("@decorator1\n"
270 "@decorator2\n"
271 "class foo():pass")
Tim Peterse8906822005-04-20 17:45:13 +0000272
Fred Drake58422e52001-06-04 03:56:24 +0000273 def test_import_from_statement(self):
274 self.check_suite("from sys.path import *")
275 self.check_suite("from sys.path import dirname")
Anthony Baxter1a4ddae2004-08-31 10:07:13 +0000276 self.check_suite("from sys.path import (dirname)")
277 self.check_suite("from sys.path import (dirname,)")
Fred Drake58422e52001-06-04 03:56:24 +0000278 self.check_suite("from sys.path import dirname as my_dirname")
Anthony Baxter1a4ddae2004-08-31 10:07:13 +0000279 self.check_suite("from sys.path import (dirname as my_dirname)")
280 self.check_suite("from sys.path import (dirname as my_dirname,)")
Fred Drake58422e52001-06-04 03:56:24 +0000281 self.check_suite("from sys.path import dirname, basename")
Anthony Baxter1a4ddae2004-08-31 10:07:13 +0000282 self.check_suite("from sys.path import (dirname, basename)")
283 self.check_suite("from sys.path import (dirname, basename,)")
Fred Drake58422e52001-06-04 03:56:24 +0000284 self.check_suite(
285 "from sys.path import dirname as my_dirname, basename")
286 self.check_suite(
Anthony Baxter1a4ddae2004-08-31 10:07:13 +0000287 "from sys.path import (dirname as my_dirname, basename)")
288 self.check_suite(
289 "from sys.path import (dirname as my_dirname, basename,)")
290 self.check_suite(
Fred Drake58422e52001-06-04 03:56:24 +0000291 "from sys.path import dirname, basename as my_basename")
Anthony Baxter1a4ddae2004-08-31 10:07:13 +0000292 self.check_suite(
293 "from sys.path import (dirname, basename as my_basename)")
294 self.check_suite(
295 "from sys.path import (dirname, basename as my_basename,)")
Benjamin Petersonc0747cf2008-11-03 20:31:38 +0000296 self.check_suite("from .bogus import x")
Fred Drakee3fb18c2001-01-07 06:02:19 +0000297
Fred Drake58422e52001-06-04 03:56:24 +0000298 def test_basic_import_statement(self):
299 self.check_suite("import sys")
300 self.check_suite("import sys as system")
301 self.check_suite("import sys, math")
302 self.check_suite("import sys as system, math")
303 self.check_suite("import sys, math as my_math")
Fred Drake79ca79d2000-08-21 22:30:53 +0000304
Mark Dickinson2cc8a5e2010-07-04 18:11:51 +0000305 def test_relative_imports(self):
306 self.check_suite("from . import name")
307 self.check_suite("from .. import name")
Mark Dickinsonfeb3b752010-07-04 18:38:57 +0000308 # check all the way up to '....', since '...' is tokenized
309 # differently from '.' (it's an ellipsis token).
310 self.check_suite("from ... import name")
311 self.check_suite("from .... import name")
Mark Dickinson2cc8a5e2010-07-04 18:11:51 +0000312 self.check_suite("from .pkg import name")
313 self.check_suite("from ..pkg import name")
Mark Dickinsonfeb3b752010-07-04 18:38:57 +0000314 self.check_suite("from ...pkg import name")
315 self.check_suite("from ....pkg import name")
Mark Dickinson2cc8a5e2010-07-04 18:11:51 +0000316
Neal Norwitz9caf9c02003-02-10 01:54:06 +0000317 def test_pep263(self):
318 self.check_suite("# -*- coding: iso-8859-1 -*-\n"
319 "pass\n")
320
321 def test_assert(self):
322 self.check_suite("assert alo < ahi and blo < bhi\n")
323
Benjamin Peterson4469d0c2008-11-30 22:46:23 +0000324 def test_with(self):
325 self.check_suite("with open('x'): pass\n")
326 self.check_suite("with open('x') as f: pass\n")
Georg Brandl0c315622009-05-25 21:10:36 +0000327 self.check_suite("with open('x') as f, open('y') as g: pass\n")
Benjamin Peterson4469d0c2008-11-30 22:46:23 +0000328
Georg Brandleee31162008-12-07 15:15:22 +0000329 def test_try_stmt(self):
330 self.check_suite("try: pass\nexcept: pass\n")
331 self.check_suite("try: pass\nfinally: pass\n")
332 self.check_suite("try: pass\nexcept A: pass\nfinally: pass\n")
333 self.check_suite("try: pass\nexcept A: pass\nexcept: pass\n"
334 "finally: pass\n")
335 self.check_suite("try: pass\nexcept: pass\nelse: pass\n")
336 self.check_suite("try: pass\nexcept: pass\nelse: pass\n"
337 "finally: pass\n")
338
Pablo Galindo9a0000d2019-03-21 23:33:02 +0000339 def test_if_stmt(self):
340 self.check_suite("if True:\n pass\nelse:\n pass\n")
341 self.check_suite("if True:\n pass\nelif True:\n pass\nelse:\n pass\n")
342
Thomas Wouters89f507f2006-12-13 04:49:30 +0000343 def test_position(self):
344 # An absolutely minimal test of position information. Better
345 # tests would be a big project.
Benjamin Peterson8f326b22009-12-13 02:10:36 +0000346 code = "def f(x):\n return x + 1"
Serhiy Storchakae5362ea2018-04-19 01:55:37 +0300347 st = parser.suite(code)
Thomas Wouters89f507f2006-12-13 04:49:30 +0000348
349 def walk(tree):
350 node_type = tree[0]
351 next = tree[1]
Serhiy Storchakae5362ea2018-04-19 01:55:37 +0300352 if isinstance(next, (tuple, list)):
Thomas Wouters89f507f2006-12-13 04:49:30 +0000353 for elt in tree[1:]:
354 for x in walk(elt):
355 yield x
356 else:
357 yield tree
358
Serhiy Storchakae5362ea2018-04-19 01:55:37 +0300359 expected = [
Thomas Wouters89f507f2006-12-13 04:49:30 +0000360 (1, 'def', 1, 0),
361 (1, 'f', 1, 4),
362 (7, '(', 1, 5),
363 (1, 'x', 1, 6),
364 (8, ')', 1, 7),
365 (11, ':', 1, 8),
366 (4, '', 1, 9),
367 (5, '', 2, -1),
368 (1, 'return', 2, 4),
369 (1, 'x', 2, 11),
370 (14, '+', 2, 13),
371 (2, '1', 2, 15),
372 (4, '', 2, 16),
Benjamin Peterson8f326b22009-12-13 02:10:36 +0000373 (6, '', 2, -1),
374 (4, '', 2, -1),
Serhiy Storchakae5362ea2018-04-19 01:55:37 +0300375 (0, '', 2, -1),
376 ]
377
378 self.assertEqual(list(walk(st.totuple(line_info=True, col_info=True))),
379 expected)
380 self.assertEqual(list(walk(st.totuple())),
381 [(t, n) for t, n, l, c in expected])
382 self.assertEqual(list(walk(st.totuple(line_info=True))),
383 [(t, n, l) for t, n, l, c in expected])
384 self.assertEqual(list(walk(st.totuple(col_info=True))),
385 [(t, n, c) for t, n, l, c in expected])
386 self.assertEqual(list(walk(st.tolist(line_info=True, col_info=True))),
387 [list(x) for x in expected])
388 self.assertEqual(list(walk(parser.st2tuple(st, line_info=True,
389 col_info=True))),
390 expected)
391 self.assertEqual(list(walk(parser.st2list(st, line_info=True,
392 col_info=True))),
393 [list(x) for x in expected])
Thomas Wouters89f507f2006-12-13 04:49:30 +0000394
Benjamin Peterson4905e802009-09-27 02:43:28 +0000395 def test_extended_unpacking(self):
396 self.check_suite("*a = y")
397 self.check_suite("x, *b, = m")
398 self.check_suite("[*a, *b] = y")
399 self.check_suite("for [*x, b] in x: pass")
400
Mark Dickinsoncf360b92012-05-07 12:01:27 +0100401 def test_raise_statement(self):
402 self.check_suite("raise\n")
403 self.check_suite("raise e\n")
404 self.check_suite("try:\n"
405 " suite\n"
406 "except Exception as e:\n"
407 " raise ValueError from e\n")
408
Benjamin Peterson025e9eb2015-05-05 20:16:41 -0400409 def test_list_displays(self):
410 self.check_expr('[]')
411 self.check_expr('[*{2}, 3, *[4]]')
412
Mark Dickinson11c1dee2012-05-07 16:34:34 +0100413 def test_set_displays(self):
Benjamin Peterson025e9eb2015-05-05 20:16:41 -0400414 self.check_expr('{*{2}, 3, *[4]}')
Mark Dickinson11c1dee2012-05-07 16:34:34 +0100415 self.check_expr('{2}')
416 self.check_expr('{2,}')
417 self.check_expr('{2, 3}')
418 self.check_expr('{2, 3,}')
419
420 def test_dict_displays(self):
421 self.check_expr('{}')
422 self.check_expr('{a:b}')
423 self.check_expr('{a:b,}')
424 self.check_expr('{a:b, c:d}')
425 self.check_expr('{a:b, c:d,}')
Benjamin Peterson025e9eb2015-05-05 20:16:41 -0400426 self.check_expr('{**{}}')
427 self.check_expr('{**{}, 3:4, **{5:6, 7:8}}')
428
429 def test_argument_unpacking(self):
Yury Selivanov50a26142015-08-05 17:59:45 -0400430 self.check_expr("f(*a, **b)")
Benjamin Peterson025e9eb2015-05-05 20:16:41 -0400431 self.check_expr('f(a, *b, *c, *d)')
432 self.check_expr('f(**a, **b)')
433 self.check_expr('f(2, *a, *b, **b, **c, **d)')
Yury Selivanov50a26142015-08-05 17:59:45 -0400434 self.check_expr("f(*b, *() or () and (), **{} and {}, **() or {})")
Mark Dickinson11c1dee2012-05-07 16:34:34 +0100435
436 def test_set_comprehensions(self):
437 self.check_expr('{x for x in seq}')
438 self.check_expr('{f(x) for x in seq}')
439 self.check_expr('{f(x) for x in seq if condition(x)}')
440
441 def test_dict_comprehensions(self):
442 self.check_expr('{x:x for x in seq}')
443 self.check_expr('{x**2:x[3] for x in seq if condition(x)}')
444 self.check_expr('{x:x for x in seq1 for y in seq2 if condition(x, y)}')
445
Emily Morehouse8f59ee02019-01-24 16:49:56 -0700446 def test_named_expressions(self):
447 self.check_suite("(a := 1)")
448 self.check_suite("(a := a)")
449 self.check_suite("if (match := pattern.search(data)) is None: pass")
Xtreakd4fceaa2019-02-02 03:10:16 +0530450 self.check_suite("while match := pattern.search(f.read()): pass")
Emily Morehouse8f59ee02019-01-24 16:49:56 -0700451 self.check_suite("[y := f(x), y**2, y**3]")
452 self.check_suite("filtered_data = [y for x in data if (y := f(x)) is None]")
453 self.check_suite("(y := f(x))")
454 self.check_suite("y0 = (y1 := f(x))")
455 self.check_suite("foo(x=(y := f(x)))")
456 self.check_suite("def foo(answer=(p := 42)): pass")
457 self.check_suite("def foo(answer: (p := 42) = 5): pass")
458 self.check_suite("lambda: (x := 1)")
459 self.check_suite("(x := lambda: 1)")
460 self.check_suite("(x := lambda: (y := 1))") # not in PEP
461 self.check_suite("lambda line: (m := re.match(pattern, line)) and m.group(1)")
462 self.check_suite("x = (y := 0)")
463 self.check_suite("(z:=(y:=(x:=0)))")
464 self.check_suite("(info := (name, phone, *rest))")
465 self.check_suite("(x:=1,2)")
466 self.check_suite("(total := total + tax)")
467 self.check_suite("len(lines := f.readlines())")
468 self.check_suite("foo(x := 3, cat='vector')")
469 self.check_suite("foo(cat=(category := 'vector'))")
470 self.check_suite("if any(len(longline := l) >= 100 for l in lines): print(longline)")
471 self.check_suite(
472 "if env_base := os.environ.get('PYTHONUSERBASE', None): return env_base"
473 )
474 self.check_suite(
475 "if self._is_special and (ans := self._check_nans(context=context)): return ans"
476 )
477 self.check_suite("foo(b := 2, a=1)")
478 self.check_suite("foo(b := 2, a=1)")
479 self.check_suite("foo((b := 2), a=1)")
480 self.check_suite("foo(c=(b := 2), a=1)")
Jörn Heisslerc8a35412019-06-22 16:40:55 +0200481 self.check_suite("{(x := C(i)).q: x for i in y}")
482
Thomas Wouters89f507f2006-12-13 04:49:30 +0000483
Fred Drake79ca79d2000-08-21 22:30:53 +0000484#
485# Second, we take *invalid* trees and make sure we get ParserError
486# rejections for them.
487#
488
Fred Drake58422e52001-06-04 03:56:24 +0000489class IllegalSyntaxTestCase(unittest.TestCase):
Guido van Rossum32c2ae72002-08-22 19:45:32 +0000490
Fred Drake58422e52001-06-04 03:56:24 +0000491 def check_bad_tree(self, tree, label):
492 try:
Fred Drake6e4f2c02001-07-17 19:33:25 +0000493 parser.sequence2st(tree)
Fred Drake58422e52001-06-04 03:56:24 +0000494 except parser.ParserError:
495 pass
496 else:
497 self.fail("did not detect invalid tree for %r" % label)
Fred Drake79ca79d2000-08-21 22:30:53 +0000498
Fred Drake58422e52001-06-04 03:56:24 +0000499 def test_junk(self):
500 # not even remotely valid:
501 self.check_bad_tree((1, 2, 3), "<junk>")
502
Serhiy Storchakaa79f4c22017-04-19 21:09:21 +0300503 def test_illegal_terminal(self):
504 tree = \
505 (257,
506 (269,
507 (270,
508 (271,
509 (277,
510 (1,))),
511 (4, ''))),
512 (4, ''),
513 (0, ''))
514 self.check_bad_tree(tree, "too small items in terminal node")
515 tree = \
516 (257,
517 (269,
518 (270,
519 (271,
520 (277,
521 (1, b'pass'))),
522 (4, ''))),
523 (4, ''),
524 (0, ''))
525 self.check_bad_tree(tree, "non-string second item in terminal node")
526 tree = \
527 (257,
528 (269,
529 (270,
530 (271,
531 (277,
532 (1, 'pass', '0', 0))),
533 (4, ''))),
534 (4, ''),
535 (0, ''))
536 self.check_bad_tree(tree, "non-integer third item in terminal node")
537 tree = \
538 (257,
539 (269,
540 (270,
541 (271,
542 (277,
543 (1, 'pass', 0, 0))),
544 (4, ''))),
545 (4, ''),
546 (0, ''))
547 self.check_bad_tree(tree, "too many items in terminal node")
548
Fred Drakecf580c72001-07-17 03:01:29 +0000549 def test_illegal_yield_1(self):
Guido van Rossum32c2ae72002-08-22 19:45:32 +0000550 # Illegal yield statement: def f(): return 1; yield 1
Fred Drakecf580c72001-07-17 03:01:29 +0000551 tree = \
552 (257,
553 (264,
554 (285,
555 (259,
556 (1, 'def'),
557 (1, 'f'),
558 (260, (7, '('), (8, ')')),
559 (11, ':'),
560 (291,
561 (4, ''),
562 (5, ''),
563 (264,
564 (265,
565 (266,
566 (272,
567 (275,
568 (1, 'return'),
569 (313,
570 (292,
571 (293,
572 (294,
573 (295,
574 (297,
575 (298,
576 (299,
577 (300,
578 (301,
579 (302, (303, (304, (305, (2, '1')))))))))))))))))),
580 (264,
581 (265,
582 (266,
583 (272,
584 (276,
585 (1, 'yield'),
586 (313,
587 (292,
588 (293,
589 (294,
590 (295,
591 (297,
592 (298,
593 (299,
594 (300,
595 (301,
596 (302,
597 (303, (304, (305, (2, '1')))))))))))))))))),
598 (4, ''))),
599 (6, ''))))),
600 (4, ''),
601 (0, ''))))
602 self.check_bad_tree(tree, "def f():\n return 1\n yield 1")
603
604 def test_illegal_yield_2(self):
Guido van Rossum32c2ae72002-08-22 19:45:32 +0000605 # Illegal return in generator: def f(): return 1; yield 1
Fred Drakecf580c72001-07-17 03:01:29 +0000606 tree = \
607 (257,
608 (264,
609 (265,
610 (266,
611 (278,
612 (1, 'from'),
613 (281, (1, '__future__')),
614 (1, 'import'),
615 (279, (1, 'generators')))),
616 (4, ''))),
617 (264,
618 (285,
619 (259,
620 (1, 'def'),
621 (1, 'f'),
622 (260, (7, '('), (8, ')')),
623 (11, ':'),
624 (291,
625 (4, ''),
626 (5, ''),
627 (264,
628 (265,
629 (266,
630 (272,
631 (275,
632 (1, 'return'),
633 (313,
634 (292,
635 (293,
636 (294,
637 (295,
638 (297,
639 (298,
640 (299,
641 (300,
642 (301,
643 (302, (303, (304, (305, (2, '1')))))))))))))))))),
644 (264,
645 (265,
646 (266,
647 (272,
648 (276,
649 (1, 'yield'),
650 (313,
651 (292,
652 (293,
653 (294,
654 (295,
655 (297,
656 (298,
657 (299,
658 (300,
659 (301,
660 (302,
661 (303, (304, (305, (2, '1')))))))))))))))))),
662 (4, ''))),
663 (6, ''))))),
664 (4, ''),
665 (0, ''))))
666 self.check_bad_tree(tree, "def f():\n return 1\n yield 1")
667
Fred Drake58422e52001-06-04 03:56:24 +0000668 def test_a_comma_comma_c(self):
Guido van Rossum32c2ae72002-08-22 19:45:32 +0000669 # Illegal input: a,,c
Fred Drake58422e52001-06-04 03:56:24 +0000670 tree = \
671 (258,
672 (311,
673 (290,
674 (291,
675 (292,
676 (293,
677 (295,
678 (296,
679 (297,
680 (298, (299, (300, (301, (302, (303, (1, 'a')))))))))))))),
681 (12, ','),
682 (12, ','),
683 (290,
684 (291,
685 (292,
686 (293,
687 (295,
688 (296,
689 (297,
690 (298, (299, (300, (301, (302, (303, (1, 'c'))))))))))))))),
691 (4, ''),
692 (0, ''))
693 self.check_bad_tree(tree, "a,,c")
694
695 def test_illegal_operator(self):
Guido van Rossum32c2ae72002-08-22 19:45:32 +0000696 # Illegal input: a $= b
Fred Drake58422e52001-06-04 03:56:24 +0000697 tree = \
698 (257,
699 (264,
700 (265,
701 (266,
702 (267,
703 (312,
704 (291,
705 (292,
706 (293,
707 (294,
708 (296,
709 (297,
710 (298,
711 (299,
712 (300, (301, (302, (303, (304, (1, 'a'))))))))))))))),
713 (268, (37, '$=')),
714 (312,
715 (291,
716 (292,
717 (293,
718 (294,
719 (296,
720 (297,
721 (298,
722 (299,
723 (300, (301, (302, (303, (304, (1, 'b'))))))))))))))))),
724 (4, ''))),
725 (0, ''))
726 self.check_bad_tree(tree, "a $= b")
Fred Drake79ca79d2000-08-21 22:30:53 +0000727
Neal Norwitz9caf9c02003-02-10 01:54:06 +0000728 def test_malformed_global(self):
729 #doesn't have global keyword in ast
730 tree = (257,
731 (264,
732 (265,
733 (266,
734 (282, (1, 'foo'))), (4, ''))),
735 (4, ''),
Tim Petersf2715e02003-02-19 02:35:07 +0000736 (0, ''))
Neal Norwitz9caf9c02003-02-10 01:54:06 +0000737 self.check_bad_tree(tree, "malformed global ast")
Fred Drake79ca79d2000-08-21 22:30:53 +0000738
Mark Dickinson2cc8a5e2010-07-04 18:11:51 +0000739 def test_missing_import_source(self):
Mark Dickinson3445b482010-07-04 18:15:26 +0000740 # from import fred
Mark Dickinson2cc8a5e2010-07-04 18:11:51 +0000741 tree = \
742 (257,
Mark Dickinson3445b482010-07-04 18:15:26 +0000743 (268,
744 (269,
745 (270,
746 (282,
747 (284, (1, 'from'), (1, 'import'),
748 (287, (285, (1, 'fred')))))),
Mark Dickinson2cc8a5e2010-07-04 18:11:51 +0000749 (4, ''))),
750 (4, ''), (0, ''))
Mark Dickinson3445b482010-07-04 18:15:26 +0000751 self.check_bad_tree(tree, "from import fred")
Mark Dickinson2cc8a5e2010-07-04 18:11:51 +0000752
Serhiy Storchakaa79f4c22017-04-19 21:09:21 +0300753 def test_illegal_encoding(self):
754 # Illegal encoding declaration
755 tree = \
Emily Morehouse8f59ee02019-01-24 16:49:56 -0700756 (341,
Serhiy Storchakaa79f4c22017-04-19 21:09:21 +0300757 (257, (0, '')))
758 self.check_bad_tree(tree, "missed encoding")
759 tree = \
Emily Morehouse8f59ee02019-01-24 16:49:56 -0700760 (341,
Serhiy Storchakaa79f4c22017-04-19 21:09:21 +0300761 (257, (0, '')),
762 b'iso-8859-1')
763 self.check_bad_tree(tree, "non-string encoding")
764 tree = \
Emily Morehouse8f59ee02019-01-24 16:49:56 -0700765 (341,
Serhiy Storchakaa79f4c22017-04-19 21:09:21 +0300766 (257, (0, '')),
767 '\udcff')
768 with self.assertRaises(UnicodeEncodeError):
769 parser.sequence2st(tree)
770
tyomitchcb0748d2019-04-03 08:12:07 +0300771 def test_invalid_node_id(self):
772 tree = (257, (269, (-7, '')))
773 self.check_bad_tree(tree, "negative node id")
774 tree = (257, (269, (99, '')))
775 self.check_bad_tree(tree, "invalid token id")
776 tree = (257, (269, (9999, (0, ''))))
777 self.check_bad_tree(tree, "invalid symbol id")
778
779 def test_ParserError_message(self):
780 try:
781 parser.sequence2st((257,(269,(257,(0,'')))))
782 except parser.ParserError as why:
783 self.assertIn("compound_stmt", str(why)) # Expected
784 self.assertIn("file_input", str(why)) # Got
785
786
Jeremy Hylton3e0055f2005-10-20 19:59:25 +0000787
788class CompileTestCase(unittest.TestCase):
789
790 # These tests are very minimal. :-(
791
792 def test_compile_expr(self):
793 st = parser.expr('2 + 3')
794 code = parser.compilest(st)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000795 self.assertEqual(eval(code), 5)
Jeremy Hylton3e0055f2005-10-20 19:59:25 +0000796
797 def test_compile_suite(self):
798 st = parser.suite('x = 2; y = x + 3')
799 code = parser.compilest(st)
800 globs = {}
Georg Brandl7cae87c2006-09-06 06:51:57 +0000801 exec(code, globs)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000802 self.assertEqual(globs['y'], 5)
Jeremy Hylton3e0055f2005-10-20 19:59:25 +0000803
804 def test_compile_error(self):
805 st = parser.suite('1 = 3 + 4')
806 self.assertRaises(SyntaxError, parser.compilest, st)
807
Guido van Rossumb5a755e2007-07-18 18:15:48 +0000808 def test_compile_badunicode(self):
Guido van Rossum7eb6ca52007-07-18 21:00:22 +0000809 st = parser.suite('a = "\\U12345678"')
Guido van Rossumb5a755e2007-07-18 18:15:48 +0000810 self.assertRaises(SyntaxError, parser.compilest, st)
Guido van Rossum7eb6ca52007-07-18 21:00:22 +0000811 st = parser.suite('a = "\\u1"')
Guido van Rossumb5a755e2007-07-18 18:15:48 +0000812 self.assertRaises(SyntaxError, parser.compilest, st)
813
Mark Dickinsond35a32e2010-06-17 12:33:22 +0000814 def test_issue_9011(self):
815 # Issue 9011: compilation of an unary minus expression changed
816 # the meaning of the ST, so that a second compilation produced
817 # incorrect results.
818 st = parser.expr('-3')
819 code1 = parser.compilest(st)
820 self.assertEqual(eval(code1), -3)
821 code2 = parser.compilest(st)
822 self.assertEqual(eval(code2), -3)
823
Serhiy Storchaka9305d832016-06-18 13:53:36 +0300824 def test_compile_filename(self):
825 st = parser.expr('a + 5')
826 code = parser.compilest(st)
827 self.assertEqual(code.co_filename, '<syntax-tree>')
828 code = st.compile()
829 self.assertEqual(code.co_filename, '<syntax-tree>')
Serhiy Storchakafebc3322016-08-06 23:29:29 +0300830 for filename in 'file.py', b'file.py':
Serhiy Storchaka9305d832016-06-18 13:53:36 +0300831 code = parser.compilest(st, filename)
832 self.assertEqual(code.co_filename, 'file.py')
833 code = st.compile(filename)
834 self.assertEqual(code.co_filename, 'file.py')
Serhiy Storchakafebc3322016-08-06 23:29:29 +0300835 for filename in bytearray(b'file.py'), memoryview(b'file.py'):
836 with self.assertWarns(DeprecationWarning):
837 code = parser.compilest(st, filename)
838 self.assertEqual(code.co_filename, 'file.py')
839 with self.assertWarns(DeprecationWarning):
840 code = st.compile(filename)
841 self.assertEqual(code.co_filename, 'file.py')
Serhiy Storchaka9305d832016-06-18 13:53:36 +0300842 self.assertRaises(TypeError, parser.compilest, st, list(b'file.py'))
843 self.assertRaises(TypeError, st.compile, list(b'file.py'))
844
845
Christian Heimes90c3d9b2008-02-23 13:18:03 +0000846class ParserStackLimitTestCase(unittest.TestCase):
Mark Dickinsond35a32e2010-06-17 12:33:22 +0000847 """try to push the parser to/over its limits.
Christian Heimes90c3d9b2008-02-23 13:18:03 +0000848 see http://bugs.python.org/issue1881 for a discussion
849 """
850 def _nested_expression(self, level):
851 return "["*level+"]"*level
852
853 def test_deeply_nested_list(self):
Emily Morehouse8f59ee02019-01-24 16:49:56 -0700854 # This has fluctuated between 99 levels in 2.x, down to 93 levels in
855 # 3.7.X and back up to 99 in 3.8.X. Related to MAXSTACK size in Parser.h
856 e = self._nested_expression(99)
Christian Heimes90c3d9b2008-02-23 13:18:03 +0000857 st = parser.expr(e)
858 st.compile()
859
860 def test_trigger_memory_error(self):
861 e = self._nested_expression(100)
Ezio Melotti39191842013-03-09 22:17:33 +0200862 rc, out, err = assert_python_failure('-c', e)
863 # parsing the expression will result in an error message
864 # followed by a MemoryError (see #11963)
Ezio Melottie7c32992013-03-10 03:25:45 +0200865 self.assertIn(b's_push: parser stack overflow', err)
866 self.assertIn(b'MemoryError', err)
Christian Heimes90c3d9b2008-02-23 13:18:03 +0000867
Mark Dickinson211c6252009-02-01 10:28:51 +0000868class STObjectTestCase(unittest.TestCase):
869 """Test operations on ST objects themselves"""
870
871 def test_comparisons(self):
872 # ST objects should support order and equality comparisons
873 st1 = parser.expr('2 + 3')
874 st2 = parser.suite('x = 2; y = x + 3')
875 st3 = parser.expr('list(x**3 for x in range(20))')
876 st1_copy = parser.expr('2 + 3')
877 st2_copy = parser.suite('x = 2; y = x + 3')
878 st3_copy = parser.expr('list(x**3 for x in range(20))')
879
880 # exercise fast path for object identity
Ezio Melottib3aedd42010-11-20 19:04:17 +0000881 self.assertEqual(st1 == st1, True)
882 self.assertEqual(st2 == st2, True)
883 self.assertEqual(st3 == st3, True)
Mark Dickinson211c6252009-02-01 10:28:51 +0000884 # slow path equality
885 self.assertEqual(st1, st1_copy)
886 self.assertEqual(st2, st2_copy)
887 self.assertEqual(st3, st3_copy)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000888 self.assertEqual(st1 == st2, False)
889 self.assertEqual(st1 == st3, False)
890 self.assertEqual(st2 == st3, False)
891 self.assertEqual(st1 != st1, False)
892 self.assertEqual(st2 != st2, False)
893 self.assertEqual(st3 != st3, False)
894 self.assertEqual(st1 != st1_copy, False)
895 self.assertEqual(st2 != st2_copy, False)
896 self.assertEqual(st3 != st3_copy, False)
897 self.assertEqual(st2 != st1, True)
898 self.assertEqual(st1 != st3, True)
899 self.assertEqual(st3 != st2, True)
Mark Dickinson211c6252009-02-01 10:28:51 +0000900 # we don't particularly care what the ordering is; just that
901 # it's usable and self-consistent
Ezio Melottib3aedd42010-11-20 19:04:17 +0000902 self.assertEqual(st1 < st2, not (st2 <= st1))
903 self.assertEqual(st1 < st3, not (st3 <= st1))
904 self.assertEqual(st2 < st3, not (st3 <= st2))
905 self.assertEqual(st1 < st2, st2 > st1)
906 self.assertEqual(st1 < st3, st3 > st1)
907 self.assertEqual(st2 < st3, st3 > st2)
908 self.assertEqual(st1 <= st2, st2 >= st1)
909 self.assertEqual(st3 <= st1, st1 >= st3)
910 self.assertEqual(st2 <= st3, st3 >= st2)
Mark Dickinson211c6252009-02-01 10:28:51 +0000911 # transitivity
912 bottom = min(st1, st2, st3)
913 top = max(st1, st2, st3)
914 mid = sorted([st1, st2, st3])[1]
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000915 self.assertTrue(bottom < mid)
916 self.assertTrue(bottom < top)
917 self.assertTrue(mid < top)
918 self.assertTrue(bottom <= mid)
919 self.assertTrue(bottom <= top)
920 self.assertTrue(mid <= top)
921 self.assertTrue(bottom <= bottom)
922 self.assertTrue(mid <= mid)
923 self.assertTrue(top <= top)
Mark Dickinson211c6252009-02-01 10:28:51 +0000924 # interaction with other types
Ezio Melottib3aedd42010-11-20 19:04:17 +0000925 self.assertEqual(st1 == 1588.602459, False)
926 self.assertEqual('spanish armada' != st2, True)
Mark Dickinson211c6252009-02-01 10:28:51 +0000927 self.assertRaises(TypeError, operator.ge, st3, None)
928 self.assertRaises(TypeError, operator.le, False, st1)
929 self.assertRaises(TypeError, operator.lt, st1, 1815)
930 self.assertRaises(TypeError, operator.gt, b'waterloo', st2)
931
Serhiy Storchakaa79f4c22017-04-19 21:09:21 +0300932 def test_copy_pickle(self):
933 sts = [
934 parser.expr('2 + 3'),
935 parser.suite('x = 2; y = x + 3'),
936 parser.expr('list(x**3 for x in range(20))')
937 ]
938 for st in sts:
939 st_copy = copy.copy(st)
940 self.assertEqual(st_copy.totuple(), st.totuple())
941 st_copy = copy.deepcopy(st)
942 self.assertEqual(st_copy.totuple(), st.totuple())
943 for proto in range(pickle.HIGHEST_PROTOCOL+1):
944 st_copy = pickle.loads(pickle.dumps(st, proto))
945 self.assertEqual(st_copy.totuple(), st.totuple())
946
Jesus Ceae9c53182012-08-03 14:28:37 +0200947 check_sizeof = support.check_sizeof
948
949 @support.cpython_only
950 def test_sizeof(self):
951 def XXXROUNDUP(n):
952 if n <= 1:
953 return n
954 if n <= 128:
955 return (n + 3) & ~3
956 return 1 << (n - 1).bit_length()
957
Guido van Rossum495da292019-03-07 12:38:08 -0800958 basesize = support.calcobjsize('Piii')
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000959 nodesize = struct.calcsize('hP3iP0h2i')
Jesus Ceae9c53182012-08-03 14:28:37 +0200960 def sizeofchildren(node):
961 if node is None:
962 return 0
963 res = 0
964 hasstr = len(node) > 1 and isinstance(node[-1], str)
965 if hasstr:
966 res += len(node[-1]) + 1
967 children = node[1:-1] if hasstr else node[1:]
968 if children:
969 res += XXXROUNDUP(len(children)) * nodesize
Jesus Ceae9c53182012-08-03 14:28:37 +0200970 for child in children:
971 res += sizeofchildren(child)
972 return res
973
974 def check_st_sizeof(st):
975 self.check_sizeof(st, basesize + nodesize +
976 sizeofchildren(st.totuple()))
977
978 check_st_sizeof(parser.expr('2 + 3'))
979 check_st_sizeof(parser.expr('2 + 3 + 4'))
980 check_st_sizeof(parser.suite('x = 2 + 3'))
981 check_st_sizeof(parser.suite(''))
982 check_st_sizeof(parser.suite('# -*- coding: utf-8 -*-'))
983 check_st_sizeof(parser.expr('[' + '2,' * 1000 + ']'))
984
Mark Dickinson211c6252009-02-01 10:28:51 +0000985
986 # XXX tests for pickling and unpickling of ST objects should go here
987
Benjamin Petersonf719957d2011-06-04 22:06:42 -0500988class OtherParserCase(unittest.TestCase):
989
990 def test_two_args_to_expr(self):
991 # See bug #12264
992 with self.assertRaises(TypeError):
993 parser.expr("a", "b")
994
Pablo Galindo9211e2f2019-07-30 12:04:01 +0100995
996class TestDeprecation(unittest.TestCase):
997 def test_deprecation_message(self):
998 code = "def f():\n import parser\n\nf()"
999 rc, out, err = assert_python_ok('-c', code)
1000 self.assertIn(b'<string>:2: DeprecationWarning', err)
1001
1002
Fred Drake2e2be372001-09-20 21:33:42 +00001003if __name__ == "__main__":
Zachary Ware38c707e2015-04-13 15:00:43 -05001004 unittest.main()