blob: 5548a871c0244f7d6b6371ff518616a752ca9ac2 [file] [log] [blame]
Serhiy Storchakaa79f4c22017-04-19 21:09:21 +03001import copy
Fred Drake79ca79d2000-08-21 22:30:53 +00002import parser
Serhiy Storchakaa79f4c22017-04-19 21:09:21 +03003import pickle
Fred Drake58422e52001-06-04 03:56:24 +00004import unittest
Mark Dickinson211c6252009-02-01 10:28:51 +00005import operator
Jesus Ceae9c53182012-08-03 14:28:37 +02006import struct
Benjamin Petersonee8712c2008-05-20 21:35:26 +00007from test import support
Berker Peksagce643912015-05-06 06:33:17 +03008from test.support.script_helper import assert_python_failure
Fred Drake79ca79d2000-08-21 22:30:53 +00009
10#
11# First, we test that we can generate trees from valid source fragments,
12# and that these valid trees are indeed allowed by the tree-loading side
13# of the parser module.
14#
15
Fred Drake58422e52001-06-04 03:56:24 +000016class RoundtripLegalSyntaxTestCase(unittest.TestCase):
Guido van Rossum32c2ae72002-08-22 19:45:32 +000017
Fred Drake58422e52001-06-04 03:56:24 +000018 def roundtrip(self, f, s):
19 st1 = f(s)
20 t = st1.totuple()
21 try:
Fred Drake6e4f2c02001-07-17 19:33:25 +000022 st2 = parser.sequence2st(t)
Guido van Rossumb940e112007-01-10 16:19:56 +000023 except parser.ParserError as why:
Anthony Baxterc2a5a632004-08-02 06:10:11 +000024 self.fail("could not roundtrip %r: %s" % (s, why))
Fred Drake79ca79d2000-08-21 22:30:53 +000025
Ezio Melottib3aedd42010-11-20 19:04:17 +000026 self.assertEqual(t, st2.totuple(),
27 "could not re-generate syntax tree")
Fred Drake28f739a2000-08-25 22:42:40 +000028
Fred Drake58422e52001-06-04 03:56:24 +000029 def check_expr(self, s):
30 self.roundtrip(parser.expr, s)
Fred Drake28f739a2000-08-25 22:42:40 +000031
Benjamin Petersonf216c942008-10-31 02:28:05 +000032 def test_flags_passed(self):
Mike53f7a7c2017-12-14 14:04:53 +030033 # The unicode literals flags has to be passed from the parser to AST
Benjamin Petersonf216c942008-10-31 02:28:05 +000034 # generation.
35 suite = parser.suite("from __future__ import unicode_literals; x = ''")
36 code = suite.compile()
37 scope = {}
38 exec(code, {}, scope)
Ezio Melottie9615932010-01-24 19:26:24 +000039 self.assertIsInstance(scope["x"], str)
Benjamin Petersonf216c942008-10-31 02:28:05 +000040
Fred Drake58422e52001-06-04 03:56:24 +000041 def check_suite(self, s):
42 self.roundtrip(parser.suite, s)
Fred Drake28f739a2000-08-25 22:42:40 +000043
Fred Drakecf580c72001-07-17 03:01:29 +000044 def test_yield_statement(self):
Tim Peters496563a2002-04-01 00:28:59 +000045 self.check_suite("def f(): yield 1")
Phillip J. Eby0d6615f2005-08-02 00:46:46 +000046 self.check_suite("def f(): yield")
47 self.check_suite("def f(): x += yield")
48 self.check_suite("def f(): x = yield 1")
49 self.check_suite("def f(): x = y = yield 1")
50 self.check_suite("def f(): x = yield")
51 self.check_suite("def f(): x = y = yield")
52 self.check_suite("def f(): 1 + (yield)*2")
53 self.check_suite("def f(): (yield 1)*2")
Tim Peters496563a2002-04-01 00:28:59 +000054 self.check_suite("def f(): return; yield 1")
55 self.check_suite("def f(): yield 1; return")
Nick Coghlan1f7ce622012-01-13 21:43:40 +100056 self.check_suite("def f(): yield from 1")
57 self.check_suite("def f(): x = yield from 1")
58 self.check_suite("def f(): f((yield from 1))")
59 self.check_suite("def f(): yield 1; return 1")
Tim Peters496563a2002-04-01 00:28:59 +000060 self.check_suite("def f():\n"
Fred Drakecf580c72001-07-17 03:01:29 +000061 " for x in range(30):\n"
62 " yield x\n")
Phillip J. Eby0d6615f2005-08-02 00:46:46 +000063 self.check_suite("def f():\n"
64 " if (yield):\n"
65 " yield x\n")
Fred Drakecf580c72001-07-17 03:01:29 +000066
Yury Selivanov75445082015-05-11 22:57:16 -040067 def test_await_statement(self):
68 self.check_suite("async def f():\n await smth()")
69 self.check_suite("async def f():\n foo = await smth()")
70 self.check_suite("async def f():\n foo, bar = await smth()")
71 self.check_suite("async def f():\n (await smth())")
72 self.check_suite("async def f():\n foo((await smth()))")
73 self.check_suite("async def f():\n await foo(); return 42")
74
75 def test_async_with_statement(self):
76 self.check_suite("async def f():\n async with 1: pass")
77 self.check_suite("async def f():\n async with a as b, c as d: pass")
78
79 def test_async_for_statement(self):
80 self.check_suite("async def f():\n async for i in (): pass")
81 self.check_suite("async def f():\n async for i, b in (): pass")
82
Mark Dickinson407b3bd2012-04-29 22:18:31 +010083 def test_nonlocal_statement(self):
84 self.check_suite("def f():\n"
85 " x = 0\n"
86 " def g():\n"
87 " nonlocal x\n")
88 self.check_suite("def f():\n"
89 " x = y = 0\n"
90 " def g():\n"
91 " nonlocal x, y\n")
92
Fred Drake58422e52001-06-04 03:56:24 +000093 def test_expressions(self):
94 self.check_expr("foo(1)")
95 self.check_expr("[1, 2, 3]")
96 self.check_expr("[x**3 for x in range(20)]")
97 self.check_expr("[x**3 for x in range(20) if x % 3]")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000098 self.check_expr("[x**3 for x in range(20) if x % 2 if x % 3]")
99 self.check_expr("list(x**3 for x in range(20))")
100 self.check_expr("list(x**3 for x in range(20) if x % 3)")
101 self.check_expr("list(x**3 for x in range(20) if x % 2 if x % 3)")
Fred Drake58422e52001-06-04 03:56:24 +0000102 self.check_expr("foo(*args)")
103 self.check_expr("foo(*args, **kw)")
104 self.check_expr("foo(**kw)")
105 self.check_expr("foo(key=value)")
106 self.check_expr("foo(key=value, *args)")
107 self.check_expr("foo(key=value, *args, **kw)")
108 self.check_expr("foo(key=value, **kw)")
109 self.check_expr("foo(a, b, c, *args)")
110 self.check_expr("foo(a, b, c, *args, **kw)")
111 self.check_expr("foo(a, b, c, **kw)")
Benjamin Peterson3938a902008-08-20 02:33:00 +0000112 self.check_expr("foo(a, *args, keyword=23)")
Fred Drake58422e52001-06-04 03:56:24 +0000113 self.check_expr("foo + bar")
Michael W. Hudson5e83b7a2003-01-29 14:20:23 +0000114 self.check_expr("foo - bar")
115 self.check_expr("foo * bar")
116 self.check_expr("foo / bar")
117 self.check_expr("foo // bar")
Emily Morehouse8f59ee02019-01-24 16:49:56 -0700118 self.check_expr("(foo := 1)")
Fred Drake58422e52001-06-04 03:56:24 +0000119 self.check_expr("lambda: 0")
120 self.check_expr("lambda x: 0")
121 self.check_expr("lambda *y: 0")
122 self.check_expr("lambda *y, **z: 0")
123 self.check_expr("lambda **z: 0")
124 self.check_expr("lambda x, y: 0")
125 self.check_expr("lambda foo=bar: 0")
126 self.check_expr("lambda foo=bar, spaz=nifty+spit: 0")
127 self.check_expr("lambda foo=bar, **z: 0")
128 self.check_expr("lambda foo=bar, blaz=blat+2, **z: 0")
129 self.check_expr("lambda foo=bar, blaz=blat+2, *y, **z: 0")
130 self.check_expr("lambda x, *y, **z: 0")
Raymond Hettinger354433a2004-05-19 08:20:33 +0000131 self.check_expr("(x for x in range(10))")
132 self.check_expr("foo(x for x in range(10))")
Mark Dickinsonda029fb2012-05-07 17:24:04 +0100133 self.check_expr("...")
134 self.check_expr("a[...]")
Fred Drake79ca79d2000-08-21 22:30:53 +0000135
Fred Drake58422e52001-06-04 03:56:24 +0000136 def test_simple_expression(self):
137 # expr_stmt
138 self.check_suite("a")
Fred Drake79ca79d2000-08-21 22:30:53 +0000139
Fred Drake58422e52001-06-04 03:56:24 +0000140 def test_simple_assignments(self):
141 self.check_suite("a = b")
142 self.check_suite("a = b = c = d = e")
Fred Drake28f739a2000-08-25 22:42:40 +0000143
Yury Selivanovf8cb8a12016-09-08 20:50:03 -0700144 def test_var_annot(self):
145 self.check_suite("x: int = 5")
146 self.check_suite("y: List[T] = []; z: [list] = fun()")
147 self.check_suite("x: tuple = (1, 2)")
148 self.check_suite("d[f()]: int = 42")
149 self.check_suite("f(d[x]): str = 'abc'")
150 self.check_suite("x.y.z.w: complex = 42j")
151 self.check_suite("x: int")
152 self.check_suite("def f():\n"
153 " x: str\n"
154 " y: int = 5\n")
155 self.check_suite("class C:\n"
156 " x: str\n"
157 " y: int = 5\n")
158 self.check_suite("class C:\n"
159 " def __init__(self, x: int) -> None:\n"
160 " self.x: int = x\n")
161 # double check for nonsense
162 with self.assertRaises(SyntaxError):
163 exec("2+2: int", {}, {})
164 with self.assertRaises(SyntaxError):
165 exec("[]: int = 5", {}, {})
166 with self.assertRaises(SyntaxError):
167 exec("x, *y, z: int = range(5)", {}, {})
168 with self.assertRaises(SyntaxError):
Ivan Levkivskyi62c35a82019-01-25 01:39:19 +0000169 exec("x: int = 1, y = 2", {}, {})
Yury Selivanovf8cb8a12016-09-08 20:50:03 -0700170 with self.assertRaises(SyntaxError):
171 exec("u = v: int", {}, {})
172 with self.assertRaises(SyntaxError):
173 exec("False: int", {}, {})
174 with self.assertRaises(SyntaxError):
175 exec("x.False: int", {}, {})
176 with self.assertRaises(SyntaxError):
177 exec("x.y,: int", {}, {})
178 with self.assertRaises(SyntaxError):
179 exec("[0]: int", {}, {})
180 with self.assertRaises(SyntaxError):
181 exec("f(): int", {}, {})
182
Fred Drake58422e52001-06-04 03:56:24 +0000183 def test_simple_augmented_assignments(self):
184 self.check_suite("a += b")
185 self.check_suite("a -= b")
186 self.check_suite("a *= b")
187 self.check_suite("a /= b")
Michael W. Hudson5e83b7a2003-01-29 14:20:23 +0000188 self.check_suite("a //= b")
Fred Drake58422e52001-06-04 03:56:24 +0000189 self.check_suite("a %= b")
190 self.check_suite("a &= b")
191 self.check_suite("a |= b")
192 self.check_suite("a ^= b")
193 self.check_suite("a <<= b")
194 self.check_suite("a >>= b")
195 self.check_suite("a **= b")
Fred Drakee3fb18c2001-01-07 06:02:19 +0000196
Fred Drake58422e52001-06-04 03:56:24 +0000197 def test_function_defs(self):
198 self.check_suite("def f(): pass")
199 self.check_suite("def f(*args): pass")
200 self.check_suite("def f(*args, **kw): pass")
201 self.check_suite("def f(**kw): pass")
202 self.check_suite("def f(foo=bar): pass")
203 self.check_suite("def f(foo=bar, *args): pass")
204 self.check_suite("def f(foo=bar, *args, **kw): pass")
205 self.check_suite("def f(foo=bar, **kw): pass")
Fred Drakee3fb18c2001-01-07 06:02:19 +0000206
Fred Drake58422e52001-06-04 03:56:24 +0000207 self.check_suite("def f(a, b): pass")
208 self.check_suite("def f(a, b, *args): pass")
209 self.check_suite("def f(a, b, *args, **kw): pass")
210 self.check_suite("def f(a, b, **kw): pass")
211 self.check_suite("def f(a, b, foo=bar): pass")
212 self.check_suite("def f(a, b, foo=bar, *args): pass")
213 self.check_suite("def f(a, b, foo=bar, *args, **kw): pass")
214 self.check_suite("def f(a, b, foo=bar, **kw): pass")
Fred Drakee3fb18c2001-01-07 06:02:19 +0000215
Anthony Baxterc2a5a632004-08-02 06:10:11 +0000216 self.check_suite("@staticmethod\n"
217 "def f(): pass")
218 self.check_suite("@staticmethod\n"
219 "@funcattrs(x, y)\n"
220 "def f(): pass")
221 self.check_suite("@funcattrs()\n"
222 "def f(): pass")
223
Mark Dickinsonea7e9f92012-04-29 18:34:40 +0100224 # keyword-only arguments
225 self.check_suite("def f(*, a): pass")
226 self.check_suite("def f(*, a = 5): pass")
227 self.check_suite("def f(*, a = 5, b): pass")
228 self.check_suite("def f(*, a, b = 5): pass")
229 self.check_suite("def f(*, a, b = 5, **kwds): pass")
230 self.check_suite("def f(*args, a): pass")
231 self.check_suite("def f(*args, a = 5): pass")
232 self.check_suite("def f(*args, a = 5, b): pass")
233 self.check_suite("def f(*args, a, b = 5): pass")
234 self.check_suite("def f(*args, a, b = 5, **kwds): pass")
235
236 # function annotations
237 self.check_suite("def f(a: int): pass")
238 self.check_suite("def f(a: int = 5): pass")
239 self.check_suite("def f(*args: list): pass")
240 self.check_suite("def f(**kwds: dict): pass")
241 self.check_suite("def f(*, a: int): pass")
242 self.check_suite("def f(*, a: int = 5): pass")
243 self.check_suite("def f() -> int: pass")
244
Brett Cannonf4189912005-04-09 02:30:16 +0000245 def test_class_defs(self):
246 self.check_suite("class foo():pass")
Guido van Rossumfc158e22007-11-15 19:17:28 +0000247 self.check_suite("class foo(object):pass")
Mark Dickinson2bd61a92010-07-04 16:37:31 +0000248 self.check_suite("@class_decorator\n"
249 "class foo():pass")
250 self.check_suite("@class_decorator(arg)\n"
251 "class foo():pass")
252 self.check_suite("@decorator1\n"
253 "@decorator2\n"
254 "class foo():pass")
Tim Peterse8906822005-04-20 17:45:13 +0000255
Fred Drake58422e52001-06-04 03:56:24 +0000256 def test_import_from_statement(self):
257 self.check_suite("from sys.path import *")
258 self.check_suite("from sys.path import dirname")
Anthony Baxter1a4ddae2004-08-31 10:07:13 +0000259 self.check_suite("from sys.path import (dirname)")
260 self.check_suite("from sys.path import (dirname,)")
Fred Drake58422e52001-06-04 03:56:24 +0000261 self.check_suite("from sys.path import dirname as my_dirname")
Anthony Baxter1a4ddae2004-08-31 10:07:13 +0000262 self.check_suite("from sys.path import (dirname as my_dirname)")
263 self.check_suite("from sys.path import (dirname as my_dirname,)")
Fred Drake58422e52001-06-04 03:56:24 +0000264 self.check_suite("from sys.path import dirname, basename")
Anthony Baxter1a4ddae2004-08-31 10:07:13 +0000265 self.check_suite("from sys.path import (dirname, basename)")
266 self.check_suite("from sys.path import (dirname, basename,)")
Fred Drake58422e52001-06-04 03:56:24 +0000267 self.check_suite(
268 "from sys.path import dirname as my_dirname, basename")
269 self.check_suite(
Anthony Baxter1a4ddae2004-08-31 10:07:13 +0000270 "from sys.path import (dirname as my_dirname, basename)")
271 self.check_suite(
272 "from sys.path import (dirname as my_dirname, basename,)")
273 self.check_suite(
Fred Drake58422e52001-06-04 03:56:24 +0000274 "from sys.path import dirname, basename as my_basename")
Anthony Baxter1a4ddae2004-08-31 10:07:13 +0000275 self.check_suite(
276 "from sys.path import (dirname, basename as my_basename)")
277 self.check_suite(
278 "from sys.path import (dirname, basename as my_basename,)")
Benjamin Petersonc0747cf2008-11-03 20:31:38 +0000279 self.check_suite("from .bogus import x")
Fred Drakee3fb18c2001-01-07 06:02:19 +0000280
Fred Drake58422e52001-06-04 03:56:24 +0000281 def test_basic_import_statement(self):
282 self.check_suite("import sys")
283 self.check_suite("import sys as system")
284 self.check_suite("import sys, math")
285 self.check_suite("import sys as system, math")
286 self.check_suite("import sys, math as my_math")
Fred Drake79ca79d2000-08-21 22:30:53 +0000287
Mark Dickinson2cc8a5e2010-07-04 18:11:51 +0000288 def test_relative_imports(self):
289 self.check_suite("from . import name")
290 self.check_suite("from .. import name")
Mark Dickinsonfeb3b752010-07-04 18:38:57 +0000291 # check all the way up to '....', since '...' is tokenized
292 # differently from '.' (it's an ellipsis token).
293 self.check_suite("from ... import name")
294 self.check_suite("from .... import name")
Mark Dickinson2cc8a5e2010-07-04 18:11:51 +0000295 self.check_suite("from .pkg import name")
296 self.check_suite("from ..pkg import name")
Mark Dickinsonfeb3b752010-07-04 18:38:57 +0000297 self.check_suite("from ...pkg import name")
298 self.check_suite("from ....pkg import name")
Mark Dickinson2cc8a5e2010-07-04 18:11:51 +0000299
Neal Norwitz9caf9c02003-02-10 01:54:06 +0000300 def test_pep263(self):
301 self.check_suite("# -*- coding: iso-8859-1 -*-\n"
302 "pass\n")
303
304 def test_assert(self):
305 self.check_suite("assert alo < ahi and blo < bhi\n")
306
Benjamin Peterson4469d0c2008-11-30 22:46:23 +0000307 def test_with(self):
308 self.check_suite("with open('x'): pass\n")
309 self.check_suite("with open('x') as f: pass\n")
Georg Brandl0c315622009-05-25 21:10:36 +0000310 self.check_suite("with open('x') as f, open('y') as g: pass\n")
Benjamin Peterson4469d0c2008-11-30 22:46:23 +0000311
Georg Brandleee31162008-12-07 15:15:22 +0000312 def test_try_stmt(self):
313 self.check_suite("try: pass\nexcept: pass\n")
314 self.check_suite("try: pass\nfinally: pass\n")
315 self.check_suite("try: pass\nexcept A: pass\nfinally: pass\n")
316 self.check_suite("try: pass\nexcept A: pass\nexcept: pass\n"
317 "finally: pass\n")
318 self.check_suite("try: pass\nexcept: pass\nelse: pass\n")
319 self.check_suite("try: pass\nexcept: pass\nelse: pass\n"
320 "finally: pass\n")
321
Thomas Wouters89f507f2006-12-13 04:49:30 +0000322 def test_position(self):
323 # An absolutely minimal test of position information. Better
324 # tests would be a big project.
Benjamin Peterson8f326b22009-12-13 02:10:36 +0000325 code = "def f(x):\n return x + 1"
Serhiy Storchakae5362ea2018-04-19 01:55:37 +0300326 st = parser.suite(code)
Thomas Wouters89f507f2006-12-13 04:49:30 +0000327
328 def walk(tree):
329 node_type = tree[0]
330 next = tree[1]
Serhiy Storchakae5362ea2018-04-19 01:55:37 +0300331 if isinstance(next, (tuple, list)):
Thomas Wouters89f507f2006-12-13 04:49:30 +0000332 for elt in tree[1:]:
333 for x in walk(elt):
334 yield x
335 else:
336 yield tree
337
Serhiy Storchakae5362ea2018-04-19 01:55:37 +0300338 expected = [
Thomas Wouters89f507f2006-12-13 04:49:30 +0000339 (1, 'def', 1, 0),
340 (1, 'f', 1, 4),
341 (7, '(', 1, 5),
342 (1, 'x', 1, 6),
343 (8, ')', 1, 7),
344 (11, ':', 1, 8),
345 (4, '', 1, 9),
346 (5, '', 2, -1),
347 (1, 'return', 2, 4),
348 (1, 'x', 2, 11),
349 (14, '+', 2, 13),
350 (2, '1', 2, 15),
351 (4, '', 2, 16),
Benjamin Peterson8f326b22009-12-13 02:10:36 +0000352 (6, '', 2, -1),
353 (4, '', 2, -1),
Serhiy Storchakae5362ea2018-04-19 01:55:37 +0300354 (0, '', 2, -1),
355 ]
356
357 self.assertEqual(list(walk(st.totuple(line_info=True, col_info=True))),
358 expected)
359 self.assertEqual(list(walk(st.totuple())),
360 [(t, n) for t, n, l, c in expected])
361 self.assertEqual(list(walk(st.totuple(line_info=True))),
362 [(t, n, l) for t, n, l, c in expected])
363 self.assertEqual(list(walk(st.totuple(col_info=True))),
364 [(t, n, c) for t, n, l, c in expected])
365 self.assertEqual(list(walk(st.tolist(line_info=True, col_info=True))),
366 [list(x) for x in expected])
367 self.assertEqual(list(walk(parser.st2tuple(st, line_info=True,
368 col_info=True))),
369 expected)
370 self.assertEqual(list(walk(parser.st2list(st, line_info=True,
371 col_info=True))),
372 [list(x) for x in expected])
Thomas Wouters89f507f2006-12-13 04:49:30 +0000373
Benjamin Peterson4905e802009-09-27 02:43:28 +0000374 def test_extended_unpacking(self):
375 self.check_suite("*a = y")
376 self.check_suite("x, *b, = m")
377 self.check_suite("[*a, *b] = y")
378 self.check_suite("for [*x, b] in x: pass")
379
Mark Dickinsoncf360b92012-05-07 12:01:27 +0100380 def test_raise_statement(self):
381 self.check_suite("raise\n")
382 self.check_suite("raise e\n")
383 self.check_suite("try:\n"
384 " suite\n"
385 "except Exception as e:\n"
386 " raise ValueError from e\n")
387
Benjamin Peterson025e9eb2015-05-05 20:16:41 -0400388 def test_list_displays(self):
389 self.check_expr('[]')
390 self.check_expr('[*{2}, 3, *[4]]')
391
Mark Dickinson11c1dee2012-05-07 16:34:34 +0100392 def test_set_displays(self):
Benjamin Peterson025e9eb2015-05-05 20:16:41 -0400393 self.check_expr('{*{2}, 3, *[4]}')
Mark Dickinson11c1dee2012-05-07 16:34:34 +0100394 self.check_expr('{2}')
395 self.check_expr('{2,}')
396 self.check_expr('{2, 3}')
397 self.check_expr('{2, 3,}')
398
399 def test_dict_displays(self):
400 self.check_expr('{}')
401 self.check_expr('{a:b}')
402 self.check_expr('{a:b,}')
403 self.check_expr('{a:b, c:d}')
404 self.check_expr('{a:b, c:d,}')
Benjamin Peterson025e9eb2015-05-05 20:16:41 -0400405 self.check_expr('{**{}}')
406 self.check_expr('{**{}, 3:4, **{5:6, 7:8}}')
407
408 def test_argument_unpacking(self):
Yury Selivanov50a26142015-08-05 17:59:45 -0400409 self.check_expr("f(*a, **b)")
Benjamin Peterson025e9eb2015-05-05 20:16:41 -0400410 self.check_expr('f(a, *b, *c, *d)')
411 self.check_expr('f(**a, **b)')
412 self.check_expr('f(2, *a, *b, **b, **c, **d)')
Yury Selivanov50a26142015-08-05 17:59:45 -0400413 self.check_expr("f(*b, *() or () and (), **{} and {}, **() or {})")
Mark Dickinson11c1dee2012-05-07 16:34:34 +0100414
415 def test_set_comprehensions(self):
416 self.check_expr('{x for x in seq}')
417 self.check_expr('{f(x) for x in seq}')
418 self.check_expr('{f(x) for x in seq if condition(x)}')
419
420 def test_dict_comprehensions(self):
421 self.check_expr('{x:x for x in seq}')
422 self.check_expr('{x**2:x[3] for x in seq if condition(x)}')
423 self.check_expr('{x:x for x in seq1 for y in seq2 if condition(x, y)}')
424
Emily Morehouse8f59ee02019-01-24 16:49:56 -0700425 def test_named_expressions(self):
426 self.check_suite("(a := 1)")
427 self.check_suite("(a := a)")
428 self.check_suite("if (match := pattern.search(data)) is None: pass")
Xtreakd4fceaa2019-02-02 03:10:16 +0530429 self.check_suite("while match := pattern.search(f.read()): pass")
Emily Morehouse8f59ee02019-01-24 16:49:56 -0700430 self.check_suite("[y := f(x), y**2, y**3]")
431 self.check_suite("filtered_data = [y for x in data if (y := f(x)) is None]")
432 self.check_suite("(y := f(x))")
433 self.check_suite("y0 = (y1 := f(x))")
434 self.check_suite("foo(x=(y := f(x)))")
435 self.check_suite("def foo(answer=(p := 42)): pass")
436 self.check_suite("def foo(answer: (p := 42) = 5): pass")
437 self.check_suite("lambda: (x := 1)")
438 self.check_suite("(x := lambda: 1)")
439 self.check_suite("(x := lambda: (y := 1))") # not in PEP
440 self.check_suite("lambda line: (m := re.match(pattern, line)) and m.group(1)")
441 self.check_suite("x = (y := 0)")
442 self.check_suite("(z:=(y:=(x:=0)))")
443 self.check_suite("(info := (name, phone, *rest))")
444 self.check_suite("(x:=1,2)")
445 self.check_suite("(total := total + tax)")
446 self.check_suite("len(lines := f.readlines())")
447 self.check_suite("foo(x := 3, cat='vector')")
448 self.check_suite("foo(cat=(category := 'vector'))")
449 self.check_suite("if any(len(longline := l) >= 100 for l in lines): print(longline)")
450 self.check_suite(
451 "if env_base := os.environ.get('PYTHONUSERBASE', None): return env_base"
452 )
453 self.check_suite(
454 "if self._is_special and (ans := self._check_nans(context=context)): return ans"
455 )
456 self.check_suite("foo(b := 2, a=1)")
457 self.check_suite("foo(b := 2, a=1)")
458 self.check_suite("foo((b := 2), a=1)")
459 self.check_suite("foo(c=(b := 2), a=1)")
Thomas Wouters89f507f2006-12-13 04:49:30 +0000460
Fred Drake79ca79d2000-08-21 22:30:53 +0000461#
462# Second, we take *invalid* trees and make sure we get ParserError
463# rejections for them.
464#
465
Fred Drake58422e52001-06-04 03:56:24 +0000466class IllegalSyntaxTestCase(unittest.TestCase):
Guido van Rossum32c2ae72002-08-22 19:45:32 +0000467
Fred Drake58422e52001-06-04 03:56:24 +0000468 def check_bad_tree(self, tree, label):
469 try:
Fred Drake6e4f2c02001-07-17 19:33:25 +0000470 parser.sequence2st(tree)
Fred Drake58422e52001-06-04 03:56:24 +0000471 except parser.ParserError:
472 pass
473 else:
474 self.fail("did not detect invalid tree for %r" % label)
Fred Drake79ca79d2000-08-21 22:30:53 +0000475
Fred Drake58422e52001-06-04 03:56:24 +0000476 def test_junk(self):
477 # not even remotely valid:
478 self.check_bad_tree((1, 2, 3), "<junk>")
479
Serhiy Storchakaa79f4c22017-04-19 21:09:21 +0300480 def test_illegal_terminal(self):
481 tree = \
482 (257,
483 (269,
484 (270,
485 (271,
486 (277,
487 (1,))),
488 (4, ''))),
489 (4, ''),
490 (0, ''))
491 self.check_bad_tree(tree, "too small items in terminal node")
492 tree = \
493 (257,
494 (269,
495 (270,
496 (271,
497 (277,
498 (1, b'pass'))),
499 (4, ''))),
500 (4, ''),
501 (0, ''))
502 self.check_bad_tree(tree, "non-string second item in terminal node")
503 tree = \
504 (257,
505 (269,
506 (270,
507 (271,
508 (277,
509 (1, 'pass', '0', 0))),
510 (4, ''))),
511 (4, ''),
512 (0, ''))
513 self.check_bad_tree(tree, "non-integer third item in terminal node")
514 tree = \
515 (257,
516 (269,
517 (270,
518 (271,
519 (277,
520 (1, 'pass', 0, 0))),
521 (4, ''))),
522 (4, ''),
523 (0, ''))
524 self.check_bad_tree(tree, "too many items in terminal node")
525
Fred Drakecf580c72001-07-17 03:01:29 +0000526 def test_illegal_yield_1(self):
Guido van Rossum32c2ae72002-08-22 19:45:32 +0000527 # Illegal yield statement: def f(): return 1; yield 1
Fred Drakecf580c72001-07-17 03:01:29 +0000528 tree = \
529 (257,
530 (264,
531 (285,
532 (259,
533 (1, 'def'),
534 (1, 'f'),
535 (260, (7, '('), (8, ')')),
536 (11, ':'),
537 (291,
538 (4, ''),
539 (5, ''),
540 (264,
541 (265,
542 (266,
543 (272,
544 (275,
545 (1, 'return'),
546 (313,
547 (292,
548 (293,
549 (294,
550 (295,
551 (297,
552 (298,
553 (299,
554 (300,
555 (301,
556 (302, (303, (304, (305, (2, '1')))))))))))))))))),
557 (264,
558 (265,
559 (266,
560 (272,
561 (276,
562 (1, 'yield'),
563 (313,
564 (292,
565 (293,
566 (294,
567 (295,
568 (297,
569 (298,
570 (299,
571 (300,
572 (301,
573 (302,
574 (303, (304, (305, (2, '1')))))))))))))))))),
575 (4, ''))),
576 (6, ''))))),
577 (4, ''),
578 (0, ''))))
579 self.check_bad_tree(tree, "def f():\n return 1\n yield 1")
580
581 def test_illegal_yield_2(self):
Guido van Rossum32c2ae72002-08-22 19:45:32 +0000582 # Illegal return in generator: def f(): return 1; yield 1
Fred Drakecf580c72001-07-17 03:01:29 +0000583 tree = \
584 (257,
585 (264,
586 (265,
587 (266,
588 (278,
589 (1, 'from'),
590 (281, (1, '__future__')),
591 (1, 'import'),
592 (279, (1, 'generators')))),
593 (4, ''))),
594 (264,
595 (285,
596 (259,
597 (1, 'def'),
598 (1, 'f'),
599 (260, (7, '('), (8, ')')),
600 (11, ':'),
601 (291,
602 (4, ''),
603 (5, ''),
604 (264,
605 (265,
606 (266,
607 (272,
608 (275,
609 (1, 'return'),
610 (313,
611 (292,
612 (293,
613 (294,
614 (295,
615 (297,
616 (298,
617 (299,
618 (300,
619 (301,
620 (302, (303, (304, (305, (2, '1')))))))))))))))))),
621 (264,
622 (265,
623 (266,
624 (272,
625 (276,
626 (1, 'yield'),
627 (313,
628 (292,
629 (293,
630 (294,
631 (295,
632 (297,
633 (298,
634 (299,
635 (300,
636 (301,
637 (302,
638 (303, (304, (305, (2, '1')))))))))))))))))),
639 (4, ''))),
640 (6, ''))))),
641 (4, ''),
642 (0, ''))))
643 self.check_bad_tree(tree, "def f():\n return 1\n yield 1")
644
Fred Drake58422e52001-06-04 03:56:24 +0000645 def test_a_comma_comma_c(self):
Guido van Rossum32c2ae72002-08-22 19:45:32 +0000646 # Illegal input: a,,c
Fred Drake58422e52001-06-04 03:56:24 +0000647 tree = \
648 (258,
649 (311,
650 (290,
651 (291,
652 (292,
653 (293,
654 (295,
655 (296,
656 (297,
657 (298, (299, (300, (301, (302, (303, (1, 'a')))))))))))))),
658 (12, ','),
659 (12, ','),
660 (290,
661 (291,
662 (292,
663 (293,
664 (295,
665 (296,
666 (297,
667 (298, (299, (300, (301, (302, (303, (1, 'c'))))))))))))))),
668 (4, ''),
669 (0, ''))
670 self.check_bad_tree(tree, "a,,c")
671
672 def test_illegal_operator(self):
Guido van Rossum32c2ae72002-08-22 19:45:32 +0000673 # Illegal input: a $= b
Fred Drake58422e52001-06-04 03:56:24 +0000674 tree = \
675 (257,
676 (264,
677 (265,
678 (266,
679 (267,
680 (312,
681 (291,
682 (292,
683 (293,
684 (294,
685 (296,
686 (297,
687 (298,
688 (299,
689 (300, (301, (302, (303, (304, (1, 'a'))))))))))))))),
690 (268, (37, '$=')),
691 (312,
692 (291,
693 (292,
694 (293,
695 (294,
696 (296,
697 (297,
698 (298,
699 (299,
700 (300, (301, (302, (303, (304, (1, 'b'))))))))))))))))),
701 (4, ''))),
702 (0, ''))
703 self.check_bad_tree(tree, "a $= b")
Fred Drake79ca79d2000-08-21 22:30:53 +0000704
Neal Norwitz9caf9c02003-02-10 01:54:06 +0000705 def test_malformed_global(self):
706 #doesn't have global keyword in ast
707 tree = (257,
708 (264,
709 (265,
710 (266,
711 (282, (1, 'foo'))), (4, ''))),
712 (4, ''),
Tim Petersf2715e02003-02-19 02:35:07 +0000713 (0, ''))
Neal Norwitz9caf9c02003-02-10 01:54:06 +0000714 self.check_bad_tree(tree, "malformed global ast")
Fred Drake79ca79d2000-08-21 22:30:53 +0000715
Mark Dickinson2cc8a5e2010-07-04 18:11:51 +0000716 def test_missing_import_source(self):
Mark Dickinson3445b482010-07-04 18:15:26 +0000717 # from import fred
Mark Dickinson2cc8a5e2010-07-04 18:11:51 +0000718 tree = \
719 (257,
Mark Dickinson3445b482010-07-04 18:15:26 +0000720 (268,
721 (269,
722 (270,
723 (282,
724 (284, (1, 'from'), (1, 'import'),
725 (287, (285, (1, 'fred')))))),
Mark Dickinson2cc8a5e2010-07-04 18:11:51 +0000726 (4, ''))),
727 (4, ''), (0, ''))
Mark Dickinson3445b482010-07-04 18:15:26 +0000728 self.check_bad_tree(tree, "from import fred")
Mark Dickinson2cc8a5e2010-07-04 18:11:51 +0000729
Serhiy Storchakaa79f4c22017-04-19 21:09:21 +0300730 def test_illegal_encoding(self):
731 # Illegal encoding declaration
732 tree = \
Emily Morehouse8f59ee02019-01-24 16:49:56 -0700733 (341,
Serhiy Storchakaa79f4c22017-04-19 21:09:21 +0300734 (257, (0, '')))
735 self.check_bad_tree(tree, "missed encoding")
736 tree = \
Emily Morehouse8f59ee02019-01-24 16:49:56 -0700737 (341,
Serhiy Storchakaa79f4c22017-04-19 21:09:21 +0300738 (257, (0, '')),
739 b'iso-8859-1')
740 self.check_bad_tree(tree, "non-string encoding")
741 tree = \
Emily Morehouse8f59ee02019-01-24 16:49:56 -0700742 (341,
Serhiy Storchakaa79f4c22017-04-19 21:09:21 +0300743 (257, (0, '')),
744 '\udcff')
745 with self.assertRaises(UnicodeEncodeError):
746 parser.sequence2st(tree)
747
Jeremy Hylton3e0055f2005-10-20 19:59:25 +0000748
749class CompileTestCase(unittest.TestCase):
750
751 # These tests are very minimal. :-(
752
753 def test_compile_expr(self):
754 st = parser.expr('2 + 3')
755 code = parser.compilest(st)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000756 self.assertEqual(eval(code), 5)
Jeremy Hylton3e0055f2005-10-20 19:59:25 +0000757
758 def test_compile_suite(self):
759 st = parser.suite('x = 2; y = x + 3')
760 code = parser.compilest(st)
761 globs = {}
Georg Brandl7cae87c2006-09-06 06:51:57 +0000762 exec(code, globs)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000763 self.assertEqual(globs['y'], 5)
Jeremy Hylton3e0055f2005-10-20 19:59:25 +0000764
765 def test_compile_error(self):
766 st = parser.suite('1 = 3 + 4')
767 self.assertRaises(SyntaxError, parser.compilest, st)
768
Guido van Rossumb5a755e2007-07-18 18:15:48 +0000769 def test_compile_badunicode(self):
Guido van Rossum7eb6ca52007-07-18 21:00:22 +0000770 st = parser.suite('a = "\\U12345678"')
Guido van Rossumb5a755e2007-07-18 18:15:48 +0000771 self.assertRaises(SyntaxError, parser.compilest, st)
Guido van Rossum7eb6ca52007-07-18 21:00:22 +0000772 st = parser.suite('a = "\\u1"')
Guido van Rossumb5a755e2007-07-18 18:15:48 +0000773 self.assertRaises(SyntaxError, parser.compilest, st)
774
Mark Dickinsond35a32e2010-06-17 12:33:22 +0000775 def test_issue_9011(self):
776 # Issue 9011: compilation of an unary minus expression changed
777 # the meaning of the ST, so that a second compilation produced
778 # incorrect results.
779 st = parser.expr('-3')
780 code1 = parser.compilest(st)
781 self.assertEqual(eval(code1), -3)
782 code2 = parser.compilest(st)
783 self.assertEqual(eval(code2), -3)
784
Serhiy Storchaka9305d832016-06-18 13:53:36 +0300785 def test_compile_filename(self):
786 st = parser.expr('a + 5')
787 code = parser.compilest(st)
788 self.assertEqual(code.co_filename, '<syntax-tree>')
789 code = st.compile()
790 self.assertEqual(code.co_filename, '<syntax-tree>')
Serhiy Storchakafebc3322016-08-06 23:29:29 +0300791 for filename in 'file.py', b'file.py':
Serhiy Storchaka9305d832016-06-18 13:53:36 +0300792 code = parser.compilest(st, filename)
793 self.assertEqual(code.co_filename, 'file.py')
794 code = st.compile(filename)
795 self.assertEqual(code.co_filename, 'file.py')
Serhiy Storchakafebc3322016-08-06 23:29:29 +0300796 for filename in bytearray(b'file.py'), memoryview(b'file.py'):
797 with self.assertWarns(DeprecationWarning):
798 code = parser.compilest(st, filename)
799 self.assertEqual(code.co_filename, 'file.py')
800 with self.assertWarns(DeprecationWarning):
801 code = st.compile(filename)
802 self.assertEqual(code.co_filename, 'file.py')
Serhiy Storchaka9305d832016-06-18 13:53:36 +0300803 self.assertRaises(TypeError, parser.compilest, st, list(b'file.py'))
804 self.assertRaises(TypeError, st.compile, list(b'file.py'))
805
806
Christian Heimes90c3d9b2008-02-23 13:18:03 +0000807class ParserStackLimitTestCase(unittest.TestCase):
Mark Dickinsond35a32e2010-06-17 12:33:22 +0000808 """try to push the parser to/over its limits.
Christian Heimes90c3d9b2008-02-23 13:18:03 +0000809 see http://bugs.python.org/issue1881 for a discussion
810 """
811 def _nested_expression(self, level):
812 return "["*level+"]"*level
813
814 def test_deeply_nested_list(self):
Emily Morehouse8f59ee02019-01-24 16:49:56 -0700815 # This has fluctuated between 99 levels in 2.x, down to 93 levels in
816 # 3.7.X and back up to 99 in 3.8.X. Related to MAXSTACK size in Parser.h
817 e = self._nested_expression(99)
Christian Heimes90c3d9b2008-02-23 13:18:03 +0000818 st = parser.expr(e)
819 st.compile()
820
821 def test_trigger_memory_error(self):
822 e = self._nested_expression(100)
Ezio Melotti39191842013-03-09 22:17:33 +0200823 rc, out, err = assert_python_failure('-c', e)
824 # parsing the expression will result in an error message
825 # followed by a MemoryError (see #11963)
Ezio Melottie7c32992013-03-10 03:25:45 +0200826 self.assertIn(b's_push: parser stack overflow', err)
827 self.assertIn(b'MemoryError', err)
Christian Heimes90c3d9b2008-02-23 13:18:03 +0000828
Mark Dickinson211c6252009-02-01 10:28:51 +0000829class STObjectTestCase(unittest.TestCase):
830 """Test operations on ST objects themselves"""
831
832 def test_comparisons(self):
833 # ST objects should support order and equality comparisons
834 st1 = parser.expr('2 + 3')
835 st2 = parser.suite('x = 2; y = x + 3')
836 st3 = parser.expr('list(x**3 for x in range(20))')
837 st1_copy = parser.expr('2 + 3')
838 st2_copy = parser.suite('x = 2; y = x + 3')
839 st3_copy = parser.expr('list(x**3 for x in range(20))')
840
841 # exercise fast path for object identity
Ezio Melottib3aedd42010-11-20 19:04:17 +0000842 self.assertEqual(st1 == st1, True)
843 self.assertEqual(st2 == st2, True)
844 self.assertEqual(st3 == st3, True)
Mark Dickinson211c6252009-02-01 10:28:51 +0000845 # slow path equality
846 self.assertEqual(st1, st1_copy)
847 self.assertEqual(st2, st2_copy)
848 self.assertEqual(st3, st3_copy)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000849 self.assertEqual(st1 == st2, False)
850 self.assertEqual(st1 == st3, False)
851 self.assertEqual(st2 == st3, False)
852 self.assertEqual(st1 != st1, False)
853 self.assertEqual(st2 != st2, False)
854 self.assertEqual(st3 != st3, False)
855 self.assertEqual(st1 != st1_copy, False)
856 self.assertEqual(st2 != st2_copy, False)
857 self.assertEqual(st3 != st3_copy, False)
858 self.assertEqual(st2 != st1, True)
859 self.assertEqual(st1 != st3, True)
860 self.assertEqual(st3 != st2, True)
Mark Dickinson211c6252009-02-01 10:28:51 +0000861 # we don't particularly care what the ordering is; just that
862 # it's usable and self-consistent
Ezio Melottib3aedd42010-11-20 19:04:17 +0000863 self.assertEqual(st1 < st2, not (st2 <= st1))
864 self.assertEqual(st1 < st3, not (st3 <= st1))
865 self.assertEqual(st2 < st3, not (st3 <= st2))
866 self.assertEqual(st1 < st2, st2 > st1)
867 self.assertEqual(st1 < st3, st3 > st1)
868 self.assertEqual(st2 < st3, st3 > st2)
869 self.assertEqual(st1 <= st2, st2 >= st1)
870 self.assertEqual(st3 <= st1, st1 >= st3)
871 self.assertEqual(st2 <= st3, st3 >= st2)
Mark Dickinson211c6252009-02-01 10:28:51 +0000872 # transitivity
873 bottom = min(st1, st2, st3)
874 top = max(st1, st2, st3)
875 mid = sorted([st1, st2, st3])[1]
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000876 self.assertTrue(bottom < mid)
877 self.assertTrue(bottom < top)
878 self.assertTrue(mid < top)
879 self.assertTrue(bottom <= mid)
880 self.assertTrue(bottom <= top)
881 self.assertTrue(mid <= top)
882 self.assertTrue(bottom <= bottom)
883 self.assertTrue(mid <= mid)
884 self.assertTrue(top <= top)
Mark Dickinson211c6252009-02-01 10:28:51 +0000885 # interaction with other types
Ezio Melottib3aedd42010-11-20 19:04:17 +0000886 self.assertEqual(st1 == 1588.602459, False)
887 self.assertEqual('spanish armada' != st2, True)
Mark Dickinson211c6252009-02-01 10:28:51 +0000888 self.assertRaises(TypeError, operator.ge, st3, None)
889 self.assertRaises(TypeError, operator.le, False, st1)
890 self.assertRaises(TypeError, operator.lt, st1, 1815)
891 self.assertRaises(TypeError, operator.gt, b'waterloo', st2)
892
Serhiy Storchakaa79f4c22017-04-19 21:09:21 +0300893 def test_copy_pickle(self):
894 sts = [
895 parser.expr('2 + 3'),
896 parser.suite('x = 2; y = x + 3'),
897 parser.expr('list(x**3 for x in range(20))')
898 ]
899 for st in sts:
900 st_copy = copy.copy(st)
901 self.assertEqual(st_copy.totuple(), st.totuple())
902 st_copy = copy.deepcopy(st)
903 self.assertEqual(st_copy.totuple(), st.totuple())
904 for proto in range(pickle.HIGHEST_PROTOCOL+1):
905 st_copy = pickle.loads(pickle.dumps(st, proto))
906 self.assertEqual(st_copy.totuple(), st.totuple())
907
Jesus Ceae9c53182012-08-03 14:28:37 +0200908 check_sizeof = support.check_sizeof
909
910 @support.cpython_only
911 def test_sizeof(self):
912 def XXXROUNDUP(n):
913 if n <= 1:
914 return n
915 if n <= 128:
916 return (n + 3) & ~3
917 return 1 << (n - 1).bit_length()
918
Guido van Rossum495da292019-03-07 12:38:08 -0800919 basesize = support.calcobjsize('Piii')
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000920 nodesize = struct.calcsize('hP3iP0h2i')
Jesus Ceae9c53182012-08-03 14:28:37 +0200921 def sizeofchildren(node):
922 if node is None:
923 return 0
924 res = 0
925 hasstr = len(node) > 1 and isinstance(node[-1], str)
926 if hasstr:
927 res += len(node[-1]) + 1
928 children = node[1:-1] if hasstr else node[1:]
929 if children:
930 res += XXXROUNDUP(len(children)) * nodesize
Jesus Ceae9c53182012-08-03 14:28:37 +0200931 for child in children:
932 res += sizeofchildren(child)
933 return res
934
935 def check_st_sizeof(st):
936 self.check_sizeof(st, basesize + nodesize +
937 sizeofchildren(st.totuple()))
938
939 check_st_sizeof(parser.expr('2 + 3'))
940 check_st_sizeof(parser.expr('2 + 3 + 4'))
941 check_st_sizeof(parser.suite('x = 2 + 3'))
942 check_st_sizeof(parser.suite(''))
943 check_st_sizeof(parser.suite('# -*- coding: utf-8 -*-'))
944 check_st_sizeof(parser.expr('[' + '2,' * 1000 + ']'))
945
Mark Dickinson211c6252009-02-01 10:28:51 +0000946
947 # XXX tests for pickling and unpickling of ST objects should go here
948
Benjamin Petersonf719957d2011-06-04 22:06:42 -0500949class OtherParserCase(unittest.TestCase):
950
951 def test_two_args_to_expr(self):
952 # See bug #12264
953 with self.assertRaises(TypeError):
954 parser.expr("a", "b")
955
Fred Drake2e2be372001-09-20 21:33:42 +0000956if __name__ == "__main__":
Zachary Ware38c707e2015-04-13 15:00:43 -0500957 unittest.main()