blob: e08a965d96f76e161b752942bad35d12bd57dc5d [file] [log] [blame]
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001import ast
Victor Stinnere5fbe0c2020-09-15 18:03:34 +02002import builtins
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01003import dis
Ethan Furmana02cb472021-04-21 10:20:44 -07004import enum
Benjamin Peterson832bfe22011-08-09 16:15:04 -05005import os
6import sys
Victor Stinnere5fbe0c2020-09-15 18:03:34 +02007import types
Benjamin Peterson832bfe22011-08-09 16:15:04 -05008import unittest
Serhiy Storchakac3ea41e2019-08-26 10:13:19 +03009import warnings
Benjamin Peterson9ed37432012-07-08 11:13:36 -070010import weakref
Ivan Levkivskyi9932a222019-01-22 11:18:22 +000011from textwrap import dedent
Benjamin Peterson9ed37432012-07-08 11:13:36 -070012
13from test import support
Tim Peters400cbc32006-02-28 18:44:41 +000014
15def to_tuple(t):
Guido van Rossum3172c5d2007-10-16 18:12:55 +000016 if t is None or isinstance(t, (str, int, complex)):
Tim Peters400cbc32006-02-28 18:44:41 +000017 return t
18 elif isinstance(t, list):
19 return [to_tuple(e) for e in t]
20 result = [t.__class__.__name__]
Martin v. Löwis49c5da12006-03-01 22:49:05 +000021 if hasattr(t, 'lineno') and hasattr(t, 'col_offset'):
22 result.append((t.lineno, t.col_offset))
Serhiy Storchaka850a8852020-01-10 10:12:55 +020023 if hasattr(t, 'end_lineno') and hasattr(t, 'end_col_offset'):
24 result[-1] += (t.end_lineno, t.end_col_offset)
Tim Peters400cbc32006-02-28 18:44:41 +000025 if t._fields is None:
26 return tuple(result)
27 for f in t._fields:
28 result.append(to_tuple(getattr(t, f)))
29 return tuple(result)
30
Neal Norwitzee9b10a2008-03-31 05:29:39 +000031
Tim Peters400cbc32006-02-28 18:44:41 +000032# These tests are compiled through "exec"
Ezio Melotti85a86292013-08-17 16:57:41 +030033# There should be at least one test per statement
Tim Peters400cbc32006-02-28 18:44:41 +000034exec_tests = [
Benjamin Peterson6ccfe852011-06-27 17:46:06 -050035 # None
36 "None",
INADA Naokicb41b272017-02-23 00:31:59 +090037 # Module docstring
38 "'module docstring'",
Tim Peters400cbc32006-02-28 18:44:41 +000039 # FunctionDef
40 "def f(): pass",
INADA Naokicb41b272017-02-23 00:31:59 +090041 # FunctionDef with docstring
42 "def f(): 'function docstring'",
Benjamin Peterson6ccfe852011-06-27 17:46:06 -050043 # FunctionDef with arg
44 "def f(a): pass",
45 # FunctionDef with arg and default value
46 "def f(a=0): pass",
47 # FunctionDef with varargs
48 "def f(*args): pass",
49 # FunctionDef with kwargs
50 "def f(**kwargs): pass",
INADA Naokicb41b272017-02-23 00:31:59 +090051 # FunctionDef with all kind of args and docstring
52 "def f(a, b=1, c=None, d=[], e={}, *args, f=42, **kwargs): 'doc for f()'",
Tim Peters400cbc32006-02-28 18:44:41 +000053 # ClassDef
54 "class C:pass",
INADA Naokicb41b272017-02-23 00:31:59 +090055 # ClassDef with docstring
56 "class C: 'docstring for class C'",
Benjamin Peterson6ccfe852011-06-27 17:46:06 -050057 # ClassDef, new style class
58 "class C(object): pass",
Tim Peters400cbc32006-02-28 18:44:41 +000059 # Return
60 "def f():return 1",
61 # Delete
62 "del v",
63 # Assign
64 "v = 1",
Serhiy Storchakab619b092018-11-27 09:40:29 +020065 "a,b = c",
66 "(a,b) = c",
67 "[a,b] = c",
Tim Peters400cbc32006-02-28 18:44:41 +000068 # AugAssign
69 "v += 1",
Tim Peters400cbc32006-02-28 18:44:41 +000070 # For
71 "for v in v:pass",
72 # While
73 "while v:pass",
74 # If
75 "if v:pass",
Lysandros Nikolaou025a6022019-12-12 22:40:21 +010076 # If-Elif
77 "if a:\n pass\nelif b:\n pass",
Lysandros Nikolaou5936a4c2019-12-14 11:24:57 +010078 # If-Elif-Else
79 "if a:\n pass\nelif b:\n pass\nelse:\n pass",
Benjamin Petersonaeabd5f2011-05-27 15:02:03 -050080 # With
81 "with x as y: pass",
82 "with x as y, z as q: pass",
Tim Peters400cbc32006-02-28 18:44:41 +000083 # Raise
Collin Winter828f04a2007-08-31 00:04:24 +000084 "raise Exception('string')",
Tim Peters400cbc32006-02-28 18:44:41 +000085 # TryExcept
86 "try:\n pass\nexcept Exception:\n pass",
87 # TryFinally
88 "try:\n pass\nfinally:\n pass",
89 # Assert
90 "assert v",
91 # Import
92 "import sys",
93 # ImportFrom
94 "from sys import v",
Tim Peters400cbc32006-02-28 18:44:41 +000095 # Global
96 "global v",
97 # Expr
98 "1",
99 # Pass,
100 "pass",
101 # Break
Yury Selivanovb3d53132015-09-01 16:10:49 -0400102 "for v in v:break",
Tim Peters400cbc32006-02-28 18:44:41 +0000103 # Continue
Yury Selivanovb3d53132015-09-01 16:10:49 -0400104 "for v in v:continue",
Benjamin Peterson2e4b0e12009-09-11 22:36:20 +0000105 # for statements with naked tuples (see http://bugs.python.org/issue6704)
106 "for a,b in c: pass",
Serhiy Storchakab619b092018-11-27 09:40:29 +0200107 "for (a,b) in c: pass",
108 "for [a,b] in c: pass",
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500109 # Multiline generator expression (test for .lineno & .col_offset)
110 """(
111 (
112 Aa
113 ,
114 Bb
115 )
116 for
117 Aa
118 ,
119 Bb in Cc
120 )""",
121 # dictcomp
122 "{a : b for w in x for m in p if g}",
123 # dictcomp with naked tuple
124 "{a : b for v,w in x}",
125 # setcomp
126 "{r for l in x if g}",
127 # setcomp with naked tuple
128 "{r for l,m in x}",
Yury Selivanov75445082015-05-11 22:57:16 -0400129 # AsyncFunctionDef
INADA Naokicb41b272017-02-23 00:31:59 +0900130 "async def f():\n 'async function'\n await something()",
Yury Selivanov75445082015-05-11 22:57:16 -0400131 # AsyncFor
132 "async def f():\n async for e in i: 1\n else: 2",
133 # AsyncWith
134 "async def f():\n async with a as b: 1",
Yury Selivanovb3d53132015-09-01 16:10:49 -0400135 # PEP 448: Additional Unpacking Generalizations
136 "{**{1:2}, 2:3}",
137 "{*{1, 2}, 3}",
Yury Selivanov52c4e7c2016-09-09 10:36:01 -0700138 # Asynchronous comprehensions
139 "async def f():\n [i async for b in c]",
Serhiy Storchaka95b6acf2018-10-30 13:16:02 +0200140 # Decorated FunctionDef
Serhiy Storchaka26ae9f62019-10-26 16:46:05 +0300141 "@deco1\n@deco2()\n@deco3(1)\ndef f(): pass",
Serhiy Storchaka95b6acf2018-10-30 13:16:02 +0200142 # Decorated AsyncFunctionDef
Serhiy Storchaka26ae9f62019-10-26 16:46:05 +0300143 "@deco1\n@deco2()\n@deco3(1)\nasync def f(): pass",
Serhiy Storchaka95b6acf2018-10-30 13:16:02 +0200144 # Decorated ClassDef
Serhiy Storchaka26ae9f62019-10-26 16:46:05 +0300145 "@deco1\n@deco2()\n@deco3(1)\nclass C: pass",
Serhiy Storchakab619b092018-11-27 09:40:29 +0200146 # Decorator with generator argument
147 "@deco(a for a in b)\ndef f(): pass",
Lysandros Nikolaoud2e10982020-02-08 00:36:32 +0100148 # Decorator with attribute
149 "@a.b.c\ndef f(): pass",
Pablo Galindo0c9258a2019-03-18 13:51:53 +0000150 # Simple assignment expression
151 "(a := 1)",
Pablo Galindo2f58a842019-05-31 14:09:49 +0100152 # Positional-only arguments
153 "def f(a, /,): pass",
154 "def f(a, /, c, d, e): pass",
155 "def f(a, /, c, *, d, e): pass",
156 "def f(a, /, c, *, d, e, **kwargs): pass",
157 # Positional-only arguments with defaults
158 "def f(a=1, /,): pass",
159 "def f(a=1, /, b=2, c=4): pass",
160 "def f(a=1, /, b=2, *, c=4): pass",
161 "def f(a=1, /, b=2, *, c): pass",
162 "def f(a=1, /, b=2, *, c=4, **kwargs): pass",
163 "def f(a=1, /, b=2, *, c, **kwargs): pass",
Pablo Galindo0c9258a2019-03-18 13:51:53 +0000164
Tim Peters400cbc32006-02-28 18:44:41 +0000165]
166
167# These are compiled through "single"
168# because of overlap with "eval", it just tests what
169# can't be tested with "eval"
170single_tests = [
171 "1+2"
172]
173
174# These are compiled through "eval"
175# It should test all expressions
176eval_tests = [
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500177 # None
178 "None",
Tim Peters400cbc32006-02-28 18:44:41 +0000179 # BoolOp
180 "a and b",
181 # BinOp
182 "a + b",
183 # UnaryOp
184 "not v",
185 # Lambda
186 "lambda:None",
187 # Dict
188 "{ 1:2 }",
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500189 # Empty dict
190 "{}",
191 # Set
192 "{None,}",
193 # Multiline dict (test for .lineno & .col_offset)
194 """{
195 1
196 :
197 2
198 }""",
Tim Peters400cbc32006-02-28 18:44:41 +0000199 # ListComp
200 "[a for b in c if d]",
201 # GeneratorExp
202 "(a for b in c if d)",
Serhiy Storchakab619b092018-11-27 09:40:29 +0200203 # Comprehensions with multiple for targets
204 "[(a,b) for a,b in c]",
205 "[(a,b) for (a,b) in c]",
206 "[(a,b) for [a,b] in c]",
207 "{(a,b) for a,b in c}",
208 "{(a,b) for (a,b) in c}",
209 "{(a,b) for [a,b] in c}",
210 "((a,b) for a,b in c)",
211 "((a,b) for (a,b) in c)",
212 "((a,b) for [a,b] in c)",
Tim Peters400cbc32006-02-28 18:44:41 +0000213 # Yield - yield expressions can't work outside a function
214 #
215 # Compare
216 "1 < 2 < 3",
217 # Call
218 "f(1,2,c=3,*d,**e)",
Lysandros Nikolaou50d4f122019-12-18 01:20:55 +0100219 # Call with multi-character starred
220 "f(*[0, 1])",
Serhiy Storchakab619b092018-11-27 09:40:29 +0200221 # Call with a generator argument
222 "f(a for a in b)",
Tim Peters400cbc32006-02-28 18:44:41 +0000223 # Num
Guido van Rossume2a383d2007-01-15 16:59:06 +0000224 "10",
Tim Peters400cbc32006-02-28 18:44:41 +0000225 # Str
226 "'string'",
227 # Attribute
228 "a.b",
229 # Subscript
230 "a[b:c]",
231 # Name
232 "v",
233 # List
234 "[1,2,3]",
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500235 # Empty list
236 "[]",
Tim Peters400cbc32006-02-28 18:44:41 +0000237 # Tuple
Martin v. Löwis49c5da12006-03-01 22:49:05 +0000238 "1,2,3",
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500239 # Tuple
240 "(1,2,3)",
241 # Empty tuple
242 "()",
Martin v. Löwis49c5da12006-03-01 22:49:05 +0000243 # Combination
244 "a.b.c.d(a.b[1:2])",
245
Tim Peters400cbc32006-02-28 18:44:41 +0000246]
247
248# TODO: expr_context, slice, boolop, operator, unaryop, cmpop, comprehension
249# excepthandler, arguments, keywords, alias
250
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000251class AST_Tests(unittest.TestCase):
Tim Peters400cbc32006-02-28 18:44:41 +0000252
Batuhan TaĹźkaya397b96f2020-03-01 23:12:17 +0300253 def _is_ast_node(self, name, node):
254 if not isinstance(node, type):
255 return False
256 if "ast" not in node.__module__:
257 return False
258 return name != 'AST' and name[0].isupper()
259
Benjamin Peterson7a66fc22015-02-02 10:51:20 -0500260 def _assertTrueorder(self, ast_node, parent_pos):
Georg Brandl0c77a822008-06-10 16:37:50 +0000261 if not isinstance(ast_node, ast.AST) or ast_node._fields is None:
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000262 return
Georg Brandl0c77a822008-06-10 16:37:50 +0000263 if isinstance(ast_node, (ast.expr, ast.stmt, ast.excepthandler)):
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000264 node_pos = (ast_node.lineno, ast_node.col_offset)
Serhiy Storchaka95b6acf2018-10-30 13:16:02 +0200265 self.assertGreaterEqual(node_pos, parent_pos)
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000266 parent_pos = (ast_node.lineno, ast_node.col_offset)
267 for name in ast_node._fields:
268 value = getattr(ast_node, name)
269 if isinstance(value, list):
Serhiy Storchaka95b6acf2018-10-30 13:16:02 +0200270 first_pos = parent_pos
271 if value and name == 'decorator_list':
272 first_pos = (value[0].lineno, value[0].col_offset)
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000273 for child in value:
Serhiy Storchaka95b6acf2018-10-30 13:16:02 +0200274 self._assertTrueorder(child, first_pos)
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000275 elif value is not None:
Benjamin Peterson7a66fc22015-02-02 10:51:20 -0500276 self._assertTrueorder(value, parent_pos)
Brandt Bucher145bf262021-02-26 14:51:55 -0800277 self.assertEqual(ast_node._fields, ast_node.__match_args__)
Tim Peters5ddfe412006-03-01 23:02:57 +0000278
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500279 def test_AST_objects(self):
280 x = ast.AST()
281 self.assertEqual(x._fields, ())
Benjamin Peterson7e0dbfb2012-03-12 09:46:44 -0700282 x.foobar = 42
283 self.assertEqual(x.foobar, 42)
284 self.assertEqual(x.__dict__["foobar"], 42)
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500285
286 with self.assertRaises(AttributeError):
287 x.vararg
288
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500289 with self.assertRaises(TypeError):
Serhiy Storchakabace59d2020-03-22 20:33:34 +0200290 # "ast.AST constructor takes 0 positional arguments"
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500291 ast.AST(2)
292
Benjamin Peterson9ed37432012-07-08 11:13:36 -0700293 def test_AST_garbage_collection(self):
294 class X:
295 pass
296 a = ast.AST()
297 a.x = X()
298 a.x.a = a
299 ref = weakref.ref(a.x)
300 del a
301 support.gc_collect()
302 self.assertIsNone(ref())
303
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000304 def test_snippets(self):
305 for input, output, kind in ((exec_tests, exec_results, "exec"),
306 (single_tests, single_results, "single"),
307 (eval_tests, eval_results, "eval")):
308 for i, o in zip(input, output):
Yury Selivanovb3d53132015-09-01 16:10:49 -0400309 with self.subTest(action="parsing", input=i):
310 ast_tree = compile(i, "?", kind, ast.PyCF_ONLY_AST)
311 self.assertEqual(to_tuple(ast_tree), o)
312 self._assertTrueorder(ast_tree, (0, 0))
Victor Stinner15a30952016-02-08 22:45:06 +0100313 with self.subTest(action="compiling", input=i, kind=kind):
314 compile(ast_tree, "?", kind)
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000315
Pablo Galindo0c9258a2019-03-18 13:51:53 +0000316 def test_ast_validation(self):
317 # compile() is the only function that calls PyAST_Validate
318 snippets_to_validate = exec_tests + single_tests + eval_tests
319 for snippet in snippets_to_validate:
320 tree = ast.parse(snippet)
321 compile(tree, '<string>', 'exec')
322
Benjamin Peterson78565b22009-06-28 19:19:51 +0000323 def test_slice(self):
324 slc = ast.parse("x[::]").body[0].value.slice
325 self.assertIsNone(slc.upper)
326 self.assertIsNone(slc.lower)
327 self.assertIsNone(slc.step)
328
329 def test_from_import(self):
330 im = ast.parse("from . import y").body[0]
331 self.assertIsNone(im.module)
332
Benjamin Petersona4e4e352012-03-22 08:19:04 -0400333 def test_non_interned_future_from_ast(self):
334 mod = ast.parse("from __future__ import division")
335 self.assertIsInstance(mod.body[0], ast.ImportFrom)
336 mod.body[0].module = " __future__ ".strip()
337 compile(mod, "<test>", "exec")
338
Matthew Suozzo75a06f02021-04-10 16:56:28 -0400339 def test_alias(self):
340 im = ast.parse("from bar import y").body[0]
341 self.assertEqual(len(im.names), 1)
342 alias = im.names[0]
343 self.assertEqual(alias.name, 'y')
344 self.assertIsNone(alias.asname)
345 self.assertEqual(alias.lineno, 1)
346 self.assertEqual(alias.end_lineno, 1)
347 self.assertEqual(alias.col_offset, 16)
348 self.assertEqual(alias.end_col_offset, 17)
349
350 im = ast.parse("from bar import *").body[0]
351 alias = im.names[0]
352 self.assertEqual(alias.name, '*')
353 self.assertIsNone(alias.asname)
354 self.assertEqual(alias.lineno, 1)
355 self.assertEqual(alias.end_lineno, 1)
356 self.assertEqual(alias.col_offset, 16)
357 self.assertEqual(alias.end_col_offset, 17)
358
Benjamin Petersona0dfa822009-11-13 02:25:08 +0000359 def test_base_classes(self):
360 self.assertTrue(issubclass(ast.For, ast.stmt))
361 self.assertTrue(issubclass(ast.Name, ast.expr))
362 self.assertTrue(issubclass(ast.stmt, ast.AST))
363 self.assertTrue(issubclass(ast.expr, ast.AST))
364 self.assertTrue(issubclass(ast.comprehension, ast.AST))
365 self.assertTrue(issubclass(ast.Gt, ast.AST))
366
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500367 def test_field_attr_existence(self):
368 for name, item in ast.__dict__.items():
Batuhan TaĹźkaya397b96f2020-03-01 23:12:17 +0300369 if self._is_ast_node(name, item):
Serhiy Storchaka13d52c22020-03-10 18:52:34 +0200370 if name == 'Index':
371 # Index(value) just returns value now.
372 # The argument is required.
373 continue
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500374 x = item()
375 if isinstance(x, ast.AST):
376 self.assertEqual(type(x._fields), tuple)
377
378 def test_arguments(self):
379 x = ast.arguments()
Pablo Galindocd6e83b2019-07-15 01:32:18 +0200380 self.assertEqual(x._fields, ('posonlyargs', 'args', 'vararg', 'kwonlyargs',
381 'kw_defaults', 'kwarg', 'defaults'))
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500382
383 with self.assertRaises(AttributeError):
Serhiy Storchakab7e95252020-03-10 00:07:47 +0200384 x.args
385 self.assertIsNone(x.vararg)
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500386
Pablo Galindo8c77b8c2019-04-29 13:36:57 +0100387 x = ast.arguments(*range(1, 8))
Serhiy Storchakab7e95252020-03-10 00:07:47 +0200388 self.assertEqual(x.args, 2)
Pablo Galindo8c77b8c2019-04-29 13:36:57 +0100389 self.assertEqual(x.vararg, 3)
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500390
391 def test_field_attr_writable(self):
392 x = ast.Num()
393 # We can assign to _fields
394 x._fields = 666
395 self.assertEqual(x._fields, 666)
396
397 def test_classattrs(self):
398 x = ast.Num()
Guido van Rossum10f8ce62019-03-13 13:00:46 -0700399 self.assertEqual(x._fields, ('value', 'kind'))
Serhiy Storchaka3f228112018-09-27 17:42:37 +0300400
401 with self.assertRaises(AttributeError):
402 x.value
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500403
404 with self.assertRaises(AttributeError):
405 x.n
406
407 x = ast.Num(42)
Serhiy Storchaka3f228112018-09-27 17:42:37 +0300408 self.assertEqual(x.value, 42)
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500409 self.assertEqual(x.n, 42)
410
411 with self.assertRaises(AttributeError):
412 x.lineno
413
414 with self.assertRaises(AttributeError):
415 x.foobar
416
417 x = ast.Num(lineno=2)
418 self.assertEqual(x.lineno, 2)
419
420 x = ast.Num(42, lineno=0)
421 self.assertEqual(x.lineno, 0)
Guido van Rossum10f8ce62019-03-13 13:00:46 -0700422 self.assertEqual(x._fields, ('value', 'kind'))
Serhiy Storchaka3f228112018-09-27 17:42:37 +0300423 self.assertEqual(x.value, 42)
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500424 self.assertEqual(x.n, 42)
425
Guido van Rossum10f8ce62019-03-13 13:00:46 -0700426 self.assertRaises(TypeError, ast.Num, 1, None, 2)
427 self.assertRaises(TypeError, ast.Num, 1, None, 2, lineno=0)
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500428
Rémi Lapeyrec73914a2020-05-24 23:12:57 +0200429 # Arbitrary keyword arguments are supported
430 self.assertEqual(ast.Constant(1, foo='bar').foo, 'bar')
431 self.assertEqual(ast.Num(1, foo='bar').foo, 'bar')
432
433 with self.assertRaisesRegex(TypeError, "Num got multiple values for argument 'n'"):
434 ast.Num(1, n=2)
435 with self.assertRaisesRegex(TypeError, "Constant got multiple values for argument 'value'"):
436 ast.Constant(1, value=2)
437
Serhiy Storchaka3f228112018-09-27 17:42:37 +0300438 self.assertEqual(ast.Num(42).n, 42)
439 self.assertEqual(ast.Num(4.25).n, 4.25)
440 self.assertEqual(ast.Num(4.25j).n, 4.25j)
441 self.assertEqual(ast.Str('42').s, '42')
442 self.assertEqual(ast.Bytes(b'42').s, b'42')
443 self.assertIs(ast.NameConstant(True).value, True)
444 self.assertIs(ast.NameConstant(False).value, False)
445 self.assertIs(ast.NameConstant(None).value, None)
446
447 self.assertEqual(ast.Constant(42).value, 42)
448 self.assertEqual(ast.Constant(4.25).value, 4.25)
449 self.assertEqual(ast.Constant(4.25j).value, 4.25j)
450 self.assertEqual(ast.Constant('42').value, '42')
451 self.assertEqual(ast.Constant(b'42').value, b'42')
452 self.assertIs(ast.Constant(True).value, True)
453 self.assertIs(ast.Constant(False).value, False)
454 self.assertIs(ast.Constant(None).value, None)
455 self.assertIs(ast.Constant(...).value, ...)
456
457 def test_realtype(self):
458 self.assertEqual(type(ast.Num(42)), ast.Constant)
459 self.assertEqual(type(ast.Num(4.25)), ast.Constant)
460 self.assertEqual(type(ast.Num(4.25j)), ast.Constant)
461 self.assertEqual(type(ast.Str('42')), ast.Constant)
462 self.assertEqual(type(ast.Bytes(b'42')), ast.Constant)
463 self.assertEqual(type(ast.NameConstant(True)), ast.Constant)
464 self.assertEqual(type(ast.NameConstant(False)), ast.Constant)
465 self.assertEqual(type(ast.NameConstant(None)), ast.Constant)
466 self.assertEqual(type(ast.Ellipsis()), ast.Constant)
467
468 def test_isinstance(self):
469 self.assertTrue(isinstance(ast.Num(42), ast.Num))
470 self.assertTrue(isinstance(ast.Num(4.2), ast.Num))
471 self.assertTrue(isinstance(ast.Num(4.2j), ast.Num))
472 self.assertTrue(isinstance(ast.Str('42'), ast.Str))
473 self.assertTrue(isinstance(ast.Bytes(b'42'), ast.Bytes))
474 self.assertTrue(isinstance(ast.NameConstant(True), ast.NameConstant))
475 self.assertTrue(isinstance(ast.NameConstant(False), ast.NameConstant))
476 self.assertTrue(isinstance(ast.NameConstant(None), ast.NameConstant))
477 self.assertTrue(isinstance(ast.Ellipsis(), ast.Ellipsis))
478
479 self.assertTrue(isinstance(ast.Constant(42), ast.Num))
480 self.assertTrue(isinstance(ast.Constant(4.2), ast.Num))
481 self.assertTrue(isinstance(ast.Constant(4.2j), ast.Num))
482 self.assertTrue(isinstance(ast.Constant('42'), ast.Str))
483 self.assertTrue(isinstance(ast.Constant(b'42'), ast.Bytes))
484 self.assertTrue(isinstance(ast.Constant(True), ast.NameConstant))
485 self.assertTrue(isinstance(ast.Constant(False), ast.NameConstant))
486 self.assertTrue(isinstance(ast.Constant(None), ast.NameConstant))
487 self.assertTrue(isinstance(ast.Constant(...), ast.Ellipsis))
488
489 self.assertFalse(isinstance(ast.Str('42'), ast.Num))
490 self.assertFalse(isinstance(ast.Num(42), ast.Str))
491 self.assertFalse(isinstance(ast.Str('42'), ast.Bytes))
492 self.assertFalse(isinstance(ast.Num(42), ast.NameConstant))
493 self.assertFalse(isinstance(ast.Num(42), ast.Ellipsis))
Anthony Sottile74176222019-01-18 11:30:28 -0800494 self.assertFalse(isinstance(ast.NameConstant(True), ast.Num))
495 self.assertFalse(isinstance(ast.NameConstant(False), ast.Num))
Serhiy Storchaka3f228112018-09-27 17:42:37 +0300496
497 self.assertFalse(isinstance(ast.Constant('42'), ast.Num))
498 self.assertFalse(isinstance(ast.Constant(42), ast.Str))
499 self.assertFalse(isinstance(ast.Constant('42'), ast.Bytes))
500 self.assertFalse(isinstance(ast.Constant(42), ast.NameConstant))
501 self.assertFalse(isinstance(ast.Constant(42), ast.Ellipsis))
Anthony Sottile74176222019-01-18 11:30:28 -0800502 self.assertFalse(isinstance(ast.Constant(True), ast.Num))
503 self.assertFalse(isinstance(ast.Constant(False), ast.Num))
Serhiy Storchaka3f228112018-09-27 17:42:37 +0300504
505 self.assertFalse(isinstance(ast.Constant(), ast.Num))
506 self.assertFalse(isinstance(ast.Constant(), ast.Str))
507 self.assertFalse(isinstance(ast.Constant(), ast.Bytes))
508 self.assertFalse(isinstance(ast.Constant(), ast.NameConstant))
509 self.assertFalse(isinstance(ast.Constant(), ast.Ellipsis))
510
Serhiy Storchaka6015cc52018-10-28 13:43:03 +0200511 class S(str): pass
512 self.assertTrue(isinstance(ast.Constant(S('42')), ast.Str))
513 self.assertFalse(isinstance(ast.Constant(S('42')), ast.Num))
514
Serhiy Storchaka3f228112018-09-27 17:42:37 +0300515 def test_subclasses(self):
516 class N(ast.Num):
517 def __init__(self, *args, **kwargs):
518 super().__init__(*args, **kwargs)
519 self.z = 'spam'
520 class N2(ast.Num):
521 pass
522
523 n = N(42)
524 self.assertEqual(n.n, 42)
525 self.assertEqual(n.z, 'spam')
526 self.assertEqual(type(n), N)
527 self.assertTrue(isinstance(n, N))
528 self.assertTrue(isinstance(n, ast.Num))
529 self.assertFalse(isinstance(n, N2))
530 self.assertFalse(isinstance(ast.Num(42), N))
531 n = N(n=42)
532 self.assertEqual(n.n, 42)
533 self.assertEqual(type(n), N)
534
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500535 def test_module(self):
536 body = [ast.Num(42)]
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800537 x = ast.Module(body, [])
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500538 self.assertEqual(x.body, body)
539
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000540 def test_nodeclasses(self):
Florent Xicluna992d9e02011-11-11 19:35:42 +0100541 # Zero arguments constructor explicitly allowed
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500542 x = ast.BinOp()
543 self.assertEqual(x._fields, ('left', 'op', 'right'))
544
545 # Random attribute allowed too
546 x.foobarbaz = 5
547 self.assertEqual(x.foobarbaz, 5)
548
549 n1 = ast.Num(1)
550 n3 = ast.Num(3)
551 addop = ast.Add()
552 x = ast.BinOp(n1, addop, n3)
553 self.assertEqual(x.left, n1)
554 self.assertEqual(x.op, addop)
555 self.assertEqual(x.right, n3)
Benjamin Peterson68b543a2011-06-27 17:51:18 -0500556
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500557 x = ast.BinOp(1, 2, 3)
558 self.assertEqual(x.left, 1)
559 self.assertEqual(x.op, 2)
560 self.assertEqual(x.right, 3)
561
Georg Brandl0c77a822008-06-10 16:37:50 +0000562 x = ast.BinOp(1, 2, 3, lineno=0)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000563 self.assertEqual(x.left, 1)
564 self.assertEqual(x.op, 2)
565 self.assertEqual(x.right, 3)
566 self.assertEqual(x.lineno, 0)
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000567
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500568 # node raises exception when given too many arguments
569 self.assertRaises(TypeError, ast.BinOp, 1, 2, 3, 4)
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500570 # node raises exception when given too many arguments
571 self.assertRaises(TypeError, ast.BinOp, 1, 2, 3, 4, lineno=0)
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000572
573 # can set attributes through kwargs too
Georg Brandl0c77a822008-06-10 16:37:50 +0000574 x = ast.BinOp(left=1, op=2, right=3, lineno=0)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000575 self.assertEqual(x.left, 1)
576 self.assertEqual(x.op, 2)
577 self.assertEqual(x.right, 3)
578 self.assertEqual(x.lineno, 0)
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000579
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500580 # Random kwargs also allowed
581 x = ast.BinOp(1, 2, 3, foobarbaz=42)
582 self.assertEqual(x.foobarbaz, 42)
583
584 def test_no_fields(self):
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000585 # this used to fail because Sub._fields was None
Georg Brandl0c77a822008-06-10 16:37:50 +0000586 x = ast.Sub()
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500587 self.assertEqual(x._fields, ())
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000588
589 def test_pickling(self):
590 import pickle
591 mods = [pickle]
592 try:
593 import cPickle
594 mods.append(cPickle)
595 except ImportError:
596 pass
597 protocols = [0, 1, 2]
598 for mod in mods:
599 for protocol in protocols:
600 for ast in (compile(i, "?", "exec", 0x400) for i in exec_tests):
601 ast2 = mod.loads(mod.dumps(ast, protocol))
Ezio Melottib3aedd42010-11-20 19:04:17 +0000602 self.assertEqual(to_tuple(ast2), to_tuple(ast))
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000603
Benjamin Peterson5b066812010-11-20 01:38:49 +0000604 def test_invalid_sum(self):
605 pos = dict(lineno=2, col_offset=3)
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800606 m = ast.Module([ast.Expr(ast.expr(**pos), **pos)], [])
Benjamin Peterson5b066812010-11-20 01:38:49 +0000607 with self.assertRaises(TypeError) as cm:
608 compile(m, "<test>", "exec")
Serhiy Storchakabace59d2020-03-22 20:33:34 +0200609 self.assertIn("but got <ast.expr", str(cm.exception))
Benjamin Peterson5b066812010-11-20 01:38:49 +0000610
Min ho Kimc4cacc82019-07-31 08:16:13 +1000611 def test_invalid_identifier(self):
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800612 m = ast.Module([ast.Expr(ast.Name(42, ast.Load()))], [])
Benjamin Peterson2193d2b2011-07-22 10:50:23 -0500613 ast.fix_missing_locations(m)
614 with self.assertRaises(TypeError) as cm:
615 compile(m, "<test>", "exec")
616 self.assertIn("identifier must be of type str", str(cm.exception))
617
Batuhan TaĹźkaya0ac59f92020-03-19 14:32:28 +0300618 def test_invalid_constant(self):
619 for invalid_constant in int, (1, 2, int), frozenset((1, 2, int)):
620 e = ast.Expression(body=ast.Constant(invalid_constant))
621 ast.fix_missing_locations(e)
622 with self.assertRaisesRegex(
623 TypeError, "invalid type in Constant: type"
624 ):
625 compile(e, "<test>", "eval")
626
Mark Dickinsonded35ae2012-11-25 14:36:26 +0000627 def test_empty_yield_from(self):
628 # Issue 16546: yield from value is not optional.
629 empty_yield_from = ast.parse("def f():\n yield from g()")
630 empty_yield_from.body[0].body[0].value.value = None
631 with self.assertRaises(ValueError) as cm:
632 compile(empty_yield_from, "<test>", "exec")
Batuhan Taskaya091951a2020-05-06 17:29:32 +0300633 self.assertIn("field 'value' is required", str(cm.exception))
Mark Dickinsonded35ae2012-11-25 14:36:26 +0000634
Oren Milman7dc46d82017-09-30 20:16:24 +0300635 @support.cpython_only
636 def test_issue31592(self):
637 # There shouldn't be an assertion failure in case of a bad
638 # unicodedata.normalize().
639 import unicodedata
640 def bad_normalize(*args):
641 return None
642 with support.swap_attr(unicodedata, 'normalize', bad_normalize):
643 self.assertRaises(TypeError, ast.parse, '\u03D5')
644
Carl Friedrich Bolz-Tereick110a47c2019-07-08 23:17:56 +0200645 def test_issue18374_binop_col_offset(self):
646 tree = ast.parse('4+5+6+7')
647 parent_binop = tree.body[0].value
648 child_binop = parent_binop.left
649 grandchild_binop = child_binop.left
650 self.assertEqual(parent_binop.col_offset, 0)
651 self.assertEqual(parent_binop.end_col_offset, 7)
652 self.assertEqual(child_binop.col_offset, 0)
653 self.assertEqual(child_binop.end_col_offset, 5)
654 self.assertEqual(grandchild_binop.col_offset, 0)
655 self.assertEqual(grandchild_binop.end_col_offset, 3)
656
657 tree = ast.parse('4+5-\\\n 6-7')
658 parent_binop = tree.body[0].value
659 child_binop = parent_binop.left
660 grandchild_binop = child_binop.left
661 self.assertEqual(parent_binop.col_offset, 0)
662 self.assertEqual(parent_binop.lineno, 1)
663 self.assertEqual(parent_binop.end_col_offset, 4)
664 self.assertEqual(parent_binop.end_lineno, 2)
665
666 self.assertEqual(child_binop.col_offset, 0)
Carl Friedrich Bolz-Tereick430a9f42019-07-09 14:20:01 +0200667 self.assertEqual(child_binop.lineno, 1)
Carl Friedrich Bolz-Tereick110a47c2019-07-08 23:17:56 +0200668 self.assertEqual(child_binop.end_col_offset, 2)
Carl Friedrich Bolz-Tereick430a9f42019-07-09 14:20:01 +0200669 self.assertEqual(child_binop.end_lineno, 2)
Carl Friedrich Bolz-Tereick110a47c2019-07-08 23:17:56 +0200670
671 self.assertEqual(grandchild_binop.col_offset, 0)
Carl Friedrich Bolz-Tereick430a9f42019-07-09 14:20:01 +0200672 self.assertEqual(grandchild_binop.lineno, 1)
Carl Friedrich Bolz-Tereick110a47c2019-07-08 23:17:56 +0200673 self.assertEqual(grandchild_binop.end_col_offset, 3)
Carl Friedrich Bolz-Tereick430a9f42019-07-09 14:20:01 +0200674 self.assertEqual(grandchild_binop.end_lineno, 1)
Georg Brandl0c77a822008-06-10 16:37:50 +0000675
Lysandros Nikolaoud2e10982020-02-08 00:36:32 +0100676 def test_issue39579_dotted_name_end_col_offset(self):
677 tree = ast.parse('@a.b.c\ndef f(): pass')
678 attr_b = tree.body[0].decorator_list[0].value
679 self.assertEqual(attr_b.end_col_offset, 4)
680
Batuhan TaĹźkaya4ab362c2020-03-16 11:12:53 +0300681 def test_ast_asdl_signature(self):
682 self.assertEqual(ast.withitem.__doc__, "withitem(expr context_expr, expr? optional_vars)")
683 self.assertEqual(ast.GtE.__doc__, "GtE")
684 self.assertEqual(ast.Name.__doc__, "Name(identifier id, expr_context ctx)")
685 self.assertEqual(ast.cmpop.__doc__, "cmpop = Eq | NotEq | Lt | LtE | Gt | GtE | Is | IsNot | In | NotIn")
686 expressions = [f" | {node.__doc__}" for node in ast.expr.__subclasses__()]
687 expressions[0] = f"expr = {ast.expr.__subclasses__()[0].__doc__}"
688 self.assertCountEqual(ast.expr.__doc__.split("\n"), expressions)
689
Shantanuc116c942020-05-27 13:30:38 -0700690 def test_issue40614_feature_version(self):
691 ast.parse('f"{x=}"', feature_version=(3, 8))
692 with self.assertRaises(SyntaxError):
693 ast.parse('f"{x=}"', feature_version=(3, 7))
694
Batuhan Taskaya68874a82020-06-06 15:44:16 +0300695 def test_constant_as_name(self):
696 for constant in "True", "False", "None":
697 expr = ast.Expression(ast.Name(constant, ast.Load()))
698 ast.fix_missing_locations(expr)
699 with self.assertRaisesRegex(ValueError, f"Name node can't be used with '{constant}' constant"):
700 compile(expr, "<test>", "eval")
701
Ethan Furmana02cb472021-04-21 10:20:44 -0700702 def test_precedence_enum(self):
703 class _Precedence(enum.IntEnum):
704 """Precedence table that originated from python grammar."""
705 TUPLE = enum.auto()
706 YIELD = enum.auto() # 'yield', 'yield from'
707 TEST = enum.auto() # 'if'-'else', 'lambda'
708 OR = enum.auto() # 'or'
709 AND = enum.auto() # 'and'
710 NOT = enum.auto() # 'not'
711 CMP = enum.auto() # '<', '>', '==', '>=', '<=', '!=',
712 # 'in', 'not in', 'is', 'is not'
713 EXPR = enum.auto()
714 BOR = EXPR # '|'
715 BXOR = enum.auto() # '^'
716 BAND = enum.auto() # '&'
717 SHIFT = enum.auto() # '<<', '>>'
718 ARITH = enum.auto() # '+', '-'
719 TERM = enum.auto() # '*', '@', '/', '%', '//'
720 FACTOR = enum.auto() # unary '+', '-', '~'
721 POWER = enum.auto() # '**'
722 AWAIT = enum.auto() # 'await'
723 ATOM = enum.auto()
724 def next(self):
725 try:
726 return self.__class__(self + 1)
727 except ValueError:
728 return self
729 enum._test_simple_enum(_Precedence, ast._Precedence)
730
Batuhan TaĹźkaya4ab362c2020-03-16 11:12:53 +0300731
Georg Brandl0c77a822008-06-10 16:37:50 +0000732class ASTHelpers_Test(unittest.TestCase):
Guido van Rossum10f8ce62019-03-13 13:00:46 -0700733 maxDiff = None
Georg Brandl0c77a822008-06-10 16:37:50 +0000734
735 def test_parse(self):
736 a = ast.parse('foo(1 + 1)')
737 b = compile('foo(1 + 1)', '<unknown>', 'exec', ast.PyCF_ONLY_AST)
738 self.assertEqual(ast.dump(a), ast.dump(b))
739
Benjamin Peterson2e2c9032012-09-02 14:23:15 -0400740 def test_parse_in_error(self):
741 try:
742 1/0
743 except Exception:
Benjamin Petersonbd0df502012-09-02 15:04:51 -0400744 with self.assertRaises(SyntaxError) as e:
745 ast.literal_eval(r"'\U'")
746 self.assertIsNotNone(e.exception.__context__)
Benjamin Peterson2e2c9032012-09-02 14:23:15 -0400747
Georg Brandl0c77a822008-06-10 16:37:50 +0000748 def test_dump(self):
749 node = ast.parse('spam(eggs, "and cheese")')
750 self.assertEqual(ast.dump(node),
751 "Module(body=[Expr(value=Call(func=Name(id='spam', ctx=Load()), "
Serhiy Storchakab7e95252020-03-10 00:07:47 +0200752 "args=[Name(id='eggs', ctx=Load()), Constant(value='and cheese')], "
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800753 "keywords=[]))], type_ignores=[])"
Georg Brandl0c77a822008-06-10 16:37:50 +0000754 )
755 self.assertEqual(ast.dump(node, annotate_fields=False),
756 "Module([Expr(Call(Name('spam', Load()), [Name('eggs', Load()), "
Serhiy Storchakab7e95252020-03-10 00:07:47 +0200757 "Constant('and cheese')], []))], [])"
Georg Brandl0c77a822008-06-10 16:37:50 +0000758 )
759 self.assertEqual(ast.dump(node, include_attributes=True),
760 "Module(body=[Expr(value=Call(func=Name(id='spam', ctx=Load(), "
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000761 "lineno=1, col_offset=0, end_lineno=1, end_col_offset=4), "
762 "args=[Name(id='eggs', ctx=Load(), lineno=1, col_offset=5, "
Serhiy Storchakab7e95252020-03-10 00:07:47 +0200763 "end_lineno=1, end_col_offset=9), Constant(value='and cheese', "
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000764 "lineno=1, col_offset=11, end_lineno=1, end_col_offset=23)], keywords=[], "
765 "lineno=1, col_offset=0, end_lineno=1, end_col_offset=24), "
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800766 "lineno=1, col_offset=0, end_lineno=1, end_col_offset=24)], type_ignores=[])"
Georg Brandl0c77a822008-06-10 16:37:50 +0000767 )
768
Serhiy Storchaka850573b2019-09-09 19:33:13 +0300769 def test_dump_indent(self):
770 node = ast.parse('spam(eggs, "and cheese")')
771 self.assertEqual(ast.dump(node, indent=3), """\
772Module(
773 body=[
774 Expr(
775 value=Call(
776 func=Name(id='spam', ctx=Load()),
777 args=[
778 Name(id='eggs', ctx=Load()),
Serhiy Storchakab7e95252020-03-10 00:07:47 +0200779 Constant(value='and cheese')],
Serhiy Storchaka850573b2019-09-09 19:33:13 +0300780 keywords=[]))],
781 type_ignores=[])""")
782 self.assertEqual(ast.dump(node, annotate_fields=False, indent='\t'), """\
783Module(
784\t[
785\t\tExpr(
786\t\t\tCall(
787\t\t\t\tName('spam', Load()),
788\t\t\t\t[
789\t\t\t\t\tName('eggs', Load()),
Serhiy Storchakab7e95252020-03-10 00:07:47 +0200790\t\t\t\t\tConstant('and cheese')],
Serhiy Storchaka850573b2019-09-09 19:33:13 +0300791\t\t\t\t[]))],
792\t[])""")
793 self.assertEqual(ast.dump(node, include_attributes=True, indent=3), """\
794Module(
795 body=[
796 Expr(
797 value=Call(
798 func=Name(
799 id='spam',
800 ctx=Load(),
801 lineno=1,
802 col_offset=0,
803 end_lineno=1,
804 end_col_offset=4),
805 args=[
806 Name(
807 id='eggs',
808 ctx=Load(),
809 lineno=1,
810 col_offset=5,
811 end_lineno=1,
812 end_col_offset=9),
813 Constant(
814 value='and cheese',
Serhiy Storchaka850573b2019-09-09 19:33:13 +0300815 lineno=1,
816 col_offset=11,
817 end_lineno=1,
818 end_col_offset=23)],
819 keywords=[],
820 lineno=1,
821 col_offset=0,
822 end_lineno=1,
823 end_col_offset=24),
824 lineno=1,
825 col_offset=0,
826 end_lineno=1,
827 end_col_offset=24)],
828 type_ignores=[])""")
829
Serhiy Storchakae64f9482019-08-29 09:30:23 +0300830 def test_dump_incomplete(self):
831 node = ast.Raise(lineno=3, col_offset=4)
832 self.assertEqual(ast.dump(node),
833 "Raise()"
834 )
835 self.assertEqual(ast.dump(node, include_attributes=True),
836 "Raise(lineno=3, col_offset=4)"
837 )
838 node = ast.Raise(exc=ast.Name(id='e', ctx=ast.Load()), lineno=3, col_offset=4)
839 self.assertEqual(ast.dump(node),
840 "Raise(exc=Name(id='e', ctx=Load()))"
841 )
842 self.assertEqual(ast.dump(node, annotate_fields=False),
843 "Raise(Name('e', Load()))"
844 )
845 self.assertEqual(ast.dump(node, include_attributes=True),
846 "Raise(exc=Name(id='e', ctx=Load()), lineno=3, col_offset=4)"
847 )
848 self.assertEqual(ast.dump(node, annotate_fields=False, include_attributes=True),
849 "Raise(Name('e', Load()), lineno=3, col_offset=4)"
850 )
851 node = ast.Raise(cause=ast.Name(id='e', ctx=ast.Load()))
852 self.assertEqual(ast.dump(node),
853 "Raise(cause=Name(id='e', ctx=Load()))"
854 )
855 self.assertEqual(ast.dump(node, annotate_fields=False),
856 "Raise(cause=Name('e', Load()))"
857 )
858
Georg Brandl0c77a822008-06-10 16:37:50 +0000859 def test_copy_location(self):
860 src = ast.parse('1 + 1', mode='eval')
861 src.body.right = ast.copy_location(ast.Num(2), src.body.right)
862 self.assertEqual(ast.dump(src, include_attributes=True),
Serhiy Storchakab7e95252020-03-10 00:07:47 +0200863 'Expression(body=BinOp(left=Constant(value=1, lineno=1, col_offset=0, '
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000864 'end_lineno=1, end_col_offset=1), op=Add(), right=Constant(value=2, '
865 'lineno=1, col_offset=4, end_lineno=1, end_col_offset=5), lineno=1, '
866 'col_offset=0, end_lineno=1, end_col_offset=5))'
Georg Brandl0c77a822008-06-10 16:37:50 +0000867 )
Batuhan Taskaya8f4380d2020-08-05 16:32:32 +0300868 src = ast.Call(col_offset=1, lineno=1, end_lineno=1, end_col_offset=1)
869 new = ast.copy_location(src, ast.Call(col_offset=None, lineno=None))
870 self.assertIsNone(new.end_lineno)
871 self.assertIsNone(new.end_col_offset)
872 self.assertEqual(new.lineno, 1)
873 self.assertEqual(new.col_offset, 1)
Georg Brandl0c77a822008-06-10 16:37:50 +0000874
875 def test_fix_missing_locations(self):
876 src = ast.parse('write("spam")')
877 src.body.append(ast.Expr(ast.Call(ast.Name('spam', ast.Load()),
Benjamin Peterson025e9eb2015-05-05 20:16:41 -0400878 [ast.Str('eggs')], [])))
Georg Brandl0c77a822008-06-10 16:37:50 +0000879 self.assertEqual(src, ast.fix_missing_locations(src))
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000880 self.maxDiff = None
Georg Brandl0c77a822008-06-10 16:37:50 +0000881 self.assertEqual(ast.dump(src, include_attributes=True),
882 "Module(body=[Expr(value=Call(func=Name(id='write', ctx=Load(), "
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000883 "lineno=1, col_offset=0, end_lineno=1, end_col_offset=5), "
Serhiy Storchakab7e95252020-03-10 00:07:47 +0200884 "args=[Constant(value='spam', lineno=1, col_offset=6, end_lineno=1, "
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000885 "end_col_offset=12)], keywords=[], lineno=1, col_offset=0, end_lineno=1, "
886 "end_col_offset=13), lineno=1, col_offset=0, end_lineno=1, "
887 "end_col_offset=13), Expr(value=Call(func=Name(id='spam', ctx=Load(), "
888 "lineno=1, col_offset=0, end_lineno=1, end_col_offset=0), "
889 "args=[Constant(value='eggs', lineno=1, col_offset=0, end_lineno=1, "
890 "end_col_offset=0)], keywords=[], lineno=1, col_offset=0, end_lineno=1, "
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800891 "end_col_offset=0), lineno=1, col_offset=0, end_lineno=1, end_col_offset=0)], "
892 "type_ignores=[])"
Georg Brandl0c77a822008-06-10 16:37:50 +0000893 )
894
895 def test_increment_lineno(self):
896 src = ast.parse('1 + 1', mode='eval')
897 self.assertEqual(ast.increment_lineno(src, n=3), src)
898 self.assertEqual(ast.dump(src, include_attributes=True),
Serhiy Storchakab7e95252020-03-10 00:07:47 +0200899 'Expression(body=BinOp(left=Constant(value=1, lineno=4, col_offset=0, '
900 'end_lineno=4, end_col_offset=1), op=Add(), right=Constant(value=1, '
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000901 'lineno=4, col_offset=4, end_lineno=4, end_col_offset=5), lineno=4, '
902 'col_offset=0, end_lineno=4, end_col_offset=5))'
Georg Brandl0c77a822008-06-10 16:37:50 +0000903 )
Georg Brandl619e7ba2011-01-09 07:38:51 +0000904 # issue10869: do not increment lineno of root twice
Georg Brandlefb69022011-01-09 07:50:48 +0000905 src = ast.parse('1 + 1', mode='eval')
Georg Brandl619e7ba2011-01-09 07:38:51 +0000906 self.assertEqual(ast.increment_lineno(src.body, n=3), src.body)
907 self.assertEqual(ast.dump(src, include_attributes=True),
Serhiy Storchakab7e95252020-03-10 00:07:47 +0200908 'Expression(body=BinOp(left=Constant(value=1, lineno=4, col_offset=0, '
909 'end_lineno=4, end_col_offset=1), op=Add(), right=Constant(value=1, '
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000910 'lineno=4, col_offset=4, end_lineno=4, end_col_offset=5), lineno=4, '
911 'col_offset=0, end_lineno=4, end_col_offset=5))'
Georg Brandl619e7ba2011-01-09 07:38:51 +0000912 )
Batuhan Taskaya8f4380d2020-08-05 16:32:32 +0300913 src = ast.Call(
914 func=ast.Name("test", ast.Load()), args=[], keywords=[], lineno=1
915 )
916 self.assertEqual(ast.increment_lineno(src).lineno, 2)
917 self.assertIsNone(ast.increment_lineno(src).end_lineno)
Georg Brandl0c77a822008-06-10 16:37:50 +0000918
919 def test_iter_fields(self):
920 node = ast.parse('foo()', mode='eval')
921 d = dict(ast.iter_fields(node.body))
922 self.assertEqual(d.pop('func').id, 'foo')
Benjamin Peterson025e9eb2015-05-05 20:16:41 -0400923 self.assertEqual(d, {'keywords': [], 'args': []})
Georg Brandl0c77a822008-06-10 16:37:50 +0000924
925 def test_iter_child_nodes(self):
926 node = ast.parse("spam(23, 42, eggs='leek')", mode='eval')
927 self.assertEqual(len(list(ast.iter_child_nodes(node.body))), 4)
928 iterator = ast.iter_child_nodes(node.body)
929 self.assertEqual(next(iterator).id, 'spam')
Serhiy Storchaka3f228112018-09-27 17:42:37 +0300930 self.assertEqual(next(iterator).value, 23)
931 self.assertEqual(next(iterator).value, 42)
Georg Brandl0c77a822008-06-10 16:37:50 +0000932 self.assertEqual(ast.dump(next(iterator)),
Serhiy Storchakab7e95252020-03-10 00:07:47 +0200933 "keyword(arg='eggs', value=Constant(value='leek'))"
Georg Brandl0c77a822008-06-10 16:37:50 +0000934 )
935
936 def test_get_docstring(self):
Serhiy Storchaka08f127a2018-06-15 11:05:15 +0300937 node = ast.parse('"""line one\n line two"""')
938 self.assertEqual(ast.get_docstring(node),
939 'line one\nline two')
940
941 node = ast.parse('class foo:\n """line one\n line two"""')
942 self.assertEqual(ast.get_docstring(node.body[0]),
943 'line one\nline two')
944
Georg Brandl0c77a822008-06-10 16:37:50 +0000945 node = ast.parse('def foo():\n """line one\n line two"""')
946 self.assertEqual(ast.get_docstring(node.body[0]),
947 'line one\nline two')
948
Yury Selivanov2f07a662015-07-23 08:54:35 +0300949 node = ast.parse('async def foo():\n """spam\n ham"""')
950 self.assertEqual(ast.get_docstring(node.body[0]), 'spam\nham')
Serhiy Storchaka08f127a2018-06-15 11:05:15 +0300951
952 def test_get_docstring_none(self):
Matthias Bussonnier41cea702017-02-23 22:44:19 -0800953 self.assertIsNone(ast.get_docstring(ast.parse('')))
Serhiy Storchaka08f127a2018-06-15 11:05:15 +0300954 node = ast.parse('x = "not docstring"')
955 self.assertIsNone(ast.get_docstring(node))
956 node = ast.parse('def foo():\n pass')
957 self.assertIsNone(ast.get_docstring(node))
958
959 node = ast.parse('class foo:\n pass')
960 self.assertIsNone(ast.get_docstring(node.body[0]))
961 node = ast.parse('class foo:\n x = "not docstring"')
962 self.assertIsNone(ast.get_docstring(node.body[0]))
963 node = ast.parse('class foo:\n def bar(self): pass')
964 self.assertIsNone(ast.get_docstring(node.body[0]))
965
966 node = ast.parse('def foo():\n pass')
967 self.assertIsNone(ast.get_docstring(node.body[0]))
968 node = ast.parse('def foo():\n x = "not docstring"')
969 self.assertIsNone(ast.get_docstring(node.body[0]))
970
971 node = ast.parse('async def foo():\n pass')
972 self.assertIsNone(ast.get_docstring(node.body[0]))
973 node = ast.parse('async def foo():\n x = "not docstring"')
974 self.assertIsNone(ast.get_docstring(node.body[0]))
Yury Selivanov2f07a662015-07-23 08:54:35 +0300975
Anthony Sottile995d9b92019-01-12 20:05:13 -0800976 def test_multi_line_docstring_col_offset_and_lineno_issue16806(self):
977 node = ast.parse(
978 '"""line one\nline two"""\n\n'
979 'def foo():\n """line one\n line two"""\n\n'
980 ' def bar():\n """line one\n line two"""\n'
981 ' """line one\n line two"""\n'
982 '"""line one\nline two"""\n\n'
983 )
984 self.assertEqual(node.body[0].col_offset, 0)
985 self.assertEqual(node.body[0].lineno, 1)
986 self.assertEqual(node.body[1].body[0].col_offset, 2)
987 self.assertEqual(node.body[1].body[0].lineno, 5)
988 self.assertEqual(node.body[1].body[1].body[0].col_offset, 4)
989 self.assertEqual(node.body[1].body[1].body[0].lineno, 9)
990 self.assertEqual(node.body[1].body[2].col_offset, 2)
991 self.assertEqual(node.body[1].body[2].lineno, 11)
992 self.assertEqual(node.body[2].col_offset, 0)
993 self.assertEqual(node.body[2].lineno, 13)
994
Lysandros Nikolaou025a6022019-12-12 22:40:21 +0100995 def test_elif_stmt_start_position(self):
996 node = ast.parse('if a:\n pass\nelif b:\n pass\n')
997 elif_stmt = node.body[0].orelse[0]
998 self.assertEqual(elif_stmt.lineno, 3)
999 self.assertEqual(elif_stmt.col_offset, 0)
1000
Lysandros Nikolaou5936a4c2019-12-14 11:24:57 +01001001 def test_elif_stmt_start_position_with_else(self):
1002 node = ast.parse('if a:\n pass\nelif b:\n pass\nelse:\n pass\n')
1003 elif_stmt = node.body[0].orelse[0]
1004 self.assertEqual(elif_stmt.lineno, 3)
1005 self.assertEqual(elif_stmt.col_offset, 0)
1006
Lysandros Nikolaou50d4f122019-12-18 01:20:55 +01001007 def test_starred_expr_end_position_within_call(self):
1008 node = ast.parse('f(*[0, 1])')
1009 starred_expr = node.body[0].value.args[0]
1010 self.assertEqual(starred_expr.end_lineno, 1)
1011 self.assertEqual(starred_expr.end_col_offset, 9)
1012
Georg Brandl0c77a822008-06-10 16:37:50 +00001013 def test_literal_eval(self):
1014 self.assertEqual(ast.literal_eval('[1, 2, 3]'), [1, 2, 3])
1015 self.assertEqual(ast.literal_eval('{"foo": 42}'), {"foo": 42})
1016 self.assertEqual(ast.literal_eval('(True, False, None)'), (True, False, None))
Benjamin Peterson3e742892010-07-11 12:59:24 +00001017 self.assertEqual(ast.literal_eval('{1, 2, 3}'), {1, 2, 3})
Benjamin Peterson5ef96e52010-07-11 23:06:06 +00001018 self.assertEqual(ast.literal_eval('b"hi"'), b"hi")
Raymond Hettinger4fcf5c12020-01-02 22:21:18 -07001019 self.assertEqual(ast.literal_eval('set()'), set())
Georg Brandl0c77a822008-06-10 16:37:50 +00001020 self.assertRaises(ValueError, ast.literal_eval, 'foo()')
Serhiy Storchakad8ac4d12018-01-04 11:15:39 +02001021 self.assertEqual(ast.literal_eval('6'), 6)
1022 self.assertEqual(ast.literal_eval('+6'), 6)
Raymond Hettingerbc959732010-10-08 00:47:45 +00001023 self.assertEqual(ast.literal_eval('-6'), -6)
Raymond Hettingerbc959732010-10-08 00:47:45 +00001024 self.assertEqual(ast.literal_eval('3.25'), 3.25)
Serhiy Storchakad8ac4d12018-01-04 11:15:39 +02001025 self.assertEqual(ast.literal_eval('+3.25'), 3.25)
1026 self.assertEqual(ast.literal_eval('-3.25'), -3.25)
1027 self.assertEqual(repr(ast.literal_eval('-0.0')), '-0.0')
1028 self.assertRaises(ValueError, ast.literal_eval, '++6')
1029 self.assertRaises(ValueError, ast.literal_eval, '+True')
1030 self.assertRaises(ValueError, ast.literal_eval, '2+3')
Georg Brandl0c77a822008-06-10 16:37:50 +00001031
Serhiy Storchakad8ac4d12018-01-04 11:15:39 +02001032 def test_literal_eval_complex(self):
1033 # Issue #4907
1034 self.assertEqual(ast.literal_eval('6j'), 6j)
1035 self.assertEqual(ast.literal_eval('-6j'), -6j)
1036 self.assertEqual(ast.literal_eval('6.75j'), 6.75j)
1037 self.assertEqual(ast.literal_eval('-6.75j'), -6.75j)
1038 self.assertEqual(ast.literal_eval('3+6j'), 3+6j)
1039 self.assertEqual(ast.literal_eval('-3+6j'), -3+6j)
1040 self.assertEqual(ast.literal_eval('3-6j'), 3-6j)
1041 self.assertEqual(ast.literal_eval('-3-6j'), -3-6j)
1042 self.assertEqual(ast.literal_eval('3.25+6.75j'), 3.25+6.75j)
1043 self.assertEqual(ast.literal_eval('-3.25+6.75j'), -3.25+6.75j)
1044 self.assertEqual(ast.literal_eval('3.25-6.75j'), 3.25-6.75j)
1045 self.assertEqual(ast.literal_eval('-3.25-6.75j'), -3.25-6.75j)
1046 self.assertEqual(ast.literal_eval('(3+6j)'), 3+6j)
1047 self.assertRaises(ValueError, ast.literal_eval, '-6j+3')
1048 self.assertRaises(ValueError, ast.literal_eval, '-6j+3j')
1049 self.assertRaises(ValueError, ast.literal_eval, '3+-6j')
1050 self.assertRaises(ValueError, ast.literal_eval, '3+(0+6j)')
1051 self.assertRaises(ValueError, ast.literal_eval, '-(3+6j)')
Benjamin Peterson058e31e2009-01-16 03:54:08 +00001052
Curtis Bucherc21c5122020-05-05 12:40:56 -07001053 def test_literal_eval_malformed_dict_nodes(self):
1054 malformed = ast.Dict(keys=[ast.Constant(1), ast.Constant(2)], values=[ast.Constant(3)])
1055 self.assertRaises(ValueError, ast.literal_eval, malformed)
1056 malformed = ast.Dict(keys=[ast.Constant(1)], values=[ast.Constant(2), ast.Constant(3)])
1057 self.assertRaises(ValueError, ast.literal_eval, malformed)
1058
Batuhan Taskayae799aa82020-10-04 03:46:44 +03001059 def test_literal_eval_trailing_ws(self):
1060 self.assertEqual(ast.literal_eval(" -1"), -1)
1061 self.assertEqual(ast.literal_eval("\t\t-1"), -1)
1062 self.assertEqual(ast.literal_eval(" \t -1"), -1)
1063 self.assertRaises(IndentationError, ast.literal_eval, "\n -1")
1064
Irit Katriel586f3db2020-12-25 17:04:31 +00001065 def test_literal_eval_malformed_lineno(self):
1066 msg = r'malformed node or string on line 3:'
1067 with self.assertRaisesRegex(ValueError, msg):
1068 ast.literal_eval("{'a': 1,\n'b':2,\n'c':++3,\n'd':4}")
1069
1070 node = ast.UnaryOp(
1071 ast.UAdd(), ast.UnaryOp(ast.UAdd(), ast.Constant(6)))
1072 self.assertIsNone(getattr(node, 'lineno', None))
1073 msg = r'malformed node or string:'
1074 with self.assertRaisesRegex(ValueError, msg):
1075 ast.literal_eval(node)
1076
Amaury Forgeot d'Arc58e87612011-11-22 21:51:55 +01001077 def test_bad_integer(self):
1078 # issue13436: Bad error message with invalid numeric values
1079 body = [ast.ImportFrom(module='time',
1080 names=[ast.alias(name='sleep')],
1081 level=None,
1082 lineno=None, col_offset=None)]
Guido van Rossumdcfcd142019-01-31 03:40:27 -08001083 mod = ast.Module(body, [])
Amaury Forgeot d'Arc58e87612011-11-22 21:51:55 +01001084 with self.assertRaises(ValueError) as cm:
1085 compile(mod, 'test', 'exec')
1086 self.assertIn("invalid integer value: None", str(cm.exception))
1087
Berker Peksag0a5bd512016-04-29 19:50:02 +03001088 def test_level_as_none(self):
1089 body = [ast.ImportFrom(module='time',
Matthew Suozzo75a06f02021-04-10 16:56:28 -04001090 names=[ast.alias(name='sleep',
1091 lineno=0, col_offset=0)],
Berker Peksag0a5bd512016-04-29 19:50:02 +03001092 level=None,
1093 lineno=0, col_offset=0)]
Guido van Rossumdcfcd142019-01-31 03:40:27 -08001094 mod = ast.Module(body, [])
Berker Peksag0a5bd512016-04-29 19:50:02 +03001095 code = compile(mod, 'test', 'exec')
1096 ns = {}
1097 exec(code, ns)
1098 self.assertIn('sleep', ns)
1099
Miss Islington (bot)976598d2021-06-03 13:27:00 -07001100 def test_recursion_direct(self):
1101 e = ast.UnaryOp(op=ast.Not(), lineno=0, col_offset=0)
1102 e.operand = e
1103 with self.assertRaises(RecursionError):
1104 compile(ast.Expression(e), "<test>", "eval")
1105
1106 def test_recursion_indirect(self):
1107 e = ast.UnaryOp(op=ast.Not(), lineno=0, col_offset=0)
1108 f = ast.UnaryOp(op=ast.Not(), lineno=0, col_offset=0)
1109 e.operand = f
1110 f.operand = e
1111 with self.assertRaises(RecursionError):
1112 compile(ast.Expression(e), "<test>", "eval")
1113
Georg Brandl0c77a822008-06-10 16:37:50 +00001114
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001115class ASTValidatorTests(unittest.TestCase):
1116
1117 def mod(self, mod, msg=None, mode="exec", *, exc=ValueError):
1118 mod.lineno = mod.col_offset = 0
1119 ast.fix_missing_locations(mod)
Serhiy Storchaka3f228112018-09-27 17:42:37 +03001120 if msg is None:
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001121 compile(mod, "<test>", mode)
Serhiy Storchaka3f228112018-09-27 17:42:37 +03001122 else:
1123 with self.assertRaises(exc) as cm:
1124 compile(mod, "<test>", mode)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001125 self.assertIn(msg, str(cm.exception))
1126
1127 def expr(self, node, msg=None, *, exc=ValueError):
Guido van Rossumdcfcd142019-01-31 03:40:27 -08001128 mod = ast.Module([ast.Expr(node)], [])
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001129 self.mod(mod, msg, exc=exc)
1130
1131 def stmt(self, stmt, msg=None):
Guido van Rossumdcfcd142019-01-31 03:40:27 -08001132 mod = ast.Module([stmt], [])
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001133 self.mod(mod, msg)
1134
1135 def test_module(self):
1136 m = ast.Interactive([ast.Expr(ast.Name("x", ast.Store()))])
1137 self.mod(m, "must have Load context", "single")
1138 m = ast.Expression(ast.Name("x", ast.Store()))
1139 self.mod(m, "must have Load context", "eval")
1140
1141 def _check_arguments(self, fac, check):
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01001142 def arguments(args=None, posonlyargs=None, vararg=None,
Benjamin Petersoncda75be2013-03-18 10:48:58 -07001143 kwonlyargs=None, kwarg=None,
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001144 defaults=None, kw_defaults=None):
1145 if args is None:
1146 args = []
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01001147 if posonlyargs is None:
1148 posonlyargs = []
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001149 if kwonlyargs is None:
1150 kwonlyargs = []
1151 if defaults is None:
1152 defaults = []
1153 if kw_defaults is None:
1154 kw_defaults = []
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01001155 args = ast.arguments(args, posonlyargs, vararg, kwonlyargs,
1156 kw_defaults, kwarg, defaults)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001157 return fac(args)
1158 args = [ast.arg("x", ast.Name("x", ast.Store()))]
1159 check(arguments(args=args), "must have Load context")
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01001160 check(arguments(posonlyargs=args), "must have Load context")
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001161 check(arguments(kwonlyargs=args), "must have Load context")
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001162 check(arguments(defaults=[ast.Num(3)]),
1163 "more positional defaults than args")
1164 check(arguments(kw_defaults=[ast.Num(4)]),
1165 "length of kwonlyargs is not the same as kw_defaults")
1166 args = [ast.arg("x", ast.Name("x", ast.Load()))]
1167 check(arguments(args=args, defaults=[ast.Name("x", ast.Store())]),
1168 "must have Load context")
1169 args = [ast.arg("a", ast.Name("x", ast.Load())),
1170 ast.arg("b", ast.Name("y", ast.Load()))]
1171 check(arguments(kwonlyargs=args,
1172 kw_defaults=[None, ast.Name("x", ast.Store())]),
1173 "must have Load context")
1174
1175 def test_funcdef(self):
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01001176 a = ast.arguments([], [], None, [], [], None, [])
Serhiy Storchaka73cbe7a2018-05-29 12:04:55 +03001177 f = ast.FunctionDef("x", a, [], [], None)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001178 self.stmt(f, "empty body on FunctionDef")
1179 f = ast.FunctionDef("x", a, [ast.Pass()], [ast.Name("x", ast.Store())],
Serhiy Storchaka73cbe7a2018-05-29 12:04:55 +03001180 None)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001181 self.stmt(f, "must have Load context")
1182 f = ast.FunctionDef("x", a, [ast.Pass()], [],
Serhiy Storchaka73cbe7a2018-05-29 12:04:55 +03001183 ast.Name("x", ast.Store()))
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001184 self.stmt(f, "must have Load context")
1185 def fac(args):
Serhiy Storchaka73cbe7a2018-05-29 12:04:55 +03001186 return ast.FunctionDef("x", args, [ast.Pass()], [], None)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001187 self._check_arguments(fac, self.stmt)
1188
1189 def test_classdef(self):
Benjamin Peterson025e9eb2015-05-05 20:16:41 -04001190 def cls(bases=None, keywords=None, body=None, decorator_list=None):
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001191 if bases is None:
1192 bases = []
1193 if keywords is None:
1194 keywords = []
1195 if body is None:
1196 body = [ast.Pass()]
1197 if decorator_list is None:
1198 decorator_list = []
Benjamin Peterson025e9eb2015-05-05 20:16:41 -04001199 return ast.ClassDef("myclass", bases, keywords,
Serhiy Storchaka73cbe7a2018-05-29 12:04:55 +03001200 body, decorator_list)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001201 self.stmt(cls(bases=[ast.Name("x", ast.Store())]),
1202 "must have Load context")
1203 self.stmt(cls(keywords=[ast.keyword("x", ast.Name("x", ast.Store()))]),
1204 "must have Load context")
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001205 self.stmt(cls(body=[]), "empty body on ClassDef")
1206 self.stmt(cls(body=[None]), "None disallowed")
1207 self.stmt(cls(decorator_list=[ast.Name("x", ast.Store())]),
1208 "must have Load context")
1209
1210 def test_delete(self):
1211 self.stmt(ast.Delete([]), "empty targets on Delete")
1212 self.stmt(ast.Delete([None]), "None disallowed")
1213 self.stmt(ast.Delete([ast.Name("x", ast.Load())]),
1214 "must have Del context")
1215
1216 def test_assign(self):
1217 self.stmt(ast.Assign([], ast.Num(3)), "empty targets on Assign")
1218 self.stmt(ast.Assign([None], ast.Num(3)), "None disallowed")
1219 self.stmt(ast.Assign([ast.Name("x", ast.Load())], ast.Num(3)),
1220 "must have Store context")
1221 self.stmt(ast.Assign([ast.Name("x", ast.Store())],
1222 ast.Name("y", ast.Store())),
1223 "must have Load context")
1224
1225 def test_augassign(self):
1226 aug = ast.AugAssign(ast.Name("x", ast.Load()), ast.Add(),
1227 ast.Name("y", ast.Load()))
1228 self.stmt(aug, "must have Store context")
1229 aug = ast.AugAssign(ast.Name("x", ast.Store()), ast.Add(),
1230 ast.Name("y", ast.Store()))
1231 self.stmt(aug, "must have Load context")
1232
1233 def test_for(self):
1234 x = ast.Name("x", ast.Store())
1235 y = ast.Name("y", ast.Load())
1236 p = ast.Pass()
1237 self.stmt(ast.For(x, y, [], []), "empty body on For")
1238 self.stmt(ast.For(ast.Name("x", ast.Load()), y, [p], []),
1239 "must have Store context")
1240 self.stmt(ast.For(x, ast.Name("y", ast.Store()), [p], []),
1241 "must have Load context")
1242 e = ast.Expr(ast.Name("x", ast.Store()))
1243 self.stmt(ast.For(x, y, [e], []), "must have Load context")
1244 self.stmt(ast.For(x, y, [p], [e]), "must have Load context")
1245
1246 def test_while(self):
1247 self.stmt(ast.While(ast.Num(3), [], []), "empty body on While")
1248 self.stmt(ast.While(ast.Name("x", ast.Store()), [ast.Pass()], []),
1249 "must have Load context")
1250 self.stmt(ast.While(ast.Num(3), [ast.Pass()],
1251 [ast.Expr(ast.Name("x", ast.Store()))]),
1252 "must have Load context")
1253
1254 def test_if(self):
1255 self.stmt(ast.If(ast.Num(3), [], []), "empty body on If")
1256 i = ast.If(ast.Name("x", ast.Store()), [ast.Pass()], [])
1257 self.stmt(i, "must have Load context")
1258 i = ast.If(ast.Num(3), [ast.Expr(ast.Name("x", ast.Store()))], [])
1259 self.stmt(i, "must have Load context")
1260 i = ast.If(ast.Num(3), [ast.Pass()],
1261 [ast.Expr(ast.Name("x", ast.Store()))])
1262 self.stmt(i, "must have Load context")
1263
1264 def test_with(self):
1265 p = ast.Pass()
1266 self.stmt(ast.With([], [p]), "empty items on With")
1267 i = ast.withitem(ast.Num(3), None)
1268 self.stmt(ast.With([i], []), "empty body on With")
1269 i = ast.withitem(ast.Name("x", ast.Store()), None)
1270 self.stmt(ast.With([i], [p]), "must have Load context")
1271 i = ast.withitem(ast.Num(3), ast.Name("x", ast.Load()))
1272 self.stmt(ast.With([i], [p]), "must have Store context")
1273
1274 def test_raise(self):
1275 r = ast.Raise(None, ast.Num(3))
1276 self.stmt(r, "Raise with cause but no exception")
1277 r = ast.Raise(ast.Name("x", ast.Store()), None)
1278 self.stmt(r, "must have Load context")
1279 r = ast.Raise(ast.Num(4), ast.Name("x", ast.Store()))
1280 self.stmt(r, "must have Load context")
1281
1282 def test_try(self):
1283 p = ast.Pass()
1284 t = ast.Try([], [], [], [p])
1285 self.stmt(t, "empty body on Try")
1286 t = ast.Try([ast.Expr(ast.Name("x", ast.Store()))], [], [], [p])
1287 self.stmt(t, "must have Load context")
1288 t = ast.Try([p], [], [], [])
1289 self.stmt(t, "Try has neither except handlers nor finalbody")
1290 t = ast.Try([p], [], [p], [p])
1291 self.stmt(t, "Try has orelse but no except handlers")
1292 t = ast.Try([p], [ast.ExceptHandler(None, "x", [])], [], [])
1293 self.stmt(t, "empty body on ExceptHandler")
1294 e = [ast.ExceptHandler(ast.Name("x", ast.Store()), "y", [p])]
1295 self.stmt(ast.Try([p], e, [], []), "must have Load context")
1296 e = [ast.ExceptHandler(None, "x", [p])]
1297 t = ast.Try([p], e, [ast.Expr(ast.Name("x", ast.Store()))], [p])
1298 self.stmt(t, "must have Load context")
1299 t = ast.Try([p], e, [p], [ast.Expr(ast.Name("x", ast.Store()))])
1300 self.stmt(t, "must have Load context")
1301
1302 def test_assert(self):
1303 self.stmt(ast.Assert(ast.Name("x", ast.Store()), None),
1304 "must have Load context")
1305 assrt = ast.Assert(ast.Name("x", ast.Load()),
1306 ast.Name("y", ast.Store()))
1307 self.stmt(assrt, "must have Load context")
1308
1309 def test_import(self):
1310 self.stmt(ast.Import([]), "empty names on Import")
1311
1312 def test_importfrom(self):
1313 imp = ast.ImportFrom(None, [ast.alias("x", None)], -42)
Serhiy Storchaka7de28402016-06-27 23:40:43 +03001314 self.stmt(imp, "Negative ImportFrom level")
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001315 self.stmt(ast.ImportFrom(None, [], 0), "empty names on ImportFrom")
1316
1317 def test_global(self):
1318 self.stmt(ast.Global([]), "empty names on Global")
1319
1320 def test_nonlocal(self):
1321 self.stmt(ast.Nonlocal([]), "empty names on Nonlocal")
1322
1323 def test_expr(self):
1324 e = ast.Expr(ast.Name("x", ast.Store()))
1325 self.stmt(e, "must have Load context")
1326
1327 def test_boolop(self):
1328 b = ast.BoolOp(ast.And(), [])
1329 self.expr(b, "less than 2 values")
1330 b = ast.BoolOp(ast.And(), [ast.Num(3)])
1331 self.expr(b, "less than 2 values")
1332 b = ast.BoolOp(ast.And(), [ast.Num(4), None])
1333 self.expr(b, "None disallowed")
1334 b = ast.BoolOp(ast.And(), [ast.Num(4), ast.Name("x", ast.Store())])
1335 self.expr(b, "must have Load context")
1336
1337 def test_unaryop(self):
1338 u = ast.UnaryOp(ast.Not(), ast.Name("x", ast.Store()))
1339 self.expr(u, "must have Load context")
1340
1341 def test_lambda(self):
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01001342 a = ast.arguments([], [], None, [], [], None, [])
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001343 self.expr(ast.Lambda(a, ast.Name("x", ast.Store())),
1344 "must have Load context")
1345 def fac(args):
1346 return ast.Lambda(args, ast.Name("x", ast.Load()))
1347 self._check_arguments(fac, self.expr)
1348
1349 def test_ifexp(self):
1350 l = ast.Name("x", ast.Load())
1351 s = ast.Name("y", ast.Store())
1352 for args in (s, l, l), (l, s, l), (l, l, s):
Benjamin Peterson71ce8972011-08-09 16:17:12 -05001353 self.expr(ast.IfExp(*args), "must have Load context")
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001354
1355 def test_dict(self):
1356 d = ast.Dict([], [ast.Name("x", ast.Load())])
1357 self.expr(d, "same number of keys as values")
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001358 d = ast.Dict([ast.Name("x", ast.Load())], [None])
1359 self.expr(d, "None disallowed")
1360
1361 def test_set(self):
1362 self.expr(ast.Set([None]), "None disallowed")
1363 s = ast.Set([ast.Name("x", ast.Store())])
1364 self.expr(s, "must have Load context")
1365
1366 def _check_comprehension(self, fac):
1367 self.expr(fac([]), "comprehension with no generators")
1368 g = ast.comprehension(ast.Name("x", ast.Load()),
Yury Selivanov52c4e7c2016-09-09 10:36:01 -07001369 ast.Name("x", ast.Load()), [], 0)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001370 self.expr(fac([g]), "must have Store context")
1371 g = ast.comprehension(ast.Name("x", ast.Store()),
Yury Selivanov52c4e7c2016-09-09 10:36:01 -07001372 ast.Name("x", ast.Store()), [], 0)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001373 self.expr(fac([g]), "must have Load context")
1374 x = ast.Name("x", ast.Store())
1375 y = ast.Name("y", ast.Load())
Yury Selivanov52c4e7c2016-09-09 10:36:01 -07001376 g = ast.comprehension(x, y, [None], 0)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001377 self.expr(fac([g]), "None disallowed")
Yury Selivanov52c4e7c2016-09-09 10:36:01 -07001378 g = ast.comprehension(x, y, [ast.Name("x", ast.Store())], 0)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001379 self.expr(fac([g]), "must have Load context")
1380
1381 def _simple_comp(self, fac):
1382 g = ast.comprehension(ast.Name("x", ast.Store()),
Yury Selivanov52c4e7c2016-09-09 10:36:01 -07001383 ast.Name("x", ast.Load()), [], 0)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001384 self.expr(fac(ast.Name("x", ast.Store()), [g]),
1385 "must have Load context")
1386 def wrap(gens):
1387 return fac(ast.Name("x", ast.Store()), gens)
1388 self._check_comprehension(wrap)
1389
1390 def test_listcomp(self):
1391 self._simple_comp(ast.ListComp)
1392
1393 def test_setcomp(self):
1394 self._simple_comp(ast.SetComp)
1395
1396 def test_generatorexp(self):
1397 self._simple_comp(ast.GeneratorExp)
1398
1399 def test_dictcomp(self):
1400 g = ast.comprehension(ast.Name("y", ast.Store()),
Yury Selivanov52c4e7c2016-09-09 10:36:01 -07001401 ast.Name("p", ast.Load()), [], 0)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001402 c = ast.DictComp(ast.Name("x", ast.Store()),
1403 ast.Name("y", ast.Load()), [g])
1404 self.expr(c, "must have Load context")
1405 c = ast.DictComp(ast.Name("x", ast.Load()),
1406 ast.Name("y", ast.Store()), [g])
1407 self.expr(c, "must have Load context")
1408 def factory(comps):
1409 k = ast.Name("x", ast.Load())
1410 v = ast.Name("y", ast.Load())
1411 return ast.DictComp(k, v, comps)
1412 self._check_comprehension(factory)
1413
1414 def test_yield(self):
Benjamin Peterson527c6222012-01-14 08:58:23 -05001415 self.expr(ast.Yield(ast.Name("x", ast.Store())), "must have Load")
1416 self.expr(ast.YieldFrom(ast.Name("x", ast.Store())), "must have Load")
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001417
1418 def test_compare(self):
1419 left = ast.Name("x", ast.Load())
1420 comp = ast.Compare(left, [ast.In()], [])
1421 self.expr(comp, "no comparators")
1422 comp = ast.Compare(left, [ast.In()], [ast.Num(4), ast.Num(5)])
1423 self.expr(comp, "different number of comparators and operands")
1424 comp = ast.Compare(ast.Num("blah"), [ast.In()], [left])
Serhiy Storchaka3f228112018-09-27 17:42:37 +03001425 self.expr(comp)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001426 comp = ast.Compare(left, [ast.In()], [ast.Num("blah")])
Serhiy Storchaka3f228112018-09-27 17:42:37 +03001427 self.expr(comp)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001428
1429 def test_call(self):
1430 func = ast.Name("x", ast.Load())
1431 args = [ast.Name("y", ast.Load())]
1432 keywords = [ast.keyword("w", ast.Name("z", ast.Load()))]
Benjamin Peterson025e9eb2015-05-05 20:16:41 -04001433 call = ast.Call(ast.Name("x", ast.Store()), args, keywords)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001434 self.expr(call, "must have Load context")
Benjamin Peterson025e9eb2015-05-05 20:16:41 -04001435 call = ast.Call(func, [None], keywords)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001436 self.expr(call, "None disallowed")
1437 bad_keywords = [ast.keyword("w", ast.Name("z", ast.Store()))]
Benjamin Peterson025e9eb2015-05-05 20:16:41 -04001438 call = ast.Call(func, args, bad_keywords)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001439 self.expr(call, "must have Load context")
1440
1441 def test_num(self):
1442 class subint(int):
1443 pass
1444 class subfloat(float):
1445 pass
1446 class subcomplex(complex):
1447 pass
Serhiy Storchaka3f228112018-09-27 17:42:37 +03001448 for obj in "0", "hello":
1449 self.expr(ast.Num(obj))
1450 for obj in subint(), subfloat(), subcomplex():
1451 self.expr(ast.Num(obj), "invalid type", exc=TypeError)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001452
1453 def test_attribute(self):
1454 attr = ast.Attribute(ast.Name("x", ast.Store()), "y", ast.Load())
1455 self.expr(attr, "must have Load context")
1456
1457 def test_subscript(self):
Serhiy Storchaka13d52c22020-03-10 18:52:34 +02001458 sub = ast.Subscript(ast.Name("x", ast.Store()), ast.Num(3),
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001459 ast.Load())
1460 self.expr(sub, "must have Load context")
1461 x = ast.Name("x", ast.Load())
Serhiy Storchaka13d52c22020-03-10 18:52:34 +02001462 sub = ast.Subscript(x, ast.Name("y", ast.Store()),
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001463 ast.Load())
1464 self.expr(sub, "must have Load context")
1465 s = ast.Name("x", ast.Store())
1466 for args in (s, None, None), (None, s, None), (None, None, s):
1467 sl = ast.Slice(*args)
1468 self.expr(ast.Subscript(x, sl, ast.Load()),
1469 "must have Load context")
Serhiy Storchaka13d52c22020-03-10 18:52:34 +02001470 sl = ast.Tuple([], ast.Load())
1471 self.expr(ast.Subscript(x, sl, ast.Load()))
1472 sl = ast.Tuple([s], ast.Load())
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001473 self.expr(ast.Subscript(x, sl, ast.Load()), "must have Load context")
1474
1475 def test_starred(self):
1476 left = ast.List([ast.Starred(ast.Name("x", ast.Load()), ast.Store())],
1477 ast.Store())
1478 assign = ast.Assign([left], ast.Num(4))
1479 self.stmt(assign, "must have Store context")
1480
1481 def _sequence(self, fac):
1482 self.expr(fac([None], ast.Load()), "None disallowed")
1483 self.expr(fac([ast.Name("x", ast.Store())], ast.Load()),
1484 "must have Load context")
1485
1486 def test_list(self):
1487 self._sequence(ast.List)
1488
1489 def test_tuple(self):
1490 self._sequence(ast.Tuple)
1491
Benjamin Peterson442f2092012-12-06 17:41:04 -05001492 def test_nameconstant(self):
Serhiy Storchaka3f228112018-09-27 17:42:37 +03001493 self.expr(ast.NameConstant(4))
Benjamin Peterson442f2092012-12-06 17:41:04 -05001494
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001495 def test_stdlib_validates(self):
1496 stdlib = os.path.dirname(ast.__file__)
1497 tests = [fn for fn in os.listdir(stdlib) if fn.endswith(".py")]
1498 tests.extend(["test/test_grammar.py", "test/test_unpack_ex.py"])
1499 for module in tests:
Serhiy Storchaka3bcbedc2019-01-18 07:47:48 +02001500 with self.subTest(module):
1501 fn = os.path.join(stdlib, module)
1502 with open(fn, "r", encoding="utf-8") as fp:
1503 source = fp.read()
1504 mod = ast.parse(source, fn)
1505 compile(mod, fn, "exec")
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001506
1507
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001508class ConstantTests(unittest.TestCase):
1509 """Tests on the ast.Constant node type."""
1510
1511 def compile_constant(self, value):
1512 tree = ast.parse("x = 123")
1513
1514 node = tree.body[0].value
1515 new_node = ast.Constant(value=value)
1516 ast.copy_location(new_node, node)
1517 tree.body[0].value = new_node
1518
1519 code = compile(tree, "<string>", "exec")
1520
1521 ns = {}
1522 exec(code, ns)
1523 return ns['x']
1524
Victor Stinnerbe59d142016-01-27 00:39:12 +01001525 def test_validation(self):
1526 with self.assertRaises(TypeError) as cm:
1527 self.compile_constant([1, 2, 3])
1528 self.assertEqual(str(cm.exception),
1529 "got an invalid type in Constant: list")
1530
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001531 def test_singletons(self):
1532 for const in (None, False, True, Ellipsis, b'', frozenset()):
1533 with self.subTest(const=const):
1534 value = self.compile_constant(const)
1535 self.assertIs(value, const)
1536
1537 def test_values(self):
1538 nested_tuple = (1,)
1539 nested_frozenset = frozenset({1})
1540 for level in range(3):
1541 nested_tuple = (nested_tuple, 2)
1542 nested_frozenset = frozenset({nested_frozenset, 2})
1543 values = (123, 123.0, 123j,
1544 "unicode", b'bytes',
1545 tuple("tuple"), frozenset("frozenset"),
1546 nested_tuple, nested_frozenset)
1547 for value in values:
1548 with self.subTest(value=value):
1549 result = self.compile_constant(value)
1550 self.assertEqual(result, value)
1551
1552 def test_assign_to_constant(self):
1553 tree = ast.parse("x = 1")
1554
1555 target = tree.body[0].targets[0]
1556 new_target = ast.Constant(value=1)
1557 ast.copy_location(new_target, target)
1558 tree.body[0].targets[0] = new_target
1559
1560 with self.assertRaises(ValueError) as cm:
1561 compile(tree, "string", "exec")
1562 self.assertEqual(str(cm.exception),
1563 "expression which can't be assigned "
1564 "to in Store context")
1565
1566 def test_get_docstring(self):
1567 tree = ast.parse("'docstring'\nx = 1")
1568 self.assertEqual(ast.get_docstring(tree), 'docstring')
1569
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001570 def get_load_const(self, tree):
1571 # Compile to bytecode, disassemble and get parameter of LOAD_CONST
1572 # instructions
1573 co = compile(tree, '<string>', 'exec')
1574 consts = []
1575 for instr in dis.get_instructions(co):
1576 if instr.opname == 'LOAD_CONST':
1577 consts.append(instr.argval)
1578 return consts
1579
1580 @support.cpython_only
1581 def test_load_const(self):
1582 consts = [None,
1583 True, False,
1584 124,
1585 2.0,
1586 3j,
1587 "unicode",
1588 b'bytes',
1589 (1, 2, 3)]
1590
Victor Stinnera2724092016-02-08 18:17:58 +01001591 code = '\n'.join(['x={!r}'.format(const) for const in consts])
1592 code += '\nx = ...'
1593 consts.extend((Ellipsis, None))
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001594
1595 tree = ast.parse(code)
Victor Stinnera2724092016-02-08 18:17:58 +01001596 self.assertEqual(self.get_load_const(tree),
1597 consts)
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001598
1599 # Replace expression nodes with constants
Victor Stinnera2724092016-02-08 18:17:58 +01001600 for assign, const in zip(tree.body, consts):
1601 assert isinstance(assign, ast.Assign), ast.dump(assign)
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001602 new_node = ast.Constant(value=const)
Victor Stinnera2724092016-02-08 18:17:58 +01001603 ast.copy_location(new_node, assign.value)
1604 assign.value = new_node
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001605
Victor Stinnera2724092016-02-08 18:17:58 +01001606 self.assertEqual(self.get_load_const(tree),
1607 consts)
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001608
1609 def test_literal_eval(self):
1610 tree = ast.parse("1 + 2")
1611 binop = tree.body[0].value
1612
1613 new_left = ast.Constant(value=10)
1614 ast.copy_location(new_left, binop.left)
1615 binop.left = new_left
1616
Serhiy Storchakad8ac4d12018-01-04 11:15:39 +02001617 new_right = ast.Constant(value=20j)
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001618 ast.copy_location(new_right, binop.right)
1619 binop.right = new_right
1620
Serhiy Storchakad8ac4d12018-01-04 11:15:39 +02001621 self.assertEqual(ast.literal_eval(binop), 10+20j)
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001622
Guido van Rossum10f8ce62019-03-13 13:00:46 -07001623 def test_string_kind(self):
1624 c = ast.parse('"x"', mode='eval').body
1625 self.assertEqual(c.value, "x")
1626 self.assertEqual(c.kind, None)
1627
1628 c = ast.parse('u"x"', mode='eval').body
1629 self.assertEqual(c.value, "x")
1630 self.assertEqual(c.kind, "u")
1631
1632 c = ast.parse('r"x"', mode='eval').body
1633 self.assertEqual(c.value, "x")
1634 self.assertEqual(c.kind, None)
1635
1636 c = ast.parse('b"x"', mode='eval').body
1637 self.assertEqual(c.value, b"x")
1638 self.assertEqual(c.kind, None)
1639
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001640
Ivan Levkivskyi9932a222019-01-22 11:18:22 +00001641class EndPositionTests(unittest.TestCase):
1642 """Tests for end position of AST nodes.
1643
1644 Testing end positions of nodes requires a bit of extra care
1645 because of how LL parsers work.
1646 """
1647 def _check_end_pos(self, ast_node, end_lineno, end_col_offset):
1648 self.assertEqual(ast_node.end_lineno, end_lineno)
1649 self.assertEqual(ast_node.end_col_offset, end_col_offset)
1650
1651 def _check_content(self, source, ast_node, content):
1652 self.assertEqual(ast.get_source_segment(source, ast_node), content)
1653
1654 def _parse_value(self, s):
1655 # Use duck-typing to support both single expression
1656 # and a right hand side of an assignment statement.
1657 return ast.parse(s).body[0].value
1658
1659 def test_lambda(self):
1660 s = 'lambda x, *y: None'
1661 lam = self._parse_value(s)
1662 self._check_content(s, lam.body, 'None')
1663 self._check_content(s, lam.args.args[0], 'x')
1664 self._check_content(s, lam.args.vararg, 'y')
1665
1666 def test_func_def(self):
1667 s = dedent('''
1668 def func(x: int,
1669 *args: str,
1670 z: float = 0,
1671 **kwargs: Any) -> bool:
1672 return True
1673 ''').strip()
1674 fdef = ast.parse(s).body[0]
1675 self._check_end_pos(fdef, 5, 15)
1676 self._check_content(s, fdef.body[0], 'return True')
1677 self._check_content(s, fdef.args.args[0], 'x: int')
1678 self._check_content(s, fdef.args.args[0].annotation, 'int')
1679 self._check_content(s, fdef.args.kwarg, 'kwargs: Any')
1680 self._check_content(s, fdef.args.kwarg.annotation, 'Any')
1681
1682 def test_call(self):
1683 s = 'func(x, y=2, **kw)'
1684 call = self._parse_value(s)
1685 self._check_content(s, call.func, 'func')
1686 self._check_content(s, call.keywords[0].value, '2')
1687 self._check_content(s, call.keywords[1].value, 'kw')
1688
1689 def test_call_noargs(self):
1690 s = 'x[0]()'
1691 call = self._parse_value(s)
1692 self._check_content(s, call.func, 'x[0]')
1693 self._check_end_pos(call, 1, 6)
1694
1695 def test_class_def(self):
1696 s = dedent('''
1697 class C(A, B):
1698 x: int = 0
1699 ''').strip()
1700 cdef = ast.parse(s).body[0]
1701 self._check_end_pos(cdef, 2, 14)
1702 self._check_content(s, cdef.bases[1], 'B')
1703 self._check_content(s, cdef.body[0], 'x: int = 0')
1704
1705 def test_class_kw(self):
1706 s = 'class S(metaclass=abc.ABCMeta): pass'
1707 cdef = ast.parse(s).body[0]
1708 self._check_content(s, cdef.keywords[0].value, 'abc.ABCMeta')
1709
1710 def test_multi_line_str(self):
1711 s = dedent('''
1712 x = """Some multi-line text.
1713
1714 It goes on starting from same indent."""
1715 ''').strip()
1716 assign = ast.parse(s).body[0]
1717 self._check_end_pos(assign, 3, 40)
1718 self._check_end_pos(assign.value, 3, 40)
1719
1720 def test_continued_str(self):
1721 s = dedent('''
1722 x = "first part" \\
1723 "second part"
1724 ''').strip()
1725 assign = ast.parse(s).body[0]
1726 self._check_end_pos(assign, 2, 13)
1727 self._check_end_pos(assign.value, 2, 13)
1728
1729 def test_suites(self):
1730 # We intentionally put these into the same string to check
1731 # that empty lines are not part of the suite.
1732 s = dedent('''
1733 while True:
1734 pass
1735
1736 if one():
1737 x = None
1738 elif other():
1739 y = None
1740 else:
1741 z = None
1742
1743 for x, y in stuff:
1744 assert True
1745
1746 try:
1747 raise RuntimeError
1748 except TypeError as e:
1749 pass
1750
1751 pass
1752 ''').strip()
1753 mod = ast.parse(s)
1754 while_loop = mod.body[0]
1755 if_stmt = mod.body[1]
1756 for_loop = mod.body[2]
1757 try_stmt = mod.body[3]
1758 pass_stmt = mod.body[4]
1759
1760 self._check_end_pos(while_loop, 2, 8)
1761 self._check_end_pos(if_stmt, 9, 12)
1762 self._check_end_pos(for_loop, 12, 15)
1763 self._check_end_pos(try_stmt, 17, 8)
1764 self._check_end_pos(pass_stmt, 19, 4)
1765
1766 self._check_content(s, while_loop.test, 'True')
1767 self._check_content(s, if_stmt.body[0], 'x = None')
1768 self._check_content(s, if_stmt.orelse[0].test, 'other()')
1769 self._check_content(s, for_loop.target, 'x, y')
1770 self._check_content(s, try_stmt.body[0], 'raise RuntimeError')
1771 self._check_content(s, try_stmt.handlers[0].type, 'TypeError')
1772
1773 def test_fstring(self):
1774 s = 'x = f"abc {x + y} abc"'
1775 fstr = self._parse_value(s)
1776 binop = fstr.values[1].value
1777 self._check_content(s, binop, 'x + y')
1778
1779 def test_fstring_multi_line(self):
1780 s = dedent('''
1781 f"""Some multi-line text.
1782 {
1783 arg_one
1784 +
1785 arg_two
1786 }
1787 It goes on..."""
1788 ''').strip()
1789 fstr = self._parse_value(s)
1790 binop = fstr.values[1].value
1791 self._check_end_pos(binop, 5, 7)
1792 self._check_content(s, binop.left, 'arg_one')
1793 self._check_content(s, binop.right, 'arg_two')
1794
1795 def test_import_from_multi_line(self):
1796 s = dedent('''
1797 from x.y.z import (
1798 a, b, c as c
1799 )
1800 ''').strip()
1801 imp = ast.parse(s).body[0]
1802 self._check_end_pos(imp, 3, 1)
Matthew Suozzo75a06f02021-04-10 16:56:28 -04001803 self._check_end_pos(imp.names[2], 2, 16)
Ivan Levkivskyi9932a222019-01-22 11:18:22 +00001804
1805 def test_slices(self):
1806 s1 = 'f()[1, 2] [0]'
1807 s2 = 'x[ a.b: c.d]'
1808 sm = dedent('''
1809 x[ a.b: f () ,
1810 g () : c.d
1811 ]
1812 ''').strip()
1813 i1, i2, im = map(self._parse_value, (s1, s2, sm))
1814 self._check_content(s1, i1.value, 'f()[1, 2]')
Serhiy Storchaka13d52c22020-03-10 18:52:34 +02001815 self._check_content(s1, i1.value.slice, '1, 2')
Ivan Levkivskyi9932a222019-01-22 11:18:22 +00001816 self._check_content(s2, i2.slice.lower, 'a.b')
1817 self._check_content(s2, i2.slice.upper, 'c.d')
Serhiy Storchaka13d52c22020-03-10 18:52:34 +02001818 self._check_content(sm, im.slice.elts[0].upper, 'f ()')
1819 self._check_content(sm, im.slice.elts[1].lower, 'g ()')
Ivan Levkivskyi9932a222019-01-22 11:18:22 +00001820 self._check_end_pos(im, 3, 3)
1821
1822 def test_binop(self):
1823 s = dedent('''
1824 (1 * 2 + (3 ) +
1825 4
1826 )
1827 ''').strip()
1828 binop = self._parse_value(s)
1829 self._check_end_pos(binop, 2, 6)
1830 self._check_content(s, binop.right, '4')
1831 self._check_content(s, binop.left, '1 * 2 + (3 )')
1832 self._check_content(s, binop.left.right, '3')
1833
1834 def test_boolop(self):
1835 s = dedent('''
1836 if (one_condition and
1837 (other_condition or yet_another_one)):
1838 pass
1839 ''').strip()
1840 bop = ast.parse(s).body[0].test
1841 self._check_end_pos(bop, 2, 44)
1842 self._check_content(s, bop.values[1],
1843 'other_condition or yet_another_one')
1844
1845 def test_tuples(self):
1846 s1 = 'x = () ;'
1847 s2 = 'x = 1 , ;'
1848 s3 = 'x = (1 , 2 ) ;'
1849 sm = dedent('''
1850 x = (
1851 a, b,
1852 )
1853 ''').strip()
1854 t1, t2, t3, tm = map(self._parse_value, (s1, s2, s3, sm))
1855 self._check_content(s1, t1, '()')
1856 self._check_content(s2, t2, '1 ,')
1857 self._check_content(s3, t3, '(1 , 2 )')
1858 self._check_end_pos(tm, 3, 1)
1859
1860 def test_attribute_spaces(self):
1861 s = 'func(x. y .z)'
1862 call = self._parse_value(s)
1863 self._check_content(s, call, s)
1864 self._check_content(s, call.args[0], 'x. y .z')
1865
Serhiy Storchaka6e619c42020-02-12 22:37:49 +02001866 def test_redundant_parenthesis(self):
1867 s = '( ( ( a + b ) ) )'
1868 v = ast.parse(s).body[0].value
1869 self.assertEqual(type(v).__name__, 'BinOp')
1870 self._check_content(s, v, 'a + b')
1871 s2 = 'await ' + s
1872 v = ast.parse(s2).body[0].value.value
1873 self.assertEqual(type(v).__name__, 'BinOp')
1874 self._check_content(s2, v, 'a + b')
1875
1876 def test_trailers_with_redundant_parenthesis(self):
1877 tests = (
1878 ('( ( ( a ) ) ) ( )', 'Call'),
1879 ('( ( ( a ) ) ) ( b )', 'Call'),
1880 ('( ( ( a ) ) ) [ b ]', 'Subscript'),
1881 ('( ( ( a ) ) ) . b', 'Attribute'),
1882 )
1883 for s, t in tests:
1884 with self.subTest(s):
1885 v = ast.parse(s).body[0].value
1886 self.assertEqual(type(v).__name__, t)
1887 self._check_content(s, v, s)
1888 s2 = 'await ' + s
1889 v = ast.parse(s2).body[0].value.value
1890 self.assertEqual(type(v).__name__, t)
1891 self._check_content(s2, v, s)
1892
Ivan Levkivskyi9932a222019-01-22 11:18:22 +00001893 def test_displays(self):
1894 s1 = '[{}, {1, }, {1, 2,} ]'
1895 s2 = '{a: b, f (): g () ,}'
1896 c1 = self._parse_value(s1)
1897 c2 = self._parse_value(s2)
1898 self._check_content(s1, c1.elts[0], '{}')
1899 self._check_content(s1, c1.elts[1], '{1, }')
1900 self._check_content(s1, c1.elts[2], '{1, 2,}')
1901 self._check_content(s2, c2.keys[1], 'f ()')
1902 self._check_content(s2, c2.values[1], 'g ()')
1903
1904 def test_comprehensions(self):
1905 s = dedent('''
1906 x = [{x for x, y in stuff
1907 if cond.x} for stuff in things]
1908 ''').strip()
1909 cmp = self._parse_value(s)
1910 self._check_end_pos(cmp, 2, 37)
1911 self._check_content(s, cmp.generators[0].iter, 'things')
1912 self._check_content(s, cmp.elt.generators[0].iter, 'stuff')
1913 self._check_content(s, cmp.elt.generators[0].ifs[0], 'cond.x')
1914 self._check_content(s, cmp.elt.generators[0].target, 'x, y')
1915
1916 def test_yield_await(self):
1917 s = dedent('''
1918 async def f():
1919 yield x
1920 await y
1921 ''').strip()
1922 fdef = ast.parse(s).body[0]
1923 self._check_content(s, fdef.body[0].value, 'yield x')
1924 self._check_content(s, fdef.body[1].value, 'await y')
1925
1926 def test_source_segment_multi(self):
1927 s_orig = dedent('''
1928 x = (
1929 a, b,
1930 ) + ()
1931 ''').strip()
1932 s_tuple = dedent('''
1933 (
1934 a, b,
1935 )
1936 ''').strip()
1937 binop = self._parse_value(s_orig)
1938 self.assertEqual(ast.get_source_segment(s_orig, binop.left), s_tuple)
1939
1940 def test_source_segment_padded(self):
1941 s_orig = dedent('''
1942 class C:
1943 def fun(self) -> None:
1944 "Đ–Đ–Đ–Đ–Đ–"
1945 ''').strip()
1946 s_method = ' def fun(self) -> None:\n' \
1947 ' "Đ–Đ–Đ–Đ–Đ–"'
1948 cdef = ast.parse(s_orig).body[0]
1949 self.assertEqual(ast.get_source_segment(s_orig, cdef.body[0], padded=True),
1950 s_method)
1951
1952 def test_source_segment_endings(self):
1953 s = 'v = 1\r\nw = 1\nx = 1\n\ry = 1\rz = 1\r\n'
1954 v, w, x, y, z = ast.parse(s).body
1955 self._check_content(s, v, 'v = 1')
1956 self._check_content(s, w, 'w = 1')
1957 self._check_content(s, x, 'x = 1')
1958 self._check_content(s, y, 'y = 1')
1959 self._check_content(s, z, 'z = 1')
1960
1961 def test_source_segment_tabs(self):
1962 s = dedent('''
1963 class C:
1964 \t\f def fun(self) -> None:
1965 \t\f pass
1966 ''').strip()
1967 s_method = ' \t\f def fun(self) -> None:\n' \
1968 ' \t\f pass'
1969
1970 cdef = ast.parse(s).body[0]
1971 self.assertEqual(ast.get_source_segment(s, cdef.body[0], padded=True), s_method)
1972
Irit Katriele6578a22020-05-18 19:14:12 +01001973 def test_source_segment_missing_info(self):
1974 s = 'v = 1\r\nw = 1\nx = 1\n\ry = 1\r\n'
1975 v, w, x, y = ast.parse(s).body
1976 del v.lineno
1977 del w.end_lineno
1978 del x.col_offset
1979 del y.end_col_offset
1980 self.assertIsNone(ast.get_source_segment(s, v))
1981 self.assertIsNone(ast.get_source_segment(s, w))
1982 self.assertIsNone(ast.get_source_segment(s, x))
1983 self.assertIsNone(ast.get_source_segment(s, y))
Ivan Levkivskyi9932a222019-01-22 11:18:22 +00001984
Serhiy Storchakac3ea41e2019-08-26 10:13:19 +03001985class NodeVisitorTests(unittest.TestCase):
1986 def test_old_constant_nodes(self):
1987 class Visitor(ast.NodeVisitor):
1988 def visit_Num(self, node):
1989 log.append((node.lineno, 'Num', node.n))
1990 def visit_Str(self, node):
1991 log.append((node.lineno, 'Str', node.s))
1992 def visit_Bytes(self, node):
1993 log.append((node.lineno, 'Bytes', node.s))
1994 def visit_NameConstant(self, node):
1995 log.append((node.lineno, 'NameConstant', node.value))
1996 def visit_Ellipsis(self, node):
1997 log.append((node.lineno, 'Ellipsis', ...))
1998 mod = ast.parse(dedent('''\
1999 i = 42
2000 f = 4.25
2001 c = 4.25j
2002 s = 'string'
2003 b = b'bytes'
2004 t = True
2005 n = None
2006 e = ...
2007 '''))
2008 visitor = Visitor()
2009 log = []
2010 with warnings.catch_warnings(record=True) as wlog:
2011 warnings.filterwarnings('always', '', DeprecationWarning)
2012 visitor.visit(mod)
2013 self.assertEqual(log, [
2014 (1, 'Num', 42),
2015 (2, 'Num', 4.25),
2016 (3, 'Num', 4.25j),
2017 (4, 'Str', 'string'),
2018 (5, 'Bytes', b'bytes'),
2019 (6, 'NameConstant', True),
2020 (7, 'NameConstant', None),
2021 (8, 'Ellipsis', ...),
2022 ])
2023 self.assertEqual([str(w.message) for w in wlog], [
2024 'visit_Num is deprecated; add visit_Constant',
2025 'visit_Num is deprecated; add visit_Constant',
2026 'visit_Num is deprecated; add visit_Constant',
2027 'visit_Str is deprecated; add visit_Constant',
2028 'visit_Bytes is deprecated; add visit_Constant',
2029 'visit_NameConstant is deprecated; add visit_Constant',
2030 'visit_NameConstant is deprecated; add visit_Constant',
2031 'visit_Ellipsis is deprecated; add visit_Constant',
2032 ])
2033
2034
Victor Stinnere5fbe0c2020-09-15 18:03:34 +02002035@support.cpython_only
2036class ModuleStateTests(unittest.TestCase):
2037 # bpo-41194, bpo-41261, bpo-41631: The _ast module uses a global state.
2038
2039 def check_ast_module(self):
2040 # Check that the _ast module still works as expected
2041 code = 'x + 1'
2042 filename = '<string>'
2043 mode = 'eval'
2044
2045 # Create _ast.AST subclasses instances
2046 ast_tree = compile(code, filename, mode, flags=ast.PyCF_ONLY_AST)
2047
2048 # Call PyAST_Check()
2049 code = compile(ast_tree, filename, mode)
2050 self.assertIsInstance(code, types.CodeType)
2051
2052 def test_reload_module(self):
2053 # bpo-41194: Importing the _ast module twice must not crash.
2054 with support.swap_item(sys.modules, '_ast', None):
2055 del sys.modules['_ast']
2056 import _ast as ast1
2057
2058 del sys.modules['_ast']
2059 import _ast as ast2
2060
2061 self.check_ast_module()
2062
2063 # Unloading the two _ast module instances must not crash.
2064 del ast1
2065 del ast2
2066 support.gc_collect()
2067
2068 self.check_ast_module()
2069
2070 def test_sys_modules(self):
2071 # bpo-41631: Test reproducing a Mercurial crash when PyAST_Check()
2072 # imported the _ast module internally.
2073 lazy_mod = object()
2074
2075 def my_import(name, *args, **kw):
2076 sys.modules[name] = lazy_mod
2077 return lazy_mod
2078
2079 with support.swap_item(sys.modules, '_ast', None):
2080 del sys.modules['_ast']
2081
2082 with support.swap_attr(builtins, '__import__', my_import):
2083 # Test that compile() does not import the _ast module
2084 self.check_ast_module()
2085 self.assertNotIn('_ast', sys.modules)
2086
2087 # Sanity check of the test itself
2088 import _ast
2089 self.assertIs(_ast, lazy_mod)
2090
2091 def test_subinterpreter(self):
2092 # bpo-41631: Importing and using the _ast module in a subinterpreter
2093 # must not crash.
2094 code = dedent('''
2095 import _ast
2096 import ast
2097 import gc
2098 import sys
2099 import types
2100
2101 # Create _ast.AST subclasses instances and call PyAST_Check()
2102 ast_tree = compile('x+1', '<string>', 'eval',
2103 flags=ast.PyCF_ONLY_AST)
2104 code = compile(ast_tree, 'string', 'eval')
2105 if not isinstance(code, types.CodeType):
2106 raise AssertionError
2107
2108 # Unloading the _ast module must not crash.
2109 del ast, _ast
2110 del sys.modules['ast'], sys.modules['_ast']
2111 gc.collect()
2112 ''')
2113 res = support.run_in_subinterp(code)
2114 self.assertEqual(res, 0)
2115
2116
Neal Norwitzee9b10a2008-03-31 05:29:39 +00002117def main():
2118 if __name__ != '__main__':
Martin v. Löwis49c5da12006-03-01 22:49:05 +00002119 return
Neal Norwitzee9b10a2008-03-31 05:29:39 +00002120 if sys.argv[1:] == ['-g']:
2121 for statements, kind in ((exec_tests, "exec"), (single_tests, "single"),
2122 (eval_tests, "eval")):
2123 print(kind+"_results = [")
Victor Stinnerf0891962016-02-08 17:15:21 +01002124 for statement in statements:
2125 tree = ast.parse(statement, "?", kind)
2126 print("%r," % (to_tuple(tree),))
Neal Norwitzee9b10a2008-03-31 05:29:39 +00002127 print("]")
2128 print("main()")
2129 raise SystemExit
Brett Cannon3e9a9ae2013-06-12 21:25:59 -04002130 unittest.main()
Tim Peters400cbc32006-02-28 18:44:41 +00002131
Guido van Rossumdcfcd142019-01-31 03:40:27 -08002132#### EVERYTHING BELOW IS GENERATED BY python Lib/test/test_ast.py -g #####
Tim Peters400cbc32006-02-28 18:44:41 +00002133exec_results = [
Serhiy Storchaka850a8852020-01-10 10:12:55 +02002134('Module', [('Expr', (1, 0, 1, 4), ('Constant', (1, 0, 1, 4), None, None))], []),
2135('Module', [('Expr', (1, 0, 1, 18), ('Constant', (1, 0, 1, 18), 'module docstring', None))], []),
2136('Module', [('FunctionDef', (1, 0, 1, 13), 'f', ('arguments', [], [], None, [], [], None, []), [('Pass', (1, 9, 1, 13))], [], None, None)], []),
2137('Module', [('FunctionDef', (1, 0, 1, 29), 'f', ('arguments', [], [], None, [], [], None, []), [('Expr', (1, 9, 1, 29), ('Constant', (1, 9, 1, 29), 'function docstring', None))], [], None, None)], []),
2138('Module', [('FunctionDef', (1, 0, 1, 14), 'f', ('arguments', [], [('arg', (1, 6, 1, 7), 'a', None, None)], None, [], [], None, []), [('Pass', (1, 10, 1, 14))], [], None, None)], []),
2139('Module', [('FunctionDef', (1, 0, 1, 16), 'f', ('arguments', [], [('arg', (1, 6, 1, 7), 'a', None, None)], None, [], [], None, [('Constant', (1, 8, 1, 9), 0, None)]), [('Pass', (1, 12, 1, 16))], [], None, None)], []),
2140('Module', [('FunctionDef', (1, 0, 1, 18), 'f', ('arguments', [], [], ('arg', (1, 7, 1, 11), 'args', None, None), [], [], None, []), [('Pass', (1, 14, 1, 18))], [], None, None)], []),
2141('Module', [('FunctionDef', (1, 0, 1, 21), 'f', ('arguments', [], [], None, [], [], ('arg', (1, 8, 1, 14), 'kwargs', None, None), []), [('Pass', (1, 17, 1, 21))], [], None, None)], []),
2142('Module', [('FunctionDef', (1, 0, 1, 71), 'f', ('arguments', [], [('arg', (1, 6, 1, 7), 'a', None, None), ('arg', (1, 9, 1, 10), 'b', None, None), ('arg', (1, 14, 1, 15), 'c', None, None), ('arg', (1, 22, 1, 23), 'd', None, None), ('arg', (1, 28, 1, 29), 'e', None, None)], ('arg', (1, 35, 1, 39), 'args', None, None), [('arg', (1, 41, 1, 42), 'f', None, None)], [('Constant', (1, 43, 1, 45), 42, None)], ('arg', (1, 49, 1, 55), 'kwargs', None, None), [('Constant', (1, 11, 1, 12), 1, None), ('Constant', (1, 16, 1, 20), None, None), ('List', (1, 24, 1, 26), [], ('Load',)), ('Dict', (1, 30, 1, 32), [], [])]), [('Expr', (1, 58, 1, 71), ('Constant', (1, 58, 1, 71), 'doc for f()', None))], [], None, None)], []),
2143('Module', [('ClassDef', (1, 0, 1, 12), 'C', [], [], [('Pass', (1, 8, 1, 12))], [])], []),
2144('Module', [('ClassDef', (1, 0, 1, 32), 'C', [], [], [('Expr', (1, 9, 1, 32), ('Constant', (1, 9, 1, 32), 'docstring for class C', None))], [])], []),
2145('Module', [('ClassDef', (1, 0, 1, 21), 'C', [('Name', (1, 8, 1, 14), 'object', ('Load',))], [], [('Pass', (1, 17, 1, 21))], [])], []),
2146('Module', [('FunctionDef', (1, 0, 1, 16), 'f', ('arguments', [], [], None, [], [], None, []), [('Return', (1, 8, 1, 16), ('Constant', (1, 15, 1, 16), 1, None))], [], None, None)], []),
2147('Module', [('Delete', (1, 0, 1, 5), [('Name', (1, 4, 1, 5), 'v', ('Del',))])], []),
2148('Module', [('Assign', (1, 0, 1, 5), [('Name', (1, 0, 1, 1), 'v', ('Store',))], ('Constant', (1, 4, 1, 5), 1, None), None)], []),
2149('Module', [('Assign', (1, 0, 1, 7), [('Tuple', (1, 0, 1, 3), [('Name', (1, 0, 1, 1), 'a', ('Store',)), ('Name', (1, 2, 1, 3), 'b', ('Store',))], ('Store',))], ('Name', (1, 6, 1, 7), 'c', ('Load',)), None)], []),
2150('Module', [('Assign', (1, 0, 1, 9), [('Tuple', (1, 0, 1, 5), [('Name', (1, 1, 1, 2), 'a', ('Store',)), ('Name', (1, 3, 1, 4), 'b', ('Store',))], ('Store',))], ('Name', (1, 8, 1, 9), 'c', ('Load',)), None)], []),
2151('Module', [('Assign', (1, 0, 1, 9), [('List', (1, 0, 1, 5), [('Name', (1, 1, 1, 2), 'a', ('Store',)), ('Name', (1, 3, 1, 4), 'b', ('Store',))], ('Store',))], ('Name', (1, 8, 1, 9), 'c', ('Load',)), None)], []),
2152('Module', [('AugAssign', (1, 0, 1, 6), ('Name', (1, 0, 1, 1), 'v', ('Store',)), ('Add',), ('Constant', (1, 5, 1, 6), 1, None))], []),
2153('Module', [('For', (1, 0, 1, 15), ('Name', (1, 4, 1, 5), 'v', ('Store',)), ('Name', (1, 9, 1, 10), 'v', ('Load',)), [('Pass', (1, 11, 1, 15))], [], None)], []),
2154('Module', [('While', (1, 0, 1, 12), ('Name', (1, 6, 1, 7), 'v', ('Load',)), [('Pass', (1, 8, 1, 12))], [])], []),
2155('Module', [('If', (1, 0, 1, 9), ('Name', (1, 3, 1, 4), 'v', ('Load',)), [('Pass', (1, 5, 1, 9))], [])], []),
2156('Module', [('If', (1, 0, 4, 6), ('Name', (1, 3, 1, 4), 'a', ('Load',)), [('Pass', (2, 2, 2, 6))], [('If', (3, 0, 4, 6), ('Name', (3, 5, 3, 6), 'b', ('Load',)), [('Pass', (4, 2, 4, 6))], [])])], []),
2157('Module', [('If', (1, 0, 6, 6), ('Name', (1, 3, 1, 4), 'a', ('Load',)), [('Pass', (2, 2, 2, 6))], [('If', (3, 0, 6, 6), ('Name', (3, 5, 3, 6), 'b', ('Load',)), [('Pass', (4, 2, 4, 6))], [('Pass', (6, 2, 6, 6))])])], []),
2158('Module', [('With', (1, 0, 1, 17), [('withitem', ('Name', (1, 5, 1, 6), 'x', ('Load',)), ('Name', (1, 10, 1, 11), 'y', ('Store',)))], [('Pass', (1, 13, 1, 17))], None)], []),
2159('Module', [('With', (1, 0, 1, 25), [('withitem', ('Name', (1, 5, 1, 6), 'x', ('Load',)), ('Name', (1, 10, 1, 11), 'y', ('Store',))), ('withitem', ('Name', (1, 13, 1, 14), 'z', ('Load',)), ('Name', (1, 18, 1, 19), 'q', ('Store',)))], [('Pass', (1, 21, 1, 25))], None)], []),
2160('Module', [('Raise', (1, 0, 1, 25), ('Call', (1, 6, 1, 25), ('Name', (1, 6, 1, 15), 'Exception', ('Load',)), [('Constant', (1, 16, 1, 24), 'string', None)], []), None)], []),
2161('Module', [('Try', (1, 0, 4, 6), [('Pass', (2, 2, 2, 6))], [('ExceptHandler', (3, 0, 4, 6), ('Name', (3, 7, 3, 16), 'Exception', ('Load',)), None, [('Pass', (4, 2, 4, 6))])], [], [])], []),
2162('Module', [('Try', (1, 0, 4, 6), [('Pass', (2, 2, 2, 6))], [], [], [('Pass', (4, 2, 4, 6))])], []),
2163('Module', [('Assert', (1, 0, 1, 8), ('Name', (1, 7, 1, 8), 'v', ('Load',)), None)], []),
Matthew Suozzo75a06f02021-04-10 16:56:28 -04002164('Module', [('Import', (1, 0, 1, 10), [('alias', (1, 7, 1, 10), 'sys', None)])], []),
2165('Module', [('ImportFrom', (1, 0, 1, 17), 'sys', [('alias', (1, 16, 1, 17), 'v', None)], 0)], []),
Serhiy Storchaka850a8852020-01-10 10:12:55 +02002166('Module', [('Global', (1, 0, 1, 8), ['v'])], []),
2167('Module', [('Expr', (1, 0, 1, 1), ('Constant', (1, 0, 1, 1), 1, None))], []),
2168('Module', [('Pass', (1, 0, 1, 4))], []),
2169('Module', [('For', (1, 0, 1, 16), ('Name', (1, 4, 1, 5), 'v', ('Store',)), ('Name', (1, 9, 1, 10), 'v', ('Load',)), [('Break', (1, 11, 1, 16))], [], None)], []),
2170('Module', [('For', (1, 0, 1, 19), ('Name', (1, 4, 1, 5), 'v', ('Store',)), ('Name', (1, 9, 1, 10), 'v', ('Load',)), [('Continue', (1, 11, 1, 19))], [], None)], []),
2171('Module', [('For', (1, 0, 1, 18), ('Tuple', (1, 4, 1, 7), [('Name', (1, 4, 1, 5), 'a', ('Store',)), ('Name', (1, 6, 1, 7), 'b', ('Store',))], ('Store',)), ('Name', (1, 11, 1, 12), 'c', ('Load',)), [('Pass', (1, 14, 1, 18))], [], None)], []),
2172('Module', [('For', (1, 0, 1, 20), ('Tuple', (1, 4, 1, 9), [('Name', (1, 5, 1, 6), 'a', ('Store',)), ('Name', (1, 7, 1, 8), 'b', ('Store',))], ('Store',)), ('Name', (1, 13, 1, 14), 'c', ('Load',)), [('Pass', (1, 16, 1, 20))], [], None)], []),
2173('Module', [('For', (1, 0, 1, 20), ('List', (1, 4, 1, 9), [('Name', (1, 5, 1, 6), 'a', ('Store',)), ('Name', (1, 7, 1, 8), 'b', ('Store',))], ('Store',)), ('Name', (1, 13, 1, 14), 'c', ('Load',)), [('Pass', (1, 16, 1, 20))], [], None)], []),
2174('Module', [('Expr', (1, 0, 11, 5), ('GeneratorExp', (1, 0, 11, 5), ('Tuple', (2, 4, 6, 5), [('Name', (3, 4, 3, 6), 'Aa', ('Load',)), ('Name', (5, 7, 5, 9), 'Bb', ('Load',))], ('Load',)), [('comprehension', ('Tuple', (8, 4, 10, 6), [('Name', (8, 4, 8, 6), 'Aa', ('Store',)), ('Name', (10, 4, 10, 6), 'Bb', ('Store',))], ('Store',)), ('Name', (10, 10, 10, 12), 'Cc', ('Load',)), [], 0)]))], []),
2175('Module', [('Expr', (1, 0, 1, 34), ('DictComp', (1, 0, 1, 34), ('Name', (1, 1, 1, 2), 'a', ('Load',)), ('Name', (1, 5, 1, 6), 'b', ('Load',)), [('comprehension', ('Name', (1, 11, 1, 12), 'w', ('Store',)), ('Name', (1, 16, 1, 17), 'x', ('Load',)), [], 0), ('comprehension', ('Name', (1, 22, 1, 23), 'm', ('Store',)), ('Name', (1, 27, 1, 28), 'p', ('Load',)), [('Name', (1, 32, 1, 33), 'g', ('Load',))], 0)]))], []),
2176('Module', [('Expr', (1, 0, 1, 20), ('DictComp', (1, 0, 1, 20), ('Name', (1, 1, 1, 2), 'a', ('Load',)), ('Name', (1, 5, 1, 6), 'b', ('Load',)), [('comprehension', ('Tuple', (1, 11, 1, 14), [('Name', (1, 11, 1, 12), 'v', ('Store',)), ('Name', (1, 13, 1, 14), 'w', ('Store',))], ('Store',)), ('Name', (1, 18, 1, 19), 'x', ('Load',)), [], 0)]))], []),
2177('Module', [('Expr', (1, 0, 1, 19), ('SetComp', (1, 0, 1, 19), ('Name', (1, 1, 1, 2), 'r', ('Load',)), [('comprehension', ('Name', (1, 7, 1, 8), 'l', ('Store',)), ('Name', (1, 12, 1, 13), 'x', ('Load',)), [('Name', (1, 17, 1, 18), 'g', ('Load',))], 0)]))], []),
2178('Module', [('Expr', (1, 0, 1, 16), ('SetComp', (1, 0, 1, 16), ('Name', (1, 1, 1, 2), 'r', ('Load',)), [('comprehension', ('Tuple', (1, 7, 1, 10), [('Name', (1, 7, 1, 8), 'l', ('Store',)), ('Name', (1, 9, 1, 10), 'm', ('Store',))], ('Store',)), ('Name', (1, 14, 1, 15), 'x', ('Load',)), [], 0)]))], []),
2179('Module', [('AsyncFunctionDef', (1, 0, 3, 18), 'f', ('arguments', [], [], None, [], [], None, []), [('Expr', (2, 1, 2, 17), ('Constant', (2, 1, 2, 17), 'async function', None)), ('Expr', (3, 1, 3, 18), ('Await', (3, 1, 3, 18), ('Call', (3, 7, 3, 18), ('Name', (3, 7, 3, 16), 'something', ('Load',)), [], [])))], [], None, None)], []),
2180('Module', [('AsyncFunctionDef', (1, 0, 3, 8), 'f', ('arguments', [], [], None, [], [], None, []), [('AsyncFor', (2, 1, 3, 8), ('Name', (2, 11, 2, 12), 'e', ('Store',)), ('Name', (2, 16, 2, 17), 'i', ('Load',)), [('Expr', (2, 19, 2, 20), ('Constant', (2, 19, 2, 20), 1, None))], [('Expr', (3, 7, 3, 8), ('Constant', (3, 7, 3, 8), 2, None))], None)], [], None, None)], []),
2181('Module', [('AsyncFunctionDef', (1, 0, 2, 21), 'f', ('arguments', [], [], None, [], [], None, []), [('AsyncWith', (2, 1, 2, 21), [('withitem', ('Name', (2, 12, 2, 13), 'a', ('Load',)), ('Name', (2, 17, 2, 18), 'b', ('Store',)))], [('Expr', (2, 20, 2, 21), ('Constant', (2, 20, 2, 21), 1, None))], None)], [], None, None)], []),
2182('Module', [('Expr', (1, 0, 1, 14), ('Dict', (1, 0, 1, 14), [None, ('Constant', (1, 10, 1, 11), 2, None)], [('Dict', (1, 3, 1, 8), [('Constant', (1, 4, 1, 5), 1, None)], [('Constant', (1, 6, 1, 7), 2, None)]), ('Constant', (1, 12, 1, 13), 3, None)]))], []),
2183('Module', [('Expr', (1, 0, 1, 12), ('Set', (1, 0, 1, 12), [('Starred', (1, 1, 1, 8), ('Set', (1, 2, 1, 8), [('Constant', (1, 3, 1, 4), 1, None), ('Constant', (1, 6, 1, 7), 2, None)]), ('Load',)), ('Constant', (1, 10, 1, 11), 3, None)]))], []),
2184('Module', [('AsyncFunctionDef', (1, 0, 2, 21), 'f', ('arguments', [], [], None, [], [], None, []), [('Expr', (2, 1, 2, 21), ('ListComp', (2, 1, 2, 21), ('Name', (2, 2, 2, 3), 'i', ('Load',)), [('comprehension', ('Name', (2, 14, 2, 15), 'b', ('Store',)), ('Name', (2, 19, 2, 20), 'c', ('Load',)), [], 1)]))], [], None, None)], []),
2185('Module', [('FunctionDef', (4, 0, 4, 13), 'f', ('arguments', [], [], None, [], [], None, []), [('Pass', (4, 9, 4, 13))], [('Name', (1, 1, 1, 6), 'deco1', ('Load',)), ('Call', (2, 1, 2, 8), ('Name', (2, 1, 2, 6), 'deco2', ('Load',)), [], []), ('Call', (3, 1, 3, 9), ('Name', (3, 1, 3, 6), 'deco3', ('Load',)), [('Constant', (3, 7, 3, 8), 1, None)], [])], None, None)], []),
2186('Module', [('AsyncFunctionDef', (4, 0, 4, 19), 'f', ('arguments', [], [], None, [], [], None, []), [('Pass', (4, 15, 4, 19))], [('Name', (1, 1, 1, 6), 'deco1', ('Load',)), ('Call', (2, 1, 2, 8), ('Name', (2, 1, 2, 6), 'deco2', ('Load',)), [], []), ('Call', (3, 1, 3, 9), ('Name', (3, 1, 3, 6), 'deco3', ('Load',)), [('Constant', (3, 7, 3, 8), 1, None)], [])], None, None)], []),
2187('Module', [('ClassDef', (4, 0, 4, 13), 'C', [], [], [('Pass', (4, 9, 4, 13))], [('Name', (1, 1, 1, 6), 'deco1', ('Load',)), ('Call', (2, 1, 2, 8), ('Name', (2, 1, 2, 6), 'deco2', ('Load',)), [], []), ('Call', (3, 1, 3, 9), ('Name', (3, 1, 3, 6), 'deco3', ('Load',)), [('Constant', (3, 7, 3, 8), 1, None)], [])])], []),
2188('Module', [('FunctionDef', (2, 0, 2, 13), 'f', ('arguments', [], [], None, [], [], None, []), [('Pass', (2, 9, 2, 13))], [('Call', (1, 1, 1, 19), ('Name', (1, 1, 1, 5), 'deco', ('Load',)), [('GeneratorExp', (1, 5, 1, 19), ('Name', (1, 6, 1, 7), 'a', ('Load',)), [('comprehension', ('Name', (1, 12, 1, 13), 'a', ('Store',)), ('Name', (1, 17, 1, 18), 'b', ('Load',)), [], 0)])], [])], None, None)], []),
Lysandros Nikolaoud2e10982020-02-08 00:36:32 +01002189('Module', [('FunctionDef', (2, 0, 2, 13), 'f', ('arguments', [], [], None, [], [], None, []), [('Pass', (2, 9, 2, 13))], [('Attribute', (1, 1, 1, 6), ('Attribute', (1, 1, 1, 4), ('Name', (1, 1, 1, 2), 'a', ('Load',)), 'b', ('Load',)), 'c', ('Load',))], None, None)], []),
Serhiy Storchaka850a8852020-01-10 10:12:55 +02002190('Module', [('Expr', (1, 0, 1, 8), ('NamedExpr', (1, 1, 1, 7), ('Name', (1, 1, 1, 2), 'a', ('Store',)), ('Constant', (1, 6, 1, 7), 1, None)))], []),
2191('Module', [('FunctionDef', (1, 0, 1, 18), 'f', ('arguments', [('arg', (1, 6, 1, 7), 'a', None, None)], [], None, [], [], None, []), [('Pass', (1, 14, 1, 18))], [], None, None)], []),
2192('Module', [('FunctionDef', (1, 0, 1, 26), 'f', ('arguments', [('arg', (1, 6, 1, 7), 'a', None, None)], [('arg', (1, 12, 1, 13), 'c', None, None), ('arg', (1, 15, 1, 16), 'd', None, None), ('arg', (1, 18, 1, 19), 'e', None, None)], None, [], [], None, []), [('Pass', (1, 22, 1, 26))], [], None, None)], []),
2193('Module', [('FunctionDef', (1, 0, 1, 29), 'f', ('arguments', [('arg', (1, 6, 1, 7), 'a', None, None)], [('arg', (1, 12, 1, 13), 'c', None, None)], None, [('arg', (1, 18, 1, 19), 'd', None, None), ('arg', (1, 21, 1, 22), 'e', None, None)], [None, None], None, []), [('Pass', (1, 25, 1, 29))], [], None, None)], []),
2194('Module', [('FunctionDef', (1, 0, 1, 39), 'f', ('arguments', [('arg', (1, 6, 1, 7), 'a', None, None)], [('arg', (1, 12, 1, 13), 'c', None, None)], None, [('arg', (1, 18, 1, 19), 'd', None, None), ('arg', (1, 21, 1, 22), 'e', None, None)], [None, None], ('arg', (1, 26, 1, 32), 'kwargs', None, None), []), [('Pass', (1, 35, 1, 39))], [], None, None)], []),
2195('Module', [('FunctionDef', (1, 0, 1, 20), 'f', ('arguments', [('arg', (1, 6, 1, 7), 'a', None, None)], [], None, [], [], None, [('Constant', (1, 8, 1, 9), 1, None)]), [('Pass', (1, 16, 1, 20))], [], None, None)], []),
2196('Module', [('FunctionDef', (1, 0, 1, 29), 'f', ('arguments', [('arg', (1, 6, 1, 7), 'a', None, None)], [('arg', (1, 14, 1, 15), 'b', None, None), ('arg', (1, 19, 1, 20), 'c', None, None)], None, [], [], None, [('Constant', (1, 8, 1, 9), 1, None), ('Constant', (1, 16, 1, 17), 2, None), ('Constant', (1, 21, 1, 22), 4, None)]), [('Pass', (1, 25, 1, 29))], [], None, None)], []),
2197('Module', [('FunctionDef', (1, 0, 1, 32), 'f', ('arguments', [('arg', (1, 6, 1, 7), 'a', None, None)], [('arg', (1, 14, 1, 15), 'b', None, None)], None, [('arg', (1, 22, 1, 23), 'c', None, None)], [('Constant', (1, 24, 1, 25), 4, None)], None, [('Constant', (1, 8, 1, 9), 1, None), ('Constant', (1, 16, 1, 17), 2, None)]), [('Pass', (1, 28, 1, 32))], [], None, None)], []),
2198('Module', [('FunctionDef', (1, 0, 1, 30), 'f', ('arguments', [('arg', (1, 6, 1, 7), 'a', None, None)], [('arg', (1, 14, 1, 15), 'b', None, None)], None, [('arg', (1, 22, 1, 23), 'c', None, None)], [None], None, [('Constant', (1, 8, 1, 9), 1, None), ('Constant', (1, 16, 1, 17), 2, None)]), [('Pass', (1, 26, 1, 30))], [], None, None)], []),
2199('Module', [('FunctionDef', (1, 0, 1, 42), 'f', ('arguments', [('arg', (1, 6, 1, 7), 'a', None, None)], [('arg', (1, 14, 1, 15), 'b', None, None)], None, [('arg', (1, 22, 1, 23), 'c', None, None)], [('Constant', (1, 24, 1, 25), 4, None)], ('arg', (1, 29, 1, 35), 'kwargs', None, None), [('Constant', (1, 8, 1, 9), 1, None), ('Constant', (1, 16, 1, 17), 2, None)]), [('Pass', (1, 38, 1, 42))], [], None, None)], []),
2200('Module', [('FunctionDef', (1, 0, 1, 40), 'f', ('arguments', [('arg', (1, 6, 1, 7), 'a', None, None)], [('arg', (1, 14, 1, 15), 'b', None, None)], None, [('arg', (1, 22, 1, 23), 'c', None, None)], [None], ('arg', (1, 27, 1, 33), 'kwargs', None, None), [('Constant', (1, 8, 1, 9), 1, None), ('Constant', (1, 16, 1, 17), 2, None)]), [('Pass', (1, 36, 1, 40))], [], None, None)], []),
Tim Peters400cbc32006-02-28 18:44:41 +00002201]
2202single_results = [
Serhiy Storchaka850a8852020-01-10 10:12:55 +02002203('Interactive', [('Expr', (1, 0, 1, 3), ('BinOp', (1, 0, 1, 3), ('Constant', (1, 0, 1, 1), 1, None), ('Add',), ('Constant', (1, 2, 1, 3), 2, None)))]),
Tim Peters400cbc32006-02-28 18:44:41 +00002204]
2205eval_results = [
Serhiy Storchaka850a8852020-01-10 10:12:55 +02002206('Expression', ('Constant', (1, 0, 1, 4), None, None)),
2207('Expression', ('BoolOp', (1, 0, 1, 7), ('And',), [('Name', (1, 0, 1, 1), 'a', ('Load',)), ('Name', (1, 6, 1, 7), 'b', ('Load',))])),
2208('Expression', ('BinOp', (1, 0, 1, 5), ('Name', (1, 0, 1, 1), 'a', ('Load',)), ('Add',), ('Name', (1, 4, 1, 5), 'b', ('Load',)))),
2209('Expression', ('UnaryOp', (1, 0, 1, 5), ('Not',), ('Name', (1, 4, 1, 5), 'v', ('Load',)))),
2210('Expression', ('Lambda', (1, 0, 1, 11), ('arguments', [], [], None, [], [], None, []), ('Constant', (1, 7, 1, 11), None, None))),
2211('Expression', ('Dict', (1, 0, 1, 7), [('Constant', (1, 2, 1, 3), 1, None)], [('Constant', (1, 4, 1, 5), 2, None)])),
2212('Expression', ('Dict', (1, 0, 1, 2), [], [])),
2213('Expression', ('Set', (1, 0, 1, 7), [('Constant', (1, 1, 1, 5), None, None)])),
2214('Expression', ('Dict', (1, 0, 5, 6), [('Constant', (2, 6, 2, 7), 1, None)], [('Constant', (4, 10, 4, 11), 2, None)])),
2215('Expression', ('ListComp', (1, 0, 1, 19), ('Name', (1, 1, 1, 2), 'a', ('Load',)), [('comprehension', ('Name', (1, 7, 1, 8), 'b', ('Store',)), ('Name', (1, 12, 1, 13), 'c', ('Load',)), [('Name', (1, 17, 1, 18), 'd', ('Load',))], 0)])),
2216('Expression', ('GeneratorExp', (1, 0, 1, 19), ('Name', (1, 1, 1, 2), 'a', ('Load',)), [('comprehension', ('Name', (1, 7, 1, 8), 'b', ('Store',)), ('Name', (1, 12, 1, 13), 'c', ('Load',)), [('Name', (1, 17, 1, 18), 'd', ('Load',))], 0)])),
2217('Expression', ('ListComp', (1, 0, 1, 20), ('Tuple', (1, 1, 1, 6), [('Name', (1, 2, 1, 3), 'a', ('Load',)), ('Name', (1, 4, 1, 5), 'b', ('Load',))], ('Load',)), [('comprehension', ('Tuple', (1, 11, 1, 14), [('Name', (1, 11, 1, 12), 'a', ('Store',)), ('Name', (1, 13, 1, 14), 'b', ('Store',))], ('Store',)), ('Name', (1, 18, 1, 19), 'c', ('Load',)), [], 0)])),
2218('Expression', ('ListComp', (1, 0, 1, 22), ('Tuple', (1, 1, 1, 6), [('Name', (1, 2, 1, 3), 'a', ('Load',)), ('Name', (1, 4, 1, 5), 'b', ('Load',))], ('Load',)), [('comprehension', ('Tuple', (1, 11, 1, 16), [('Name', (1, 12, 1, 13), 'a', ('Store',)), ('Name', (1, 14, 1, 15), 'b', ('Store',))], ('Store',)), ('Name', (1, 20, 1, 21), 'c', ('Load',)), [], 0)])),
2219('Expression', ('ListComp', (1, 0, 1, 22), ('Tuple', (1, 1, 1, 6), [('Name', (1, 2, 1, 3), 'a', ('Load',)), ('Name', (1, 4, 1, 5), 'b', ('Load',))], ('Load',)), [('comprehension', ('List', (1, 11, 1, 16), [('Name', (1, 12, 1, 13), 'a', ('Store',)), ('Name', (1, 14, 1, 15), 'b', ('Store',))], ('Store',)), ('Name', (1, 20, 1, 21), 'c', ('Load',)), [], 0)])),
2220('Expression', ('SetComp', (1, 0, 1, 20), ('Tuple', (1, 1, 1, 6), [('Name', (1, 2, 1, 3), 'a', ('Load',)), ('Name', (1, 4, 1, 5), 'b', ('Load',))], ('Load',)), [('comprehension', ('Tuple', (1, 11, 1, 14), [('Name', (1, 11, 1, 12), 'a', ('Store',)), ('Name', (1, 13, 1, 14), 'b', ('Store',))], ('Store',)), ('Name', (1, 18, 1, 19), 'c', ('Load',)), [], 0)])),
2221('Expression', ('SetComp', (1, 0, 1, 22), ('Tuple', (1, 1, 1, 6), [('Name', (1, 2, 1, 3), 'a', ('Load',)), ('Name', (1, 4, 1, 5), 'b', ('Load',))], ('Load',)), [('comprehension', ('Tuple', (1, 11, 1, 16), [('Name', (1, 12, 1, 13), 'a', ('Store',)), ('Name', (1, 14, 1, 15), 'b', ('Store',))], ('Store',)), ('Name', (1, 20, 1, 21), 'c', ('Load',)), [], 0)])),
2222('Expression', ('SetComp', (1, 0, 1, 22), ('Tuple', (1, 1, 1, 6), [('Name', (1, 2, 1, 3), 'a', ('Load',)), ('Name', (1, 4, 1, 5), 'b', ('Load',))], ('Load',)), [('comprehension', ('List', (1, 11, 1, 16), [('Name', (1, 12, 1, 13), 'a', ('Store',)), ('Name', (1, 14, 1, 15), 'b', ('Store',))], ('Store',)), ('Name', (1, 20, 1, 21), 'c', ('Load',)), [], 0)])),
2223('Expression', ('GeneratorExp', (1, 0, 1, 20), ('Tuple', (1, 1, 1, 6), [('Name', (1, 2, 1, 3), 'a', ('Load',)), ('Name', (1, 4, 1, 5), 'b', ('Load',))], ('Load',)), [('comprehension', ('Tuple', (1, 11, 1, 14), [('Name', (1, 11, 1, 12), 'a', ('Store',)), ('Name', (1, 13, 1, 14), 'b', ('Store',))], ('Store',)), ('Name', (1, 18, 1, 19), 'c', ('Load',)), [], 0)])),
2224('Expression', ('GeneratorExp', (1, 0, 1, 22), ('Tuple', (1, 1, 1, 6), [('Name', (1, 2, 1, 3), 'a', ('Load',)), ('Name', (1, 4, 1, 5), 'b', ('Load',))], ('Load',)), [('comprehension', ('Tuple', (1, 11, 1, 16), [('Name', (1, 12, 1, 13), 'a', ('Store',)), ('Name', (1, 14, 1, 15), 'b', ('Store',))], ('Store',)), ('Name', (1, 20, 1, 21), 'c', ('Load',)), [], 0)])),
2225('Expression', ('GeneratorExp', (1, 0, 1, 22), ('Tuple', (1, 1, 1, 6), [('Name', (1, 2, 1, 3), 'a', ('Load',)), ('Name', (1, 4, 1, 5), 'b', ('Load',))], ('Load',)), [('comprehension', ('List', (1, 11, 1, 16), [('Name', (1, 12, 1, 13), 'a', ('Store',)), ('Name', (1, 14, 1, 15), 'b', ('Store',))], ('Store',)), ('Name', (1, 20, 1, 21), 'c', ('Load',)), [], 0)])),
2226('Expression', ('Compare', (1, 0, 1, 9), ('Constant', (1, 0, 1, 1), 1, None), [('Lt',), ('Lt',)], [('Constant', (1, 4, 1, 5), 2, None), ('Constant', (1, 8, 1, 9), 3, None)])),
Pablo Galindo40cf35c2020-04-03 21:02:26 +01002227('Expression', ('Call', (1, 0, 1, 17), ('Name', (1, 0, 1, 1), 'f', ('Load',)), [('Constant', (1, 2, 1, 3), 1, None), ('Constant', (1, 4, 1, 5), 2, None), ('Starred', (1, 10, 1, 12), ('Name', (1, 11, 1, 12), 'd', ('Load',)), ('Load',))], [('keyword', (1, 6, 1, 9), 'c', ('Constant', (1, 8, 1, 9), 3, None)), ('keyword', (1, 13, 1, 16), None, ('Name', (1, 15, 1, 16), 'e', ('Load',)))])),
Serhiy Storchaka850a8852020-01-10 10:12:55 +02002228('Expression', ('Call', (1, 0, 1, 10), ('Name', (1, 0, 1, 1), 'f', ('Load',)), [('Starred', (1, 2, 1, 9), ('List', (1, 3, 1, 9), [('Constant', (1, 4, 1, 5), 0, None), ('Constant', (1, 7, 1, 8), 1, None)], ('Load',)), ('Load',))], [])),
2229('Expression', ('Call', (1, 0, 1, 15), ('Name', (1, 0, 1, 1), 'f', ('Load',)), [('GeneratorExp', (1, 1, 1, 15), ('Name', (1, 2, 1, 3), 'a', ('Load',)), [('comprehension', ('Name', (1, 8, 1, 9), 'a', ('Store',)), ('Name', (1, 13, 1, 14), 'b', ('Load',)), [], 0)])], [])),
2230('Expression', ('Constant', (1, 0, 1, 2), 10, None)),
2231('Expression', ('Constant', (1, 0, 1, 8), 'string', None)),
2232('Expression', ('Attribute', (1, 0, 1, 3), ('Name', (1, 0, 1, 1), 'a', ('Load',)), 'b', ('Load',))),
Serhiy Storchaka13d52c22020-03-10 18:52:34 +02002233('Expression', ('Subscript', (1, 0, 1, 6), ('Name', (1, 0, 1, 1), 'a', ('Load',)), ('Slice', (1, 2, 1, 5), ('Name', (1, 2, 1, 3), 'b', ('Load',)), ('Name', (1, 4, 1, 5), 'c', ('Load',)), None), ('Load',))),
Serhiy Storchaka850a8852020-01-10 10:12:55 +02002234('Expression', ('Name', (1, 0, 1, 1), 'v', ('Load',))),
2235('Expression', ('List', (1, 0, 1, 7), [('Constant', (1, 1, 1, 2), 1, None), ('Constant', (1, 3, 1, 4), 2, None), ('Constant', (1, 5, 1, 6), 3, None)], ('Load',))),
2236('Expression', ('List', (1, 0, 1, 2), [], ('Load',))),
2237('Expression', ('Tuple', (1, 0, 1, 5), [('Constant', (1, 0, 1, 1), 1, None), ('Constant', (1, 2, 1, 3), 2, None), ('Constant', (1, 4, 1, 5), 3, None)], ('Load',))),
2238('Expression', ('Tuple', (1, 0, 1, 7), [('Constant', (1, 1, 1, 2), 1, None), ('Constant', (1, 3, 1, 4), 2, None), ('Constant', (1, 5, 1, 6), 3, None)], ('Load',))),
2239('Expression', ('Tuple', (1, 0, 1, 2), [], ('Load',))),
Serhiy Storchaka13d52c22020-03-10 18:52:34 +02002240('Expression', ('Call', (1, 0, 1, 17), ('Attribute', (1, 0, 1, 7), ('Attribute', (1, 0, 1, 5), ('Attribute', (1, 0, 1, 3), ('Name', (1, 0, 1, 1), 'a', ('Load',)), 'b', ('Load',)), 'c', ('Load',)), 'd', ('Load',)), [('Subscript', (1, 8, 1, 16), ('Attribute', (1, 8, 1, 11), ('Name', (1, 8, 1, 9), 'a', ('Load',)), 'b', ('Load',)), ('Slice', (1, 12, 1, 15), ('Constant', (1, 12, 1, 13), 1, None), ('Constant', (1, 14, 1, 15), 2, None), None), ('Load',))], [])),
Tim Peters400cbc32006-02-28 18:44:41 +00002241]
Neal Norwitzee9b10a2008-03-31 05:29:39 +00002242main()