blob: f5aef61ec6f7c037363a5e7016940ee763fbdb19 [file] [log] [blame]
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001import ast
2import dis
Benjamin Peterson832bfe22011-08-09 16:15:04 -05003import os
4import sys
5import unittest
Serhiy Storchakac3ea41e2019-08-26 10:13:19 +03006import warnings
Benjamin Peterson9ed37432012-07-08 11:13:36 -07007import weakref
Ivan Levkivskyi9932a222019-01-22 11:18:22 +00008from textwrap import dedent
Benjamin Peterson9ed37432012-07-08 11:13:36 -07009
10from test import support
Tim Peters400cbc32006-02-28 18:44:41 +000011
12def to_tuple(t):
Guido van Rossum3172c5d2007-10-16 18:12:55 +000013 if t is None or isinstance(t, (str, int, complex)):
Tim Peters400cbc32006-02-28 18:44:41 +000014 return t
15 elif isinstance(t, list):
16 return [to_tuple(e) for e in t]
17 result = [t.__class__.__name__]
Martin v. Löwis49c5da12006-03-01 22:49:05 +000018 if hasattr(t, 'lineno') and hasattr(t, 'col_offset'):
19 result.append((t.lineno, t.col_offset))
Serhiy Storchaka850a8852020-01-10 10:12:55 +020020 if hasattr(t, 'end_lineno') and hasattr(t, 'end_col_offset'):
21 result[-1] += (t.end_lineno, t.end_col_offset)
Tim Peters400cbc32006-02-28 18:44:41 +000022 if t._fields is None:
23 return tuple(result)
24 for f in t._fields:
25 result.append(to_tuple(getattr(t, f)))
26 return tuple(result)
27
Neal Norwitzee9b10a2008-03-31 05:29:39 +000028
Tim Peters400cbc32006-02-28 18:44:41 +000029# These tests are compiled through "exec"
Ezio Melotti85a86292013-08-17 16:57:41 +030030# There should be at least one test per statement
Tim Peters400cbc32006-02-28 18:44:41 +000031exec_tests = [
Benjamin Peterson6ccfe852011-06-27 17:46:06 -050032 # None
33 "None",
INADA Naokicb41b272017-02-23 00:31:59 +090034 # Module docstring
35 "'module docstring'",
Tim Peters400cbc32006-02-28 18:44:41 +000036 # FunctionDef
37 "def f(): pass",
INADA Naokicb41b272017-02-23 00:31:59 +090038 # FunctionDef with docstring
39 "def f(): 'function docstring'",
Benjamin Peterson6ccfe852011-06-27 17:46:06 -050040 # FunctionDef with arg
41 "def f(a): pass",
42 # FunctionDef with arg and default value
43 "def f(a=0): pass",
44 # FunctionDef with varargs
45 "def f(*args): pass",
46 # FunctionDef with kwargs
47 "def f(**kwargs): pass",
INADA Naokicb41b272017-02-23 00:31:59 +090048 # FunctionDef with all kind of args and docstring
49 "def f(a, b=1, c=None, d=[], e={}, *args, f=42, **kwargs): 'doc for f()'",
Tim Peters400cbc32006-02-28 18:44:41 +000050 # ClassDef
51 "class C:pass",
INADA Naokicb41b272017-02-23 00:31:59 +090052 # ClassDef with docstring
53 "class C: 'docstring for class C'",
Benjamin Peterson6ccfe852011-06-27 17:46:06 -050054 # ClassDef, new style class
55 "class C(object): pass",
Tim Peters400cbc32006-02-28 18:44:41 +000056 # Return
57 "def f():return 1",
58 # Delete
59 "del v",
60 # Assign
61 "v = 1",
Serhiy Storchakab619b092018-11-27 09:40:29 +020062 "a,b = c",
63 "(a,b) = c",
64 "[a,b] = c",
Tim Peters400cbc32006-02-28 18:44:41 +000065 # AugAssign
66 "v += 1",
Tim Peters400cbc32006-02-28 18:44:41 +000067 # For
68 "for v in v:pass",
69 # While
70 "while v:pass",
71 # If
72 "if v:pass",
Lysandros Nikolaou025a6022019-12-12 22:40:21 +010073 # If-Elif
74 "if a:\n pass\nelif b:\n pass",
Lysandros Nikolaou5936a4c2019-12-14 11:24:57 +010075 # If-Elif-Else
76 "if a:\n pass\nelif b:\n pass\nelse:\n pass",
Benjamin Petersonaeabd5f2011-05-27 15:02:03 -050077 # With
78 "with x as y: pass",
79 "with x as y, z as q: pass",
Tim Peters400cbc32006-02-28 18:44:41 +000080 # Raise
Collin Winter828f04a2007-08-31 00:04:24 +000081 "raise Exception('string')",
Tim Peters400cbc32006-02-28 18:44:41 +000082 # TryExcept
83 "try:\n pass\nexcept Exception:\n pass",
84 # TryFinally
85 "try:\n pass\nfinally:\n pass",
86 # Assert
87 "assert v",
88 # Import
89 "import sys",
90 # ImportFrom
91 "from sys import v",
Tim Peters400cbc32006-02-28 18:44:41 +000092 # Global
93 "global v",
94 # Expr
95 "1",
96 # Pass,
97 "pass",
98 # Break
Yury Selivanovb3d53132015-09-01 16:10:49 -040099 "for v in v:break",
Tim Peters400cbc32006-02-28 18:44:41 +0000100 # Continue
Yury Selivanovb3d53132015-09-01 16:10:49 -0400101 "for v in v:continue",
Benjamin Peterson2e4b0e12009-09-11 22:36:20 +0000102 # for statements with naked tuples (see http://bugs.python.org/issue6704)
103 "for a,b in c: pass",
Serhiy Storchakab619b092018-11-27 09:40:29 +0200104 "for (a,b) in c: pass",
105 "for [a,b] in c: pass",
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500106 # Multiline generator expression (test for .lineno & .col_offset)
107 """(
108 (
109 Aa
110 ,
111 Bb
112 )
113 for
114 Aa
115 ,
116 Bb in Cc
117 )""",
118 # dictcomp
119 "{a : b for w in x for m in p if g}",
120 # dictcomp with naked tuple
121 "{a : b for v,w in x}",
122 # setcomp
123 "{r for l in x if g}",
124 # setcomp with naked tuple
125 "{r for l,m in x}",
Yury Selivanov75445082015-05-11 22:57:16 -0400126 # AsyncFunctionDef
INADA Naokicb41b272017-02-23 00:31:59 +0900127 "async def f():\n 'async function'\n await something()",
Yury Selivanov75445082015-05-11 22:57:16 -0400128 # AsyncFor
129 "async def f():\n async for e in i: 1\n else: 2",
130 # AsyncWith
131 "async def f():\n async with a as b: 1",
Yury Selivanovb3d53132015-09-01 16:10:49 -0400132 # PEP 448: Additional Unpacking Generalizations
133 "{**{1:2}, 2:3}",
134 "{*{1, 2}, 3}",
Yury Selivanov52c4e7c2016-09-09 10:36:01 -0700135 # Asynchronous comprehensions
136 "async def f():\n [i async for b in c]",
Serhiy Storchaka95b6acf2018-10-30 13:16:02 +0200137 # Decorated FunctionDef
Serhiy Storchaka26ae9f62019-10-26 16:46:05 +0300138 "@deco1\n@deco2()\n@deco3(1)\ndef f(): pass",
Serhiy Storchaka95b6acf2018-10-30 13:16:02 +0200139 # Decorated AsyncFunctionDef
Serhiy Storchaka26ae9f62019-10-26 16:46:05 +0300140 "@deco1\n@deco2()\n@deco3(1)\nasync def f(): pass",
Serhiy Storchaka95b6acf2018-10-30 13:16:02 +0200141 # Decorated ClassDef
Serhiy Storchaka26ae9f62019-10-26 16:46:05 +0300142 "@deco1\n@deco2()\n@deco3(1)\nclass C: pass",
Serhiy Storchakab619b092018-11-27 09:40:29 +0200143 # Decorator with generator argument
144 "@deco(a for a in b)\ndef f(): pass",
Lysandros Nikolaoud2e10982020-02-08 00:36:32 +0100145 # Decorator with attribute
146 "@a.b.c\ndef f(): pass",
Pablo Galindo0c9258a2019-03-18 13:51:53 +0000147 # Simple assignment expression
148 "(a := 1)",
Pablo Galindo2f58a842019-05-31 14:09:49 +0100149 # Positional-only arguments
150 "def f(a, /,): pass",
151 "def f(a, /, c, d, e): pass",
152 "def f(a, /, c, *, d, e): pass",
153 "def f(a, /, c, *, d, e, **kwargs): pass",
154 # Positional-only arguments with defaults
155 "def f(a=1, /,): pass",
156 "def f(a=1, /, b=2, c=4): pass",
157 "def f(a=1, /, b=2, *, c=4): pass",
158 "def f(a=1, /, b=2, *, c): pass",
159 "def f(a=1, /, b=2, *, c=4, **kwargs): pass",
160 "def f(a=1, /, b=2, *, c, **kwargs): pass",
Pablo Galindo0c9258a2019-03-18 13:51:53 +0000161
Tim Peters400cbc32006-02-28 18:44:41 +0000162]
163
164# These are compiled through "single"
165# because of overlap with "eval", it just tests what
166# can't be tested with "eval"
167single_tests = [
168 "1+2"
169]
170
171# These are compiled through "eval"
172# It should test all expressions
173eval_tests = [
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500174 # None
175 "None",
Tim Peters400cbc32006-02-28 18:44:41 +0000176 # BoolOp
177 "a and b",
178 # BinOp
179 "a + b",
180 # UnaryOp
181 "not v",
182 # Lambda
183 "lambda:None",
184 # Dict
185 "{ 1:2 }",
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500186 # Empty dict
187 "{}",
188 # Set
189 "{None,}",
190 # Multiline dict (test for .lineno & .col_offset)
191 """{
192 1
193 :
194 2
195 }""",
Tim Peters400cbc32006-02-28 18:44:41 +0000196 # ListComp
197 "[a for b in c if d]",
198 # GeneratorExp
199 "(a for b in c if d)",
Serhiy Storchakab619b092018-11-27 09:40:29 +0200200 # Comprehensions with multiple for targets
201 "[(a,b) for a,b in c]",
202 "[(a,b) for (a,b) in c]",
203 "[(a,b) for [a,b] in c]",
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)",
Tim Peters400cbc32006-02-28 18:44:41 +0000210 # Yield - yield expressions can't work outside a function
211 #
212 # Compare
213 "1 < 2 < 3",
214 # Call
215 "f(1,2,c=3,*d,**e)",
Lysandros Nikolaou50d4f122019-12-18 01:20:55 +0100216 # Call with multi-character starred
217 "f(*[0, 1])",
Serhiy Storchakab619b092018-11-27 09:40:29 +0200218 # Call with a generator argument
219 "f(a for a in b)",
Tim Peters400cbc32006-02-28 18:44:41 +0000220 # Num
Guido van Rossume2a383d2007-01-15 16:59:06 +0000221 "10",
Tim Peters400cbc32006-02-28 18:44:41 +0000222 # Str
223 "'string'",
224 # Attribute
225 "a.b",
226 # Subscript
227 "a[b:c]",
228 # Name
229 "v",
230 # List
231 "[1,2,3]",
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500232 # Empty list
233 "[]",
Tim Peters400cbc32006-02-28 18:44:41 +0000234 # Tuple
Martin v. Löwis49c5da12006-03-01 22:49:05 +0000235 "1,2,3",
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500236 # Tuple
237 "(1,2,3)",
238 # Empty tuple
239 "()",
Martin v. Löwis49c5da12006-03-01 22:49:05 +0000240 # Combination
241 "a.b.c.d(a.b[1:2])",
242
Tim Peters400cbc32006-02-28 18:44:41 +0000243]
244
245# TODO: expr_context, slice, boolop, operator, unaryop, cmpop, comprehension
246# excepthandler, arguments, keywords, alias
247
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000248class AST_Tests(unittest.TestCase):
Tim Peters400cbc32006-02-28 18:44:41 +0000249
Batuhan TaĹźkaya397b96f2020-03-01 23:12:17 +0300250 def _is_ast_node(self, name, node):
251 if not isinstance(node, type):
252 return False
253 if "ast" not in node.__module__:
254 return False
255 return name != 'AST' and name[0].isupper()
256
Benjamin Peterson7a66fc22015-02-02 10:51:20 -0500257 def _assertTrueorder(self, ast_node, parent_pos):
Georg Brandl0c77a822008-06-10 16:37:50 +0000258 if not isinstance(ast_node, ast.AST) or ast_node._fields is None:
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000259 return
Georg Brandl0c77a822008-06-10 16:37:50 +0000260 if isinstance(ast_node, (ast.expr, ast.stmt, ast.excepthandler)):
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000261 node_pos = (ast_node.lineno, ast_node.col_offset)
Serhiy Storchaka95b6acf2018-10-30 13:16:02 +0200262 self.assertGreaterEqual(node_pos, parent_pos)
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000263 parent_pos = (ast_node.lineno, ast_node.col_offset)
264 for name in ast_node._fields:
265 value = getattr(ast_node, name)
266 if isinstance(value, list):
Serhiy Storchaka95b6acf2018-10-30 13:16:02 +0200267 first_pos = parent_pos
268 if value and name == 'decorator_list':
269 first_pos = (value[0].lineno, value[0].col_offset)
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000270 for child in value:
Serhiy Storchaka95b6acf2018-10-30 13:16:02 +0200271 self._assertTrueorder(child, first_pos)
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000272 elif value is not None:
Benjamin Peterson7a66fc22015-02-02 10:51:20 -0500273 self._assertTrueorder(value, parent_pos)
Tim Peters5ddfe412006-03-01 23:02:57 +0000274
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500275 def test_AST_objects(self):
276 x = ast.AST()
277 self.assertEqual(x._fields, ())
Benjamin Peterson7e0dbfb2012-03-12 09:46:44 -0700278 x.foobar = 42
279 self.assertEqual(x.foobar, 42)
280 self.assertEqual(x.__dict__["foobar"], 42)
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500281
282 with self.assertRaises(AttributeError):
283 x.vararg
284
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500285 with self.assertRaises(TypeError):
Serhiy Storchakabace59d2020-03-22 20:33:34 +0200286 # "ast.AST constructor takes 0 positional arguments"
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500287 ast.AST(2)
288
Benjamin Peterson9ed37432012-07-08 11:13:36 -0700289 def test_AST_garbage_collection(self):
290 class X:
291 pass
292 a = ast.AST()
293 a.x = X()
294 a.x.a = a
295 ref = weakref.ref(a.x)
296 del a
297 support.gc_collect()
298 self.assertIsNone(ref())
299
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000300 def test_snippets(self):
301 for input, output, kind in ((exec_tests, exec_results, "exec"),
302 (single_tests, single_results, "single"),
303 (eval_tests, eval_results, "eval")):
304 for i, o in zip(input, output):
Yury Selivanovb3d53132015-09-01 16:10:49 -0400305 with self.subTest(action="parsing", input=i):
306 ast_tree = compile(i, "?", kind, ast.PyCF_ONLY_AST)
307 self.assertEqual(to_tuple(ast_tree), o)
308 self._assertTrueorder(ast_tree, (0, 0))
Victor Stinner15a30952016-02-08 22:45:06 +0100309 with self.subTest(action="compiling", input=i, kind=kind):
310 compile(ast_tree, "?", kind)
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000311
Pablo Galindo0c9258a2019-03-18 13:51:53 +0000312 def test_ast_validation(self):
313 # compile() is the only function that calls PyAST_Validate
314 snippets_to_validate = exec_tests + single_tests + eval_tests
315 for snippet in snippets_to_validate:
316 tree = ast.parse(snippet)
317 compile(tree, '<string>', 'exec')
318
Benjamin Peterson78565b22009-06-28 19:19:51 +0000319 def test_slice(self):
320 slc = ast.parse("x[::]").body[0].value.slice
321 self.assertIsNone(slc.upper)
322 self.assertIsNone(slc.lower)
323 self.assertIsNone(slc.step)
324
325 def test_from_import(self):
326 im = ast.parse("from . import y").body[0]
327 self.assertIsNone(im.module)
328
Benjamin Petersona4e4e352012-03-22 08:19:04 -0400329 def test_non_interned_future_from_ast(self):
330 mod = ast.parse("from __future__ import division")
331 self.assertIsInstance(mod.body[0], ast.ImportFrom)
332 mod.body[0].module = " __future__ ".strip()
333 compile(mod, "<test>", "exec")
334
Benjamin Petersona0dfa822009-11-13 02:25:08 +0000335 def test_base_classes(self):
336 self.assertTrue(issubclass(ast.For, ast.stmt))
337 self.assertTrue(issubclass(ast.Name, ast.expr))
338 self.assertTrue(issubclass(ast.stmt, ast.AST))
339 self.assertTrue(issubclass(ast.expr, ast.AST))
340 self.assertTrue(issubclass(ast.comprehension, ast.AST))
341 self.assertTrue(issubclass(ast.Gt, ast.AST))
342
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500343 def test_field_attr_existence(self):
344 for name, item in ast.__dict__.items():
Batuhan TaĹźkaya397b96f2020-03-01 23:12:17 +0300345 if self._is_ast_node(name, item):
Serhiy Storchaka13d52c22020-03-10 18:52:34 +0200346 if name == 'Index':
347 # Index(value) just returns value now.
348 # The argument is required.
349 continue
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500350 x = item()
351 if isinstance(x, ast.AST):
352 self.assertEqual(type(x._fields), tuple)
353
354 def test_arguments(self):
355 x = ast.arguments()
Pablo Galindocd6e83b2019-07-15 01:32:18 +0200356 self.assertEqual(x._fields, ('posonlyargs', 'args', 'vararg', 'kwonlyargs',
357 'kw_defaults', 'kwarg', 'defaults'))
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500358
359 with self.assertRaises(AttributeError):
Serhiy Storchakab7e95252020-03-10 00:07:47 +0200360 x.args
361 self.assertIsNone(x.vararg)
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500362
Pablo Galindo8c77b8c2019-04-29 13:36:57 +0100363 x = ast.arguments(*range(1, 8))
Serhiy Storchakab7e95252020-03-10 00:07:47 +0200364 self.assertEqual(x.args, 2)
Pablo Galindo8c77b8c2019-04-29 13:36:57 +0100365 self.assertEqual(x.vararg, 3)
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500366
367 def test_field_attr_writable(self):
368 x = ast.Num()
369 # We can assign to _fields
370 x._fields = 666
371 self.assertEqual(x._fields, 666)
372
373 def test_classattrs(self):
374 x = ast.Num()
Guido van Rossum10f8ce62019-03-13 13:00:46 -0700375 self.assertEqual(x._fields, ('value', 'kind'))
Serhiy Storchaka3f228112018-09-27 17:42:37 +0300376
377 with self.assertRaises(AttributeError):
378 x.value
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500379
380 with self.assertRaises(AttributeError):
381 x.n
382
383 x = ast.Num(42)
Serhiy Storchaka3f228112018-09-27 17:42:37 +0300384 self.assertEqual(x.value, 42)
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500385 self.assertEqual(x.n, 42)
386
387 with self.assertRaises(AttributeError):
388 x.lineno
389
390 with self.assertRaises(AttributeError):
391 x.foobar
392
393 x = ast.Num(lineno=2)
394 self.assertEqual(x.lineno, 2)
395
396 x = ast.Num(42, lineno=0)
397 self.assertEqual(x.lineno, 0)
Guido van Rossum10f8ce62019-03-13 13:00:46 -0700398 self.assertEqual(x._fields, ('value', 'kind'))
Serhiy Storchaka3f228112018-09-27 17:42:37 +0300399 self.assertEqual(x.value, 42)
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500400 self.assertEqual(x.n, 42)
401
Guido van Rossum10f8ce62019-03-13 13:00:46 -0700402 self.assertRaises(TypeError, ast.Num, 1, None, 2)
403 self.assertRaises(TypeError, ast.Num, 1, None, 2, lineno=0)
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500404
Rémi Lapeyrec73914a2020-05-24 23:12:57 +0200405 # Arbitrary keyword arguments are supported
406 self.assertEqual(ast.Constant(1, foo='bar').foo, 'bar')
407 self.assertEqual(ast.Num(1, foo='bar').foo, 'bar')
408
409 with self.assertRaisesRegex(TypeError, "Num got multiple values for argument 'n'"):
410 ast.Num(1, n=2)
411 with self.assertRaisesRegex(TypeError, "Constant got multiple values for argument 'value'"):
412 ast.Constant(1, value=2)
413
Serhiy Storchaka3f228112018-09-27 17:42:37 +0300414 self.assertEqual(ast.Num(42).n, 42)
415 self.assertEqual(ast.Num(4.25).n, 4.25)
416 self.assertEqual(ast.Num(4.25j).n, 4.25j)
417 self.assertEqual(ast.Str('42').s, '42')
418 self.assertEqual(ast.Bytes(b'42').s, b'42')
419 self.assertIs(ast.NameConstant(True).value, True)
420 self.assertIs(ast.NameConstant(False).value, False)
421 self.assertIs(ast.NameConstant(None).value, None)
422
423 self.assertEqual(ast.Constant(42).value, 42)
424 self.assertEqual(ast.Constant(4.25).value, 4.25)
425 self.assertEqual(ast.Constant(4.25j).value, 4.25j)
426 self.assertEqual(ast.Constant('42').value, '42')
427 self.assertEqual(ast.Constant(b'42').value, b'42')
428 self.assertIs(ast.Constant(True).value, True)
429 self.assertIs(ast.Constant(False).value, False)
430 self.assertIs(ast.Constant(None).value, None)
431 self.assertIs(ast.Constant(...).value, ...)
432
433 def test_realtype(self):
434 self.assertEqual(type(ast.Num(42)), ast.Constant)
435 self.assertEqual(type(ast.Num(4.25)), ast.Constant)
436 self.assertEqual(type(ast.Num(4.25j)), ast.Constant)
437 self.assertEqual(type(ast.Str('42')), ast.Constant)
438 self.assertEqual(type(ast.Bytes(b'42')), ast.Constant)
439 self.assertEqual(type(ast.NameConstant(True)), ast.Constant)
440 self.assertEqual(type(ast.NameConstant(False)), ast.Constant)
441 self.assertEqual(type(ast.NameConstant(None)), ast.Constant)
442 self.assertEqual(type(ast.Ellipsis()), ast.Constant)
443
444 def test_isinstance(self):
445 self.assertTrue(isinstance(ast.Num(42), ast.Num))
446 self.assertTrue(isinstance(ast.Num(4.2), ast.Num))
447 self.assertTrue(isinstance(ast.Num(4.2j), ast.Num))
448 self.assertTrue(isinstance(ast.Str('42'), ast.Str))
449 self.assertTrue(isinstance(ast.Bytes(b'42'), ast.Bytes))
450 self.assertTrue(isinstance(ast.NameConstant(True), ast.NameConstant))
451 self.assertTrue(isinstance(ast.NameConstant(False), ast.NameConstant))
452 self.assertTrue(isinstance(ast.NameConstant(None), ast.NameConstant))
453 self.assertTrue(isinstance(ast.Ellipsis(), ast.Ellipsis))
454
455 self.assertTrue(isinstance(ast.Constant(42), ast.Num))
456 self.assertTrue(isinstance(ast.Constant(4.2), ast.Num))
457 self.assertTrue(isinstance(ast.Constant(4.2j), ast.Num))
458 self.assertTrue(isinstance(ast.Constant('42'), ast.Str))
459 self.assertTrue(isinstance(ast.Constant(b'42'), ast.Bytes))
460 self.assertTrue(isinstance(ast.Constant(True), ast.NameConstant))
461 self.assertTrue(isinstance(ast.Constant(False), ast.NameConstant))
462 self.assertTrue(isinstance(ast.Constant(None), ast.NameConstant))
463 self.assertTrue(isinstance(ast.Constant(...), ast.Ellipsis))
464
465 self.assertFalse(isinstance(ast.Str('42'), ast.Num))
466 self.assertFalse(isinstance(ast.Num(42), ast.Str))
467 self.assertFalse(isinstance(ast.Str('42'), ast.Bytes))
468 self.assertFalse(isinstance(ast.Num(42), ast.NameConstant))
469 self.assertFalse(isinstance(ast.Num(42), ast.Ellipsis))
Anthony Sottile74176222019-01-18 11:30:28 -0800470 self.assertFalse(isinstance(ast.NameConstant(True), ast.Num))
471 self.assertFalse(isinstance(ast.NameConstant(False), ast.Num))
Serhiy Storchaka3f228112018-09-27 17:42:37 +0300472
473 self.assertFalse(isinstance(ast.Constant('42'), ast.Num))
474 self.assertFalse(isinstance(ast.Constant(42), ast.Str))
475 self.assertFalse(isinstance(ast.Constant('42'), ast.Bytes))
476 self.assertFalse(isinstance(ast.Constant(42), ast.NameConstant))
477 self.assertFalse(isinstance(ast.Constant(42), ast.Ellipsis))
Anthony Sottile74176222019-01-18 11:30:28 -0800478 self.assertFalse(isinstance(ast.Constant(True), ast.Num))
479 self.assertFalse(isinstance(ast.Constant(False), ast.Num))
Serhiy Storchaka3f228112018-09-27 17:42:37 +0300480
481 self.assertFalse(isinstance(ast.Constant(), ast.Num))
482 self.assertFalse(isinstance(ast.Constant(), ast.Str))
483 self.assertFalse(isinstance(ast.Constant(), ast.Bytes))
484 self.assertFalse(isinstance(ast.Constant(), ast.NameConstant))
485 self.assertFalse(isinstance(ast.Constant(), ast.Ellipsis))
486
Serhiy Storchaka6015cc52018-10-28 13:43:03 +0200487 class S(str): pass
488 self.assertTrue(isinstance(ast.Constant(S('42')), ast.Str))
489 self.assertFalse(isinstance(ast.Constant(S('42')), ast.Num))
490
Serhiy Storchaka3f228112018-09-27 17:42:37 +0300491 def test_subclasses(self):
492 class N(ast.Num):
493 def __init__(self, *args, **kwargs):
494 super().__init__(*args, **kwargs)
495 self.z = 'spam'
496 class N2(ast.Num):
497 pass
498
499 n = N(42)
500 self.assertEqual(n.n, 42)
501 self.assertEqual(n.z, 'spam')
502 self.assertEqual(type(n), N)
503 self.assertTrue(isinstance(n, N))
504 self.assertTrue(isinstance(n, ast.Num))
505 self.assertFalse(isinstance(n, N2))
506 self.assertFalse(isinstance(ast.Num(42), N))
507 n = N(n=42)
508 self.assertEqual(n.n, 42)
509 self.assertEqual(type(n), N)
510
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500511 def test_module(self):
512 body = [ast.Num(42)]
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800513 x = ast.Module(body, [])
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500514 self.assertEqual(x.body, body)
515
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000516 def test_nodeclasses(self):
Florent Xicluna992d9e02011-11-11 19:35:42 +0100517 # Zero arguments constructor explicitly allowed
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500518 x = ast.BinOp()
519 self.assertEqual(x._fields, ('left', 'op', 'right'))
520
521 # Random attribute allowed too
522 x.foobarbaz = 5
523 self.assertEqual(x.foobarbaz, 5)
524
525 n1 = ast.Num(1)
526 n3 = ast.Num(3)
527 addop = ast.Add()
528 x = ast.BinOp(n1, addop, n3)
529 self.assertEqual(x.left, n1)
530 self.assertEqual(x.op, addop)
531 self.assertEqual(x.right, n3)
Benjamin Peterson68b543a2011-06-27 17:51:18 -0500532
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500533 x = ast.BinOp(1, 2, 3)
534 self.assertEqual(x.left, 1)
535 self.assertEqual(x.op, 2)
536 self.assertEqual(x.right, 3)
537
Georg Brandl0c77a822008-06-10 16:37:50 +0000538 x = ast.BinOp(1, 2, 3, lineno=0)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000539 self.assertEqual(x.left, 1)
540 self.assertEqual(x.op, 2)
541 self.assertEqual(x.right, 3)
542 self.assertEqual(x.lineno, 0)
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000543
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500544 # node raises exception when given too many arguments
545 self.assertRaises(TypeError, ast.BinOp, 1, 2, 3, 4)
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500546 # node raises exception when given too many arguments
547 self.assertRaises(TypeError, ast.BinOp, 1, 2, 3, 4, lineno=0)
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000548
549 # can set attributes through kwargs too
Georg Brandl0c77a822008-06-10 16:37:50 +0000550 x = ast.BinOp(left=1, op=2, right=3, lineno=0)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000551 self.assertEqual(x.left, 1)
552 self.assertEqual(x.op, 2)
553 self.assertEqual(x.right, 3)
554 self.assertEqual(x.lineno, 0)
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000555
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500556 # Random kwargs also allowed
557 x = ast.BinOp(1, 2, 3, foobarbaz=42)
558 self.assertEqual(x.foobarbaz, 42)
559
560 def test_no_fields(self):
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000561 # this used to fail because Sub._fields was None
Georg Brandl0c77a822008-06-10 16:37:50 +0000562 x = ast.Sub()
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500563 self.assertEqual(x._fields, ())
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000564
565 def test_pickling(self):
566 import pickle
567 mods = [pickle]
568 try:
569 import cPickle
570 mods.append(cPickle)
571 except ImportError:
572 pass
573 protocols = [0, 1, 2]
574 for mod in mods:
575 for protocol in protocols:
576 for ast in (compile(i, "?", "exec", 0x400) for i in exec_tests):
577 ast2 = mod.loads(mod.dumps(ast, protocol))
Ezio Melottib3aedd42010-11-20 19:04:17 +0000578 self.assertEqual(to_tuple(ast2), to_tuple(ast))
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000579
Benjamin Peterson5b066812010-11-20 01:38:49 +0000580 def test_invalid_sum(self):
581 pos = dict(lineno=2, col_offset=3)
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800582 m = ast.Module([ast.Expr(ast.expr(**pos), **pos)], [])
Benjamin Peterson5b066812010-11-20 01:38:49 +0000583 with self.assertRaises(TypeError) as cm:
584 compile(m, "<test>", "exec")
Serhiy Storchakabace59d2020-03-22 20:33:34 +0200585 self.assertIn("but got <ast.expr", str(cm.exception))
Benjamin Peterson5b066812010-11-20 01:38:49 +0000586
Min ho Kimc4cacc82019-07-31 08:16:13 +1000587 def test_invalid_identifier(self):
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800588 m = ast.Module([ast.Expr(ast.Name(42, ast.Load()))], [])
Benjamin Peterson2193d2b2011-07-22 10:50:23 -0500589 ast.fix_missing_locations(m)
590 with self.assertRaises(TypeError) as cm:
591 compile(m, "<test>", "exec")
592 self.assertIn("identifier must be of type str", str(cm.exception))
593
Batuhan TaĹźkaya0ac59f92020-03-19 14:32:28 +0300594 def test_invalid_constant(self):
595 for invalid_constant in int, (1, 2, int), frozenset((1, 2, int)):
596 e = ast.Expression(body=ast.Constant(invalid_constant))
597 ast.fix_missing_locations(e)
598 with self.assertRaisesRegex(
599 TypeError, "invalid type in Constant: type"
600 ):
601 compile(e, "<test>", "eval")
602
Mark Dickinsonded35ae2012-11-25 14:36:26 +0000603 def test_empty_yield_from(self):
604 # Issue 16546: yield from value is not optional.
605 empty_yield_from = ast.parse("def f():\n yield from g()")
606 empty_yield_from.body[0].body[0].value.value = None
607 with self.assertRaises(ValueError) as cm:
608 compile(empty_yield_from, "<test>", "exec")
Batuhan Taskaya091951a2020-05-06 17:29:32 +0300609 self.assertIn("field 'value' is required", str(cm.exception))
Mark Dickinsonded35ae2012-11-25 14:36:26 +0000610
Oren Milman7dc46d82017-09-30 20:16:24 +0300611 @support.cpython_only
612 def test_issue31592(self):
613 # There shouldn't be an assertion failure in case of a bad
614 # unicodedata.normalize().
615 import unicodedata
616 def bad_normalize(*args):
617 return None
618 with support.swap_attr(unicodedata, 'normalize', bad_normalize):
619 self.assertRaises(TypeError, ast.parse, '\u03D5')
620
Carl Friedrich Bolz-Tereick110a47c2019-07-08 23:17:56 +0200621 def test_issue18374_binop_col_offset(self):
622 tree = ast.parse('4+5+6+7')
623 parent_binop = tree.body[0].value
624 child_binop = parent_binop.left
625 grandchild_binop = child_binop.left
626 self.assertEqual(parent_binop.col_offset, 0)
627 self.assertEqual(parent_binop.end_col_offset, 7)
628 self.assertEqual(child_binop.col_offset, 0)
629 self.assertEqual(child_binop.end_col_offset, 5)
630 self.assertEqual(grandchild_binop.col_offset, 0)
631 self.assertEqual(grandchild_binop.end_col_offset, 3)
632
633 tree = ast.parse('4+5-\\\n 6-7')
634 parent_binop = tree.body[0].value
635 child_binop = parent_binop.left
636 grandchild_binop = child_binop.left
637 self.assertEqual(parent_binop.col_offset, 0)
638 self.assertEqual(parent_binop.lineno, 1)
639 self.assertEqual(parent_binop.end_col_offset, 4)
640 self.assertEqual(parent_binop.end_lineno, 2)
641
642 self.assertEqual(child_binop.col_offset, 0)
Carl Friedrich Bolz-Tereick430a9f42019-07-09 14:20:01 +0200643 self.assertEqual(child_binop.lineno, 1)
Carl Friedrich Bolz-Tereick110a47c2019-07-08 23:17:56 +0200644 self.assertEqual(child_binop.end_col_offset, 2)
Carl Friedrich Bolz-Tereick430a9f42019-07-09 14:20:01 +0200645 self.assertEqual(child_binop.end_lineno, 2)
Carl Friedrich Bolz-Tereick110a47c2019-07-08 23:17:56 +0200646
647 self.assertEqual(grandchild_binop.col_offset, 0)
Carl Friedrich Bolz-Tereick430a9f42019-07-09 14:20:01 +0200648 self.assertEqual(grandchild_binop.lineno, 1)
Carl Friedrich Bolz-Tereick110a47c2019-07-08 23:17:56 +0200649 self.assertEqual(grandchild_binop.end_col_offset, 3)
Carl Friedrich Bolz-Tereick430a9f42019-07-09 14:20:01 +0200650 self.assertEqual(grandchild_binop.end_lineno, 1)
Georg Brandl0c77a822008-06-10 16:37:50 +0000651
Lysandros Nikolaoud2e10982020-02-08 00:36:32 +0100652 def test_issue39579_dotted_name_end_col_offset(self):
653 tree = ast.parse('@a.b.c\ndef f(): pass')
654 attr_b = tree.body[0].decorator_list[0].value
655 self.assertEqual(attr_b.end_col_offset, 4)
656
Batuhan TaĹźkaya4ab362c2020-03-16 11:12:53 +0300657 def test_ast_asdl_signature(self):
658 self.assertEqual(ast.withitem.__doc__, "withitem(expr context_expr, expr? optional_vars)")
659 self.assertEqual(ast.GtE.__doc__, "GtE")
660 self.assertEqual(ast.Name.__doc__, "Name(identifier id, expr_context ctx)")
661 self.assertEqual(ast.cmpop.__doc__, "cmpop = Eq | NotEq | Lt | LtE | Gt | GtE | Is | IsNot | In | NotIn")
662 expressions = [f" | {node.__doc__}" for node in ast.expr.__subclasses__()]
663 expressions[0] = f"expr = {ast.expr.__subclasses__()[0].__doc__}"
664 self.assertCountEqual(ast.expr.__doc__.split("\n"), expressions)
665
Shantanuc116c942020-05-27 13:30:38 -0700666 def test_issue40614_feature_version(self):
667 ast.parse('f"{x=}"', feature_version=(3, 8))
668 with self.assertRaises(SyntaxError):
669 ast.parse('f"{x=}"', feature_version=(3, 7))
670
Batuhan Taskaya68874a82020-06-06 15:44:16 +0300671 def test_constant_as_name(self):
672 for constant in "True", "False", "None":
673 expr = ast.Expression(ast.Name(constant, ast.Load()))
674 ast.fix_missing_locations(expr)
675 with self.assertRaisesRegex(ValueError, f"Name node can't be used with '{constant}' constant"):
676 compile(expr, "<test>", "eval")
677
Batuhan TaĹźkaya4ab362c2020-03-16 11:12:53 +0300678
Georg Brandl0c77a822008-06-10 16:37:50 +0000679class ASTHelpers_Test(unittest.TestCase):
Guido van Rossum10f8ce62019-03-13 13:00:46 -0700680 maxDiff = None
Georg Brandl0c77a822008-06-10 16:37:50 +0000681
682 def test_parse(self):
683 a = ast.parse('foo(1 + 1)')
684 b = compile('foo(1 + 1)', '<unknown>', 'exec', ast.PyCF_ONLY_AST)
685 self.assertEqual(ast.dump(a), ast.dump(b))
686
Benjamin Peterson2e2c9032012-09-02 14:23:15 -0400687 def test_parse_in_error(self):
688 try:
689 1/0
690 except Exception:
Benjamin Petersonbd0df502012-09-02 15:04:51 -0400691 with self.assertRaises(SyntaxError) as e:
692 ast.literal_eval(r"'\U'")
693 self.assertIsNotNone(e.exception.__context__)
Benjamin Peterson2e2c9032012-09-02 14:23:15 -0400694
Georg Brandl0c77a822008-06-10 16:37:50 +0000695 def test_dump(self):
696 node = ast.parse('spam(eggs, "and cheese")')
697 self.assertEqual(ast.dump(node),
698 "Module(body=[Expr(value=Call(func=Name(id='spam', ctx=Load()), "
Serhiy Storchakab7e95252020-03-10 00:07:47 +0200699 "args=[Name(id='eggs', ctx=Load()), Constant(value='and cheese')], "
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800700 "keywords=[]))], type_ignores=[])"
Georg Brandl0c77a822008-06-10 16:37:50 +0000701 )
702 self.assertEqual(ast.dump(node, annotate_fields=False),
703 "Module([Expr(Call(Name('spam', Load()), [Name('eggs', Load()), "
Serhiy Storchakab7e95252020-03-10 00:07:47 +0200704 "Constant('and cheese')], []))], [])"
Georg Brandl0c77a822008-06-10 16:37:50 +0000705 )
706 self.assertEqual(ast.dump(node, include_attributes=True),
707 "Module(body=[Expr(value=Call(func=Name(id='spam', ctx=Load(), "
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000708 "lineno=1, col_offset=0, end_lineno=1, end_col_offset=4), "
709 "args=[Name(id='eggs', ctx=Load(), lineno=1, col_offset=5, "
Serhiy Storchakab7e95252020-03-10 00:07:47 +0200710 "end_lineno=1, end_col_offset=9), Constant(value='and cheese', "
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000711 "lineno=1, col_offset=11, end_lineno=1, end_col_offset=23)], keywords=[], "
712 "lineno=1, col_offset=0, end_lineno=1, end_col_offset=24), "
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800713 "lineno=1, col_offset=0, end_lineno=1, end_col_offset=24)], type_ignores=[])"
Georg Brandl0c77a822008-06-10 16:37:50 +0000714 )
715
Serhiy Storchaka850573b2019-09-09 19:33:13 +0300716 def test_dump_indent(self):
717 node = ast.parse('spam(eggs, "and cheese")')
718 self.assertEqual(ast.dump(node, indent=3), """\
719Module(
720 body=[
721 Expr(
722 value=Call(
723 func=Name(id='spam', ctx=Load()),
724 args=[
725 Name(id='eggs', ctx=Load()),
Serhiy Storchakab7e95252020-03-10 00:07:47 +0200726 Constant(value='and cheese')],
Serhiy Storchaka850573b2019-09-09 19:33:13 +0300727 keywords=[]))],
728 type_ignores=[])""")
729 self.assertEqual(ast.dump(node, annotate_fields=False, indent='\t'), """\
730Module(
731\t[
732\t\tExpr(
733\t\t\tCall(
734\t\t\t\tName('spam', Load()),
735\t\t\t\t[
736\t\t\t\t\tName('eggs', Load()),
Serhiy Storchakab7e95252020-03-10 00:07:47 +0200737\t\t\t\t\tConstant('and cheese')],
Serhiy Storchaka850573b2019-09-09 19:33:13 +0300738\t\t\t\t[]))],
739\t[])""")
740 self.assertEqual(ast.dump(node, include_attributes=True, indent=3), """\
741Module(
742 body=[
743 Expr(
744 value=Call(
745 func=Name(
746 id='spam',
747 ctx=Load(),
748 lineno=1,
749 col_offset=0,
750 end_lineno=1,
751 end_col_offset=4),
752 args=[
753 Name(
754 id='eggs',
755 ctx=Load(),
756 lineno=1,
757 col_offset=5,
758 end_lineno=1,
759 end_col_offset=9),
760 Constant(
761 value='and cheese',
Serhiy Storchaka850573b2019-09-09 19:33:13 +0300762 lineno=1,
763 col_offset=11,
764 end_lineno=1,
765 end_col_offset=23)],
766 keywords=[],
767 lineno=1,
768 col_offset=0,
769 end_lineno=1,
770 end_col_offset=24),
771 lineno=1,
772 col_offset=0,
773 end_lineno=1,
774 end_col_offset=24)],
775 type_ignores=[])""")
776
Serhiy Storchakae64f9482019-08-29 09:30:23 +0300777 def test_dump_incomplete(self):
778 node = ast.Raise(lineno=3, col_offset=4)
779 self.assertEqual(ast.dump(node),
780 "Raise()"
781 )
782 self.assertEqual(ast.dump(node, include_attributes=True),
783 "Raise(lineno=3, col_offset=4)"
784 )
785 node = ast.Raise(exc=ast.Name(id='e', ctx=ast.Load()), lineno=3, col_offset=4)
786 self.assertEqual(ast.dump(node),
787 "Raise(exc=Name(id='e', ctx=Load()))"
788 )
789 self.assertEqual(ast.dump(node, annotate_fields=False),
790 "Raise(Name('e', Load()))"
791 )
792 self.assertEqual(ast.dump(node, include_attributes=True),
793 "Raise(exc=Name(id='e', ctx=Load()), lineno=3, col_offset=4)"
794 )
795 self.assertEqual(ast.dump(node, annotate_fields=False, include_attributes=True),
796 "Raise(Name('e', Load()), lineno=3, col_offset=4)"
797 )
798 node = ast.Raise(cause=ast.Name(id='e', ctx=ast.Load()))
799 self.assertEqual(ast.dump(node),
800 "Raise(cause=Name(id='e', ctx=Load()))"
801 )
802 self.assertEqual(ast.dump(node, annotate_fields=False),
803 "Raise(cause=Name('e', Load()))"
804 )
805
Georg Brandl0c77a822008-06-10 16:37:50 +0000806 def test_copy_location(self):
807 src = ast.parse('1 + 1', mode='eval')
808 src.body.right = ast.copy_location(ast.Num(2), src.body.right)
809 self.assertEqual(ast.dump(src, include_attributes=True),
Serhiy Storchakab7e95252020-03-10 00:07:47 +0200810 'Expression(body=BinOp(left=Constant(value=1, lineno=1, col_offset=0, '
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000811 'end_lineno=1, end_col_offset=1), op=Add(), right=Constant(value=2, '
812 'lineno=1, col_offset=4, end_lineno=1, end_col_offset=5), lineno=1, '
813 'col_offset=0, end_lineno=1, end_col_offset=5))'
Georg Brandl0c77a822008-06-10 16:37:50 +0000814 )
Batuhan Taskaya8f4380d2020-08-05 16:32:32 +0300815 src = ast.Call(col_offset=1, lineno=1, end_lineno=1, end_col_offset=1)
816 new = ast.copy_location(src, ast.Call(col_offset=None, lineno=None))
817 self.assertIsNone(new.end_lineno)
818 self.assertIsNone(new.end_col_offset)
819 self.assertEqual(new.lineno, 1)
820 self.assertEqual(new.col_offset, 1)
Georg Brandl0c77a822008-06-10 16:37:50 +0000821
822 def test_fix_missing_locations(self):
823 src = ast.parse('write("spam")')
824 src.body.append(ast.Expr(ast.Call(ast.Name('spam', ast.Load()),
Benjamin Peterson025e9eb2015-05-05 20:16:41 -0400825 [ast.Str('eggs')], [])))
Georg Brandl0c77a822008-06-10 16:37:50 +0000826 self.assertEqual(src, ast.fix_missing_locations(src))
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000827 self.maxDiff = None
Georg Brandl0c77a822008-06-10 16:37:50 +0000828 self.assertEqual(ast.dump(src, include_attributes=True),
829 "Module(body=[Expr(value=Call(func=Name(id='write', ctx=Load(), "
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000830 "lineno=1, col_offset=0, end_lineno=1, end_col_offset=5), "
Serhiy Storchakab7e95252020-03-10 00:07:47 +0200831 "args=[Constant(value='spam', lineno=1, col_offset=6, end_lineno=1, "
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000832 "end_col_offset=12)], keywords=[], lineno=1, col_offset=0, end_lineno=1, "
833 "end_col_offset=13), lineno=1, col_offset=0, end_lineno=1, "
834 "end_col_offset=13), Expr(value=Call(func=Name(id='spam', ctx=Load(), "
835 "lineno=1, col_offset=0, end_lineno=1, end_col_offset=0), "
836 "args=[Constant(value='eggs', lineno=1, col_offset=0, end_lineno=1, "
837 "end_col_offset=0)], keywords=[], lineno=1, col_offset=0, end_lineno=1, "
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800838 "end_col_offset=0), lineno=1, col_offset=0, end_lineno=1, end_col_offset=0)], "
839 "type_ignores=[])"
Georg Brandl0c77a822008-06-10 16:37:50 +0000840 )
841
842 def test_increment_lineno(self):
843 src = ast.parse('1 + 1', mode='eval')
844 self.assertEqual(ast.increment_lineno(src, n=3), src)
845 self.assertEqual(ast.dump(src, include_attributes=True),
Serhiy Storchakab7e95252020-03-10 00:07:47 +0200846 'Expression(body=BinOp(left=Constant(value=1, lineno=4, col_offset=0, '
847 'end_lineno=4, end_col_offset=1), op=Add(), right=Constant(value=1, '
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000848 'lineno=4, col_offset=4, end_lineno=4, end_col_offset=5), lineno=4, '
849 'col_offset=0, end_lineno=4, end_col_offset=5))'
Georg Brandl0c77a822008-06-10 16:37:50 +0000850 )
Georg Brandl619e7ba2011-01-09 07:38:51 +0000851 # issue10869: do not increment lineno of root twice
Georg Brandlefb69022011-01-09 07:50:48 +0000852 src = ast.parse('1 + 1', mode='eval')
Georg Brandl619e7ba2011-01-09 07:38:51 +0000853 self.assertEqual(ast.increment_lineno(src.body, n=3), src.body)
854 self.assertEqual(ast.dump(src, include_attributes=True),
Serhiy Storchakab7e95252020-03-10 00:07:47 +0200855 'Expression(body=BinOp(left=Constant(value=1, lineno=4, col_offset=0, '
856 'end_lineno=4, end_col_offset=1), op=Add(), right=Constant(value=1, '
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000857 'lineno=4, col_offset=4, end_lineno=4, end_col_offset=5), lineno=4, '
858 'col_offset=0, end_lineno=4, end_col_offset=5))'
Georg Brandl619e7ba2011-01-09 07:38:51 +0000859 )
Batuhan Taskaya8f4380d2020-08-05 16:32:32 +0300860 src = ast.Call(
861 func=ast.Name("test", ast.Load()), args=[], keywords=[], lineno=1
862 )
863 self.assertEqual(ast.increment_lineno(src).lineno, 2)
864 self.assertIsNone(ast.increment_lineno(src).end_lineno)
Georg Brandl0c77a822008-06-10 16:37:50 +0000865
866 def test_iter_fields(self):
867 node = ast.parse('foo()', mode='eval')
868 d = dict(ast.iter_fields(node.body))
869 self.assertEqual(d.pop('func').id, 'foo')
Benjamin Peterson025e9eb2015-05-05 20:16:41 -0400870 self.assertEqual(d, {'keywords': [], 'args': []})
Georg Brandl0c77a822008-06-10 16:37:50 +0000871
872 def test_iter_child_nodes(self):
873 node = ast.parse("spam(23, 42, eggs='leek')", mode='eval')
874 self.assertEqual(len(list(ast.iter_child_nodes(node.body))), 4)
875 iterator = ast.iter_child_nodes(node.body)
876 self.assertEqual(next(iterator).id, 'spam')
Serhiy Storchaka3f228112018-09-27 17:42:37 +0300877 self.assertEqual(next(iterator).value, 23)
878 self.assertEqual(next(iterator).value, 42)
Georg Brandl0c77a822008-06-10 16:37:50 +0000879 self.assertEqual(ast.dump(next(iterator)),
Serhiy Storchakab7e95252020-03-10 00:07:47 +0200880 "keyword(arg='eggs', value=Constant(value='leek'))"
Georg Brandl0c77a822008-06-10 16:37:50 +0000881 )
882
883 def test_get_docstring(self):
Serhiy Storchaka08f127a2018-06-15 11:05:15 +0300884 node = ast.parse('"""line one\n line two"""')
885 self.assertEqual(ast.get_docstring(node),
886 'line one\nline two')
887
888 node = ast.parse('class foo:\n """line one\n line two"""')
889 self.assertEqual(ast.get_docstring(node.body[0]),
890 'line one\nline two')
891
Georg Brandl0c77a822008-06-10 16:37:50 +0000892 node = ast.parse('def foo():\n """line one\n line two"""')
893 self.assertEqual(ast.get_docstring(node.body[0]),
894 'line one\nline two')
895
Yury Selivanov2f07a662015-07-23 08:54:35 +0300896 node = ast.parse('async def foo():\n """spam\n ham"""')
897 self.assertEqual(ast.get_docstring(node.body[0]), 'spam\nham')
Serhiy Storchaka08f127a2018-06-15 11:05:15 +0300898
899 def test_get_docstring_none(self):
Matthias Bussonnier41cea702017-02-23 22:44:19 -0800900 self.assertIsNone(ast.get_docstring(ast.parse('')))
Serhiy Storchaka08f127a2018-06-15 11:05:15 +0300901 node = ast.parse('x = "not docstring"')
902 self.assertIsNone(ast.get_docstring(node))
903 node = ast.parse('def foo():\n pass')
904 self.assertIsNone(ast.get_docstring(node))
905
906 node = ast.parse('class foo:\n pass')
907 self.assertIsNone(ast.get_docstring(node.body[0]))
908 node = ast.parse('class foo:\n x = "not docstring"')
909 self.assertIsNone(ast.get_docstring(node.body[0]))
910 node = ast.parse('class foo:\n def bar(self): pass')
911 self.assertIsNone(ast.get_docstring(node.body[0]))
912
913 node = ast.parse('def foo():\n pass')
914 self.assertIsNone(ast.get_docstring(node.body[0]))
915 node = ast.parse('def foo():\n x = "not docstring"')
916 self.assertIsNone(ast.get_docstring(node.body[0]))
917
918 node = ast.parse('async def foo():\n pass')
919 self.assertIsNone(ast.get_docstring(node.body[0]))
920 node = ast.parse('async def foo():\n x = "not docstring"')
921 self.assertIsNone(ast.get_docstring(node.body[0]))
Yury Selivanov2f07a662015-07-23 08:54:35 +0300922
Anthony Sottile995d9b92019-01-12 20:05:13 -0800923 def test_multi_line_docstring_col_offset_and_lineno_issue16806(self):
924 node = ast.parse(
925 '"""line one\nline two"""\n\n'
926 'def foo():\n """line one\n line two"""\n\n'
927 ' def bar():\n """line one\n line two"""\n'
928 ' """line one\n line two"""\n'
929 '"""line one\nline two"""\n\n'
930 )
931 self.assertEqual(node.body[0].col_offset, 0)
932 self.assertEqual(node.body[0].lineno, 1)
933 self.assertEqual(node.body[1].body[0].col_offset, 2)
934 self.assertEqual(node.body[1].body[0].lineno, 5)
935 self.assertEqual(node.body[1].body[1].body[0].col_offset, 4)
936 self.assertEqual(node.body[1].body[1].body[0].lineno, 9)
937 self.assertEqual(node.body[1].body[2].col_offset, 2)
938 self.assertEqual(node.body[1].body[2].lineno, 11)
939 self.assertEqual(node.body[2].col_offset, 0)
940 self.assertEqual(node.body[2].lineno, 13)
941
Lysandros Nikolaou025a6022019-12-12 22:40:21 +0100942 def test_elif_stmt_start_position(self):
943 node = ast.parse('if a:\n pass\nelif b:\n pass\n')
944 elif_stmt = node.body[0].orelse[0]
945 self.assertEqual(elif_stmt.lineno, 3)
946 self.assertEqual(elif_stmt.col_offset, 0)
947
Lysandros Nikolaou5936a4c2019-12-14 11:24:57 +0100948 def test_elif_stmt_start_position_with_else(self):
949 node = ast.parse('if a:\n pass\nelif b:\n pass\nelse:\n pass\n')
950 elif_stmt = node.body[0].orelse[0]
951 self.assertEqual(elif_stmt.lineno, 3)
952 self.assertEqual(elif_stmt.col_offset, 0)
953
Lysandros Nikolaou50d4f122019-12-18 01:20:55 +0100954 def test_starred_expr_end_position_within_call(self):
955 node = ast.parse('f(*[0, 1])')
956 starred_expr = node.body[0].value.args[0]
957 self.assertEqual(starred_expr.end_lineno, 1)
958 self.assertEqual(starred_expr.end_col_offset, 9)
959
Georg Brandl0c77a822008-06-10 16:37:50 +0000960 def test_literal_eval(self):
961 self.assertEqual(ast.literal_eval('[1, 2, 3]'), [1, 2, 3])
962 self.assertEqual(ast.literal_eval('{"foo": 42}'), {"foo": 42})
963 self.assertEqual(ast.literal_eval('(True, False, None)'), (True, False, None))
Benjamin Peterson3e742892010-07-11 12:59:24 +0000964 self.assertEqual(ast.literal_eval('{1, 2, 3}'), {1, 2, 3})
Benjamin Peterson5ef96e52010-07-11 23:06:06 +0000965 self.assertEqual(ast.literal_eval('b"hi"'), b"hi")
Raymond Hettinger4fcf5c12020-01-02 22:21:18 -0700966 self.assertEqual(ast.literal_eval('set()'), set())
Georg Brandl0c77a822008-06-10 16:37:50 +0000967 self.assertRaises(ValueError, ast.literal_eval, 'foo()')
Serhiy Storchakad8ac4d12018-01-04 11:15:39 +0200968 self.assertEqual(ast.literal_eval('6'), 6)
969 self.assertEqual(ast.literal_eval('+6'), 6)
Raymond Hettingerbc959732010-10-08 00:47:45 +0000970 self.assertEqual(ast.literal_eval('-6'), -6)
Raymond Hettingerbc959732010-10-08 00:47:45 +0000971 self.assertEqual(ast.literal_eval('3.25'), 3.25)
Serhiy Storchakad8ac4d12018-01-04 11:15:39 +0200972 self.assertEqual(ast.literal_eval('+3.25'), 3.25)
973 self.assertEqual(ast.literal_eval('-3.25'), -3.25)
974 self.assertEqual(repr(ast.literal_eval('-0.0')), '-0.0')
975 self.assertRaises(ValueError, ast.literal_eval, '++6')
976 self.assertRaises(ValueError, ast.literal_eval, '+True')
977 self.assertRaises(ValueError, ast.literal_eval, '2+3')
Georg Brandl0c77a822008-06-10 16:37:50 +0000978
Serhiy Storchakad8ac4d12018-01-04 11:15:39 +0200979 def test_literal_eval_complex(self):
980 # Issue #4907
981 self.assertEqual(ast.literal_eval('6j'), 6j)
982 self.assertEqual(ast.literal_eval('-6j'), -6j)
983 self.assertEqual(ast.literal_eval('6.75j'), 6.75j)
984 self.assertEqual(ast.literal_eval('-6.75j'), -6.75j)
985 self.assertEqual(ast.literal_eval('3+6j'), 3+6j)
986 self.assertEqual(ast.literal_eval('-3+6j'), -3+6j)
987 self.assertEqual(ast.literal_eval('3-6j'), 3-6j)
988 self.assertEqual(ast.literal_eval('-3-6j'), -3-6j)
989 self.assertEqual(ast.literal_eval('3.25+6.75j'), 3.25+6.75j)
990 self.assertEqual(ast.literal_eval('-3.25+6.75j'), -3.25+6.75j)
991 self.assertEqual(ast.literal_eval('3.25-6.75j'), 3.25-6.75j)
992 self.assertEqual(ast.literal_eval('-3.25-6.75j'), -3.25-6.75j)
993 self.assertEqual(ast.literal_eval('(3+6j)'), 3+6j)
994 self.assertRaises(ValueError, ast.literal_eval, '-6j+3')
995 self.assertRaises(ValueError, ast.literal_eval, '-6j+3j')
996 self.assertRaises(ValueError, ast.literal_eval, '3+-6j')
997 self.assertRaises(ValueError, ast.literal_eval, '3+(0+6j)')
998 self.assertRaises(ValueError, ast.literal_eval, '-(3+6j)')
Benjamin Peterson058e31e2009-01-16 03:54:08 +0000999
Curtis Bucherc21c5122020-05-05 12:40:56 -07001000 def test_literal_eval_malformed_dict_nodes(self):
1001 malformed = ast.Dict(keys=[ast.Constant(1), ast.Constant(2)], values=[ast.Constant(3)])
1002 self.assertRaises(ValueError, ast.literal_eval, malformed)
1003 malformed = ast.Dict(keys=[ast.Constant(1)], values=[ast.Constant(2), ast.Constant(3)])
1004 self.assertRaises(ValueError, ast.literal_eval, malformed)
1005
Amaury Forgeot d'Arc58e87612011-11-22 21:51:55 +01001006 def test_bad_integer(self):
1007 # issue13436: Bad error message with invalid numeric values
1008 body = [ast.ImportFrom(module='time',
1009 names=[ast.alias(name='sleep')],
1010 level=None,
1011 lineno=None, col_offset=None)]
Guido van Rossumdcfcd142019-01-31 03:40:27 -08001012 mod = ast.Module(body, [])
Amaury Forgeot d'Arc58e87612011-11-22 21:51:55 +01001013 with self.assertRaises(ValueError) as cm:
1014 compile(mod, 'test', 'exec')
1015 self.assertIn("invalid integer value: None", str(cm.exception))
1016
Berker Peksag0a5bd512016-04-29 19:50:02 +03001017 def test_level_as_none(self):
1018 body = [ast.ImportFrom(module='time',
1019 names=[ast.alias(name='sleep')],
1020 level=None,
1021 lineno=0, col_offset=0)]
Guido van Rossumdcfcd142019-01-31 03:40:27 -08001022 mod = ast.Module(body, [])
Berker Peksag0a5bd512016-04-29 19:50:02 +03001023 code = compile(mod, 'test', 'exec')
1024 ns = {}
1025 exec(code, ns)
1026 self.assertIn('sleep', ns)
1027
Georg Brandl0c77a822008-06-10 16:37:50 +00001028
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001029class ASTValidatorTests(unittest.TestCase):
1030
1031 def mod(self, mod, msg=None, mode="exec", *, exc=ValueError):
1032 mod.lineno = mod.col_offset = 0
1033 ast.fix_missing_locations(mod)
Serhiy Storchaka3f228112018-09-27 17:42:37 +03001034 if msg is None:
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001035 compile(mod, "<test>", mode)
Serhiy Storchaka3f228112018-09-27 17:42:37 +03001036 else:
1037 with self.assertRaises(exc) as cm:
1038 compile(mod, "<test>", mode)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001039 self.assertIn(msg, str(cm.exception))
1040
1041 def expr(self, node, msg=None, *, exc=ValueError):
Guido van Rossumdcfcd142019-01-31 03:40:27 -08001042 mod = ast.Module([ast.Expr(node)], [])
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001043 self.mod(mod, msg, exc=exc)
1044
1045 def stmt(self, stmt, msg=None):
Guido van Rossumdcfcd142019-01-31 03:40:27 -08001046 mod = ast.Module([stmt], [])
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001047 self.mod(mod, msg)
1048
1049 def test_module(self):
1050 m = ast.Interactive([ast.Expr(ast.Name("x", ast.Store()))])
1051 self.mod(m, "must have Load context", "single")
1052 m = ast.Expression(ast.Name("x", ast.Store()))
1053 self.mod(m, "must have Load context", "eval")
1054
1055 def _check_arguments(self, fac, check):
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01001056 def arguments(args=None, posonlyargs=None, vararg=None,
Benjamin Petersoncda75be2013-03-18 10:48:58 -07001057 kwonlyargs=None, kwarg=None,
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001058 defaults=None, kw_defaults=None):
1059 if args is None:
1060 args = []
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01001061 if posonlyargs is None:
1062 posonlyargs = []
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001063 if kwonlyargs is None:
1064 kwonlyargs = []
1065 if defaults is None:
1066 defaults = []
1067 if kw_defaults is None:
1068 kw_defaults = []
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01001069 args = ast.arguments(args, posonlyargs, vararg, kwonlyargs,
1070 kw_defaults, kwarg, defaults)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001071 return fac(args)
1072 args = [ast.arg("x", ast.Name("x", ast.Store()))]
1073 check(arguments(args=args), "must have Load context")
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01001074 check(arguments(posonlyargs=args), "must have Load context")
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001075 check(arguments(kwonlyargs=args), "must have Load context")
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001076 check(arguments(defaults=[ast.Num(3)]),
1077 "more positional defaults than args")
1078 check(arguments(kw_defaults=[ast.Num(4)]),
1079 "length of kwonlyargs is not the same as kw_defaults")
1080 args = [ast.arg("x", ast.Name("x", ast.Load()))]
1081 check(arguments(args=args, defaults=[ast.Name("x", ast.Store())]),
1082 "must have Load context")
1083 args = [ast.arg("a", ast.Name("x", ast.Load())),
1084 ast.arg("b", ast.Name("y", ast.Load()))]
1085 check(arguments(kwonlyargs=args,
1086 kw_defaults=[None, ast.Name("x", ast.Store())]),
1087 "must have Load context")
1088
1089 def test_funcdef(self):
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01001090 a = ast.arguments([], [], None, [], [], None, [])
Serhiy Storchaka73cbe7a2018-05-29 12:04:55 +03001091 f = ast.FunctionDef("x", a, [], [], None)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001092 self.stmt(f, "empty body on FunctionDef")
1093 f = ast.FunctionDef("x", a, [ast.Pass()], [ast.Name("x", ast.Store())],
Serhiy Storchaka73cbe7a2018-05-29 12:04:55 +03001094 None)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001095 self.stmt(f, "must have Load context")
1096 f = ast.FunctionDef("x", a, [ast.Pass()], [],
Serhiy Storchaka73cbe7a2018-05-29 12:04:55 +03001097 ast.Name("x", ast.Store()))
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001098 self.stmt(f, "must have Load context")
1099 def fac(args):
Serhiy Storchaka73cbe7a2018-05-29 12:04:55 +03001100 return ast.FunctionDef("x", args, [ast.Pass()], [], None)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001101 self._check_arguments(fac, self.stmt)
1102
1103 def test_classdef(self):
Benjamin Peterson025e9eb2015-05-05 20:16:41 -04001104 def cls(bases=None, keywords=None, body=None, decorator_list=None):
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001105 if bases is None:
1106 bases = []
1107 if keywords is None:
1108 keywords = []
1109 if body is None:
1110 body = [ast.Pass()]
1111 if decorator_list is None:
1112 decorator_list = []
Benjamin Peterson025e9eb2015-05-05 20:16:41 -04001113 return ast.ClassDef("myclass", bases, keywords,
Serhiy Storchaka73cbe7a2018-05-29 12:04:55 +03001114 body, decorator_list)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001115 self.stmt(cls(bases=[ast.Name("x", ast.Store())]),
1116 "must have Load context")
1117 self.stmt(cls(keywords=[ast.keyword("x", ast.Name("x", ast.Store()))]),
1118 "must have Load context")
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001119 self.stmt(cls(body=[]), "empty body on ClassDef")
1120 self.stmt(cls(body=[None]), "None disallowed")
1121 self.stmt(cls(decorator_list=[ast.Name("x", ast.Store())]),
1122 "must have Load context")
1123
1124 def test_delete(self):
1125 self.stmt(ast.Delete([]), "empty targets on Delete")
1126 self.stmt(ast.Delete([None]), "None disallowed")
1127 self.stmt(ast.Delete([ast.Name("x", ast.Load())]),
1128 "must have Del context")
1129
1130 def test_assign(self):
1131 self.stmt(ast.Assign([], ast.Num(3)), "empty targets on Assign")
1132 self.stmt(ast.Assign([None], ast.Num(3)), "None disallowed")
1133 self.stmt(ast.Assign([ast.Name("x", ast.Load())], ast.Num(3)),
1134 "must have Store context")
1135 self.stmt(ast.Assign([ast.Name("x", ast.Store())],
1136 ast.Name("y", ast.Store())),
1137 "must have Load context")
1138
1139 def test_augassign(self):
1140 aug = ast.AugAssign(ast.Name("x", ast.Load()), ast.Add(),
1141 ast.Name("y", ast.Load()))
1142 self.stmt(aug, "must have Store context")
1143 aug = ast.AugAssign(ast.Name("x", ast.Store()), ast.Add(),
1144 ast.Name("y", ast.Store()))
1145 self.stmt(aug, "must have Load context")
1146
1147 def test_for(self):
1148 x = ast.Name("x", ast.Store())
1149 y = ast.Name("y", ast.Load())
1150 p = ast.Pass()
1151 self.stmt(ast.For(x, y, [], []), "empty body on For")
1152 self.stmt(ast.For(ast.Name("x", ast.Load()), y, [p], []),
1153 "must have Store context")
1154 self.stmt(ast.For(x, ast.Name("y", ast.Store()), [p], []),
1155 "must have Load context")
1156 e = ast.Expr(ast.Name("x", ast.Store()))
1157 self.stmt(ast.For(x, y, [e], []), "must have Load context")
1158 self.stmt(ast.For(x, y, [p], [e]), "must have Load context")
1159
1160 def test_while(self):
1161 self.stmt(ast.While(ast.Num(3), [], []), "empty body on While")
1162 self.stmt(ast.While(ast.Name("x", ast.Store()), [ast.Pass()], []),
1163 "must have Load context")
1164 self.stmt(ast.While(ast.Num(3), [ast.Pass()],
1165 [ast.Expr(ast.Name("x", ast.Store()))]),
1166 "must have Load context")
1167
1168 def test_if(self):
1169 self.stmt(ast.If(ast.Num(3), [], []), "empty body on If")
1170 i = ast.If(ast.Name("x", ast.Store()), [ast.Pass()], [])
1171 self.stmt(i, "must have Load context")
1172 i = ast.If(ast.Num(3), [ast.Expr(ast.Name("x", ast.Store()))], [])
1173 self.stmt(i, "must have Load context")
1174 i = ast.If(ast.Num(3), [ast.Pass()],
1175 [ast.Expr(ast.Name("x", ast.Store()))])
1176 self.stmt(i, "must have Load context")
1177
1178 def test_with(self):
1179 p = ast.Pass()
1180 self.stmt(ast.With([], [p]), "empty items on With")
1181 i = ast.withitem(ast.Num(3), None)
1182 self.stmt(ast.With([i], []), "empty body on With")
1183 i = ast.withitem(ast.Name("x", ast.Store()), None)
1184 self.stmt(ast.With([i], [p]), "must have Load context")
1185 i = ast.withitem(ast.Num(3), ast.Name("x", ast.Load()))
1186 self.stmt(ast.With([i], [p]), "must have Store context")
1187
1188 def test_raise(self):
1189 r = ast.Raise(None, ast.Num(3))
1190 self.stmt(r, "Raise with cause but no exception")
1191 r = ast.Raise(ast.Name("x", ast.Store()), None)
1192 self.stmt(r, "must have Load context")
1193 r = ast.Raise(ast.Num(4), ast.Name("x", ast.Store()))
1194 self.stmt(r, "must have Load context")
1195
1196 def test_try(self):
1197 p = ast.Pass()
1198 t = ast.Try([], [], [], [p])
1199 self.stmt(t, "empty body on Try")
1200 t = ast.Try([ast.Expr(ast.Name("x", ast.Store()))], [], [], [p])
1201 self.stmt(t, "must have Load context")
1202 t = ast.Try([p], [], [], [])
1203 self.stmt(t, "Try has neither except handlers nor finalbody")
1204 t = ast.Try([p], [], [p], [p])
1205 self.stmt(t, "Try has orelse but no except handlers")
1206 t = ast.Try([p], [ast.ExceptHandler(None, "x", [])], [], [])
1207 self.stmt(t, "empty body on ExceptHandler")
1208 e = [ast.ExceptHandler(ast.Name("x", ast.Store()), "y", [p])]
1209 self.stmt(ast.Try([p], e, [], []), "must have Load context")
1210 e = [ast.ExceptHandler(None, "x", [p])]
1211 t = ast.Try([p], e, [ast.Expr(ast.Name("x", ast.Store()))], [p])
1212 self.stmt(t, "must have Load context")
1213 t = ast.Try([p], e, [p], [ast.Expr(ast.Name("x", ast.Store()))])
1214 self.stmt(t, "must have Load context")
1215
1216 def test_assert(self):
1217 self.stmt(ast.Assert(ast.Name("x", ast.Store()), None),
1218 "must have Load context")
1219 assrt = ast.Assert(ast.Name("x", ast.Load()),
1220 ast.Name("y", ast.Store()))
1221 self.stmt(assrt, "must have Load context")
1222
1223 def test_import(self):
1224 self.stmt(ast.Import([]), "empty names on Import")
1225
1226 def test_importfrom(self):
1227 imp = ast.ImportFrom(None, [ast.alias("x", None)], -42)
Serhiy Storchaka7de28402016-06-27 23:40:43 +03001228 self.stmt(imp, "Negative ImportFrom level")
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001229 self.stmt(ast.ImportFrom(None, [], 0), "empty names on ImportFrom")
1230
1231 def test_global(self):
1232 self.stmt(ast.Global([]), "empty names on Global")
1233
1234 def test_nonlocal(self):
1235 self.stmt(ast.Nonlocal([]), "empty names on Nonlocal")
1236
1237 def test_expr(self):
1238 e = ast.Expr(ast.Name("x", ast.Store()))
1239 self.stmt(e, "must have Load context")
1240
1241 def test_boolop(self):
1242 b = ast.BoolOp(ast.And(), [])
1243 self.expr(b, "less than 2 values")
1244 b = ast.BoolOp(ast.And(), [ast.Num(3)])
1245 self.expr(b, "less than 2 values")
1246 b = ast.BoolOp(ast.And(), [ast.Num(4), None])
1247 self.expr(b, "None disallowed")
1248 b = ast.BoolOp(ast.And(), [ast.Num(4), ast.Name("x", ast.Store())])
1249 self.expr(b, "must have Load context")
1250
1251 def test_unaryop(self):
1252 u = ast.UnaryOp(ast.Not(), ast.Name("x", ast.Store()))
1253 self.expr(u, "must have Load context")
1254
1255 def test_lambda(self):
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01001256 a = ast.arguments([], [], None, [], [], None, [])
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001257 self.expr(ast.Lambda(a, ast.Name("x", ast.Store())),
1258 "must have Load context")
1259 def fac(args):
1260 return ast.Lambda(args, ast.Name("x", ast.Load()))
1261 self._check_arguments(fac, self.expr)
1262
1263 def test_ifexp(self):
1264 l = ast.Name("x", ast.Load())
1265 s = ast.Name("y", ast.Store())
1266 for args in (s, l, l), (l, s, l), (l, l, s):
Benjamin Peterson71ce8972011-08-09 16:17:12 -05001267 self.expr(ast.IfExp(*args), "must have Load context")
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001268
1269 def test_dict(self):
1270 d = ast.Dict([], [ast.Name("x", ast.Load())])
1271 self.expr(d, "same number of keys as values")
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001272 d = ast.Dict([ast.Name("x", ast.Load())], [None])
1273 self.expr(d, "None disallowed")
1274
1275 def test_set(self):
1276 self.expr(ast.Set([None]), "None disallowed")
1277 s = ast.Set([ast.Name("x", ast.Store())])
1278 self.expr(s, "must have Load context")
1279
1280 def _check_comprehension(self, fac):
1281 self.expr(fac([]), "comprehension with no generators")
1282 g = ast.comprehension(ast.Name("x", ast.Load()),
Yury Selivanov52c4e7c2016-09-09 10:36:01 -07001283 ast.Name("x", ast.Load()), [], 0)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001284 self.expr(fac([g]), "must have Store context")
1285 g = ast.comprehension(ast.Name("x", ast.Store()),
Yury Selivanov52c4e7c2016-09-09 10:36:01 -07001286 ast.Name("x", ast.Store()), [], 0)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001287 self.expr(fac([g]), "must have Load context")
1288 x = ast.Name("x", ast.Store())
1289 y = ast.Name("y", ast.Load())
Yury Selivanov52c4e7c2016-09-09 10:36:01 -07001290 g = ast.comprehension(x, y, [None], 0)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001291 self.expr(fac([g]), "None disallowed")
Yury Selivanov52c4e7c2016-09-09 10:36:01 -07001292 g = ast.comprehension(x, y, [ast.Name("x", ast.Store())], 0)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001293 self.expr(fac([g]), "must have Load context")
1294
1295 def _simple_comp(self, fac):
1296 g = ast.comprehension(ast.Name("x", ast.Store()),
Yury Selivanov52c4e7c2016-09-09 10:36:01 -07001297 ast.Name("x", ast.Load()), [], 0)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001298 self.expr(fac(ast.Name("x", ast.Store()), [g]),
1299 "must have Load context")
1300 def wrap(gens):
1301 return fac(ast.Name("x", ast.Store()), gens)
1302 self._check_comprehension(wrap)
1303
1304 def test_listcomp(self):
1305 self._simple_comp(ast.ListComp)
1306
1307 def test_setcomp(self):
1308 self._simple_comp(ast.SetComp)
1309
1310 def test_generatorexp(self):
1311 self._simple_comp(ast.GeneratorExp)
1312
1313 def test_dictcomp(self):
1314 g = ast.comprehension(ast.Name("y", ast.Store()),
Yury Selivanov52c4e7c2016-09-09 10:36:01 -07001315 ast.Name("p", ast.Load()), [], 0)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001316 c = ast.DictComp(ast.Name("x", ast.Store()),
1317 ast.Name("y", ast.Load()), [g])
1318 self.expr(c, "must have Load context")
1319 c = ast.DictComp(ast.Name("x", ast.Load()),
1320 ast.Name("y", ast.Store()), [g])
1321 self.expr(c, "must have Load context")
1322 def factory(comps):
1323 k = ast.Name("x", ast.Load())
1324 v = ast.Name("y", ast.Load())
1325 return ast.DictComp(k, v, comps)
1326 self._check_comprehension(factory)
1327
1328 def test_yield(self):
Benjamin Peterson527c6222012-01-14 08:58:23 -05001329 self.expr(ast.Yield(ast.Name("x", ast.Store())), "must have Load")
1330 self.expr(ast.YieldFrom(ast.Name("x", ast.Store())), "must have Load")
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001331
1332 def test_compare(self):
1333 left = ast.Name("x", ast.Load())
1334 comp = ast.Compare(left, [ast.In()], [])
1335 self.expr(comp, "no comparators")
1336 comp = ast.Compare(left, [ast.In()], [ast.Num(4), ast.Num(5)])
1337 self.expr(comp, "different number of comparators and operands")
1338 comp = ast.Compare(ast.Num("blah"), [ast.In()], [left])
Serhiy Storchaka3f228112018-09-27 17:42:37 +03001339 self.expr(comp)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001340 comp = ast.Compare(left, [ast.In()], [ast.Num("blah")])
Serhiy Storchaka3f228112018-09-27 17:42:37 +03001341 self.expr(comp)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001342
1343 def test_call(self):
1344 func = ast.Name("x", ast.Load())
1345 args = [ast.Name("y", ast.Load())]
1346 keywords = [ast.keyword("w", ast.Name("z", ast.Load()))]
Benjamin Peterson025e9eb2015-05-05 20:16:41 -04001347 call = ast.Call(ast.Name("x", ast.Store()), args, keywords)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001348 self.expr(call, "must have Load context")
Benjamin Peterson025e9eb2015-05-05 20:16:41 -04001349 call = ast.Call(func, [None], keywords)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001350 self.expr(call, "None disallowed")
1351 bad_keywords = [ast.keyword("w", ast.Name("z", ast.Store()))]
Benjamin Peterson025e9eb2015-05-05 20:16:41 -04001352 call = ast.Call(func, args, bad_keywords)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001353 self.expr(call, "must have Load context")
1354
1355 def test_num(self):
1356 class subint(int):
1357 pass
1358 class subfloat(float):
1359 pass
1360 class subcomplex(complex):
1361 pass
Serhiy Storchaka3f228112018-09-27 17:42:37 +03001362 for obj in "0", "hello":
1363 self.expr(ast.Num(obj))
1364 for obj in subint(), subfloat(), subcomplex():
1365 self.expr(ast.Num(obj), "invalid type", exc=TypeError)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001366
1367 def test_attribute(self):
1368 attr = ast.Attribute(ast.Name("x", ast.Store()), "y", ast.Load())
1369 self.expr(attr, "must have Load context")
1370
1371 def test_subscript(self):
Serhiy Storchaka13d52c22020-03-10 18:52:34 +02001372 sub = ast.Subscript(ast.Name("x", ast.Store()), ast.Num(3),
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001373 ast.Load())
1374 self.expr(sub, "must have Load context")
1375 x = ast.Name("x", ast.Load())
Serhiy Storchaka13d52c22020-03-10 18:52:34 +02001376 sub = ast.Subscript(x, ast.Name("y", ast.Store()),
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001377 ast.Load())
1378 self.expr(sub, "must have Load context")
1379 s = ast.Name("x", ast.Store())
1380 for args in (s, None, None), (None, s, None), (None, None, s):
1381 sl = ast.Slice(*args)
1382 self.expr(ast.Subscript(x, sl, ast.Load()),
1383 "must have Load context")
Serhiy Storchaka13d52c22020-03-10 18:52:34 +02001384 sl = ast.Tuple([], ast.Load())
1385 self.expr(ast.Subscript(x, sl, ast.Load()))
1386 sl = ast.Tuple([s], ast.Load())
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001387 self.expr(ast.Subscript(x, sl, ast.Load()), "must have Load context")
1388
1389 def test_starred(self):
1390 left = ast.List([ast.Starred(ast.Name("x", ast.Load()), ast.Store())],
1391 ast.Store())
1392 assign = ast.Assign([left], ast.Num(4))
1393 self.stmt(assign, "must have Store context")
1394
1395 def _sequence(self, fac):
1396 self.expr(fac([None], ast.Load()), "None disallowed")
1397 self.expr(fac([ast.Name("x", ast.Store())], ast.Load()),
1398 "must have Load context")
1399
1400 def test_list(self):
1401 self._sequence(ast.List)
1402
1403 def test_tuple(self):
1404 self._sequence(ast.Tuple)
1405
Benjamin Peterson442f2092012-12-06 17:41:04 -05001406 def test_nameconstant(self):
Serhiy Storchaka3f228112018-09-27 17:42:37 +03001407 self.expr(ast.NameConstant(4))
Benjamin Peterson442f2092012-12-06 17:41:04 -05001408
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001409 def test_stdlib_validates(self):
1410 stdlib = os.path.dirname(ast.__file__)
1411 tests = [fn for fn in os.listdir(stdlib) if fn.endswith(".py")]
1412 tests.extend(["test/test_grammar.py", "test/test_unpack_ex.py"])
1413 for module in tests:
Serhiy Storchaka3bcbedc2019-01-18 07:47:48 +02001414 with self.subTest(module):
1415 fn = os.path.join(stdlib, module)
1416 with open(fn, "r", encoding="utf-8") as fp:
1417 source = fp.read()
1418 mod = ast.parse(source, fn)
1419 compile(mod, fn, "exec")
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001420
1421
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001422class ConstantTests(unittest.TestCase):
1423 """Tests on the ast.Constant node type."""
1424
1425 def compile_constant(self, value):
1426 tree = ast.parse("x = 123")
1427
1428 node = tree.body[0].value
1429 new_node = ast.Constant(value=value)
1430 ast.copy_location(new_node, node)
1431 tree.body[0].value = new_node
1432
1433 code = compile(tree, "<string>", "exec")
1434
1435 ns = {}
1436 exec(code, ns)
1437 return ns['x']
1438
Victor Stinnerbe59d142016-01-27 00:39:12 +01001439 def test_validation(self):
1440 with self.assertRaises(TypeError) as cm:
1441 self.compile_constant([1, 2, 3])
1442 self.assertEqual(str(cm.exception),
1443 "got an invalid type in Constant: list")
1444
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001445 def test_singletons(self):
1446 for const in (None, False, True, Ellipsis, b'', frozenset()):
1447 with self.subTest(const=const):
1448 value = self.compile_constant(const)
1449 self.assertIs(value, const)
1450
1451 def test_values(self):
1452 nested_tuple = (1,)
1453 nested_frozenset = frozenset({1})
1454 for level in range(3):
1455 nested_tuple = (nested_tuple, 2)
1456 nested_frozenset = frozenset({nested_frozenset, 2})
1457 values = (123, 123.0, 123j,
1458 "unicode", b'bytes',
1459 tuple("tuple"), frozenset("frozenset"),
1460 nested_tuple, nested_frozenset)
1461 for value in values:
1462 with self.subTest(value=value):
1463 result = self.compile_constant(value)
1464 self.assertEqual(result, value)
1465
1466 def test_assign_to_constant(self):
1467 tree = ast.parse("x = 1")
1468
1469 target = tree.body[0].targets[0]
1470 new_target = ast.Constant(value=1)
1471 ast.copy_location(new_target, target)
1472 tree.body[0].targets[0] = new_target
1473
1474 with self.assertRaises(ValueError) as cm:
1475 compile(tree, "string", "exec")
1476 self.assertEqual(str(cm.exception),
1477 "expression which can't be assigned "
1478 "to in Store context")
1479
1480 def test_get_docstring(self):
1481 tree = ast.parse("'docstring'\nx = 1")
1482 self.assertEqual(ast.get_docstring(tree), 'docstring')
1483
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001484 def get_load_const(self, tree):
1485 # Compile to bytecode, disassemble and get parameter of LOAD_CONST
1486 # instructions
1487 co = compile(tree, '<string>', 'exec')
1488 consts = []
1489 for instr in dis.get_instructions(co):
1490 if instr.opname == 'LOAD_CONST':
1491 consts.append(instr.argval)
1492 return consts
1493
1494 @support.cpython_only
1495 def test_load_const(self):
1496 consts = [None,
1497 True, False,
1498 124,
1499 2.0,
1500 3j,
1501 "unicode",
1502 b'bytes',
1503 (1, 2, 3)]
1504
Victor Stinnera2724092016-02-08 18:17:58 +01001505 code = '\n'.join(['x={!r}'.format(const) for const in consts])
1506 code += '\nx = ...'
1507 consts.extend((Ellipsis, None))
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001508
1509 tree = ast.parse(code)
Victor Stinnera2724092016-02-08 18:17:58 +01001510 self.assertEqual(self.get_load_const(tree),
1511 consts)
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001512
1513 # Replace expression nodes with constants
Victor Stinnera2724092016-02-08 18:17:58 +01001514 for assign, const in zip(tree.body, consts):
1515 assert isinstance(assign, ast.Assign), ast.dump(assign)
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001516 new_node = ast.Constant(value=const)
Victor Stinnera2724092016-02-08 18:17:58 +01001517 ast.copy_location(new_node, assign.value)
1518 assign.value = new_node
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001519
Victor Stinnera2724092016-02-08 18:17:58 +01001520 self.assertEqual(self.get_load_const(tree),
1521 consts)
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001522
1523 def test_literal_eval(self):
1524 tree = ast.parse("1 + 2")
1525 binop = tree.body[0].value
1526
1527 new_left = ast.Constant(value=10)
1528 ast.copy_location(new_left, binop.left)
1529 binop.left = new_left
1530
Serhiy Storchakad8ac4d12018-01-04 11:15:39 +02001531 new_right = ast.Constant(value=20j)
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001532 ast.copy_location(new_right, binop.right)
1533 binop.right = new_right
1534
Serhiy Storchakad8ac4d12018-01-04 11:15:39 +02001535 self.assertEqual(ast.literal_eval(binop), 10+20j)
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001536
Guido van Rossum10f8ce62019-03-13 13:00:46 -07001537 def test_string_kind(self):
1538 c = ast.parse('"x"', mode='eval').body
1539 self.assertEqual(c.value, "x")
1540 self.assertEqual(c.kind, None)
1541
1542 c = ast.parse('u"x"', mode='eval').body
1543 self.assertEqual(c.value, "x")
1544 self.assertEqual(c.kind, "u")
1545
1546 c = ast.parse('r"x"', mode='eval').body
1547 self.assertEqual(c.value, "x")
1548 self.assertEqual(c.kind, None)
1549
1550 c = ast.parse('b"x"', mode='eval').body
1551 self.assertEqual(c.value, b"x")
1552 self.assertEqual(c.kind, None)
1553
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001554
Ivan Levkivskyi9932a222019-01-22 11:18:22 +00001555class EndPositionTests(unittest.TestCase):
1556 """Tests for end position of AST nodes.
1557
1558 Testing end positions of nodes requires a bit of extra care
1559 because of how LL parsers work.
1560 """
1561 def _check_end_pos(self, ast_node, end_lineno, end_col_offset):
1562 self.assertEqual(ast_node.end_lineno, end_lineno)
1563 self.assertEqual(ast_node.end_col_offset, end_col_offset)
1564
1565 def _check_content(self, source, ast_node, content):
1566 self.assertEqual(ast.get_source_segment(source, ast_node), content)
1567
1568 def _parse_value(self, s):
1569 # Use duck-typing to support both single expression
1570 # and a right hand side of an assignment statement.
1571 return ast.parse(s).body[0].value
1572
1573 def test_lambda(self):
1574 s = 'lambda x, *y: None'
1575 lam = self._parse_value(s)
1576 self._check_content(s, lam.body, 'None')
1577 self._check_content(s, lam.args.args[0], 'x')
1578 self._check_content(s, lam.args.vararg, 'y')
1579
1580 def test_func_def(self):
1581 s = dedent('''
1582 def func(x: int,
1583 *args: str,
1584 z: float = 0,
1585 **kwargs: Any) -> bool:
1586 return True
1587 ''').strip()
1588 fdef = ast.parse(s).body[0]
1589 self._check_end_pos(fdef, 5, 15)
1590 self._check_content(s, fdef.body[0], 'return True')
1591 self._check_content(s, fdef.args.args[0], 'x: int')
1592 self._check_content(s, fdef.args.args[0].annotation, 'int')
1593 self._check_content(s, fdef.args.kwarg, 'kwargs: Any')
1594 self._check_content(s, fdef.args.kwarg.annotation, 'Any')
1595
1596 def test_call(self):
1597 s = 'func(x, y=2, **kw)'
1598 call = self._parse_value(s)
1599 self._check_content(s, call.func, 'func')
1600 self._check_content(s, call.keywords[0].value, '2')
1601 self._check_content(s, call.keywords[1].value, 'kw')
1602
1603 def test_call_noargs(self):
1604 s = 'x[0]()'
1605 call = self._parse_value(s)
1606 self._check_content(s, call.func, 'x[0]')
1607 self._check_end_pos(call, 1, 6)
1608
1609 def test_class_def(self):
1610 s = dedent('''
1611 class C(A, B):
1612 x: int = 0
1613 ''').strip()
1614 cdef = ast.parse(s).body[0]
1615 self._check_end_pos(cdef, 2, 14)
1616 self._check_content(s, cdef.bases[1], 'B')
1617 self._check_content(s, cdef.body[0], 'x: int = 0')
1618
1619 def test_class_kw(self):
1620 s = 'class S(metaclass=abc.ABCMeta): pass'
1621 cdef = ast.parse(s).body[0]
1622 self._check_content(s, cdef.keywords[0].value, 'abc.ABCMeta')
1623
1624 def test_multi_line_str(self):
1625 s = dedent('''
1626 x = """Some multi-line text.
1627
1628 It goes on starting from same indent."""
1629 ''').strip()
1630 assign = ast.parse(s).body[0]
1631 self._check_end_pos(assign, 3, 40)
1632 self._check_end_pos(assign.value, 3, 40)
1633
1634 def test_continued_str(self):
1635 s = dedent('''
1636 x = "first part" \\
1637 "second part"
1638 ''').strip()
1639 assign = ast.parse(s).body[0]
1640 self._check_end_pos(assign, 2, 13)
1641 self._check_end_pos(assign.value, 2, 13)
1642
1643 def test_suites(self):
1644 # We intentionally put these into the same string to check
1645 # that empty lines are not part of the suite.
1646 s = dedent('''
1647 while True:
1648 pass
1649
1650 if one():
1651 x = None
1652 elif other():
1653 y = None
1654 else:
1655 z = None
1656
1657 for x, y in stuff:
1658 assert True
1659
1660 try:
1661 raise RuntimeError
1662 except TypeError as e:
1663 pass
1664
1665 pass
1666 ''').strip()
1667 mod = ast.parse(s)
1668 while_loop = mod.body[0]
1669 if_stmt = mod.body[1]
1670 for_loop = mod.body[2]
1671 try_stmt = mod.body[3]
1672 pass_stmt = mod.body[4]
1673
1674 self._check_end_pos(while_loop, 2, 8)
1675 self._check_end_pos(if_stmt, 9, 12)
1676 self._check_end_pos(for_loop, 12, 15)
1677 self._check_end_pos(try_stmt, 17, 8)
1678 self._check_end_pos(pass_stmt, 19, 4)
1679
1680 self._check_content(s, while_loop.test, 'True')
1681 self._check_content(s, if_stmt.body[0], 'x = None')
1682 self._check_content(s, if_stmt.orelse[0].test, 'other()')
1683 self._check_content(s, for_loop.target, 'x, y')
1684 self._check_content(s, try_stmt.body[0], 'raise RuntimeError')
1685 self._check_content(s, try_stmt.handlers[0].type, 'TypeError')
1686
1687 def test_fstring(self):
1688 s = 'x = f"abc {x + y} abc"'
1689 fstr = self._parse_value(s)
1690 binop = fstr.values[1].value
1691 self._check_content(s, binop, 'x + y')
1692
1693 def test_fstring_multi_line(self):
1694 s = dedent('''
1695 f"""Some multi-line text.
1696 {
1697 arg_one
1698 +
1699 arg_two
1700 }
1701 It goes on..."""
1702 ''').strip()
1703 fstr = self._parse_value(s)
1704 binop = fstr.values[1].value
1705 self._check_end_pos(binop, 5, 7)
1706 self._check_content(s, binop.left, 'arg_one')
1707 self._check_content(s, binop.right, 'arg_two')
1708
1709 def test_import_from_multi_line(self):
1710 s = dedent('''
1711 from x.y.z import (
1712 a, b, c as c
1713 )
1714 ''').strip()
1715 imp = ast.parse(s).body[0]
1716 self._check_end_pos(imp, 3, 1)
1717
1718 def test_slices(self):
1719 s1 = 'f()[1, 2] [0]'
1720 s2 = 'x[ a.b: c.d]'
1721 sm = dedent('''
1722 x[ a.b: f () ,
1723 g () : c.d
1724 ]
1725 ''').strip()
1726 i1, i2, im = map(self._parse_value, (s1, s2, sm))
1727 self._check_content(s1, i1.value, 'f()[1, 2]')
Serhiy Storchaka13d52c22020-03-10 18:52:34 +02001728 self._check_content(s1, i1.value.slice, '1, 2')
Ivan Levkivskyi9932a222019-01-22 11:18:22 +00001729 self._check_content(s2, i2.slice.lower, 'a.b')
1730 self._check_content(s2, i2.slice.upper, 'c.d')
Serhiy Storchaka13d52c22020-03-10 18:52:34 +02001731 self._check_content(sm, im.slice.elts[0].upper, 'f ()')
1732 self._check_content(sm, im.slice.elts[1].lower, 'g ()')
Ivan Levkivskyi9932a222019-01-22 11:18:22 +00001733 self._check_end_pos(im, 3, 3)
1734
1735 def test_binop(self):
1736 s = dedent('''
1737 (1 * 2 + (3 ) +
1738 4
1739 )
1740 ''').strip()
1741 binop = self._parse_value(s)
1742 self._check_end_pos(binop, 2, 6)
1743 self._check_content(s, binop.right, '4')
1744 self._check_content(s, binop.left, '1 * 2 + (3 )')
1745 self._check_content(s, binop.left.right, '3')
1746
1747 def test_boolop(self):
1748 s = dedent('''
1749 if (one_condition and
1750 (other_condition or yet_another_one)):
1751 pass
1752 ''').strip()
1753 bop = ast.parse(s).body[0].test
1754 self._check_end_pos(bop, 2, 44)
1755 self._check_content(s, bop.values[1],
1756 'other_condition or yet_another_one')
1757
1758 def test_tuples(self):
1759 s1 = 'x = () ;'
1760 s2 = 'x = 1 , ;'
1761 s3 = 'x = (1 , 2 ) ;'
1762 sm = dedent('''
1763 x = (
1764 a, b,
1765 )
1766 ''').strip()
1767 t1, t2, t3, tm = map(self._parse_value, (s1, s2, s3, sm))
1768 self._check_content(s1, t1, '()')
1769 self._check_content(s2, t2, '1 ,')
1770 self._check_content(s3, t3, '(1 , 2 )')
1771 self._check_end_pos(tm, 3, 1)
1772
1773 def test_attribute_spaces(self):
1774 s = 'func(x. y .z)'
1775 call = self._parse_value(s)
1776 self._check_content(s, call, s)
1777 self._check_content(s, call.args[0], 'x. y .z')
1778
Serhiy Storchaka6e619c42020-02-12 22:37:49 +02001779 def test_redundant_parenthesis(self):
1780 s = '( ( ( a + b ) ) )'
1781 v = ast.parse(s).body[0].value
1782 self.assertEqual(type(v).__name__, 'BinOp')
1783 self._check_content(s, v, 'a + b')
1784 s2 = 'await ' + s
1785 v = ast.parse(s2).body[0].value.value
1786 self.assertEqual(type(v).__name__, 'BinOp')
1787 self._check_content(s2, v, 'a + b')
1788
1789 def test_trailers_with_redundant_parenthesis(self):
1790 tests = (
1791 ('( ( ( a ) ) ) ( )', 'Call'),
1792 ('( ( ( a ) ) ) ( b )', 'Call'),
1793 ('( ( ( a ) ) ) [ b ]', 'Subscript'),
1794 ('( ( ( a ) ) ) . b', 'Attribute'),
1795 )
1796 for s, t in tests:
1797 with self.subTest(s):
1798 v = ast.parse(s).body[0].value
1799 self.assertEqual(type(v).__name__, t)
1800 self._check_content(s, v, s)
1801 s2 = 'await ' + s
1802 v = ast.parse(s2).body[0].value.value
1803 self.assertEqual(type(v).__name__, t)
1804 self._check_content(s2, v, s)
1805
Ivan Levkivskyi9932a222019-01-22 11:18:22 +00001806 def test_displays(self):
1807 s1 = '[{}, {1, }, {1, 2,} ]'
1808 s2 = '{a: b, f (): g () ,}'
1809 c1 = self._parse_value(s1)
1810 c2 = self._parse_value(s2)
1811 self._check_content(s1, c1.elts[0], '{}')
1812 self._check_content(s1, c1.elts[1], '{1, }')
1813 self._check_content(s1, c1.elts[2], '{1, 2,}')
1814 self._check_content(s2, c2.keys[1], 'f ()')
1815 self._check_content(s2, c2.values[1], 'g ()')
1816
1817 def test_comprehensions(self):
1818 s = dedent('''
1819 x = [{x for x, y in stuff
1820 if cond.x} for stuff in things]
1821 ''').strip()
1822 cmp = self._parse_value(s)
1823 self._check_end_pos(cmp, 2, 37)
1824 self._check_content(s, cmp.generators[0].iter, 'things')
1825 self._check_content(s, cmp.elt.generators[0].iter, 'stuff')
1826 self._check_content(s, cmp.elt.generators[0].ifs[0], 'cond.x')
1827 self._check_content(s, cmp.elt.generators[0].target, 'x, y')
1828
1829 def test_yield_await(self):
1830 s = dedent('''
1831 async def f():
1832 yield x
1833 await y
1834 ''').strip()
1835 fdef = ast.parse(s).body[0]
1836 self._check_content(s, fdef.body[0].value, 'yield x')
1837 self._check_content(s, fdef.body[1].value, 'await y')
1838
1839 def test_source_segment_multi(self):
1840 s_orig = dedent('''
1841 x = (
1842 a, b,
1843 ) + ()
1844 ''').strip()
1845 s_tuple = dedent('''
1846 (
1847 a, b,
1848 )
1849 ''').strip()
1850 binop = self._parse_value(s_orig)
1851 self.assertEqual(ast.get_source_segment(s_orig, binop.left), s_tuple)
1852
1853 def test_source_segment_padded(self):
1854 s_orig = dedent('''
1855 class C:
1856 def fun(self) -> None:
1857 "Đ–Đ–Đ–Đ–Đ–"
1858 ''').strip()
1859 s_method = ' def fun(self) -> None:\n' \
1860 ' "Đ–Đ–Đ–Đ–Đ–"'
1861 cdef = ast.parse(s_orig).body[0]
1862 self.assertEqual(ast.get_source_segment(s_orig, cdef.body[0], padded=True),
1863 s_method)
1864
1865 def test_source_segment_endings(self):
1866 s = 'v = 1\r\nw = 1\nx = 1\n\ry = 1\rz = 1\r\n'
1867 v, w, x, y, z = ast.parse(s).body
1868 self._check_content(s, v, 'v = 1')
1869 self._check_content(s, w, 'w = 1')
1870 self._check_content(s, x, 'x = 1')
1871 self._check_content(s, y, 'y = 1')
1872 self._check_content(s, z, 'z = 1')
1873
1874 def test_source_segment_tabs(self):
1875 s = dedent('''
1876 class C:
1877 \t\f def fun(self) -> None:
1878 \t\f pass
1879 ''').strip()
1880 s_method = ' \t\f def fun(self) -> None:\n' \
1881 ' \t\f pass'
1882
1883 cdef = ast.parse(s).body[0]
1884 self.assertEqual(ast.get_source_segment(s, cdef.body[0], padded=True), s_method)
1885
Irit Katriele6578a22020-05-18 19:14:12 +01001886 def test_source_segment_missing_info(self):
1887 s = 'v = 1\r\nw = 1\nx = 1\n\ry = 1\r\n'
1888 v, w, x, y = ast.parse(s).body
1889 del v.lineno
1890 del w.end_lineno
1891 del x.col_offset
1892 del y.end_col_offset
1893 self.assertIsNone(ast.get_source_segment(s, v))
1894 self.assertIsNone(ast.get_source_segment(s, w))
1895 self.assertIsNone(ast.get_source_segment(s, x))
1896 self.assertIsNone(ast.get_source_segment(s, y))
Ivan Levkivskyi9932a222019-01-22 11:18:22 +00001897
Serhiy Storchakac3ea41e2019-08-26 10:13:19 +03001898class NodeVisitorTests(unittest.TestCase):
1899 def test_old_constant_nodes(self):
1900 class Visitor(ast.NodeVisitor):
1901 def visit_Num(self, node):
1902 log.append((node.lineno, 'Num', node.n))
1903 def visit_Str(self, node):
1904 log.append((node.lineno, 'Str', node.s))
1905 def visit_Bytes(self, node):
1906 log.append((node.lineno, 'Bytes', node.s))
1907 def visit_NameConstant(self, node):
1908 log.append((node.lineno, 'NameConstant', node.value))
1909 def visit_Ellipsis(self, node):
1910 log.append((node.lineno, 'Ellipsis', ...))
1911 mod = ast.parse(dedent('''\
1912 i = 42
1913 f = 4.25
1914 c = 4.25j
1915 s = 'string'
1916 b = b'bytes'
1917 t = True
1918 n = None
1919 e = ...
1920 '''))
1921 visitor = Visitor()
1922 log = []
1923 with warnings.catch_warnings(record=True) as wlog:
1924 warnings.filterwarnings('always', '', DeprecationWarning)
1925 visitor.visit(mod)
1926 self.assertEqual(log, [
1927 (1, 'Num', 42),
1928 (2, 'Num', 4.25),
1929 (3, 'Num', 4.25j),
1930 (4, 'Str', 'string'),
1931 (5, 'Bytes', b'bytes'),
1932 (6, 'NameConstant', True),
1933 (7, 'NameConstant', None),
1934 (8, 'Ellipsis', ...),
1935 ])
1936 self.assertEqual([str(w.message) for w in wlog], [
1937 'visit_Num is deprecated; add visit_Constant',
1938 'visit_Num is deprecated; add visit_Constant',
1939 'visit_Num is deprecated; add visit_Constant',
1940 'visit_Str is deprecated; add visit_Constant',
1941 'visit_Bytes is deprecated; add visit_Constant',
1942 'visit_NameConstant is deprecated; add visit_Constant',
1943 'visit_NameConstant is deprecated; add visit_Constant',
1944 'visit_Ellipsis is deprecated; add visit_Constant',
1945 ])
1946
1947
Neal Norwitzee9b10a2008-03-31 05:29:39 +00001948def main():
1949 if __name__ != '__main__':
Martin v. Löwis49c5da12006-03-01 22:49:05 +00001950 return
Neal Norwitzee9b10a2008-03-31 05:29:39 +00001951 if sys.argv[1:] == ['-g']:
1952 for statements, kind in ((exec_tests, "exec"), (single_tests, "single"),
1953 (eval_tests, "eval")):
1954 print(kind+"_results = [")
Victor Stinnerf0891962016-02-08 17:15:21 +01001955 for statement in statements:
1956 tree = ast.parse(statement, "?", kind)
1957 print("%r," % (to_tuple(tree),))
Neal Norwitzee9b10a2008-03-31 05:29:39 +00001958 print("]")
1959 print("main()")
1960 raise SystemExit
Brett Cannon3e9a9ae2013-06-12 21:25:59 -04001961 unittest.main()
Tim Peters400cbc32006-02-28 18:44:41 +00001962
Guido van Rossumdcfcd142019-01-31 03:40:27 -08001963#### EVERYTHING BELOW IS GENERATED BY python Lib/test/test_ast.py -g #####
Tim Peters400cbc32006-02-28 18:44:41 +00001964exec_results = [
Serhiy Storchaka850a8852020-01-10 10:12:55 +02001965('Module', [('Expr', (1, 0, 1, 4), ('Constant', (1, 0, 1, 4), None, None))], []),
1966('Module', [('Expr', (1, 0, 1, 18), ('Constant', (1, 0, 1, 18), 'module docstring', None))], []),
1967('Module', [('FunctionDef', (1, 0, 1, 13), 'f', ('arguments', [], [], None, [], [], None, []), [('Pass', (1, 9, 1, 13))], [], None, None)], []),
1968('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)], []),
1969('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)], []),
1970('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)], []),
1971('Module', [('FunctionDef', (1, 0, 1, 18), 'f', ('arguments', [], [], ('arg', (1, 7, 1, 11), 'args', None, None), [], [], None, []), [('Pass', (1, 14, 1, 18))], [], None, None)], []),
1972('Module', [('FunctionDef', (1, 0, 1, 21), 'f', ('arguments', [], [], None, [], [], ('arg', (1, 8, 1, 14), 'kwargs', None, None), []), [('Pass', (1, 17, 1, 21))], [], None, None)], []),
1973('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)], []),
1974('Module', [('ClassDef', (1, 0, 1, 12), 'C', [], [], [('Pass', (1, 8, 1, 12))], [])], []),
1975('Module', [('ClassDef', (1, 0, 1, 32), 'C', [], [], [('Expr', (1, 9, 1, 32), ('Constant', (1, 9, 1, 32), 'docstring for class C', None))], [])], []),
1976('Module', [('ClassDef', (1, 0, 1, 21), 'C', [('Name', (1, 8, 1, 14), 'object', ('Load',))], [], [('Pass', (1, 17, 1, 21))], [])], []),
1977('Module', [('FunctionDef', (1, 0, 1, 16), 'f', ('arguments', [], [], None, [], [], None, []), [('Return', (1, 8, 1, 16), ('Constant', (1, 15, 1, 16), 1, None))], [], None, None)], []),
1978('Module', [('Delete', (1, 0, 1, 5), [('Name', (1, 4, 1, 5), 'v', ('Del',))])], []),
1979('Module', [('Assign', (1, 0, 1, 5), [('Name', (1, 0, 1, 1), 'v', ('Store',))], ('Constant', (1, 4, 1, 5), 1, None), None)], []),
1980('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)], []),
1981('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)], []),
1982('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)], []),
1983('Module', [('AugAssign', (1, 0, 1, 6), ('Name', (1, 0, 1, 1), 'v', ('Store',)), ('Add',), ('Constant', (1, 5, 1, 6), 1, None))], []),
1984('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)], []),
1985('Module', [('While', (1, 0, 1, 12), ('Name', (1, 6, 1, 7), 'v', ('Load',)), [('Pass', (1, 8, 1, 12))], [])], []),
1986('Module', [('If', (1, 0, 1, 9), ('Name', (1, 3, 1, 4), 'v', ('Load',)), [('Pass', (1, 5, 1, 9))], [])], []),
1987('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))], [])])], []),
1988('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))])])], []),
1989('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)], []),
1990('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)], []),
1991('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)], []),
1992('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))])], [], [])], []),
1993('Module', [('Try', (1, 0, 4, 6), [('Pass', (2, 2, 2, 6))], [], [], [('Pass', (4, 2, 4, 6))])], []),
1994('Module', [('Assert', (1, 0, 1, 8), ('Name', (1, 7, 1, 8), 'v', ('Load',)), None)], []),
1995('Module', [('Import', (1, 0, 1, 10), [('alias', 'sys', None)])], []),
1996('Module', [('ImportFrom', (1, 0, 1, 17), 'sys', [('alias', 'v', None)], 0)], []),
1997('Module', [('Global', (1, 0, 1, 8), ['v'])], []),
1998('Module', [('Expr', (1, 0, 1, 1), ('Constant', (1, 0, 1, 1), 1, None))], []),
1999('Module', [('Pass', (1, 0, 1, 4))], []),
2000('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)], []),
2001('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)], []),
2002('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)], []),
2003('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)], []),
2004('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)], []),
2005('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)]))], []),
2006('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)]))], []),
2007('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)]))], []),
2008('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)]))], []),
2009('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)]))], []),
2010('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)], []),
2011('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)], []),
2012('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)], []),
2013('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)]))], []),
2014('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)]))], []),
2015('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)], []),
2016('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)], []),
2017('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)], []),
2018('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)], [])])], []),
2019('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 +01002020('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 +02002021('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)))], []),
2022('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)], []),
2023('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)], []),
2024('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)], []),
2025('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)], []),
2026('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)], []),
2027('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)], []),
2028('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)], []),
2029('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)], []),
2030('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)], []),
2031('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 +00002032]
2033single_results = [
Serhiy Storchaka850a8852020-01-10 10:12:55 +02002034('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 +00002035]
2036eval_results = [
Serhiy Storchaka850a8852020-01-10 10:12:55 +02002037('Expression', ('Constant', (1, 0, 1, 4), None, None)),
2038('Expression', ('BoolOp', (1, 0, 1, 7), ('And',), [('Name', (1, 0, 1, 1), 'a', ('Load',)), ('Name', (1, 6, 1, 7), 'b', ('Load',))])),
2039('Expression', ('BinOp', (1, 0, 1, 5), ('Name', (1, 0, 1, 1), 'a', ('Load',)), ('Add',), ('Name', (1, 4, 1, 5), 'b', ('Load',)))),
2040('Expression', ('UnaryOp', (1, 0, 1, 5), ('Not',), ('Name', (1, 4, 1, 5), 'v', ('Load',)))),
2041('Expression', ('Lambda', (1, 0, 1, 11), ('arguments', [], [], None, [], [], None, []), ('Constant', (1, 7, 1, 11), None, None))),
2042('Expression', ('Dict', (1, 0, 1, 7), [('Constant', (1, 2, 1, 3), 1, None)], [('Constant', (1, 4, 1, 5), 2, None)])),
2043('Expression', ('Dict', (1, 0, 1, 2), [], [])),
2044('Expression', ('Set', (1, 0, 1, 7), [('Constant', (1, 1, 1, 5), None, None)])),
2045('Expression', ('Dict', (1, 0, 5, 6), [('Constant', (2, 6, 2, 7), 1, None)], [('Constant', (4, 10, 4, 11), 2, None)])),
2046('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)])),
2047('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)])),
2048('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)])),
2049('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)])),
2050('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)])),
2051('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)])),
2052('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)])),
2053('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)])),
2054('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)])),
2055('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)])),
2056('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)])),
2057('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 +01002058('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 +02002059('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',))], [])),
2060('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)])], [])),
2061('Expression', ('Constant', (1, 0, 1, 2), 10, None)),
2062('Expression', ('Constant', (1, 0, 1, 8), 'string', None)),
2063('Expression', ('Attribute', (1, 0, 1, 3), ('Name', (1, 0, 1, 1), 'a', ('Load',)), 'b', ('Load',))),
Serhiy Storchaka13d52c22020-03-10 18:52:34 +02002064('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 +02002065('Expression', ('Name', (1, 0, 1, 1), 'v', ('Load',))),
2066('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',))),
2067('Expression', ('List', (1, 0, 1, 2), [], ('Load',))),
2068('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',))),
2069('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',))),
2070('Expression', ('Tuple', (1, 0, 1, 2), [], ('Load',))),
Serhiy Storchaka13d52c22020-03-10 18:52:34 +02002071('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 +00002072]
Neal Norwitzee9b10a2008-03-31 05:29:39 +00002073main()