blob: 0ee994f3b7505f1d3e6723dcf4bd8a273a9ee760 [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
Pablo Galindoc5fc1562020-04-22 23:29:27 +010011import sys
Benjamin Petersonee8712c2008-05-20 21:35:26 +000012from test import support
Berker Peksagce643912015-05-06 06:33:17 +030013from test.support.script_helper import assert_python_failure
Pablo Galindo9211e2f2019-07-30 12:04:01 +010014from test.support.script_helper import assert_python_ok
Fred Drake79ca79d2000-08-21 22:30:53 +000015
16#
17# First, we test that we can generate trees from valid source fragments,
18# and that these valid trees are indeed allowed by the tree-loading side
19# of the parser module.
20#
21
Fred Drake58422e52001-06-04 03:56:24 +000022class RoundtripLegalSyntaxTestCase(unittest.TestCase):
Guido van Rossum32c2ae72002-08-22 19:45:32 +000023
Fred Drake58422e52001-06-04 03:56:24 +000024 def roundtrip(self, f, s):
25 st1 = f(s)
26 t = st1.totuple()
27 try:
Fred Drake6e4f2c02001-07-17 19:33:25 +000028 st2 = parser.sequence2st(t)
Guido van Rossumb940e112007-01-10 16:19:56 +000029 except parser.ParserError as why:
Anthony Baxterc2a5a632004-08-02 06:10:11 +000030 self.fail("could not roundtrip %r: %s" % (s, why))
Fred Drake79ca79d2000-08-21 22:30:53 +000031
Ezio Melottib3aedd42010-11-20 19:04:17 +000032 self.assertEqual(t, st2.totuple(),
33 "could not re-generate syntax tree")
Fred Drake28f739a2000-08-25 22:42:40 +000034
Fred Drake58422e52001-06-04 03:56:24 +000035 def check_expr(self, s):
36 self.roundtrip(parser.expr, s)
Fred Drake28f739a2000-08-25 22:42:40 +000037
Benjamin Petersonf216c942008-10-31 02:28:05 +000038 def test_flags_passed(self):
Mike53f7a7c2017-12-14 14:04:53 +030039 # The unicode literals flags has to be passed from the parser to AST
Benjamin Petersonf216c942008-10-31 02:28:05 +000040 # generation.
41 suite = parser.suite("from __future__ import unicode_literals; x = ''")
42 code = suite.compile()
43 scope = {}
44 exec(code, {}, scope)
Ezio Melottie9615932010-01-24 19:26:24 +000045 self.assertIsInstance(scope["x"], str)
Benjamin Petersonf216c942008-10-31 02:28:05 +000046
Fred Drake58422e52001-06-04 03:56:24 +000047 def check_suite(self, s):
48 self.roundtrip(parser.suite, s)
Fred Drake28f739a2000-08-25 22:42:40 +000049
Fred Drakecf580c72001-07-17 03:01:29 +000050 def test_yield_statement(self):
Tim Peters496563a2002-04-01 00:28:59 +000051 self.check_suite("def f(): yield 1")
Phillip J. Eby0d6615f2005-08-02 00:46:46 +000052 self.check_suite("def f(): yield")
53 self.check_suite("def f(): x += yield")
54 self.check_suite("def f(): x = yield 1")
55 self.check_suite("def f(): x = y = yield 1")
56 self.check_suite("def f(): x = yield")
57 self.check_suite("def f(): x = y = yield")
58 self.check_suite("def f(): 1 + (yield)*2")
59 self.check_suite("def f(): (yield 1)*2")
Tim Peters496563a2002-04-01 00:28:59 +000060 self.check_suite("def f(): return; yield 1")
61 self.check_suite("def f(): yield 1; return")
Nick Coghlan1f7ce622012-01-13 21:43:40 +100062 self.check_suite("def f(): yield from 1")
63 self.check_suite("def f(): x = yield from 1")
64 self.check_suite("def f(): f((yield from 1))")
65 self.check_suite("def f(): yield 1; return 1")
Tim Peters496563a2002-04-01 00:28:59 +000066 self.check_suite("def f():\n"
Fred Drakecf580c72001-07-17 03:01:29 +000067 " for x in range(30):\n"
68 " yield x\n")
Phillip J. Eby0d6615f2005-08-02 00:46:46 +000069 self.check_suite("def f():\n"
70 " if (yield):\n"
71 " yield x\n")
Fred Drakecf580c72001-07-17 03:01:29 +000072
Yury Selivanov75445082015-05-11 22:57:16 -040073 def test_await_statement(self):
74 self.check_suite("async def f():\n await smth()")
75 self.check_suite("async def f():\n foo = await smth()")
76 self.check_suite("async def f():\n foo, bar = await smth()")
77 self.check_suite("async def f():\n (await smth())")
78 self.check_suite("async def f():\n foo((await smth()))")
79 self.check_suite("async def f():\n await foo(); return 42")
80
81 def test_async_with_statement(self):
82 self.check_suite("async def f():\n async with 1: pass")
83 self.check_suite("async def f():\n async with a as b, c as d: pass")
84
85 def test_async_for_statement(self):
86 self.check_suite("async def f():\n async for i in (): pass")
87 self.check_suite("async def f():\n async for i, b in (): pass")
88
Mark Dickinson407b3bd2012-04-29 22:18:31 +010089 def test_nonlocal_statement(self):
90 self.check_suite("def f():\n"
91 " x = 0\n"
92 " def g():\n"
93 " nonlocal x\n")
94 self.check_suite("def f():\n"
95 " x = y = 0\n"
96 " def g():\n"
97 " nonlocal x, y\n")
98
Fred Drake58422e52001-06-04 03:56:24 +000099 def test_expressions(self):
100 self.check_expr("foo(1)")
101 self.check_expr("[1, 2, 3]")
102 self.check_expr("[x**3 for x in range(20)]")
103 self.check_expr("[x**3 for x in range(20) if x % 3]")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000104 self.check_expr("[x**3 for x in range(20) if x % 2 if x % 3]")
105 self.check_expr("list(x**3 for x in range(20))")
106 self.check_expr("list(x**3 for x in range(20) if x % 3)")
107 self.check_expr("list(x**3 for x in range(20) if x % 2 if x % 3)")
Fred Drake58422e52001-06-04 03:56:24 +0000108 self.check_expr("foo(*args)")
109 self.check_expr("foo(*args, **kw)")
110 self.check_expr("foo(**kw)")
111 self.check_expr("foo(key=value)")
112 self.check_expr("foo(key=value, *args)")
113 self.check_expr("foo(key=value, *args, **kw)")
114 self.check_expr("foo(key=value, **kw)")
115 self.check_expr("foo(a, b, c, *args)")
116 self.check_expr("foo(a, b, c, *args, **kw)")
117 self.check_expr("foo(a, b, c, **kw)")
Benjamin Peterson3938a902008-08-20 02:33:00 +0000118 self.check_expr("foo(a, *args, keyword=23)")
Fred Drake58422e52001-06-04 03:56:24 +0000119 self.check_expr("foo + bar")
Michael W. Hudson5e83b7a2003-01-29 14:20:23 +0000120 self.check_expr("foo - bar")
121 self.check_expr("foo * bar")
122 self.check_expr("foo / bar")
123 self.check_expr("foo // bar")
Emily Morehouse8f59ee02019-01-24 16:49:56 -0700124 self.check_expr("(foo := 1)")
Fred Drake58422e52001-06-04 03:56:24 +0000125 self.check_expr("lambda: 0")
126 self.check_expr("lambda x: 0")
127 self.check_expr("lambda *y: 0")
128 self.check_expr("lambda *y, **z: 0")
129 self.check_expr("lambda **z: 0")
130 self.check_expr("lambda x, y: 0")
131 self.check_expr("lambda foo=bar: 0")
132 self.check_expr("lambda foo=bar, spaz=nifty+spit: 0")
133 self.check_expr("lambda foo=bar, **z: 0")
134 self.check_expr("lambda foo=bar, blaz=blat+2, **z: 0")
135 self.check_expr("lambda foo=bar, blaz=blat+2, *y, **z: 0")
136 self.check_expr("lambda x, *y, **z: 0")
Raymond Hettinger354433a2004-05-19 08:20:33 +0000137 self.check_expr("(x for x in range(10))")
138 self.check_expr("foo(x for x in range(10))")
Mark Dickinsonda029fb2012-05-07 17:24:04 +0100139 self.check_expr("...")
140 self.check_expr("a[...]")
Fred Drake79ca79d2000-08-21 22:30:53 +0000141
Fred Drake58422e52001-06-04 03:56:24 +0000142 def test_simple_expression(self):
143 # expr_stmt
144 self.check_suite("a")
Fred Drake79ca79d2000-08-21 22:30:53 +0000145
Fred Drake58422e52001-06-04 03:56:24 +0000146 def test_simple_assignments(self):
147 self.check_suite("a = b")
148 self.check_suite("a = b = c = d = e")
Fred Drake28f739a2000-08-25 22:42:40 +0000149
Yury Selivanovf8cb8a12016-09-08 20:50:03 -0700150 def test_var_annot(self):
151 self.check_suite("x: int = 5")
152 self.check_suite("y: List[T] = []; z: [list] = fun()")
153 self.check_suite("x: tuple = (1, 2)")
154 self.check_suite("d[f()]: int = 42")
155 self.check_suite("f(d[x]): str = 'abc'")
156 self.check_suite("x.y.z.w: complex = 42j")
157 self.check_suite("x: int")
158 self.check_suite("def f():\n"
159 " x: str\n"
160 " y: int = 5\n")
161 self.check_suite("class C:\n"
162 " x: str\n"
163 " y: int = 5\n")
164 self.check_suite("class C:\n"
165 " def __init__(self, x: int) -> None:\n"
166 " self.x: int = x\n")
167 # double check for nonsense
168 with self.assertRaises(SyntaxError):
169 exec("2+2: int", {}, {})
170 with self.assertRaises(SyntaxError):
171 exec("[]: int = 5", {}, {})
172 with self.assertRaises(SyntaxError):
173 exec("x, *y, z: int = range(5)", {}, {})
174 with self.assertRaises(SyntaxError):
Ivan Levkivskyi62c35a82019-01-25 01:39:19 +0000175 exec("x: int = 1, y = 2", {}, {})
Yury Selivanovf8cb8a12016-09-08 20:50:03 -0700176 with self.assertRaises(SyntaxError):
177 exec("u = v: int", {}, {})
178 with self.assertRaises(SyntaxError):
179 exec("False: int", {}, {})
180 with self.assertRaises(SyntaxError):
181 exec("x.False: int", {}, {})
182 with self.assertRaises(SyntaxError):
183 exec("x.y,: int", {}, {})
184 with self.assertRaises(SyntaxError):
185 exec("[0]: int", {}, {})
186 with self.assertRaises(SyntaxError):
187 exec("f(): int", {}, {})
188
Fred Drake58422e52001-06-04 03:56:24 +0000189 def test_simple_augmented_assignments(self):
190 self.check_suite("a += b")
191 self.check_suite("a -= b")
192 self.check_suite("a *= b")
193 self.check_suite("a /= b")
Michael W. Hudson5e83b7a2003-01-29 14:20:23 +0000194 self.check_suite("a //= b")
Fred Drake58422e52001-06-04 03:56:24 +0000195 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")
201 self.check_suite("a **= b")
Fred Drakee3fb18c2001-01-07 06:02:19 +0000202
Fred Drake58422e52001-06-04 03:56:24 +0000203 def test_function_defs(self):
204 self.check_suite("def f(): pass")
205 self.check_suite("def f(*args): pass")
206 self.check_suite("def f(*args, **kw): pass")
207 self.check_suite("def f(**kw): pass")
208 self.check_suite("def f(foo=bar): pass")
209 self.check_suite("def f(foo=bar, *args): pass")
210 self.check_suite("def f(foo=bar, *args, **kw): pass")
211 self.check_suite("def f(foo=bar, **kw): pass")
Fred Drakee3fb18c2001-01-07 06:02:19 +0000212
Fred Drake58422e52001-06-04 03:56:24 +0000213 self.check_suite("def f(a, b): pass")
214 self.check_suite("def f(a, b, *args): pass")
215 self.check_suite("def f(a, b, *args, **kw): pass")
216 self.check_suite("def f(a, b, **kw): pass")
217 self.check_suite("def f(a, b, foo=bar): pass")
218 self.check_suite("def f(a, b, foo=bar, *args): pass")
219 self.check_suite("def f(a, b, foo=bar, *args, **kw): pass")
220 self.check_suite("def f(a, b, foo=bar, **kw): pass")
Fred Drakee3fb18c2001-01-07 06:02:19 +0000221
Anthony Baxterc2a5a632004-08-02 06:10:11 +0000222 self.check_suite("@staticmethod\n"
223 "def f(): pass")
224 self.check_suite("@staticmethod\n"
225 "@funcattrs(x, y)\n"
226 "def f(): pass")
227 self.check_suite("@funcattrs()\n"
228 "def f(): pass")
229
Brandt Bucherbe501ca2020-03-03 14:25:44 -0800230 self.check_suite("@False or x\n"
231 "def f(): pass")
232 self.check_suite("@d := x\n"
233 "def f(): pass")
234 self.check_suite("@lambda f: x(f)\n"
235 "def f(): pass")
236 self.check_suite("@[..., x, ...][1]\n"
237 "def f(): pass")
238 self.check_suite("@x(x)(x)\n"
239 "def f(): pass")
240 self.check_suite("@(x, x)\n"
241 "def f(): pass")
242 self.check_suite("@...\n"
243 "def f(): pass")
244 self.check_suite("@None\n"
245 "def f(): pass")
246 self.check_suite("@w @(x @y) @(z)\n"
247 "def f(): pass")
248 self.check_suite("@w[x].y.z\n"
249 "def f(): pass")
250
Mark Dickinsonea7e9f92012-04-29 18:34:40 +0100251 # keyword-only arguments
252 self.check_suite("def f(*, a): pass")
253 self.check_suite("def f(*, a = 5): pass")
254 self.check_suite("def f(*, a = 5, b): pass")
255 self.check_suite("def f(*, a, b = 5): pass")
256 self.check_suite("def f(*, a, b = 5, **kwds): pass")
257 self.check_suite("def f(*args, a): pass")
258 self.check_suite("def f(*args, a = 5): pass")
259 self.check_suite("def f(*args, a = 5, b): pass")
260 self.check_suite("def f(*args, a, b = 5): pass")
261 self.check_suite("def f(*args, a, b = 5, **kwds): pass")
262
Pablo Galindo8c77b8c2019-04-29 13:36:57 +0100263 # positional-only arguments
264 self.check_suite("def f(a, /): pass")
265 self.check_suite("def f(a, /,): pass")
266 self.check_suite("def f(a, b, /): pass")
267 self.check_suite("def f(a, b, /, c): pass")
268 self.check_suite("def f(a, b, /, c = 6): pass")
269 self.check_suite("def f(a, b, /, c, *, d): pass")
270 self.check_suite("def f(a, b, /, c = 1, *, d): pass")
271 self.check_suite("def f(a, b, /, c, *, d = 1): pass")
272 self.check_suite("def f(a, b=1, /, c=2, *, d = 3): pass")
273 self.check_suite("def f(a=0, b=1, /, c=2, *, d = 3): pass")
274
Mark Dickinsonea7e9f92012-04-29 18:34:40 +0100275 # function annotations
276 self.check_suite("def f(a: int): pass")
277 self.check_suite("def f(a: int = 5): pass")
278 self.check_suite("def f(*args: list): pass")
279 self.check_suite("def f(**kwds: dict): pass")
280 self.check_suite("def f(*, a: int): pass")
281 self.check_suite("def f(*, a: int = 5): pass")
282 self.check_suite("def f() -> int: pass")
283
Brett Cannonf4189912005-04-09 02:30:16 +0000284 def test_class_defs(self):
285 self.check_suite("class foo():pass")
Guido van Rossumfc158e22007-11-15 19:17:28 +0000286 self.check_suite("class foo(object):pass")
Mark Dickinson2bd61a92010-07-04 16:37:31 +0000287 self.check_suite("@class_decorator\n"
288 "class foo():pass")
289 self.check_suite("@class_decorator(arg)\n"
290 "class foo():pass")
291 self.check_suite("@decorator1\n"
292 "@decorator2\n"
293 "class foo():pass")
Tim Peterse8906822005-04-20 17:45:13 +0000294
Brandt Bucherbe501ca2020-03-03 14:25:44 -0800295 self.check_suite("@False or x\n"
296 "class C: pass")
297 self.check_suite("@d := x\n"
298 "class C: pass")
299 self.check_suite("@lambda f: x(f)\n"
300 "class C: pass")
301 self.check_suite("@[..., x, ...][1]\n"
302 "class C: pass")
303 self.check_suite("@x(x)(x)\n"
304 "class C: pass")
305 self.check_suite("@(x, x)\n"
306 "class C: pass")
307 self.check_suite("@...\n"
308 "class C: pass")
309 self.check_suite("@None\n"
310 "class C: pass")
311 self.check_suite("@w @(x @y) @(z)\n"
312 "class C: pass")
313 self.check_suite("@w[x].y.z\n"
314 "class C: pass")
315
Fred Drake58422e52001-06-04 03:56:24 +0000316 def test_import_from_statement(self):
317 self.check_suite("from sys.path import *")
318 self.check_suite("from sys.path import dirname")
Anthony Baxter1a4ddae2004-08-31 10:07:13 +0000319 self.check_suite("from sys.path import (dirname)")
320 self.check_suite("from sys.path import (dirname,)")
Fred Drake58422e52001-06-04 03:56:24 +0000321 self.check_suite("from sys.path import dirname as my_dirname")
Anthony Baxter1a4ddae2004-08-31 10:07:13 +0000322 self.check_suite("from sys.path import (dirname as my_dirname)")
323 self.check_suite("from sys.path import (dirname as my_dirname,)")
Fred Drake58422e52001-06-04 03:56:24 +0000324 self.check_suite("from sys.path import dirname, basename")
Anthony Baxter1a4ddae2004-08-31 10:07:13 +0000325 self.check_suite("from sys.path import (dirname, basename)")
326 self.check_suite("from sys.path import (dirname, basename,)")
Fred Drake58422e52001-06-04 03:56:24 +0000327 self.check_suite(
328 "from sys.path import dirname as my_dirname, basename")
329 self.check_suite(
Anthony Baxter1a4ddae2004-08-31 10:07:13 +0000330 "from sys.path import (dirname as my_dirname, basename)")
331 self.check_suite(
332 "from sys.path import (dirname as my_dirname, basename,)")
333 self.check_suite(
Fred Drake58422e52001-06-04 03:56:24 +0000334 "from sys.path import dirname, basename as my_basename")
Anthony Baxter1a4ddae2004-08-31 10:07:13 +0000335 self.check_suite(
336 "from sys.path import (dirname, basename as my_basename)")
337 self.check_suite(
338 "from sys.path import (dirname, basename as my_basename,)")
Benjamin Petersonc0747cf2008-11-03 20:31:38 +0000339 self.check_suite("from .bogus import x")
Fred Drakee3fb18c2001-01-07 06:02:19 +0000340
Fred Drake58422e52001-06-04 03:56:24 +0000341 def test_basic_import_statement(self):
342 self.check_suite("import sys")
343 self.check_suite("import sys as system")
344 self.check_suite("import sys, math")
345 self.check_suite("import sys as system, math")
346 self.check_suite("import sys, math as my_math")
Fred Drake79ca79d2000-08-21 22:30:53 +0000347
Mark Dickinson2cc8a5e2010-07-04 18:11:51 +0000348 def test_relative_imports(self):
349 self.check_suite("from . import name")
350 self.check_suite("from .. import name")
Mark Dickinsonfeb3b752010-07-04 18:38:57 +0000351 # check all the way up to '....', since '...' is tokenized
352 # differently from '.' (it's an ellipsis token).
353 self.check_suite("from ... import name")
354 self.check_suite("from .... import name")
Mark Dickinson2cc8a5e2010-07-04 18:11:51 +0000355 self.check_suite("from .pkg import name")
356 self.check_suite("from ..pkg import name")
Mark Dickinsonfeb3b752010-07-04 18:38:57 +0000357 self.check_suite("from ...pkg import name")
358 self.check_suite("from ....pkg import name")
Mark Dickinson2cc8a5e2010-07-04 18:11:51 +0000359
Neal Norwitz9caf9c02003-02-10 01:54:06 +0000360 def test_pep263(self):
361 self.check_suite("# -*- coding: iso-8859-1 -*-\n"
362 "pass\n")
363
364 def test_assert(self):
365 self.check_suite("assert alo < ahi and blo < bhi\n")
366
Benjamin Peterson4469d0c2008-11-30 22:46:23 +0000367 def test_with(self):
368 self.check_suite("with open('x'): pass\n")
369 self.check_suite("with open('x') as f: pass\n")
Georg Brandl0c315622009-05-25 21:10:36 +0000370 self.check_suite("with open('x') as f, open('y') as g: pass\n")
Benjamin Peterson4469d0c2008-11-30 22:46:23 +0000371
Georg Brandleee31162008-12-07 15:15:22 +0000372 def test_try_stmt(self):
373 self.check_suite("try: pass\nexcept: pass\n")
374 self.check_suite("try: pass\nfinally: pass\n")
375 self.check_suite("try: pass\nexcept A: pass\nfinally: pass\n")
376 self.check_suite("try: pass\nexcept A: pass\nexcept: pass\n"
377 "finally: pass\n")
378 self.check_suite("try: pass\nexcept: pass\nelse: pass\n")
379 self.check_suite("try: pass\nexcept: pass\nelse: pass\n"
380 "finally: pass\n")
381
Pablo Galindo9a0000d2019-03-21 23:33:02 +0000382 def test_if_stmt(self):
383 self.check_suite("if True:\n pass\nelse:\n pass\n")
384 self.check_suite("if True:\n pass\nelif True:\n pass\nelse:\n pass\n")
385
Thomas Wouters89f507f2006-12-13 04:49:30 +0000386 def test_position(self):
387 # An absolutely minimal test of position information. Better
388 # tests would be a big project.
Benjamin Peterson8f326b22009-12-13 02:10:36 +0000389 code = "def f(x):\n return x + 1"
Serhiy Storchakae5362ea2018-04-19 01:55:37 +0300390 st = parser.suite(code)
Thomas Wouters89f507f2006-12-13 04:49:30 +0000391
392 def walk(tree):
393 node_type = tree[0]
394 next = tree[1]
Serhiy Storchakae5362ea2018-04-19 01:55:37 +0300395 if isinstance(next, (tuple, list)):
Thomas Wouters89f507f2006-12-13 04:49:30 +0000396 for elt in tree[1:]:
397 for x in walk(elt):
398 yield x
399 else:
400 yield tree
401
Serhiy Storchakae5362ea2018-04-19 01:55:37 +0300402 expected = [
Thomas Wouters89f507f2006-12-13 04:49:30 +0000403 (1, 'def', 1, 0),
404 (1, 'f', 1, 4),
405 (7, '(', 1, 5),
406 (1, 'x', 1, 6),
407 (8, ')', 1, 7),
408 (11, ':', 1, 8),
409 (4, '', 1, 9),
410 (5, '', 2, -1),
411 (1, 'return', 2, 4),
412 (1, 'x', 2, 11),
413 (14, '+', 2, 13),
414 (2, '1', 2, 15),
415 (4, '', 2, 16),
Benjamin Peterson8f326b22009-12-13 02:10:36 +0000416 (6, '', 2, -1),
417 (4, '', 2, -1),
Serhiy Storchakae5362ea2018-04-19 01:55:37 +0300418 (0, '', 2, -1),
419 ]
420
421 self.assertEqual(list(walk(st.totuple(line_info=True, col_info=True))),
422 expected)
423 self.assertEqual(list(walk(st.totuple())),
424 [(t, n) for t, n, l, c in expected])
425 self.assertEqual(list(walk(st.totuple(line_info=True))),
426 [(t, n, l) for t, n, l, c in expected])
427 self.assertEqual(list(walk(st.totuple(col_info=True))),
428 [(t, n, c) for t, n, l, c in expected])
429 self.assertEqual(list(walk(st.tolist(line_info=True, col_info=True))),
430 [list(x) for x in expected])
431 self.assertEqual(list(walk(parser.st2tuple(st, line_info=True,
432 col_info=True))),
433 expected)
434 self.assertEqual(list(walk(parser.st2list(st, line_info=True,
435 col_info=True))),
436 [list(x) for x in expected])
Thomas Wouters89f507f2006-12-13 04:49:30 +0000437
Benjamin Peterson4905e802009-09-27 02:43:28 +0000438 def test_extended_unpacking(self):
439 self.check_suite("*a = y")
440 self.check_suite("x, *b, = m")
441 self.check_suite("[*a, *b] = y")
442 self.check_suite("for [*x, b] in x: pass")
443
Mark Dickinsoncf360b92012-05-07 12:01:27 +0100444 def test_raise_statement(self):
445 self.check_suite("raise\n")
446 self.check_suite("raise e\n")
447 self.check_suite("try:\n"
448 " suite\n"
449 "except Exception as e:\n"
450 " raise ValueError from e\n")
451
Benjamin Peterson025e9eb2015-05-05 20:16:41 -0400452 def test_list_displays(self):
453 self.check_expr('[]')
454 self.check_expr('[*{2}, 3, *[4]]')
455
Mark Dickinson11c1dee2012-05-07 16:34:34 +0100456 def test_set_displays(self):
Benjamin Peterson025e9eb2015-05-05 20:16:41 -0400457 self.check_expr('{*{2}, 3, *[4]}')
Mark Dickinson11c1dee2012-05-07 16:34:34 +0100458 self.check_expr('{2}')
459 self.check_expr('{2,}')
460 self.check_expr('{2, 3}')
461 self.check_expr('{2, 3,}')
462
463 def test_dict_displays(self):
464 self.check_expr('{}')
465 self.check_expr('{a:b}')
466 self.check_expr('{a:b,}')
467 self.check_expr('{a:b, c:d}')
468 self.check_expr('{a:b, c:d,}')
Benjamin Peterson025e9eb2015-05-05 20:16:41 -0400469 self.check_expr('{**{}}')
470 self.check_expr('{**{}, 3:4, **{5:6, 7:8}}')
471
472 def test_argument_unpacking(self):
Yury Selivanov50a26142015-08-05 17:59:45 -0400473 self.check_expr("f(*a, **b)")
Benjamin Peterson025e9eb2015-05-05 20:16:41 -0400474 self.check_expr('f(a, *b, *c, *d)')
475 self.check_expr('f(**a, **b)')
476 self.check_expr('f(2, *a, *b, **b, **c, **d)')
Yury Selivanov50a26142015-08-05 17:59:45 -0400477 self.check_expr("f(*b, *() or () and (), **{} and {}, **() or {})")
Mark Dickinson11c1dee2012-05-07 16:34:34 +0100478
479 def test_set_comprehensions(self):
480 self.check_expr('{x for x in seq}')
481 self.check_expr('{f(x) for x in seq}')
482 self.check_expr('{f(x) for x in seq if condition(x)}')
483
484 def test_dict_comprehensions(self):
485 self.check_expr('{x:x for x in seq}')
486 self.check_expr('{x**2:x[3] for x in seq if condition(x)}')
487 self.check_expr('{x:x for x in seq1 for y in seq2 if condition(x, y)}')
488
Emily Morehouse8f59ee02019-01-24 16:49:56 -0700489 def test_named_expressions(self):
490 self.check_suite("(a := 1)")
491 self.check_suite("(a := a)")
492 self.check_suite("if (match := pattern.search(data)) is None: pass")
Xtreakd4fceaa2019-02-02 03:10:16 +0530493 self.check_suite("while match := pattern.search(f.read()): pass")
Emily Morehouse8f59ee02019-01-24 16:49:56 -0700494 self.check_suite("[y := f(x), y**2, y**3]")
495 self.check_suite("filtered_data = [y for x in data if (y := f(x)) is None]")
496 self.check_suite("(y := f(x))")
497 self.check_suite("y0 = (y1 := f(x))")
498 self.check_suite("foo(x=(y := f(x)))")
499 self.check_suite("def foo(answer=(p := 42)): pass")
500 self.check_suite("def foo(answer: (p := 42) = 5): pass")
501 self.check_suite("lambda: (x := 1)")
502 self.check_suite("(x := lambda: 1)")
503 self.check_suite("(x := lambda: (y := 1))") # not in PEP
504 self.check_suite("lambda line: (m := re.match(pattern, line)) and m.group(1)")
505 self.check_suite("x = (y := 0)")
506 self.check_suite("(z:=(y:=(x:=0)))")
507 self.check_suite("(info := (name, phone, *rest))")
508 self.check_suite("(x:=1,2)")
509 self.check_suite("(total := total + tax)")
510 self.check_suite("len(lines := f.readlines())")
511 self.check_suite("foo(x := 3, cat='vector')")
512 self.check_suite("foo(cat=(category := 'vector'))")
513 self.check_suite("if any(len(longline := l) >= 100 for l in lines): print(longline)")
514 self.check_suite(
515 "if env_base := os.environ.get('PYTHONUSERBASE', None): return env_base"
516 )
517 self.check_suite(
518 "if self._is_special and (ans := self._check_nans(context=context)): return ans"
519 )
520 self.check_suite("foo(b := 2, a=1)")
521 self.check_suite("foo(b := 2, a=1)")
522 self.check_suite("foo((b := 2), a=1)")
523 self.check_suite("foo(c=(b := 2), a=1)")
Jörn Heisslerc8a35412019-06-22 16:40:55 +0200524 self.check_suite("{(x := C(i)).q: x for i in y}")
525
Thomas Wouters89f507f2006-12-13 04:49:30 +0000526
Fred Drake79ca79d2000-08-21 22:30:53 +0000527#
528# Second, we take *invalid* trees and make sure we get ParserError
529# rejections for them.
530#
531
Fred Drake58422e52001-06-04 03:56:24 +0000532class IllegalSyntaxTestCase(unittest.TestCase):
Guido van Rossum32c2ae72002-08-22 19:45:32 +0000533
Fred Drake58422e52001-06-04 03:56:24 +0000534 def check_bad_tree(self, tree, label):
535 try:
Fred Drake6e4f2c02001-07-17 19:33:25 +0000536 parser.sequence2st(tree)
Fred Drake58422e52001-06-04 03:56:24 +0000537 except parser.ParserError:
538 pass
539 else:
540 self.fail("did not detect invalid tree for %r" % label)
Fred Drake79ca79d2000-08-21 22:30:53 +0000541
Fred Drake58422e52001-06-04 03:56:24 +0000542 def test_junk(self):
543 # not even remotely valid:
544 self.check_bad_tree((1, 2, 3), "<junk>")
545
Serhiy Storchakaa79f4c22017-04-19 21:09:21 +0300546 def test_illegal_terminal(self):
547 tree = \
548 (257,
549 (269,
550 (270,
551 (271,
552 (277,
553 (1,))),
554 (4, ''))),
555 (4, ''),
556 (0, ''))
557 self.check_bad_tree(tree, "too small items in terminal node")
558 tree = \
559 (257,
560 (269,
561 (270,
562 (271,
563 (277,
564 (1, b'pass'))),
565 (4, ''))),
566 (4, ''),
567 (0, ''))
568 self.check_bad_tree(tree, "non-string second item in terminal node")
569 tree = \
570 (257,
571 (269,
572 (270,
573 (271,
574 (277,
575 (1, 'pass', '0', 0))),
576 (4, ''))),
577 (4, ''),
578 (0, ''))
579 self.check_bad_tree(tree, "non-integer third item in terminal node")
580 tree = \
581 (257,
582 (269,
583 (270,
584 (271,
585 (277,
586 (1, 'pass', 0, 0))),
587 (4, ''))),
588 (4, ''),
589 (0, ''))
590 self.check_bad_tree(tree, "too many items in terminal node")
591
Fred Drakecf580c72001-07-17 03:01:29 +0000592 def test_illegal_yield_1(self):
Guido van Rossum32c2ae72002-08-22 19:45:32 +0000593 # Illegal yield statement: def f(): return 1; yield 1
Fred Drakecf580c72001-07-17 03:01:29 +0000594 tree = \
595 (257,
596 (264,
597 (285,
598 (259,
599 (1, 'def'),
600 (1, 'f'),
601 (260, (7, '('), (8, ')')),
602 (11, ':'),
603 (291,
604 (4, ''),
605 (5, ''),
606 (264,
607 (265,
608 (266,
609 (272,
610 (275,
611 (1, 'return'),
612 (313,
613 (292,
614 (293,
615 (294,
616 (295,
617 (297,
618 (298,
619 (299,
620 (300,
621 (301,
622 (302, (303, (304, (305, (2, '1')))))))))))))))))),
623 (264,
624 (265,
625 (266,
626 (272,
627 (276,
628 (1, 'yield'),
629 (313,
630 (292,
631 (293,
632 (294,
633 (295,
634 (297,
635 (298,
636 (299,
637 (300,
638 (301,
639 (302,
640 (303, (304, (305, (2, '1')))))))))))))))))),
641 (4, ''))),
642 (6, ''))))),
643 (4, ''),
644 (0, ''))))
645 self.check_bad_tree(tree, "def f():\n return 1\n yield 1")
646
647 def test_illegal_yield_2(self):
Guido van Rossum32c2ae72002-08-22 19:45:32 +0000648 # Illegal return in generator: def f(): return 1; yield 1
Fred Drakecf580c72001-07-17 03:01:29 +0000649 tree = \
650 (257,
651 (264,
652 (265,
653 (266,
654 (278,
655 (1, 'from'),
656 (281, (1, '__future__')),
657 (1, 'import'),
658 (279, (1, 'generators')))),
659 (4, ''))),
660 (264,
661 (285,
662 (259,
663 (1, 'def'),
664 (1, 'f'),
665 (260, (7, '('), (8, ')')),
666 (11, ':'),
667 (291,
668 (4, ''),
669 (5, ''),
670 (264,
671 (265,
672 (266,
673 (272,
674 (275,
675 (1, 'return'),
676 (313,
677 (292,
678 (293,
679 (294,
680 (295,
681 (297,
682 (298,
683 (299,
684 (300,
685 (301,
686 (302, (303, (304, (305, (2, '1')))))))))))))))))),
687 (264,
688 (265,
689 (266,
690 (272,
691 (276,
692 (1, 'yield'),
693 (313,
694 (292,
695 (293,
696 (294,
697 (295,
698 (297,
699 (298,
700 (299,
701 (300,
702 (301,
703 (302,
704 (303, (304, (305, (2, '1')))))))))))))))))),
705 (4, ''))),
706 (6, ''))))),
707 (4, ''),
708 (0, ''))))
709 self.check_bad_tree(tree, "def f():\n return 1\n yield 1")
710
Fred Drake58422e52001-06-04 03:56:24 +0000711 def test_a_comma_comma_c(self):
Guido van Rossum32c2ae72002-08-22 19:45:32 +0000712 # Illegal input: a,,c
Fred Drake58422e52001-06-04 03:56:24 +0000713 tree = \
714 (258,
715 (311,
716 (290,
717 (291,
718 (292,
719 (293,
720 (295,
721 (296,
722 (297,
723 (298, (299, (300, (301, (302, (303, (1, 'a')))))))))))))),
724 (12, ','),
725 (12, ','),
726 (290,
727 (291,
728 (292,
729 (293,
730 (295,
731 (296,
732 (297,
733 (298, (299, (300, (301, (302, (303, (1, 'c'))))))))))))))),
734 (4, ''),
735 (0, ''))
736 self.check_bad_tree(tree, "a,,c")
737
738 def test_illegal_operator(self):
Guido van Rossum32c2ae72002-08-22 19:45:32 +0000739 # Illegal input: a $= b
Fred Drake58422e52001-06-04 03:56:24 +0000740 tree = \
741 (257,
742 (264,
743 (265,
744 (266,
745 (267,
746 (312,
747 (291,
748 (292,
749 (293,
750 (294,
751 (296,
752 (297,
753 (298,
754 (299,
755 (300, (301, (302, (303, (304, (1, 'a'))))))))))))))),
756 (268, (37, '$=')),
757 (312,
758 (291,
759 (292,
760 (293,
761 (294,
762 (296,
763 (297,
764 (298,
765 (299,
766 (300, (301, (302, (303, (304, (1, 'b'))))))))))))))))),
767 (4, ''))),
768 (0, ''))
769 self.check_bad_tree(tree, "a $= b")
Fred Drake79ca79d2000-08-21 22:30:53 +0000770
Neal Norwitz9caf9c02003-02-10 01:54:06 +0000771 def test_malformed_global(self):
772 #doesn't have global keyword in ast
773 tree = (257,
774 (264,
775 (265,
776 (266,
777 (282, (1, 'foo'))), (4, ''))),
778 (4, ''),
Tim Petersf2715e02003-02-19 02:35:07 +0000779 (0, ''))
Neal Norwitz9caf9c02003-02-10 01:54:06 +0000780 self.check_bad_tree(tree, "malformed global ast")
Fred Drake79ca79d2000-08-21 22:30:53 +0000781
Mark Dickinson2cc8a5e2010-07-04 18:11:51 +0000782 def test_missing_import_source(self):
Mark Dickinson3445b482010-07-04 18:15:26 +0000783 # from import fred
Mark Dickinson2cc8a5e2010-07-04 18:11:51 +0000784 tree = \
785 (257,
Mark Dickinson3445b482010-07-04 18:15:26 +0000786 (268,
787 (269,
788 (270,
789 (282,
790 (284, (1, 'from'), (1, 'import'),
791 (287, (285, (1, 'fred')))))),
Mark Dickinson2cc8a5e2010-07-04 18:11:51 +0000792 (4, ''))),
793 (4, ''), (0, ''))
Mark Dickinson3445b482010-07-04 18:15:26 +0000794 self.check_bad_tree(tree, "from import fred")
Mark Dickinson2cc8a5e2010-07-04 18:11:51 +0000795
Serhiy Storchakaa79f4c22017-04-19 21:09:21 +0300796 def test_illegal_encoding(self):
797 # Illegal encoding declaration
798 tree = \
Emily Morehouse8f59ee02019-01-24 16:49:56 -0700799 (341,
Serhiy Storchakaa79f4c22017-04-19 21:09:21 +0300800 (257, (0, '')))
801 self.check_bad_tree(tree, "missed encoding")
802 tree = \
Emily Morehouse8f59ee02019-01-24 16:49:56 -0700803 (341,
Serhiy Storchakaa79f4c22017-04-19 21:09:21 +0300804 (257, (0, '')),
805 b'iso-8859-1')
806 self.check_bad_tree(tree, "non-string encoding")
807 tree = \
Emily Morehouse8f59ee02019-01-24 16:49:56 -0700808 (341,
Serhiy Storchakaa79f4c22017-04-19 21:09:21 +0300809 (257, (0, '')),
810 '\udcff')
811 with self.assertRaises(UnicodeEncodeError):
812 parser.sequence2st(tree)
813
tyomitchcb0748d2019-04-03 08:12:07 +0300814 def test_invalid_node_id(self):
815 tree = (257, (269, (-7, '')))
816 self.check_bad_tree(tree, "negative node id")
817 tree = (257, (269, (99, '')))
818 self.check_bad_tree(tree, "invalid token id")
819 tree = (257, (269, (9999, (0, ''))))
820 self.check_bad_tree(tree, "invalid symbol id")
821
822 def test_ParserError_message(self):
823 try:
824 parser.sequence2st((257,(269,(257,(0,'')))))
825 except parser.ParserError as why:
826 self.assertIn("compound_stmt", str(why)) # Expected
827 self.assertIn("file_input", str(why)) # Got
828
829
Jeremy Hylton3e0055f2005-10-20 19:59:25 +0000830
831class CompileTestCase(unittest.TestCase):
832
833 # These tests are very minimal. :-(
834
835 def test_compile_expr(self):
836 st = parser.expr('2 + 3')
837 code = parser.compilest(st)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000838 self.assertEqual(eval(code), 5)
Jeremy Hylton3e0055f2005-10-20 19:59:25 +0000839
840 def test_compile_suite(self):
841 st = parser.suite('x = 2; y = x + 3')
842 code = parser.compilest(st)
843 globs = {}
Georg Brandl7cae87c2006-09-06 06:51:57 +0000844 exec(code, globs)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000845 self.assertEqual(globs['y'], 5)
Jeremy Hylton3e0055f2005-10-20 19:59:25 +0000846
847 def test_compile_error(self):
848 st = parser.suite('1 = 3 + 4')
849 self.assertRaises(SyntaxError, parser.compilest, st)
850
Guido van Rossumb5a755e2007-07-18 18:15:48 +0000851 def test_compile_badunicode(self):
Guido van Rossum7eb6ca52007-07-18 21:00:22 +0000852 st = parser.suite('a = "\\U12345678"')
Guido van Rossumb5a755e2007-07-18 18:15:48 +0000853 self.assertRaises(SyntaxError, parser.compilest, st)
Guido van Rossum7eb6ca52007-07-18 21:00:22 +0000854 st = parser.suite('a = "\\u1"')
Guido van Rossumb5a755e2007-07-18 18:15:48 +0000855 self.assertRaises(SyntaxError, parser.compilest, st)
856
Mark Dickinsond35a32e2010-06-17 12:33:22 +0000857 def test_issue_9011(self):
858 # Issue 9011: compilation of an unary minus expression changed
859 # the meaning of the ST, so that a second compilation produced
860 # incorrect results.
861 st = parser.expr('-3')
862 code1 = parser.compilest(st)
863 self.assertEqual(eval(code1), -3)
864 code2 = parser.compilest(st)
865 self.assertEqual(eval(code2), -3)
866
Serhiy Storchaka9305d832016-06-18 13:53:36 +0300867 def test_compile_filename(self):
868 st = parser.expr('a + 5')
869 code = parser.compilest(st)
870 self.assertEqual(code.co_filename, '<syntax-tree>')
871 code = st.compile()
872 self.assertEqual(code.co_filename, '<syntax-tree>')
Serhiy Storchakafebc3322016-08-06 23:29:29 +0300873 for filename in 'file.py', b'file.py':
Serhiy Storchaka9305d832016-06-18 13:53:36 +0300874 code = parser.compilest(st, filename)
875 self.assertEqual(code.co_filename, 'file.py')
876 code = st.compile(filename)
877 self.assertEqual(code.co_filename, 'file.py')
Serhiy Storchakafebc3322016-08-06 23:29:29 +0300878 for filename in bytearray(b'file.py'), memoryview(b'file.py'):
879 with self.assertWarns(DeprecationWarning):
880 code = parser.compilest(st, filename)
881 self.assertEqual(code.co_filename, 'file.py')
882 with self.assertWarns(DeprecationWarning):
883 code = st.compile(filename)
884 self.assertEqual(code.co_filename, 'file.py')
Serhiy Storchaka9305d832016-06-18 13:53:36 +0300885 self.assertRaises(TypeError, parser.compilest, st, list(b'file.py'))
886 self.assertRaises(TypeError, st.compile, list(b'file.py'))
887
888
Christian Heimes90c3d9b2008-02-23 13:18:03 +0000889class ParserStackLimitTestCase(unittest.TestCase):
Mark Dickinsond35a32e2010-06-17 12:33:22 +0000890 """try to push the parser to/over its limits.
Christian Heimes90c3d9b2008-02-23 13:18:03 +0000891 see http://bugs.python.org/issue1881 for a discussion
892 """
893 def _nested_expression(self, level):
894 return "["*level+"]"*level
895
896 def test_deeply_nested_list(self):
Emily Morehouse8f59ee02019-01-24 16:49:56 -0700897 # This has fluctuated between 99 levels in 2.x, down to 93 levels in
898 # 3.7.X and back up to 99 in 3.8.X. Related to MAXSTACK size in Parser.h
899 e = self._nested_expression(99)
Christian Heimes90c3d9b2008-02-23 13:18:03 +0000900 st = parser.expr(e)
901 st.compile()
902
Victor Stinner1def7752020-04-23 03:03:24 +0200903 @support.skip_if_new_parser("Pegen does not trigger memory error with this many parenthesis")
Christian Heimes90c3d9b2008-02-23 13:18:03 +0000904 def test_trigger_memory_error(self):
905 e = self._nested_expression(100)
Pablo Galindoc5fc1562020-04-22 23:29:27 +0100906 rc, out, err = assert_python_failure('-Xoldparser', '-c', e)
Ezio Melotti39191842013-03-09 22:17:33 +0200907 # parsing the expression will result in an error message
908 # followed by a MemoryError (see #11963)
Ezio Melottie7c32992013-03-10 03:25:45 +0200909 self.assertIn(b's_push: parser stack overflow', err)
910 self.assertIn(b'MemoryError', err)
Christian Heimes90c3d9b2008-02-23 13:18:03 +0000911
Mark Dickinson211c6252009-02-01 10:28:51 +0000912class STObjectTestCase(unittest.TestCase):
913 """Test operations on ST objects themselves"""
914
915 def test_comparisons(self):
916 # ST objects should support order and equality comparisons
917 st1 = parser.expr('2 + 3')
918 st2 = parser.suite('x = 2; y = x + 3')
919 st3 = parser.expr('list(x**3 for x in range(20))')
920 st1_copy = parser.expr('2 + 3')
921 st2_copy = parser.suite('x = 2; y = x + 3')
922 st3_copy = parser.expr('list(x**3 for x in range(20))')
923
924 # exercise fast path for object identity
Ezio Melottib3aedd42010-11-20 19:04:17 +0000925 self.assertEqual(st1 == st1, True)
926 self.assertEqual(st2 == st2, True)
927 self.assertEqual(st3 == st3, True)
Mark Dickinson211c6252009-02-01 10:28:51 +0000928 # slow path equality
929 self.assertEqual(st1, st1_copy)
930 self.assertEqual(st2, st2_copy)
931 self.assertEqual(st3, st3_copy)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000932 self.assertEqual(st1 == st2, False)
933 self.assertEqual(st1 == st3, False)
934 self.assertEqual(st2 == st3, False)
935 self.assertEqual(st1 != st1, False)
936 self.assertEqual(st2 != st2, False)
937 self.assertEqual(st3 != st3, False)
938 self.assertEqual(st1 != st1_copy, False)
939 self.assertEqual(st2 != st2_copy, False)
940 self.assertEqual(st3 != st3_copy, False)
941 self.assertEqual(st2 != st1, True)
942 self.assertEqual(st1 != st3, True)
943 self.assertEqual(st3 != st2, True)
Mark Dickinson211c6252009-02-01 10:28:51 +0000944 # we don't particularly care what the ordering is; just that
945 # it's usable and self-consistent
Ezio Melottib3aedd42010-11-20 19:04:17 +0000946 self.assertEqual(st1 < st2, not (st2 <= st1))
947 self.assertEqual(st1 < st3, not (st3 <= st1))
948 self.assertEqual(st2 < st3, not (st3 <= st2))
949 self.assertEqual(st1 < st2, st2 > st1)
950 self.assertEqual(st1 < st3, st3 > st1)
951 self.assertEqual(st2 < st3, st3 > st2)
952 self.assertEqual(st1 <= st2, st2 >= st1)
953 self.assertEqual(st3 <= st1, st1 >= st3)
954 self.assertEqual(st2 <= st3, st3 >= st2)
Mark Dickinson211c6252009-02-01 10:28:51 +0000955 # transitivity
956 bottom = min(st1, st2, st3)
957 top = max(st1, st2, st3)
958 mid = sorted([st1, st2, st3])[1]
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000959 self.assertTrue(bottom < mid)
960 self.assertTrue(bottom < top)
961 self.assertTrue(mid < top)
962 self.assertTrue(bottom <= mid)
963 self.assertTrue(bottom <= top)
964 self.assertTrue(mid <= top)
965 self.assertTrue(bottom <= bottom)
966 self.assertTrue(mid <= mid)
967 self.assertTrue(top <= top)
Mark Dickinson211c6252009-02-01 10:28:51 +0000968 # interaction with other types
Ezio Melottib3aedd42010-11-20 19:04:17 +0000969 self.assertEqual(st1 == 1588.602459, False)
970 self.assertEqual('spanish armada' != st2, True)
Mark Dickinson211c6252009-02-01 10:28:51 +0000971 self.assertRaises(TypeError, operator.ge, st3, None)
972 self.assertRaises(TypeError, operator.le, False, st1)
973 self.assertRaises(TypeError, operator.lt, st1, 1815)
974 self.assertRaises(TypeError, operator.gt, b'waterloo', st2)
975
Serhiy Storchakaa79f4c22017-04-19 21:09:21 +0300976 def test_copy_pickle(self):
977 sts = [
978 parser.expr('2 + 3'),
979 parser.suite('x = 2; y = x + 3'),
980 parser.expr('list(x**3 for x in range(20))')
981 ]
982 for st in sts:
983 st_copy = copy.copy(st)
984 self.assertEqual(st_copy.totuple(), st.totuple())
985 st_copy = copy.deepcopy(st)
986 self.assertEqual(st_copy.totuple(), st.totuple())
987 for proto in range(pickle.HIGHEST_PROTOCOL+1):
988 st_copy = pickle.loads(pickle.dumps(st, proto))
989 self.assertEqual(st_copy.totuple(), st.totuple())
990
Jesus Ceae9c53182012-08-03 14:28:37 +0200991 check_sizeof = support.check_sizeof
992
993 @support.cpython_only
994 def test_sizeof(self):
995 def XXXROUNDUP(n):
996 if n <= 1:
997 return n
998 if n <= 128:
999 return (n + 3) & ~3
1000 return 1 << (n - 1).bit_length()
1001
Guido van Rossum495da292019-03-07 12:38:08 -08001002 basesize = support.calcobjsize('Piii')
Ivan Levkivskyi9932a222019-01-22 11:18:22 +00001003 nodesize = struct.calcsize('hP3iP0h2i')
Jesus Ceae9c53182012-08-03 14:28:37 +02001004 def sizeofchildren(node):
1005 if node is None:
1006 return 0
1007 res = 0
1008 hasstr = len(node) > 1 and isinstance(node[-1], str)
1009 if hasstr:
1010 res += len(node[-1]) + 1
1011 children = node[1:-1] if hasstr else node[1:]
1012 if children:
1013 res += XXXROUNDUP(len(children)) * nodesize
Jesus Ceae9c53182012-08-03 14:28:37 +02001014 for child in children:
1015 res += sizeofchildren(child)
1016 return res
1017
1018 def check_st_sizeof(st):
1019 self.check_sizeof(st, basesize + nodesize +
1020 sizeofchildren(st.totuple()))
1021
1022 check_st_sizeof(parser.expr('2 + 3'))
1023 check_st_sizeof(parser.expr('2 + 3 + 4'))
1024 check_st_sizeof(parser.suite('x = 2 + 3'))
1025 check_st_sizeof(parser.suite(''))
1026 check_st_sizeof(parser.suite('# -*- coding: utf-8 -*-'))
1027 check_st_sizeof(parser.expr('[' + '2,' * 1000 + ']'))
1028
Mark Dickinson211c6252009-02-01 10:28:51 +00001029
1030 # XXX tests for pickling and unpickling of ST objects should go here
1031
Benjamin Petersonf719957d2011-06-04 22:06:42 -05001032class OtherParserCase(unittest.TestCase):
1033
1034 def test_two_args_to_expr(self):
1035 # See bug #12264
1036 with self.assertRaises(TypeError):
1037 parser.expr("a", "b")
1038
Pablo Galindo9211e2f2019-07-30 12:04:01 +01001039
1040class TestDeprecation(unittest.TestCase):
1041 def test_deprecation_message(self):
1042 code = "def f():\n import parser\n\nf()"
1043 rc, out, err = assert_python_ok('-c', code)
1044 self.assertIn(b'<string>:2: DeprecationWarning', err)
1045
1046
Fred Drake2e2be372001-09-20 21:33:42 +00001047if __name__ == "__main__":
Zachary Ware38c707e2015-04-13 15:00:43 -05001048 unittest.main()