blob: 73178f3e7759be790f52b2079a4b108a13bf25ea [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
Brandt Bucherbe501ca2020-03-03 14:25:44 -0800229 self.check_suite("@False or x\n"
230 "def f(): pass")
231 self.check_suite("@d := x\n"
232 "def f(): pass")
233 self.check_suite("@lambda f: x(f)\n"
234 "def f(): pass")
235 self.check_suite("@[..., x, ...][1]\n"
236 "def f(): pass")
237 self.check_suite("@x(x)(x)\n"
238 "def f(): pass")
239 self.check_suite("@(x, x)\n"
240 "def f(): pass")
241 self.check_suite("@...\n"
242 "def f(): pass")
243 self.check_suite("@None\n"
244 "def f(): pass")
245 self.check_suite("@w @(x @y) @(z)\n"
246 "def f(): pass")
247 self.check_suite("@w[x].y.z\n"
248 "def f(): pass")
249
Mark Dickinsonea7e9f92012-04-29 18:34:40 +0100250 # keyword-only arguments
251 self.check_suite("def f(*, a): pass")
252 self.check_suite("def f(*, a = 5): pass")
253 self.check_suite("def f(*, a = 5, b): pass")
254 self.check_suite("def f(*, a, b = 5): pass")
255 self.check_suite("def f(*, a, b = 5, **kwds): pass")
256 self.check_suite("def f(*args, a): pass")
257 self.check_suite("def f(*args, a = 5): pass")
258 self.check_suite("def f(*args, a = 5, b): pass")
259 self.check_suite("def f(*args, a, b = 5): pass")
260 self.check_suite("def f(*args, a, b = 5, **kwds): pass")
261
Pablo Galindo8c77b8c2019-04-29 13:36:57 +0100262 # positional-only arguments
263 self.check_suite("def f(a, /): pass")
264 self.check_suite("def f(a, /,): pass")
265 self.check_suite("def f(a, b, /): pass")
266 self.check_suite("def f(a, b, /, c): pass")
267 self.check_suite("def f(a, b, /, c = 6): pass")
268 self.check_suite("def f(a, b, /, c, *, d): pass")
269 self.check_suite("def f(a, b, /, c = 1, *, d): pass")
270 self.check_suite("def f(a, b, /, c, *, d = 1): pass")
271 self.check_suite("def f(a, b=1, /, c=2, *, d = 3): pass")
272 self.check_suite("def f(a=0, b=1, /, c=2, *, d = 3): pass")
273
Mark Dickinsonea7e9f92012-04-29 18:34:40 +0100274 # function annotations
275 self.check_suite("def f(a: int): pass")
276 self.check_suite("def f(a: int = 5): pass")
277 self.check_suite("def f(*args: list): pass")
278 self.check_suite("def f(**kwds: dict): pass")
279 self.check_suite("def f(*, a: int): pass")
280 self.check_suite("def f(*, a: int = 5): pass")
281 self.check_suite("def f() -> int: pass")
282
Brett Cannonf4189912005-04-09 02:30:16 +0000283 def test_class_defs(self):
284 self.check_suite("class foo():pass")
Guido van Rossumfc158e22007-11-15 19:17:28 +0000285 self.check_suite("class foo(object):pass")
Mark Dickinson2bd61a92010-07-04 16:37:31 +0000286 self.check_suite("@class_decorator\n"
287 "class foo():pass")
288 self.check_suite("@class_decorator(arg)\n"
289 "class foo():pass")
290 self.check_suite("@decorator1\n"
291 "@decorator2\n"
292 "class foo():pass")
Tim Peterse8906822005-04-20 17:45:13 +0000293
Brandt Bucherbe501ca2020-03-03 14:25:44 -0800294 self.check_suite("@False or x\n"
295 "class C: pass")
296 self.check_suite("@d := x\n"
297 "class C: pass")
298 self.check_suite("@lambda f: x(f)\n"
299 "class C: pass")
300 self.check_suite("@[..., x, ...][1]\n"
301 "class C: pass")
302 self.check_suite("@x(x)(x)\n"
303 "class C: pass")
304 self.check_suite("@(x, x)\n"
305 "class C: pass")
306 self.check_suite("@...\n"
307 "class C: pass")
308 self.check_suite("@None\n"
309 "class C: pass")
310 self.check_suite("@w @(x @y) @(z)\n"
311 "class C: pass")
312 self.check_suite("@w[x].y.z\n"
313 "class C: pass")
314
Fred Drake58422e52001-06-04 03:56:24 +0000315 def test_import_from_statement(self):
316 self.check_suite("from sys.path import *")
317 self.check_suite("from sys.path import dirname")
Anthony Baxter1a4ddae2004-08-31 10:07:13 +0000318 self.check_suite("from sys.path import (dirname)")
319 self.check_suite("from sys.path import (dirname,)")
Fred Drake58422e52001-06-04 03:56:24 +0000320 self.check_suite("from sys.path import dirname as my_dirname")
Anthony Baxter1a4ddae2004-08-31 10:07:13 +0000321 self.check_suite("from sys.path import (dirname as my_dirname)")
322 self.check_suite("from sys.path import (dirname as my_dirname,)")
Fred Drake58422e52001-06-04 03:56:24 +0000323 self.check_suite("from sys.path import dirname, basename")
Anthony Baxter1a4ddae2004-08-31 10:07:13 +0000324 self.check_suite("from sys.path import (dirname, basename)")
325 self.check_suite("from sys.path import (dirname, basename,)")
Fred Drake58422e52001-06-04 03:56:24 +0000326 self.check_suite(
327 "from sys.path import dirname as my_dirname, basename")
328 self.check_suite(
Anthony Baxter1a4ddae2004-08-31 10:07:13 +0000329 "from sys.path import (dirname as my_dirname, basename)")
330 self.check_suite(
331 "from sys.path import (dirname as my_dirname, basename,)")
332 self.check_suite(
Fred Drake58422e52001-06-04 03:56:24 +0000333 "from sys.path import dirname, basename as my_basename")
Anthony Baxter1a4ddae2004-08-31 10:07:13 +0000334 self.check_suite(
335 "from sys.path import (dirname, basename as my_basename)")
336 self.check_suite(
337 "from sys.path import (dirname, basename as my_basename,)")
Benjamin Petersonc0747cf2008-11-03 20:31:38 +0000338 self.check_suite("from .bogus import x")
Fred Drakee3fb18c2001-01-07 06:02:19 +0000339
Fred Drake58422e52001-06-04 03:56:24 +0000340 def test_basic_import_statement(self):
341 self.check_suite("import sys")
342 self.check_suite("import sys as system")
343 self.check_suite("import sys, math")
344 self.check_suite("import sys as system, math")
345 self.check_suite("import sys, math as my_math")
Fred Drake79ca79d2000-08-21 22:30:53 +0000346
Mark Dickinson2cc8a5e2010-07-04 18:11:51 +0000347 def test_relative_imports(self):
348 self.check_suite("from . import name")
349 self.check_suite("from .. import name")
Mark Dickinsonfeb3b752010-07-04 18:38:57 +0000350 # check all the way up to '....', since '...' is tokenized
351 # differently from '.' (it's an ellipsis token).
352 self.check_suite("from ... import name")
353 self.check_suite("from .... import name")
Mark Dickinson2cc8a5e2010-07-04 18:11:51 +0000354 self.check_suite("from .pkg import name")
355 self.check_suite("from ..pkg import name")
Mark Dickinsonfeb3b752010-07-04 18:38:57 +0000356 self.check_suite("from ...pkg import name")
357 self.check_suite("from ....pkg import name")
Mark Dickinson2cc8a5e2010-07-04 18:11:51 +0000358
Neal Norwitz9caf9c02003-02-10 01:54:06 +0000359 def test_pep263(self):
360 self.check_suite("# -*- coding: iso-8859-1 -*-\n"
361 "pass\n")
362
363 def test_assert(self):
364 self.check_suite("assert alo < ahi and blo < bhi\n")
365
Benjamin Peterson4469d0c2008-11-30 22:46:23 +0000366 def test_with(self):
367 self.check_suite("with open('x'): pass\n")
368 self.check_suite("with open('x') as f: pass\n")
Georg Brandl0c315622009-05-25 21:10:36 +0000369 self.check_suite("with open('x') as f, open('y') as g: pass\n")
Benjamin Peterson4469d0c2008-11-30 22:46:23 +0000370
Georg Brandleee31162008-12-07 15:15:22 +0000371 def test_try_stmt(self):
372 self.check_suite("try: pass\nexcept: pass\n")
373 self.check_suite("try: pass\nfinally: pass\n")
374 self.check_suite("try: pass\nexcept A: pass\nfinally: pass\n")
375 self.check_suite("try: pass\nexcept A: pass\nexcept: pass\n"
376 "finally: pass\n")
377 self.check_suite("try: pass\nexcept: pass\nelse: pass\n")
378 self.check_suite("try: pass\nexcept: pass\nelse: pass\n"
379 "finally: pass\n")
380
Pablo Galindo9a0000d2019-03-21 23:33:02 +0000381 def test_if_stmt(self):
382 self.check_suite("if True:\n pass\nelse:\n pass\n")
383 self.check_suite("if True:\n pass\nelif True:\n pass\nelse:\n pass\n")
384
Thomas Wouters89f507f2006-12-13 04:49:30 +0000385 def test_position(self):
386 # An absolutely minimal test of position information. Better
387 # tests would be a big project.
Benjamin Peterson8f326b22009-12-13 02:10:36 +0000388 code = "def f(x):\n return x + 1"
Serhiy Storchakae5362ea2018-04-19 01:55:37 +0300389 st = parser.suite(code)
Thomas Wouters89f507f2006-12-13 04:49:30 +0000390
391 def walk(tree):
392 node_type = tree[0]
393 next = tree[1]
Serhiy Storchakae5362ea2018-04-19 01:55:37 +0300394 if isinstance(next, (tuple, list)):
Thomas Wouters89f507f2006-12-13 04:49:30 +0000395 for elt in tree[1:]:
396 for x in walk(elt):
397 yield x
398 else:
399 yield tree
400
Serhiy Storchakae5362ea2018-04-19 01:55:37 +0300401 expected = [
Thomas Wouters89f507f2006-12-13 04:49:30 +0000402 (1, 'def', 1, 0),
403 (1, 'f', 1, 4),
404 (7, '(', 1, 5),
405 (1, 'x', 1, 6),
406 (8, ')', 1, 7),
407 (11, ':', 1, 8),
408 (4, '', 1, 9),
409 (5, '', 2, -1),
410 (1, 'return', 2, 4),
411 (1, 'x', 2, 11),
412 (14, '+', 2, 13),
413 (2, '1', 2, 15),
414 (4, '', 2, 16),
Benjamin Peterson8f326b22009-12-13 02:10:36 +0000415 (6, '', 2, -1),
416 (4, '', 2, -1),
Serhiy Storchakae5362ea2018-04-19 01:55:37 +0300417 (0, '', 2, -1),
418 ]
419
420 self.assertEqual(list(walk(st.totuple(line_info=True, col_info=True))),
421 expected)
422 self.assertEqual(list(walk(st.totuple())),
423 [(t, n) for t, n, l, c in expected])
424 self.assertEqual(list(walk(st.totuple(line_info=True))),
425 [(t, n, l) for t, n, l, c in expected])
426 self.assertEqual(list(walk(st.totuple(col_info=True))),
427 [(t, n, c) for t, n, l, c in expected])
428 self.assertEqual(list(walk(st.tolist(line_info=True, col_info=True))),
429 [list(x) for x in expected])
430 self.assertEqual(list(walk(parser.st2tuple(st, line_info=True,
431 col_info=True))),
432 expected)
433 self.assertEqual(list(walk(parser.st2list(st, line_info=True,
434 col_info=True))),
435 [list(x) for x in expected])
Thomas Wouters89f507f2006-12-13 04:49:30 +0000436
Benjamin Peterson4905e802009-09-27 02:43:28 +0000437 def test_extended_unpacking(self):
438 self.check_suite("*a = y")
439 self.check_suite("x, *b, = m")
440 self.check_suite("[*a, *b] = y")
441 self.check_suite("for [*x, b] in x: pass")
442
Mark Dickinsoncf360b92012-05-07 12:01:27 +0100443 def test_raise_statement(self):
444 self.check_suite("raise\n")
445 self.check_suite("raise e\n")
446 self.check_suite("try:\n"
447 " suite\n"
448 "except Exception as e:\n"
449 " raise ValueError from e\n")
450
Benjamin Peterson025e9eb2015-05-05 20:16:41 -0400451 def test_list_displays(self):
452 self.check_expr('[]')
453 self.check_expr('[*{2}, 3, *[4]]')
454
Mark Dickinson11c1dee2012-05-07 16:34:34 +0100455 def test_set_displays(self):
Benjamin Peterson025e9eb2015-05-05 20:16:41 -0400456 self.check_expr('{*{2}, 3, *[4]}')
Mark Dickinson11c1dee2012-05-07 16:34:34 +0100457 self.check_expr('{2}')
458 self.check_expr('{2,}')
459 self.check_expr('{2, 3}')
460 self.check_expr('{2, 3,}')
461
462 def test_dict_displays(self):
463 self.check_expr('{}')
464 self.check_expr('{a:b}')
465 self.check_expr('{a:b,}')
466 self.check_expr('{a:b, c:d}')
467 self.check_expr('{a:b, c:d,}')
Benjamin Peterson025e9eb2015-05-05 20:16:41 -0400468 self.check_expr('{**{}}')
469 self.check_expr('{**{}, 3:4, **{5:6, 7:8}}')
470
471 def test_argument_unpacking(self):
Yury Selivanov50a26142015-08-05 17:59:45 -0400472 self.check_expr("f(*a, **b)")
Benjamin Peterson025e9eb2015-05-05 20:16:41 -0400473 self.check_expr('f(a, *b, *c, *d)')
474 self.check_expr('f(**a, **b)')
475 self.check_expr('f(2, *a, *b, **b, **c, **d)')
Yury Selivanov50a26142015-08-05 17:59:45 -0400476 self.check_expr("f(*b, *() or () and (), **{} and {}, **() or {})")
Mark Dickinson11c1dee2012-05-07 16:34:34 +0100477
478 def test_set_comprehensions(self):
479 self.check_expr('{x for x in seq}')
480 self.check_expr('{f(x) for x in seq}')
481 self.check_expr('{f(x) for x in seq if condition(x)}')
482
483 def test_dict_comprehensions(self):
484 self.check_expr('{x:x for x in seq}')
485 self.check_expr('{x**2:x[3] for x in seq if condition(x)}')
486 self.check_expr('{x:x for x in seq1 for y in seq2 if condition(x, y)}')
487
Emily Morehouse8f59ee02019-01-24 16:49:56 -0700488 def test_named_expressions(self):
489 self.check_suite("(a := 1)")
490 self.check_suite("(a := a)")
491 self.check_suite("if (match := pattern.search(data)) is None: pass")
Xtreakd4fceaa2019-02-02 03:10:16 +0530492 self.check_suite("while match := pattern.search(f.read()): pass")
Emily Morehouse8f59ee02019-01-24 16:49:56 -0700493 self.check_suite("[y := f(x), y**2, y**3]")
494 self.check_suite("filtered_data = [y for x in data if (y := f(x)) is None]")
495 self.check_suite("(y := f(x))")
496 self.check_suite("y0 = (y1 := f(x))")
497 self.check_suite("foo(x=(y := f(x)))")
498 self.check_suite("def foo(answer=(p := 42)): pass")
499 self.check_suite("def foo(answer: (p := 42) = 5): pass")
500 self.check_suite("lambda: (x := 1)")
501 self.check_suite("(x := lambda: 1)")
502 self.check_suite("(x := lambda: (y := 1))") # not in PEP
503 self.check_suite("lambda line: (m := re.match(pattern, line)) and m.group(1)")
504 self.check_suite("x = (y := 0)")
505 self.check_suite("(z:=(y:=(x:=0)))")
506 self.check_suite("(info := (name, phone, *rest))")
507 self.check_suite("(x:=1,2)")
508 self.check_suite("(total := total + tax)")
509 self.check_suite("len(lines := f.readlines())")
510 self.check_suite("foo(x := 3, cat='vector')")
511 self.check_suite("foo(cat=(category := 'vector'))")
512 self.check_suite("if any(len(longline := l) >= 100 for l in lines): print(longline)")
513 self.check_suite(
514 "if env_base := os.environ.get('PYTHONUSERBASE', None): return env_base"
515 )
516 self.check_suite(
517 "if self._is_special and (ans := self._check_nans(context=context)): return ans"
518 )
519 self.check_suite("foo(b := 2, a=1)")
520 self.check_suite("foo(b := 2, a=1)")
521 self.check_suite("foo((b := 2), a=1)")
522 self.check_suite("foo(c=(b := 2), a=1)")
Jörn Heisslerc8a35412019-06-22 16:40:55 +0200523 self.check_suite("{(x := C(i)).q: x for i in y}")
524
Thomas Wouters89f507f2006-12-13 04:49:30 +0000525
Fred Drake79ca79d2000-08-21 22:30:53 +0000526#
527# Second, we take *invalid* trees and make sure we get ParserError
528# rejections for them.
529#
530
Fred Drake58422e52001-06-04 03:56:24 +0000531class IllegalSyntaxTestCase(unittest.TestCase):
Guido van Rossum32c2ae72002-08-22 19:45:32 +0000532
Fred Drake58422e52001-06-04 03:56:24 +0000533 def check_bad_tree(self, tree, label):
534 try:
Fred Drake6e4f2c02001-07-17 19:33:25 +0000535 parser.sequence2st(tree)
Fred Drake58422e52001-06-04 03:56:24 +0000536 except parser.ParserError:
537 pass
538 else:
539 self.fail("did not detect invalid tree for %r" % label)
Fred Drake79ca79d2000-08-21 22:30:53 +0000540
Fred Drake58422e52001-06-04 03:56:24 +0000541 def test_junk(self):
542 # not even remotely valid:
543 self.check_bad_tree((1, 2, 3), "<junk>")
544
Serhiy Storchakaa79f4c22017-04-19 21:09:21 +0300545 def test_illegal_terminal(self):
546 tree = \
547 (257,
548 (269,
549 (270,
550 (271,
551 (277,
552 (1,))),
553 (4, ''))),
554 (4, ''),
555 (0, ''))
556 self.check_bad_tree(tree, "too small items in terminal node")
557 tree = \
558 (257,
559 (269,
560 (270,
561 (271,
562 (277,
563 (1, b'pass'))),
564 (4, ''))),
565 (4, ''),
566 (0, ''))
567 self.check_bad_tree(tree, "non-string second item in terminal node")
568 tree = \
569 (257,
570 (269,
571 (270,
572 (271,
573 (277,
574 (1, 'pass', '0', 0))),
575 (4, ''))),
576 (4, ''),
577 (0, ''))
578 self.check_bad_tree(tree, "non-integer third item in terminal node")
579 tree = \
580 (257,
581 (269,
582 (270,
583 (271,
584 (277,
585 (1, 'pass', 0, 0))),
586 (4, ''))),
587 (4, ''),
588 (0, ''))
589 self.check_bad_tree(tree, "too many items in terminal node")
590
Fred Drakecf580c72001-07-17 03:01:29 +0000591 def test_illegal_yield_1(self):
Guido van Rossum32c2ae72002-08-22 19:45:32 +0000592 # Illegal yield statement: def f(): return 1; yield 1
Fred Drakecf580c72001-07-17 03:01:29 +0000593 tree = \
594 (257,
595 (264,
596 (285,
597 (259,
598 (1, 'def'),
599 (1, 'f'),
600 (260, (7, '('), (8, ')')),
601 (11, ':'),
602 (291,
603 (4, ''),
604 (5, ''),
605 (264,
606 (265,
607 (266,
608 (272,
609 (275,
610 (1, 'return'),
611 (313,
612 (292,
613 (293,
614 (294,
615 (295,
616 (297,
617 (298,
618 (299,
619 (300,
620 (301,
621 (302, (303, (304, (305, (2, '1')))))))))))))))))),
622 (264,
623 (265,
624 (266,
625 (272,
626 (276,
627 (1, 'yield'),
628 (313,
629 (292,
630 (293,
631 (294,
632 (295,
633 (297,
634 (298,
635 (299,
636 (300,
637 (301,
638 (302,
639 (303, (304, (305, (2, '1')))))))))))))))))),
640 (4, ''))),
641 (6, ''))))),
642 (4, ''),
643 (0, ''))))
644 self.check_bad_tree(tree, "def f():\n return 1\n yield 1")
645
646 def test_illegal_yield_2(self):
Guido van Rossum32c2ae72002-08-22 19:45:32 +0000647 # Illegal return in generator: def f(): return 1; yield 1
Fred Drakecf580c72001-07-17 03:01:29 +0000648 tree = \
649 (257,
650 (264,
651 (265,
652 (266,
653 (278,
654 (1, 'from'),
655 (281, (1, '__future__')),
656 (1, 'import'),
657 (279, (1, 'generators')))),
658 (4, ''))),
659 (264,
660 (285,
661 (259,
662 (1, 'def'),
663 (1, 'f'),
664 (260, (7, '('), (8, ')')),
665 (11, ':'),
666 (291,
667 (4, ''),
668 (5, ''),
669 (264,
670 (265,
671 (266,
672 (272,
673 (275,
674 (1, 'return'),
675 (313,
676 (292,
677 (293,
678 (294,
679 (295,
680 (297,
681 (298,
682 (299,
683 (300,
684 (301,
685 (302, (303, (304, (305, (2, '1')))))))))))))))))),
686 (264,
687 (265,
688 (266,
689 (272,
690 (276,
691 (1, 'yield'),
692 (313,
693 (292,
694 (293,
695 (294,
696 (295,
697 (297,
698 (298,
699 (299,
700 (300,
701 (301,
702 (302,
703 (303, (304, (305, (2, '1')))))))))))))))))),
704 (4, ''))),
705 (6, ''))))),
706 (4, ''),
707 (0, ''))))
708 self.check_bad_tree(tree, "def f():\n return 1\n yield 1")
709
Fred Drake58422e52001-06-04 03:56:24 +0000710 def test_a_comma_comma_c(self):
Guido van Rossum32c2ae72002-08-22 19:45:32 +0000711 # Illegal input: a,,c
Fred Drake58422e52001-06-04 03:56:24 +0000712 tree = \
713 (258,
714 (311,
715 (290,
716 (291,
717 (292,
718 (293,
719 (295,
720 (296,
721 (297,
722 (298, (299, (300, (301, (302, (303, (1, 'a')))))))))))))),
723 (12, ','),
724 (12, ','),
725 (290,
726 (291,
727 (292,
728 (293,
729 (295,
730 (296,
731 (297,
732 (298, (299, (300, (301, (302, (303, (1, 'c'))))))))))))))),
733 (4, ''),
734 (0, ''))
735 self.check_bad_tree(tree, "a,,c")
736
737 def test_illegal_operator(self):
Guido van Rossum32c2ae72002-08-22 19:45:32 +0000738 # Illegal input: a $= b
Fred Drake58422e52001-06-04 03:56:24 +0000739 tree = \
740 (257,
741 (264,
742 (265,
743 (266,
744 (267,
745 (312,
746 (291,
747 (292,
748 (293,
749 (294,
750 (296,
751 (297,
752 (298,
753 (299,
754 (300, (301, (302, (303, (304, (1, 'a'))))))))))))))),
755 (268, (37, '$=')),
756 (312,
757 (291,
758 (292,
759 (293,
760 (294,
761 (296,
762 (297,
763 (298,
764 (299,
765 (300, (301, (302, (303, (304, (1, 'b'))))))))))))))))),
766 (4, ''))),
767 (0, ''))
768 self.check_bad_tree(tree, "a $= b")
Fred Drake79ca79d2000-08-21 22:30:53 +0000769
Neal Norwitz9caf9c02003-02-10 01:54:06 +0000770 def test_malformed_global(self):
771 #doesn't have global keyword in ast
772 tree = (257,
773 (264,
774 (265,
775 (266,
776 (282, (1, 'foo'))), (4, ''))),
777 (4, ''),
Tim Petersf2715e02003-02-19 02:35:07 +0000778 (0, ''))
Neal Norwitz9caf9c02003-02-10 01:54:06 +0000779 self.check_bad_tree(tree, "malformed global ast")
Fred Drake79ca79d2000-08-21 22:30:53 +0000780
Mark Dickinson2cc8a5e2010-07-04 18:11:51 +0000781 def test_missing_import_source(self):
Mark Dickinson3445b482010-07-04 18:15:26 +0000782 # from import fred
Mark Dickinson2cc8a5e2010-07-04 18:11:51 +0000783 tree = \
784 (257,
Mark Dickinson3445b482010-07-04 18:15:26 +0000785 (268,
786 (269,
787 (270,
788 (282,
789 (284, (1, 'from'), (1, 'import'),
790 (287, (285, (1, 'fred')))))),
Mark Dickinson2cc8a5e2010-07-04 18:11:51 +0000791 (4, ''))),
792 (4, ''), (0, ''))
Mark Dickinson3445b482010-07-04 18:15:26 +0000793 self.check_bad_tree(tree, "from import fred")
Mark Dickinson2cc8a5e2010-07-04 18:11:51 +0000794
Serhiy Storchakaa79f4c22017-04-19 21:09:21 +0300795 def test_illegal_encoding(self):
796 # Illegal encoding declaration
797 tree = \
Emily Morehouse8f59ee02019-01-24 16:49:56 -0700798 (341,
Serhiy Storchakaa79f4c22017-04-19 21:09:21 +0300799 (257, (0, '')))
800 self.check_bad_tree(tree, "missed encoding")
801 tree = \
Emily Morehouse8f59ee02019-01-24 16:49:56 -0700802 (341,
Serhiy Storchakaa79f4c22017-04-19 21:09:21 +0300803 (257, (0, '')),
804 b'iso-8859-1')
805 self.check_bad_tree(tree, "non-string encoding")
806 tree = \
Emily Morehouse8f59ee02019-01-24 16:49:56 -0700807 (341,
Serhiy Storchakaa79f4c22017-04-19 21:09:21 +0300808 (257, (0, '')),
809 '\udcff')
810 with self.assertRaises(UnicodeEncodeError):
811 parser.sequence2st(tree)
812
tyomitchcb0748d2019-04-03 08:12:07 +0300813 def test_invalid_node_id(self):
814 tree = (257, (269, (-7, '')))
815 self.check_bad_tree(tree, "negative node id")
816 tree = (257, (269, (99, '')))
817 self.check_bad_tree(tree, "invalid token id")
818 tree = (257, (269, (9999, (0, ''))))
819 self.check_bad_tree(tree, "invalid symbol id")
820
821 def test_ParserError_message(self):
822 try:
823 parser.sequence2st((257,(269,(257,(0,'')))))
824 except parser.ParserError as why:
825 self.assertIn("compound_stmt", str(why)) # Expected
826 self.assertIn("file_input", str(why)) # Got
827
828
Jeremy Hylton3e0055f2005-10-20 19:59:25 +0000829
830class CompileTestCase(unittest.TestCase):
831
832 # These tests are very minimal. :-(
833
834 def test_compile_expr(self):
835 st = parser.expr('2 + 3')
836 code = parser.compilest(st)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000837 self.assertEqual(eval(code), 5)
Jeremy Hylton3e0055f2005-10-20 19:59:25 +0000838
839 def test_compile_suite(self):
840 st = parser.suite('x = 2; y = x + 3')
841 code = parser.compilest(st)
842 globs = {}
Georg Brandl7cae87c2006-09-06 06:51:57 +0000843 exec(code, globs)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000844 self.assertEqual(globs['y'], 5)
Jeremy Hylton3e0055f2005-10-20 19:59:25 +0000845
846 def test_compile_error(self):
847 st = parser.suite('1 = 3 + 4')
848 self.assertRaises(SyntaxError, parser.compilest, st)
849
Guido van Rossumb5a755e2007-07-18 18:15:48 +0000850 def test_compile_badunicode(self):
Guido van Rossum7eb6ca52007-07-18 21:00:22 +0000851 st = parser.suite('a = "\\U12345678"')
Guido van Rossumb5a755e2007-07-18 18:15:48 +0000852 self.assertRaises(SyntaxError, parser.compilest, st)
Guido van Rossum7eb6ca52007-07-18 21:00:22 +0000853 st = parser.suite('a = "\\u1"')
Guido van Rossumb5a755e2007-07-18 18:15:48 +0000854 self.assertRaises(SyntaxError, parser.compilest, st)
855
Mark Dickinsond35a32e2010-06-17 12:33:22 +0000856 def test_issue_9011(self):
857 # Issue 9011: compilation of an unary minus expression changed
858 # the meaning of the ST, so that a second compilation produced
859 # incorrect results.
860 st = parser.expr('-3')
861 code1 = parser.compilest(st)
862 self.assertEqual(eval(code1), -3)
863 code2 = parser.compilest(st)
864 self.assertEqual(eval(code2), -3)
865
Serhiy Storchaka9305d832016-06-18 13:53:36 +0300866 def test_compile_filename(self):
867 st = parser.expr('a + 5')
868 code = parser.compilest(st)
869 self.assertEqual(code.co_filename, '<syntax-tree>')
870 code = st.compile()
871 self.assertEqual(code.co_filename, '<syntax-tree>')
Serhiy Storchakafebc3322016-08-06 23:29:29 +0300872 for filename in 'file.py', b'file.py':
Serhiy Storchaka9305d832016-06-18 13:53:36 +0300873 code = parser.compilest(st, filename)
874 self.assertEqual(code.co_filename, 'file.py')
875 code = st.compile(filename)
876 self.assertEqual(code.co_filename, 'file.py')
Serhiy Storchakafebc3322016-08-06 23:29:29 +0300877 for filename in bytearray(b'file.py'), memoryview(b'file.py'):
878 with self.assertWarns(DeprecationWarning):
879 code = parser.compilest(st, filename)
880 self.assertEqual(code.co_filename, 'file.py')
881 with self.assertWarns(DeprecationWarning):
882 code = st.compile(filename)
883 self.assertEqual(code.co_filename, 'file.py')
Serhiy Storchaka9305d832016-06-18 13:53:36 +0300884 self.assertRaises(TypeError, parser.compilest, st, list(b'file.py'))
885 self.assertRaises(TypeError, st.compile, list(b'file.py'))
886
887
Christian Heimes90c3d9b2008-02-23 13:18:03 +0000888class ParserStackLimitTestCase(unittest.TestCase):
Mark Dickinsond35a32e2010-06-17 12:33:22 +0000889 """try to push the parser to/over its limits.
Christian Heimes90c3d9b2008-02-23 13:18:03 +0000890 see http://bugs.python.org/issue1881 for a discussion
891 """
892 def _nested_expression(self, level):
893 return "["*level+"]"*level
894
895 def test_deeply_nested_list(self):
Emily Morehouse8f59ee02019-01-24 16:49:56 -0700896 # This has fluctuated between 99 levels in 2.x, down to 93 levels in
897 # 3.7.X and back up to 99 in 3.8.X. Related to MAXSTACK size in Parser.h
898 e = self._nested_expression(99)
Christian Heimes90c3d9b2008-02-23 13:18:03 +0000899 st = parser.expr(e)
900 st.compile()
901
902 def test_trigger_memory_error(self):
903 e = self._nested_expression(100)
Ezio Melotti39191842013-03-09 22:17:33 +0200904 rc, out, err = assert_python_failure('-c', e)
905 # parsing the expression will result in an error message
906 # followed by a MemoryError (see #11963)
Ezio Melottie7c32992013-03-10 03:25:45 +0200907 self.assertIn(b's_push: parser stack overflow', err)
908 self.assertIn(b'MemoryError', err)
Christian Heimes90c3d9b2008-02-23 13:18:03 +0000909
Mark Dickinson211c6252009-02-01 10:28:51 +0000910class STObjectTestCase(unittest.TestCase):
911 """Test operations on ST objects themselves"""
912
913 def test_comparisons(self):
914 # ST objects should support order and equality comparisons
915 st1 = parser.expr('2 + 3')
916 st2 = parser.suite('x = 2; y = x + 3')
917 st3 = parser.expr('list(x**3 for x in range(20))')
918 st1_copy = parser.expr('2 + 3')
919 st2_copy = parser.suite('x = 2; y = x + 3')
920 st3_copy = parser.expr('list(x**3 for x in range(20))')
921
922 # exercise fast path for object identity
Ezio Melottib3aedd42010-11-20 19:04:17 +0000923 self.assertEqual(st1 == st1, True)
924 self.assertEqual(st2 == st2, True)
925 self.assertEqual(st3 == st3, True)
Mark Dickinson211c6252009-02-01 10:28:51 +0000926 # slow path equality
927 self.assertEqual(st1, st1_copy)
928 self.assertEqual(st2, st2_copy)
929 self.assertEqual(st3, st3_copy)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000930 self.assertEqual(st1 == st2, False)
931 self.assertEqual(st1 == st3, False)
932 self.assertEqual(st2 == st3, False)
933 self.assertEqual(st1 != st1, False)
934 self.assertEqual(st2 != st2, False)
935 self.assertEqual(st3 != st3, False)
936 self.assertEqual(st1 != st1_copy, False)
937 self.assertEqual(st2 != st2_copy, False)
938 self.assertEqual(st3 != st3_copy, False)
939 self.assertEqual(st2 != st1, True)
940 self.assertEqual(st1 != st3, True)
941 self.assertEqual(st3 != st2, True)
Mark Dickinson211c6252009-02-01 10:28:51 +0000942 # we don't particularly care what the ordering is; just that
943 # it's usable and self-consistent
Ezio Melottib3aedd42010-11-20 19:04:17 +0000944 self.assertEqual(st1 < st2, not (st2 <= st1))
945 self.assertEqual(st1 < st3, not (st3 <= st1))
946 self.assertEqual(st2 < st3, not (st3 <= st2))
947 self.assertEqual(st1 < st2, st2 > st1)
948 self.assertEqual(st1 < st3, st3 > st1)
949 self.assertEqual(st2 < st3, st3 > st2)
950 self.assertEqual(st1 <= st2, st2 >= st1)
951 self.assertEqual(st3 <= st1, st1 >= st3)
952 self.assertEqual(st2 <= st3, st3 >= st2)
Mark Dickinson211c6252009-02-01 10:28:51 +0000953 # transitivity
954 bottom = min(st1, st2, st3)
955 top = max(st1, st2, st3)
956 mid = sorted([st1, st2, st3])[1]
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000957 self.assertTrue(bottom < mid)
958 self.assertTrue(bottom < top)
959 self.assertTrue(mid < top)
960 self.assertTrue(bottom <= mid)
961 self.assertTrue(bottom <= top)
962 self.assertTrue(mid <= top)
963 self.assertTrue(bottom <= bottom)
964 self.assertTrue(mid <= mid)
965 self.assertTrue(top <= top)
Mark Dickinson211c6252009-02-01 10:28:51 +0000966 # interaction with other types
Ezio Melottib3aedd42010-11-20 19:04:17 +0000967 self.assertEqual(st1 == 1588.602459, False)
968 self.assertEqual('spanish armada' != st2, True)
Mark Dickinson211c6252009-02-01 10:28:51 +0000969 self.assertRaises(TypeError, operator.ge, st3, None)
970 self.assertRaises(TypeError, operator.le, False, st1)
971 self.assertRaises(TypeError, operator.lt, st1, 1815)
972 self.assertRaises(TypeError, operator.gt, b'waterloo', st2)
973
Serhiy Storchakaa79f4c22017-04-19 21:09:21 +0300974 def test_copy_pickle(self):
975 sts = [
976 parser.expr('2 + 3'),
977 parser.suite('x = 2; y = x + 3'),
978 parser.expr('list(x**3 for x in range(20))')
979 ]
980 for st in sts:
981 st_copy = copy.copy(st)
982 self.assertEqual(st_copy.totuple(), st.totuple())
983 st_copy = copy.deepcopy(st)
984 self.assertEqual(st_copy.totuple(), st.totuple())
985 for proto in range(pickle.HIGHEST_PROTOCOL+1):
986 st_copy = pickle.loads(pickle.dumps(st, proto))
987 self.assertEqual(st_copy.totuple(), st.totuple())
988
Jesus Ceae9c53182012-08-03 14:28:37 +0200989 check_sizeof = support.check_sizeof
990
991 @support.cpython_only
992 def test_sizeof(self):
993 def XXXROUNDUP(n):
994 if n <= 1:
995 return n
996 if n <= 128:
997 return (n + 3) & ~3
998 return 1 << (n - 1).bit_length()
999
Guido van Rossum495da292019-03-07 12:38:08 -08001000 basesize = support.calcobjsize('Piii')
Ivan Levkivskyi9932a222019-01-22 11:18:22 +00001001 nodesize = struct.calcsize('hP3iP0h2i')
Jesus Ceae9c53182012-08-03 14:28:37 +02001002 def sizeofchildren(node):
1003 if node is None:
1004 return 0
1005 res = 0
1006 hasstr = len(node) > 1 and isinstance(node[-1], str)
1007 if hasstr:
1008 res += len(node[-1]) + 1
1009 children = node[1:-1] if hasstr else node[1:]
1010 if children:
1011 res += XXXROUNDUP(len(children)) * nodesize
Jesus Ceae9c53182012-08-03 14:28:37 +02001012 for child in children:
1013 res += sizeofchildren(child)
1014 return res
1015
1016 def check_st_sizeof(st):
1017 self.check_sizeof(st, basesize + nodesize +
1018 sizeofchildren(st.totuple()))
1019
1020 check_st_sizeof(parser.expr('2 + 3'))
1021 check_st_sizeof(parser.expr('2 + 3 + 4'))
1022 check_st_sizeof(parser.suite('x = 2 + 3'))
1023 check_st_sizeof(parser.suite(''))
1024 check_st_sizeof(parser.suite('# -*- coding: utf-8 -*-'))
1025 check_st_sizeof(parser.expr('[' + '2,' * 1000 + ']'))
1026
Mark Dickinson211c6252009-02-01 10:28:51 +00001027
1028 # XXX tests for pickling and unpickling of ST objects should go here
1029
Benjamin Petersonf719957d2011-06-04 22:06:42 -05001030class OtherParserCase(unittest.TestCase):
1031
1032 def test_two_args_to_expr(self):
1033 # See bug #12264
1034 with self.assertRaises(TypeError):
1035 parser.expr("a", "b")
1036
Pablo Galindo9211e2f2019-07-30 12:04:01 +01001037
1038class TestDeprecation(unittest.TestCase):
1039 def test_deprecation_message(self):
1040 code = "def f():\n import parser\n\nf()"
1041 rc, out, err = assert_python_ok('-c', code)
1042 self.assertIn(b'<string>:2: DeprecationWarning', err)
1043
1044
Fred Drake2e2be372001-09-20 21:33:42 +00001045if __name__ == "__main__":
Zachary Ware38c707e2015-04-13 15:00:43 -05001046 unittest.main()