blob: 78e4a5653d4efdfb615da1234eb5a08c365b8615 [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 )
815
816 def test_fix_missing_locations(self):
817 src = ast.parse('write("spam")')
818 src.body.append(ast.Expr(ast.Call(ast.Name('spam', ast.Load()),
Benjamin Peterson025e9eb2015-05-05 20:16:41 -0400819 [ast.Str('eggs')], [])))
Georg Brandl0c77a822008-06-10 16:37:50 +0000820 self.assertEqual(src, ast.fix_missing_locations(src))
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000821 self.maxDiff = None
Georg Brandl0c77a822008-06-10 16:37:50 +0000822 self.assertEqual(ast.dump(src, include_attributes=True),
823 "Module(body=[Expr(value=Call(func=Name(id='write', ctx=Load(), "
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000824 "lineno=1, col_offset=0, end_lineno=1, end_col_offset=5), "
Serhiy Storchakab7e95252020-03-10 00:07:47 +0200825 "args=[Constant(value='spam', lineno=1, col_offset=6, end_lineno=1, "
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000826 "end_col_offset=12)], keywords=[], lineno=1, col_offset=0, end_lineno=1, "
827 "end_col_offset=13), lineno=1, col_offset=0, end_lineno=1, "
828 "end_col_offset=13), Expr(value=Call(func=Name(id='spam', ctx=Load(), "
829 "lineno=1, col_offset=0, end_lineno=1, end_col_offset=0), "
830 "args=[Constant(value='eggs', lineno=1, col_offset=0, end_lineno=1, "
831 "end_col_offset=0)], keywords=[], lineno=1, col_offset=0, end_lineno=1, "
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800832 "end_col_offset=0), lineno=1, col_offset=0, end_lineno=1, end_col_offset=0)], "
833 "type_ignores=[])"
Georg Brandl0c77a822008-06-10 16:37:50 +0000834 )
835
836 def test_increment_lineno(self):
837 src = ast.parse('1 + 1', mode='eval')
838 self.assertEqual(ast.increment_lineno(src, n=3), src)
839 self.assertEqual(ast.dump(src, include_attributes=True),
Serhiy Storchakab7e95252020-03-10 00:07:47 +0200840 'Expression(body=BinOp(left=Constant(value=1, lineno=4, col_offset=0, '
841 'end_lineno=4, end_col_offset=1), op=Add(), right=Constant(value=1, '
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000842 'lineno=4, col_offset=4, end_lineno=4, end_col_offset=5), lineno=4, '
843 'col_offset=0, end_lineno=4, end_col_offset=5))'
Georg Brandl0c77a822008-06-10 16:37:50 +0000844 )
Georg Brandl619e7ba2011-01-09 07:38:51 +0000845 # issue10869: do not increment lineno of root twice
Georg Brandlefb69022011-01-09 07:50:48 +0000846 src = ast.parse('1 + 1', mode='eval')
Georg Brandl619e7ba2011-01-09 07:38:51 +0000847 self.assertEqual(ast.increment_lineno(src.body, n=3), src.body)
848 self.assertEqual(ast.dump(src, include_attributes=True),
Serhiy Storchakab7e95252020-03-10 00:07:47 +0200849 'Expression(body=BinOp(left=Constant(value=1, lineno=4, col_offset=0, '
850 'end_lineno=4, end_col_offset=1), op=Add(), right=Constant(value=1, '
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000851 'lineno=4, col_offset=4, end_lineno=4, end_col_offset=5), lineno=4, '
852 'col_offset=0, end_lineno=4, end_col_offset=5))'
Georg Brandl619e7ba2011-01-09 07:38:51 +0000853 )
Georg Brandl0c77a822008-06-10 16:37:50 +0000854
855 def test_iter_fields(self):
856 node = ast.parse('foo()', mode='eval')
857 d = dict(ast.iter_fields(node.body))
858 self.assertEqual(d.pop('func').id, 'foo')
Benjamin Peterson025e9eb2015-05-05 20:16:41 -0400859 self.assertEqual(d, {'keywords': [], 'args': []})
Georg Brandl0c77a822008-06-10 16:37:50 +0000860
861 def test_iter_child_nodes(self):
862 node = ast.parse("spam(23, 42, eggs='leek')", mode='eval')
863 self.assertEqual(len(list(ast.iter_child_nodes(node.body))), 4)
864 iterator = ast.iter_child_nodes(node.body)
865 self.assertEqual(next(iterator).id, 'spam')
Serhiy Storchaka3f228112018-09-27 17:42:37 +0300866 self.assertEqual(next(iterator).value, 23)
867 self.assertEqual(next(iterator).value, 42)
Georg Brandl0c77a822008-06-10 16:37:50 +0000868 self.assertEqual(ast.dump(next(iterator)),
Serhiy Storchakab7e95252020-03-10 00:07:47 +0200869 "keyword(arg='eggs', value=Constant(value='leek'))"
Georg Brandl0c77a822008-06-10 16:37:50 +0000870 )
871
872 def test_get_docstring(self):
Serhiy Storchaka08f127a2018-06-15 11:05:15 +0300873 node = ast.parse('"""line one\n line two"""')
874 self.assertEqual(ast.get_docstring(node),
875 'line one\nline two')
876
877 node = ast.parse('class foo:\n """line one\n line two"""')
878 self.assertEqual(ast.get_docstring(node.body[0]),
879 'line one\nline two')
880
Georg Brandl0c77a822008-06-10 16:37:50 +0000881 node = ast.parse('def foo():\n """line one\n line two"""')
882 self.assertEqual(ast.get_docstring(node.body[0]),
883 'line one\nline two')
884
Yury Selivanov2f07a662015-07-23 08:54:35 +0300885 node = ast.parse('async def foo():\n """spam\n ham"""')
886 self.assertEqual(ast.get_docstring(node.body[0]), 'spam\nham')
Serhiy Storchaka08f127a2018-06-15 11:05:15 +0300887
888 def test_get_docstring_none(self):
Matthias Bussonnier41cea702017-02-23 22:44:19 -0800889 self.assertIsNone(ast.get_docstring(ast.parse('')))
Serhiy Storchaka08f127a2018-06-15 11:05:15 +0300890 node = ast.parse('x = "not docstring"')
891 self.assertIsNone(ast.get_docstring(node))
892 node = ast.parse('def foo():\n pass')
893 self.assertIsNone(ast.get_docstring(node))
894
895 node = ast.parse('class foo:\n pass')
896 self.assertIsNone(ast.get_docstring(node.body[0]))
897 node = ast.parse('class foo:\n x = "not docstring"')
898 self.assertIsNone(ast.get_docstring(node.body[0]))
899 node = ast.parse('class foo:\n def bar(self): pass')
900 self.assertIsNone(ast.get_docstring(node.body[0]))
901
902 node = ast.parse('def foo():\n pass')
903 self.assertIsNone(ast.get_docstring(node.body[0]))
904 node = ast.parse('def foo():\n x = "not docstring"')
905 self.assertIsNone(ast.get_docstring(node.body[0]))
906
907 node = ast.parse('async def foo():\n pass')
908 self.assertIsNone(ast.get_docstring(node.body[0]))
909 node = ast.parse('async def foo():\n x = "not docstring"')
910 self.assertIsNone(ast.get_docstring(node.body[0]))
Yury Selivanov2f07a662015-07-23 08:54:35 +0300911
Anthony Sottile995d9b92019-01-12 20:05:13 -0800912 def test_multi_line_docstring_col_offset_and_lineno_issue16806(self):
913 node = ast.parse(
914 '"""line one\nline two"""\n\n'
915 'def foo():\n """line one\n line two"""\n\n'
916 ' def bar():\n """line one\n line two"""\n'
917 ' """line one\n line two"""\n'
918 '"""line one\nline two"""\n\n'
919 )
920 self.assertEqual(node.body[0].col_offset, 0)
921 self.assertEqual(node.body[0].lineno, 1)
922 self.assertEqual(node.body[1].body[0].col_offset, 2)
923 self.assertEqual(node.body[1].body[0].lineno, 5)
924 self.assertEqual(node.body[1].body[1].body[0].col_offset, 4)
925 self.assertEqual(node.body[1].body[1].body[0].lineno, 9)
926 self.assertEqual(node.body[1].body[2].col_offset, 2)
927 self.assertEqual(node.body[1].body[2].lineno, 11)
928 self.assertEqual(node.body[2].col_offset, 0)
929 self.assertEqual(node.body[2].lineno, 13)
930
Lysandros Nikolaou025a6022019-12-12 22:40:21 +0100931 def test_elif_stmt_start_position(self):
932 node = ast.parse('if a:\n pass\nelif b:\n pass\n')
933 elif_stmt = node.body[0].orelse[0]
934 self.assertEqual(elif_stmt.lineno, 3)
935 self.assertEqual(elif_stmt.col_offset, 0)
936
Lysandros Nikolaou5936a4c2019-12-14 11:24:57 +0100937 def test_elif_stmt_start_position_with_else(self):
938 node = ast.parse('if a:\n pass\nelif b:\n pass\nelse:\n pass\n')
939 elif_stmt = node.body[0].orelse[0]
940 self.assertEqual(elif_stmt.lineno, 3)
941 self.assertEqual(elif_stmt.col_offset, 0)
942
Lysandros Nikolaou50d4f122019-12-18 01:20:55 +0100943 def test_starred_expr_end_position_within_call(self):
944 node = ast.parse('f(*[0, 1])')
945 starred_expr = node.body[0].value.args[0]
946 self.assertEqual(starred_expr.end_lineno, 1)
947 self.assertEqual(starred_expr.end_col_offset, 9)
948
Georg Brandl0c77a822008-06-10 16:37:50 +0000949 def test_literal_eval(self):
950 self.assertEqual(ast.literal_eval('[1, 2, 3]'), [1, 2, 3])
951 self.assertEqual(ast.literal_eval('{"foo": 42}'), {"foo": 42})
952 self.assertEqual(ast.literal_eval('(True, False, None)'), (True, False, None))
Benjamin Peterson3e742892010-07-11 12:59:24 +0000953 self.assertEqual(ast.literal_eval('{1, 2, 3}'), {1, 2, 3})
Benjamin Peterson5ef96e52010-07-11 23:06:06 +0000954 self.assertEqual(ast.literal_eval('b"hi"'), b"hi")
Raymond Hettinger4fcf5c12020-01-02 22:21:18 -0700955 self.assertEqual(ast.literal_eval('set()'), set())
Georg Brandl0c77a822008-06-10 16:37:50 +0000956 self.assertRaises(ValueError, ast.literal_eval, 'foo()')
Serhiy Storchakad8ac4d12018-01-04 11:15:39 +0200957 self.assertEqual(ast.literal_eval('6'), 6)
958 self.assertEqual(ast.literal_eval('+6'), 6)
Raymond Hettingerbc959732010-10-08 00:47:45 +0000959 self.assertEqual(ast.literal_eval('-6'), -6)
Raymond Hettingerbc959732010-10-08 00:47:45 +0000960 self.assertEqual(ast.literal_eval('3.25'), 3.25)
Serhiy Storchakad8ac4d12018-01-04 11:15:39 +0200961 self.assertEqual(ast.literal_eval('+3.25'), 3.25)
962 self.assertEqual(ast.literal_eval('-3.25'), -3.25)
963 self.assertEqual(repr(ast.literal_eval('-0.0')), '-0.0')
964 self.assertRaises(ValueError, ast.literal_eval, '++6')
965 self.assertRaises(ValueError, ast.literal_eval, '+True')
966 self.assertRaises(ValueError, ast.literal_eval, '2+3')
Georg Brandl0c77a822008-06-10 16:37:50 +0000967
Serhiy Storchakad8ac4d12018-01-04 11:15:39 +0200968 def test_literal_eval_complex(self):
969 # Issue #4907
970 self.assertEqual(ast.literal_eval('6j'), 6j)
971 self.assertEqual(ast.literal_eval('-6j'), -6j)
972 self.assertEqual(ast.literal_eval('6.75j'), 6.75j)
973 self.assertEqual(ast.literal_eval('-6.75j'), -6.75j)
974 self.assertEqual(ast.literal_eval('3+6j'), 3+6j)
975 self.assertEqual(ast.literal_eval('-3+6j'), -3+6j)
976 self.assertEqual(ast.literal_eval('3-6j'), 3-6j)
977 self.assertEqual(ast.literal_eval('-3-6j'), -3-6j)
978 self.assertEqual(ast.literal_eval('3.25+6.75j'), 3.25+6.75j)
979 self.assertEqual(ast.literal_eval('-3.25+6.75j'), -3.25+6.75j)
980 self.assertEqual(ast.literal_eval('3.25-6.75j'), 3.25-6.75j)
981 self.assertEqual(ast.literal_eval('-3.25-6.75j'), -3.25-6.75j)
982 self.assertEqual(ast.literal_eval('(3+6j)'), 3+6j)
983 self.assertRaises(ValueError, ast.literal_eval, '-6j+3')
984 self.assertRaises(ValueError, ast.literal_eval, '-6j+3j')
985 self.assertRaises(ValueError, ast.literal_eval, '3+-6j')
986 self.assertRaises(ValueError, ast.literal_eval, '3+(0+6j)')
987 self.assertRaises(ValueError, ast.literal_eval, '-(3+6j)')
Benjamin Peterson058e31e2009-01-16 03:54:08 +0000988
Curtis Bucherc21c5122020-05-05 12:40:56 -0700989 def test_literal_eval_malformed_dict_nodes(self):
990 malformed = ast.Dict(keys=[ast.Constant(1), ast.Constant(2)], values=[ast.Constant(3)])
991 self.assertRaises(ValueError, ast.literal_eval, malformed)
992 malformed = ast.Dict(keys=[ast.Constant(1)], values=[ast.Constant(2), ast.Constant(3)])
993 self.assertRaises(ValueError, ast.literal_eval, malformed)
994
Amaury Forgeot d'Arc58e87612011-11-22 21:51:55 +0100995 def test_bad_integer(self):
996 # issue13436: Bad error message with invalid numeric values
997 body = [ast.ImportFrom(module='time',
998 names=[ast.alias(name='sleep')],
999 level=None,
1000 lineno=None, col_offset=None)]
Guido van Rossumdcfcd142019-01-31 03:40:27 -08001001 mod = ast.Module(body, [])
Amaury Forgeot d'Arc58e87612011-11-22 21:51:55 +01001002 with self.assertRaises(ValueError) as cm:
1003 compile(mod, 'test', 'exec')
1004 self.assertIn("invalid integer value: None", str(cm.exception))
1005
Berker Peksag0a5bd512016-04-29 19:50:02 +03001006 def test_level_as_none(self):
1007 body = [ast.ImportFrom(module='time',
1008 names=[ast.alias(name='sleep')],
1009 level=None,
1010 lineno=0, col_offset=0)]
Guido van Rossumdcfcd142019-01-31 03:40:27 -08001011 mod = ast.Module(body, [])
Berker Peksag0a5bd512016-04-29 19:50:02 +03001012 code = compile(mod, 'test', 'exec')
1013 ns = {}
1014 exec(code, ns)
1015 self.assertIn('sleep', ns)
1016
Georg Brandl0c77a822008-06-10 16:37:50 +00001017
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001018class ASTValidatorTests(unittest.TestCase):
1019
1020 def mod(self, mod, msg=None, mode="exec", *, exc=ValueError):
1021 mod.lineno = mod.col_offset = 0
1022 ast.fix_missing_locations(mod)
Serhiy Storchaka3f228112018-09-27 17:42:37 +03001023 if msg is None:
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001024 compile(mod, "<test>", mode)
Serhiy Storchaka3f228112018-09-27 17:42:37 +03001025 else:
1026 with self.assertRaises(exc) as cm:
1027 compile(mod, "<test>", mode)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001028 self.assertIn(msg, str(cm.exception))
1029
1030 def expr(self, node, msg=None, *, exc=ValueError):
Guido van Rossumdcfcd142019-01-31 03:40:27 -08001031 mod = ast.Module([ast.Expr(node)], [])
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001032 self.mod(mod, msg, exc=exc)
1033
1034 def stmt(self, stmt, msg=None):
Guido van Rossumdcfcd142019-01-31 03:40:27 -08001035 mod = ast.Module([stmt], [])
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001036 self.mod(mod, msg)
1037
1038 def test_module(self):
1039 m = ast.Interactive([ast.Expr(ast.Name("x", ast.Store()))])
1040 self.mod(m, "must have Load context", "single")
1041 m = ast.Expression(ast.Name("x", ast.Store()))
1042 self.mod(m, "must have Load context", "eval")
1043
1044 def _check_arguments(self, fac, check):
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01001045 def arguments(args=None, posonlyargs=None, vararg=None,
Benjamin Petersoncda75be2013-03-18 10:48:58 -07001046 kwonlyargs=None, kwarg=None,
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001047 defaults=None, kw_defaults=None):
1048 if args is None:
1049 args = []
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01001050 if posonlyargs is None:
1051 posonlyargs = []
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001052 if kwonlyargs is None:
1053 kwonlyargs = []
1054 if defaults is None:
1055 defaults = []
1056 if kw_defaults is None:
1057 kw_defaults = []
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01001058 args = ast.arguments(args, posonlyargs, vararg, kwonlyargs,
1059 kw_defaults, kwarg, defaults)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001060 return fac(args)
1061 args = [ast.arg("x", ast.Name("x", ast.Store()))]
1062 check(arguments(args=args), "must have Load context")
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01001063 check(arguments(posonlyargs=args), "must have Load context")
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001064 check(arguments(kwonlyargs=args), "must have Load context")
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001065 check(arguments(defaults=[ast.Num(3)]),
1066 "more positional defaults than args")
1067 check(arguments(kw_defaults=[ast.Num(4)]),
1068 "length of kwonlyargs is not the same as kw_defaults")
1069 args = [ast.arg("x", ast.Name("x", ast.Load()))]
1070 check(arguments(args=args, defaults=[ast.Name("x", ast.Store())]),
1071 "must have Load context")
1072 args = [ast.arg("a", ast.Name("x", ast.Load())),
1073 ast.arg("b", ast.Name("y", ast.Load()))]
1074 check(arguments(kwonlyargs=args,
1075 kw_defaults=[None, ast.Name("x", ast.Store())]),
1076 "must have Load context")
1077
1078 def test_funcdef(self):
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01001079 a = ast.arguments([], [], None, [], [], None, [])
Serhiy Storchaka73cbe7a2018-05-29 12:04:55 +03001080 f = ast.FunctionDef("x", a, [], [], None)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001081 self.stmt(f, "empty body on FunctionDef")
1082 f = ast.FunctionDef("x", a, [ast.Pass()], [ast.Name("x", ast.Store())],
Serhiy Storchaka73cbe7a2018-05-29 12:04:55 +03001083 None)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001084 self.stmt(f, "must have Load context")
1085 f = ast.FunctionDef("x", a, [ast.Pass()], [],
Serhiy Storchaka73cbe7a2018-05-29 12:04:55 +03001086 ast.Name("x", ast.Store()))
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001087 self.stmt(f, "must have Load context")
1088 def fac(args):
Serhiy Storchaka73cbe7a2018-05-29 12:04:55 +03001089 return ast.FunctionDef("x", args, [ast.Pass()], [], None)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001090 self._check_arguments(fac, self.stmt)
1091
1092 def test_classdef(self):
Benjamin Peterson025e9eb2015-05-05 20:16:41 -04001093 def cls(bases=None, keywords=None, body=None, decorator_list=None):
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001094 if bases is None:
1095 bases = []
1096 if keywords is None:
1097 keywords = []
1098 if body is None:
1099 body = [ast.Pass()]
1100 if decorator_list is None:
1101 decorator_list = []
Benjamin Peterson025e9eb2015-05-05 20:16:41 -04001102 return ast.ClassDef("myclass", bases, keywords,
Serhiy Storchaka73cbe7a2018-05-29 12:04:55 +03001103 body, decorator_list)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001104 self.stmt(cls(bases=[ast.Name("x", ast.Store())]),
1105 "must have Load context")
1106 self.stmt(cls(keywords=[ast.keyword("x", ast.Name("x", ast.Store()))]),
1107 "must have Load context")
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001108 self.stmt(cls(body=[]), "empty body on ClassDef")
1109 self.stmt(cls(body=[None]), "None disallowed")
1110 self.stmt(cls(decorator_list=[ast.Name("x", ast.Store())]),
1111 "must have Load context")
1112
1113 def test_delete(self):
1114 self.stmt(ast.Delete([]), "empty targets on Delete")
1115 self.stmt(ast.Delete([None]), "None disallowed")
1116 self.stmt(ast.Delete([ast.Name("x", ast.Load())]),
1117 "must have Del context")
1118
1119 def test_assign(self):
1120 self.stmt(ast.Assign([], ast.Num(3)), "empty targets on Assign")
1121 self.stmt(ast.Assign([None], ast.Num(3)), "None disallowed")
1122 self.stmt(ast.Assign([ast.Name("x", ast.Load())], ast.Num(3)),
1123 "must have Store context")
1124 self.stmt(ast.Assign([ast.Name("x", ast.Store())],
1125 ast.Name("y", ast.Store())),
1126 "must have Load context")
1127
1128 def test_augassign(self):
1129 aug = ast.AugAssign(ast.Name("x", ast.Load()), ast.Add(),
1130 ast.Name("y", ast.Load()))
1131 self.stmt(aug, "must have Store context")
1132 aug = ast.AugAssign(ast.Name("x", ast.Store()), ast.Add(),
1133 ast.Name("y", ast.Store()))
1134 self.stmt(aug, "must have Load context")
1135
1136 def test_for(self):
1137 x = ast.Name("x", ast.Store())
1138 y = ast.Name("y", ast.Load())
1139 p = ast.Pass()
1140 self.stmt(ast.For(x, y, [], []), "empty body on For")
1141 self.stmt(ast.For(ast.Name("x", ast.Load()), y, [p], []),
1142 "must have Store context")
1143 self.stmt(ast.For(x, ast.Name("y", ast.Store()), [p], []),
1144 "must have Load context")
1145 e = ast.Expr(ast.Name("x", ast.Store()))
1146 self.stmt(ast.For(x, y, [e], []), "must have Load context")
1147 self.stmt(ast.For(x, y, [p], [e]), "must have Load context")
1148
1149 def test_while(self):
1150 self.stmt(ast.While(ast.Num(3), [], []), "empty body on While")
1151 self.stmt(ast.While(ast.Name("x", ast.Store()), [ast.Pass()], []),
1152 "must have Load context")
1153 self.stmt(ast.While(ast.Num(3), [ast.Pass()],
1154 [ast.Expr(ast.Name("x", ast.Store()))]),
1155 "must have Load context")
1156
1157 def test_if(self):
1158 self.stmt(ast.If(ast.Num(3), [], []), "empty body on If")
1159 i = ast.If(ast.Name("x", ast.Store()), [ast.Pass()], [])
1160 self.stmt(i, "must have Load context")
1161 i = ast.If(ast.Num(3), [ast.Expr(ast.Name("x", ast.Store()))], [])
1162 self.stmt(i, "must have Load context")
1163 i = ast.If(ast.Num(3), [ast.Pass()],
1164 [ast.Expr(ast.Name("x", ast.Store()))])
1165 self.stmt(i, "must have Load context")
1166
1167 def test_with(self):
1168 p = ast.Pass()
1169 self.stmt(ast.With([], [p]), "empty items on With")
1170 i = ast.withitem(ast.Num(3), None)
1171 self.stmt(ast.With([i], []), "empty body on With")
1172 i = ast.withitem(ast.Name("x", ast.Store()), None)
1173 self.stmt(ast.With([i], [p]), "must have Load context")
1174 i = ast.withitem(ast.Num(3), ast.Name("x", ast.Load()))
1175 self.stmt(ast.With([i], [p]), "must have Store context")
1176
1177 def test_raise(self):
1178 r = ast.Raise(None, ast.Num(3))
1179 self.stmt(r, "Raise with cause but no exception")
1180 r = ast.Raise(ast.Name("x", ast.Store()), None)
1181 self.stmt(r, "must have Load context")
1182 r = ast.Raise(ast.Num(4), ast.Name("x", ast.Store()))
1183 self.stmt(r, "must have Load context")
1184
1185 def test_try(self):
1186 p = ast.Pass()
1187 t = ast.Try([], [], [], [p])
1188 self.stmt(t, "empty body on Try")
1189 t = ast.Try([ast.Expr(ast.Name("x", ast.Store()))], [], [], [p])
1190 self.stmt(t, "must have Load context")
1191 t = ast.Try([p], [], [], [])
1192 self.stmt(t, "Try has neither except handlers nor finalbody")
1193 t = ast.Try([p], [], [p], [p])
1194 self.stmt(t, "Try has orelse but no except handlers")
1195 t = ast.Try([p], [ast.ExceptHandler(None, "x", [])], [], [])
1196 self.stmt(t, "empty body on ExceptHandler")
1197 e = [ast.ExceptHandler(ast.Name("x", ast.Store()), "y", [p])]
1198 self.stmt(ast.Try([p], e, [], []), "must have Load context")
1199 e = [ast.ExceptHandler(None, "x", [p])]
1200 t = ast.Try([p], e, [ast.Expr(ast.Name("x", ast.Store()))], [p])
1201 self.stmt(t, "must have Load context")
1202 t = ast.Try([p], e, [p], [ast.Expr(ast.Name("x", ast.Store()))])
1203 self.stmt(t, "must have Load context")
1204
1205 def test_assert(self):
1206 self.stmt(ast.Assert(ast.Name("x", ast.Store()), None),
1207 "must have Load context")
1208 assrt = ast.Assert(ast.Name("x", ast.Load()),
1209 ast.Name("y", ast.Store()))
1210 self.stmt(assrt, "must have Load context")
1211
1212 def test_import(self):
1213 self.stmt(ast.Import([]), "empty names on Import")
1214
1215 def test_importfrom(self):
1216 imp = ast.ImportFrom(None, [ast.alias("x", None)], -42)
Serhiy Storchaka7de28402016-06-27 23:40:43 +03001217 self.stmt(imp, "Negative ImportFrom level")
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001218 self.stmt(ast.ImportFrom(None, [], 0), "empty names on ImportFrom")
1219
1220 def test_global(self):
1221 self.stmt(ast.Global([]), "empty names on Global")
1222
1223 def test_nonlocal(self):
1224 self.stmt(ast.Nonlocal([]), "empty names on Nonlocal")
1225
1226 def test_expr(self):
1227 e = ast.Expr(ast.Name("x", ast.Store()))
1228 self.stmt(e, "must have Load context")
1229
1230 def test_boolop(self):
1231 b = ast.BoolOp(ast.And(), [])
1232 self.expr(b, "less than 2 values")
1233 b = ast.BoolOp(ast.And(), [ast.Num(3)])
1234 self.expr(b, "less than 2 values")
1235 b = ast.BoolOp(ast.And(), [ast.Num(4), None])
1236 self.expr(b, "None disallowed")
1237 b = ast.BoolOp(ast.And(), [ast.Num(4), ast.Name("x", ast.Store())])
1238 self.expr(b, "must have Load context")
1239
1240 def test_unaryop(self):
1241 u = ast.UnaryOp(ast.Not(), ast.Name("x", ast.Store()))
1242 self.expr(u, "must have Load context")
1243
1244 def test_lambda(self):
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01001245 a = ast.arguments([], [], None, [], [], None, [])
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001246 self.expr(ast.Lambda(a, ast.Name("x", ast.Store())),
1247 "must have Load context")
1248 def fac(args):
1249 return ast.Lambda(args, ast.Name("x", ast.Load()))
1250 self._check_arguments(fac, self.expr)
1251
1252 def test_ifexp(self):
1253 l = ast.Name("x", ast.Load())
1254 s = ast.Name("y", ast.Store())
1255 for args in (s, l, l), (l, s, l), (l, l, s):
Benjamin Peterson71ce8972011-08-09 16:17:12 -05001256 self.expr(ast.IfExp(*args), "must have Load context")
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001257
1258 def test_dict(self):
1259 d = ast.Dict([], [ast.Name("x", ast.Load())])
1260 self.expr(d, "same number of keys as values")
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001261 d = ast.Dict([ast.Name("x", ast.Load())], [None])
1262 self.expr(d, "None disallowed")
1263
1264 def test_set(self):
1265 self.expr(ast.Set([None]), "None disallowed")
1266 s = ast.Set([ast.Name("x", ast.Store())])
1267 self.expr(s, "must have Load context")
1268
1269 def _check_comprehension(self, fac):
1270 self.expr(fac([]), "comprehension with no generators")
1271 g = ast.comprehension(ast.Name("x", ast.Load()),
Yury Selivanov52c4e7c2016-09-09 10:36:01 -07001272 ast.Name("x", ast.Load()), [], 0)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001273 self.expr(fac([g]), "must have Store context")
1274 g = ast.comprehension(ast.Name("x", ast.Store()),
Yury Selivanov52c4e7c2016-09-09 10:36:01 -07001275 ast.Name("x", ast.Store()), [], 0)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001276 self.expr(fac([g]), "must have Load context")
1277 x = ast.Name("x", ast.Store())
1278 y = ast.Name("y", ast.Load())
Yury Selivanov52c4e7c2016-09-09 10:36:01 -07001279 g = ast.comprehension(x, y, [None], 0)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001280 self.expr(fac([g]), "None disallowed")
Yury Selivanov52c4e7c2016-09-09 10:36:01 -07001281 g = ast.comprehension(x, y, [ast.Name("x", ast.Store())], 0)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001282 self.expr(fac([g]), "must have Load context")
1283
1284 def _simple_comp(self, fac):
1285 g = ast.comprehension(ast.Name("x", ast.Store()),
Yury Selivanov52c4e7c2016-09-09 10:36:01 -07001286 ast.Name("x", ast.Load()), [], 0)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001287 self.expr(fac(ast.Name("x", ast.Store()), [g]),
1288 "must have Load context")
1289 def wrap(gens):
1290 return fac(ast.Name("x", ast.Store()), gens)
1291 self._check_comprehension(wrap)
1292
1293 def test_listcomp(self):
1294 self._simple_comp(ast.ListComp)
1295
1296 def test_setcomp(self):
1297 self._simple_comp(ast.SetComp)
1298
1299 def test_generatorexp(self):
1300 self._simple_comp(ast.GeneratorExp)
1301
1302 def test_dictcomp(self):
1303 g = ast.comprehension(ast.Name("y", ast.Store()),
Yury Selivanov52c4e7c2016-09-09 10:36:01 -07001304 ast.Name("p", ast.Load()), [], 0)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001305 c = ast.DictComp(ast.Name("x", ast.Store()),
1306 ast.Name("y", ast.Load()), [g])
1307 self.expr(c, "must have Load context")
1308 c = ast.DictComp(ast.Name("x", ast.Load()),
1309 ast.Name("y", ast.Store()), [g])
1310 self.expr(c, "must have Load context")
1311 def factory(comps):
1312 k = ast.Name("x", ast.Load())
1313 v = ast.Name("y", ast.Load())
1314 return ast.DictComp(k, v, comps)
1315 self._check_comprehension(factory)
1316
1317 def test_yield(self):
Benjamin Peterson527c6222012-01-14 08:58:23 -05001318 self.expr(ast.Yield(ast.Name("x", ast.Store())), "must have Load")
1319 self.expr(ast.YieldFrom(ast.Name("x", ast.Store())), "must have Load")
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001320
1321 def test_compare(self):
1322 left = ast.Name("x", ast.Load())
1323 comp = ast.Compare(left, [ast.In()], [])
1324 self.expr(comp, "no comparators")
1325 comp = ast.Compare(left, [ast.In()], [ast.Num(4), ast.Num(5)])
1326 self.expr(comp, "different number of comparators and operands")
1327 comp = ast.Compare(ast.Num("blah"), [ast.In()], [left])
Serhiy Storchaka3f228112018-09-27 17:42:37 +03001328 self.expr(comp)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001329 comp = ast.Compare(left, [ast.In()], [ast.Num("blah")])
Serhiy Storchaka3f228112018-09-27 17:42:37 +03001330 self.expr(comp)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001331
1332 def test_call(self):
1333 func = ast.Name("x", ast.Load())
1334 args = [ast.Name("y", ast.Load())]
1335 keywords = [ast.keyword("w", ast.Name("z", ast.Load()))]
Benjamin Peterson025e9eb2015-05-05 20:16:41 -04001336 call = ast.Call(ast.Name("x", ast.Store()), args, keywords)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001337 self.expr(call, "must have Load context")
Benjamin Peterson025e9eb2015-05-05 20:16:41 -04001338 call = ast.Call(func, [None], keywords)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001339 self.expr(call, "None disallowed")
1340 bad_keywords = [ast.keyword("w", ast.Name("z", ast.Store()))]
Benjamin Peterson025e9eb2015-05-05 20:16:41 -04001341 call = ast.Call(func, args, bad_keywords)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001342 self.expr(call, "must have Load context")
1343
1344 def test_num(self):
1345 class subint(int):
1346 pass
1347 class subfloat(float):
1348 pass
1349 class subcomplex(complex):
1350 pass
Serhiy Storchaka3f228112018-09-27 17:42:37 +03001351 for obj in "0", "hello":
1352 self.expr(ast.Num(obj))
1353 for obj in subint(), subfloat(), subcomplex():
1354 self.expr(ast.Num(obj), "invalid type", exc=TypeError)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001355
1356 def test_attribute(self):
1357 attr = ast.Attribute(ast.Name("x", ast.Store()), "y", ast.Load())
1358 self.expr(attr, "must have Load context")
1359
1360 def test_subscript(self):
Serhiy Storchaka13d52c22020-03-10 18:52:34 +02001361 sub = ast.Subscript(ast.Name("x", ast.Store()), ast.Num(3),
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001362 ast.Load())
1363 self.expr(sub, "must have Load context")
1364 x = ast.Name("x", ast.Load())
Serhiy Storchaka13d52c22020-03-10 18:52:34 +02001365 sub = ast.Subscript(x, ast.Name("y", ast.Store()),
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001366 ast.Load())
1367 self.expr(sub, "must have Load context")
1368 s = ast.Name("x", ast.Store())
1369 for args in (s, None, None), (None, s, None), (None, None, s):
1370 sl = ast.Slice(*args)
1371 self.expr(ast.Subscript(x, sl, ast.Load()),
1372 "must have Load context")
Serhiy Storchaka13d52c22020-03-10 18:52:34 +02001373 sl = ast.Tuple([], ast.Load())
1374 self.expr(ast.Subscript(x, sl, ast.Load()))
1375 sl = ast.Tuple([s], ast.Load())
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001376 self.expr(ast.Subscript(x, sl, ast.Load()), "must have Load context")
1377
1378 def test_starred(self):
1379 left = ast.List([ast.Starred(ast.Name("x", ast.Load()), ast.Store())],
1380 ast.Store())
1381 assign = ast.Assign([left], ast.Num(4))
1382 self.stmt(assign, "must have Store context")
1383
1384 def _sequence(self, fac):
1385 self.expr(fac([None], ast.Load()), "None disallowed")
1386 self.expr(fac([ast.Name("x", ast.Store())], ast.Load()),
1387 "must have Load context")
1388
1389 def test_list(self):
1390 self._sequence(ast.List)
1391
1392 def test_tuple(self):
1393 self._sequence(ast.Tuple)
1394
Benjamin Peterson442f2092012-12-06 17:41:04 -05001395 def test_nameconstant(self):
Serhiy Storchaka3f228112018-09-27 17:42:37 +03001396 self.expr(ast.NameConstant(4))
Benjamin Peterson442f2092012-12-06 17:41:04 -05001397
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001398 def test_stdlib_validates(self):
1399 stdlib = os.path.dirname(ast.__file__)
1400 tests = [fn for fn in os.listdir(stdlib) if fn.endswith(".py")]
1401 tests.extend(["test/test_grammar.py", "test/test_unpack_ex.py"])
1402 for module in tests:
Serhiy Storchaka3bcbedc2019-01-18 07:47:48 +02001403 with self.subTest(module):
1404 fn = os.path.join(stdlib, module)
1405 with open(fn, "r", encoding="utf-8") as fp:
1406 source = fp.read()
1407 mod = ast.parse(source, fn)
1408 compile(mod, fn, "exec")
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001409
1410
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001411class ConstantTests(unittest.TestCase):
1412 """Tests on the ast.Constant node type."""
1413
1414 def compile_constant(self, value):
1415 tree = ast.parse("x = 123")
1416
1417 node = tree.body[0].value
1418 new_node = ast.Constant(value=value)
1419 ast.copy_location(new_node, node)
1420 tree.body[0].value = new_node
1421
1422 code = compile(tree, "<string>", "exec")
1423
1424 ns = {}
1425 exec(code, ns)
1426 return ns['x']
1427
Victor Stinnerbe59d142016-01-27 00:39:12 +01001428 def test_validation(self):
1429 with self.assertRaises(TypeError) as cm:
1430 self.compile_constant([1, 2, 3])
1431 self.assertEqual(str(cm.exception),
1432 "got an invalid type in Constant: list")
1433
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001434 def test_singletons(self):
1435 for const in (None, False, True, Ellipsis, b'', frozenset()):
1436 with self.subTest(const=const):
1437 value = self.compile_constant(const)
1438 self.assertIs(value, const)
1439
1440 def test_values(self):
1441 nested_tuple = (1,)
1442 nested_frozenset = frozenset({1})
1443 for level in range(3):
1444 nested_tuple = (nested_tuple, 2)
1445 nested_frozenset = frozenset({nested_frozenset, 2})
1446 values = (123, 123.0, 123j,
1447 "unicode", b'bytes',
1448 tuple("tuple"), frozenset("frozenset"),
1449 nested_tuple, nested_frozenset)
1450 for value in values:
1451 with self.subTest(value=value):
1452 result = self.compile_constant(value)
1453 self.assertEqual(result, value)
1454
1455 def test_assign_to_constant(self):
1456 tree = ast.parse("x = 1")
1457
1458 target = tree.body[0].targets[0]
1459 new_target = ast.Constant(value=1)
1460 ast.copy_location(new_target, target)
1461 tree.body[0].targets[0] = new_target
1462
1463 with self.assertRaises(ValueError) as cm:
1464 compile(tree, "string", "exec")
1465 self.assertEqual(str(cm.exception),
1466 "expression which can't be assigned "
1467 "to in Store context")
1468
1469 def test_get_docstring(self):
1470 tree = ast.parse("'docstring'\nx = 1")
1471 self.assertEqual(ast.get_docstring(tree), 'docstring')
1472
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001473 def get_load_const(self, tree):
1474 # Compile to bytecode, disassemble and get parameter of LOAD_CONST
1475 # instructions
1476 co = compile(tree, '<string>', 'exec')
1477 consts = []
1478 for instr in dis.get_instructions(co):
1479 if instr.opname == 'LOAD_CONST':
1480 consts.append(instr.argval)
1481 return consts
1482
1483 @support.cpython_only
1484 def test_load_const(self):
1485 consts = [None,
1486 True, False,
1487 124,
1488 2.0,
1489 3j,
1490 "unicode",
1491 b'bytes',
1492 (1, 2, 3)]
1493
Victor Stinnera2724092016-02-08 18:17:58 +01001494 code = '\n'.join(['x={!r}'.format(const) for const in consts])
1495 code += '\nx = ...'
1496 consts.extend((Ellipsis, None))
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001497
1498 tree = ast.parse(code)
Victor Stinnera2724092016-02-08 18:17:58 +01001499 self.assertEqual(self.get_load_const(tree),
1500 consts)
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001501
1502 # Replace expression nodes with constants
Victor Stinnera2724092016-02-08 18:17:58 +01001503 for assign, const in zip(tree.body, consts):
1504 assert isinstance(assign, ast.Assign), ast.dump(assign)
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001505 new_node = ast.Constant(value=const)
Victor Stinnera2724092016-02-08 18:17:58 +01001506 ast.copy_location(new_node, assign.value)
1507 assign.value = new_node
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001508
Victor Stinnera2724092016-02-08 18:17:58 +01001509 self.assertEqual(self.get_load_const(tree),
1510 consts)
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001511
1512 def test_literal_eval(self):
1513 tree = ast.parse("1 + 2")
1514 binop = tree.body[0].value
1515
1516 new_left = ast.Constant(value=10)
1517 ast.copy_location(new_left, binop.left)
1518 binop.left = new_left
1519
Serhiy Storchakad8ac4d12018-01-04 11:15:39 +02001520 new_right = ast.Constant(value=20j)
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001521 ast.copy_location(new_right, binop.right)
1522 binop.right = new_right
1523
Serhiy Storchakad8ac4d12018-01-04 11:15:39 +02001524 self.assertEqual(ast.literal_eval(binop), 10+20j)
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001525
Guido van Rossum10f8ce62019-03-13 13:00:46 -07001526 def test_string_kind(self):
1527 c = ast.parse('"x"', mode='eval').body
1528 self.assertEqual(c.value, "x")
1529 self.assertEqual(c.kind, None)
1530
1531 c = ast.parse('u"x"', mode='eval').body
1532 self.assertEqual(c.value, "x")
1533 self.assertEqual(c.kind, "u")
1534
1535 c = ast.parse('r"x"', mode='eval').body
1536 self.assertEqual(c.value, "x")
1537 self.assertEqual(c.kind, None)
1538
1539 c = ast.parse('b"x"', mode='eval').body
1540 self.assertEqual(c.value, b"x")
1541 self.assertEqual(c.kind, None)
1542
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001543
Ivan Levkivskyi9932a222019-01-22 11:18:22 +00001544class EndPositionTests(unittest.TestCase):
1545 """Tests for end position of AST nodes.
1546
1547 Testing end positions of nodes requires a bit of extra care
1548 because of how LL parsers work.
1549 """
1550 def _check_end_pos(self, ast_node, end_lineno, end_col_offset):
1551 self.assertEqual(ast_node.end_lineno, end_lineno)
1552 self.assertEqual(ast_node.end_col_offset, end_col_offset)
1553
1554 def _check_content(self, source, ast_node, content):
1555 self.assertEqual(ast.get_source_segment(source, ast_node), content)
1556
1557 def _parse_value(self, s):
1558 # Use duck-typing to support both single expression
1559 # and a right hand side of an assignment statement.
1560 return ast.parse(s).body[0].value
1561
1562 def test_lambda(self):
1563 s = 'lambda x, *y: None'
1564 lam = self._parse_value(s)
1565 self._check_content(s, lam.body, 'None')
1566 self._check_content(s, lam.args.args[0], 'x')
1567 self._check_content(s, lam.args.vararg, 'y')
1568
1569 def test_func_def(self):
1570 s = dedent('''
1571 def func(x: int,
1572 *args: str,
1573 z: float = 0,
1574 **kwargs: Any) -> bool:
1575 return True
1576 ''').strip()
1577 fdef = ast.parse(s).body[0]
1578 self._check_end_pos(fdef, 5, 15)
1579 self._check_content(s, fdef.body[0], 'return True')
1580 self._check_content(s, fdef.args.args[0], 'x: int')
1581 self._check_content(s, fdef.args.args[0].annotation, 'int')
1582 self._check_content(s, fdef.args.kwarg, 'kwargs: Any')
1583 self._check_content(s, fdef.args.kwarg.annotation, 'Any')
1584
1585 def test_call(self):
1586 s = 'func(x, y=2, **kw)'
1587 call = self._parse_value(s)
1588 self._check_content(s, call.func, 'func')
1589 self._check_content(s, call.keywords[0].value, '2')
1590 self._check_content(s, call.keywords[1].value, 'kw')
1591
1592 def test_call_noargs(self):
1593 s = 'x[0]()'
1594 call = self._parse_value(s)
1595 self._check_content(s, call.func, 'x[0]')
1596 self._check_end_pos(call, 1, 6)
1597
1598 def test_class_def(self):
1599 s = dedent('''
1600 class C(A, B):
1601 x: int = 0
1602 ''').strip()
1603 cdef = ast.parse(s).body[0]
1604 self._check_end_pos(cdef, 2, 14)
1605 self._check_content(s, cdef.bases[1], 'B')
1606 self._check_content(s, cdef.body[0], 'x: int = 0')
1607
1608 def test_class_kw(self):
1609 s = 'class S(metaclass=abc.ABCMeta): pass'
1610 cdef = ast.parse(s).body[0]
1611 self._check_content(s, cdef.keywords[0].value, 'abc.ABCMeta')
1612
1613 def test_multi_line_str(self):
1614 s = dedent('''
1615 x = """Some multi-line text.
1616
1617 It goes on starting from same indent."""
1618 ''').strip()
1619 assign = ast.parse(s).body[0]
1620 self._check_end_pos(assign, 3, 40)
1621 self._check_end_pos(assign.value, 3, 40)
1622
1623 def test_continued_str(self):
1624 s = dedent('''
1625 x = "first part" \\
1626 "second part"
1627 ''').strip()
1628 assign = ast.parse(s).body[0]
1629 self._check_end_pos(assign, 2, 13)
1630 self._check_end_pos(assign.value, 2, 13)
1631
1632 def test_suites(self):
1633 # We intentionally put these into the same string to check
1634 # that empty lines are not part of the suite.
1635 s = dedent('''
1636 while True:
1637 pass
1638
1639 if one():
1640 x = None
1641 elif other():
1642 y = None
1643 else:
1644 z = None
1645
1646 for x, y in stuff:
1647 assert True
1648
1649 try:
1650 raise RuntimeError
1651 except TypeError as e:
1652 pass
1653
1654 pass
1655 ''').strip()
1656 mod = ast.parse(s)
1657 while_loop = mod.body[0]
1658 if_stmt = mod.body[1]
1659 for_loop = mod.body[2]
1660 try_stmt = mod.body[3]
1661 pass_stmt = mod.body[4]
1662
1663 self._check_end_pos(while_loop, 2, 8)
1664 self._check_end_pos(if_stmt, 9, 12)
1665 self._check_end_pos(for_loop, 12, 15)
1666 self._check_end_pos(try_stmt, 17, 8)
1667 self._check_end_pos(pass_stmt, 19, 4)
1668
1669 self._check_content(s, while_loop.test, 'True')
1670 self._check_content(s, if_stmt.body[0], 'x = None')
1671 self._check_content(s, if_stmt.orelse[0].test, 'other()')
1672 self._check_content(s, for_loop.target, 'x, y')
1673 self._check_content(s, try_stmt.body[0], 'raise RuntimeError')
1674 self._check_content(s, try_stmt.handlers[0].type, 'TypeError')
1675
1676 def test_fstring(self):
1677 s = 'x = f"abc {x + y} abc"'
1678 fstr = self._parse_value(s)
1679 binop = fstr.values[1].value
1680 self._check_content(s, binop, 'x + y')
1681
1682 def test_fstring_multi_line(self):
1683 s = dedent('''
1684 f"""Some multi-line text.
1685 {
1686 arg_one
1687 +
1688 arg_two
1689 }
1690 It goes on..."""
1691 ''').strip()
1692 fstr = self._parse_value(s)
1693 binop = fstr.values[1].value
1694 self._check_end_pos(binop, 5, 7)
1695 self._check_content(s, binop.left, 'arg_one')
1696 self._check_content(s, binop.right, 'arg_two')
1697
1698 def test_import_from_multi_line(self):
1699 s = dedent('''
1700 from x.y.z import (
1701 a, b, c as c
1702 )
1703 ''').strip()
1704 imp = ast.parse(s).body[0]
1705 self._check_end_pos(imp, 3, 1)
1706
1707 def test_slices(self):
1708 s1 = 'f()[1, 2] [0]'
1709 s2 = 'x[ a.b: c.d]'
1710 sm = dedent('''
1711 x[ a.b: f () ,
1712 g () : c.d
1713 ]
1714 ''').strip()
1715 i1, i2, im = map(self._parse_value, (s1, s2, sm))
1716 self._check_content(s1, i1.value, 'f()[1, 2]')
Serhiy Storchaka13d52c22020-03-10 18:52:34 +02001717 self._check_content(s1, i1.value.slice, '1, 2')
Ivan Levkivskyi9932a222019-01-22 11:18:22 +00001718 self._check_content(s2, i2.slice.lower, 'a.b')
1719 self._check_content(s2, i2.slice.upper, 'c.d')
Serhiy Storchaka13d52c22020-03-10 18:52:34 +02001720 self._check_content(sm, im.slice.elts[0].upper, 'f ()')
1721 self._check_content(sm, im.slice.elts[1].lower, 'g ()')
Ivan Levkivskyi9932a222019-01-22 11:18:22 +00001722 self._check_end_pos(im, 3, 3)
1723
1724 def test_binop(self):
1725 s = dedent('''
1726 (1 * 2 + (3 ) +
1727 4
1728 )
1729 ''').strip()
1730 binop = self._parse_value(s)
1731 self._check_end_pos(binop, 2, 6)
1732 self._check_content(s, binop.right, '4')
1733 self._check_content(s, binop.left, '1 * 2 + (3 )')
1734 self._check_content(s, binop.left.right, '3')
1735
1736 def test_boolop(self):
1737 s = dedent('''
1738 if (one_condition and
1739 (other_condition or yet_another_one)):
1740 pass
1741 ''').strip()
1742 bop = ast.parse(s).body[0].test
1743 self._check_end_pos(bop, 2, 44)
1744 self._check_content(s, bop.values[1],
1745 'other_condition or yet_another_one')
1746
1747 def test_tuples(self):
1748 s1 = 'x = () ;'
1749 s2 = 'x = 1 , ;'
1750 s3 = 'x = (1 , 2 ) ;'
1751 sm = dedent('''
1752 x = (
1753 a, b,
1754 )
1755 ''').strip()
1756 t1, t2, t3, tm = map(self._parse_value, (s1, s2, s3, sm))
1757 self._check_content(s1, t1, '()')
1758 self._check_content(s2, t2, '1 ,')
1759 self._check_content(s3, t3, '(1 , 2 )')
1760 self._check_end_pos(tm, 3, 1)
1761
1762 def test_attribute_spaces(self):
1763 s = 'func(x. y .z)'
1764 call = self._parse_value(s)
1765 self._check_content(s, call, s)
1766 self._check_content(s, call.args[0], 'x. y .z')
1767
Serhiy Storchaka6e619c42020-02-12 22:37:49 +02001768 def test_redundant_parenthesis(self):
1769 s = '( ( ( a + b ) ) )'
1770 v = ast.parse(s).body[0].value
1771 self.assertEqual(type(v).__name__, 'BinOp')
1772 self._check_content(s, v, 'a + b')
1773 s2 = 'await ' + s
1774 v = ast.parse(s2).body[0].value.value
1775 self.assertEqual(type(v).__name__, 'BinOp')
1776 self._check_content(s2, v, 'a + b')
1777
1778 def test_trailers_with_redundant_parenthesis(self):
1779 tests = (
1780 ('( ( ( a ) ) ) ( )', 'Call'),
1781 ('( ( ( a ) ) ) ( b )', 'Call'),
1782 ('( ( ( a ) ) ) [ b ]', 'Subscript'),
1783 ('( ( ( a ) ) ) . b', 'Attribute'),
1784 )
1785 for s, t in tests:
1786 with self.subTest(s):
1787 v = ast.parse(s).body[0].value
1788 self.assertEqual(type(v).__name__, t)
1789 self._check_content(s, v, s)
1790 s2 = 'await ' + s
1791 v = ast.parse(s2).body[0].value.value
1792 self.assertEqual(type(v).__name__, t)
1793 self._check_content(s2, v, s)
1794
Ivan Levkivskyi9932a222019-01-22 11:18:22 +00001795 def test_displays(self):
1796 s1 = '[{}, {1, }, {1, 2,} ]'
1797 s2 = '{a: b, f (): g () ,}'
1798 c1 = self._parse_value(s1)
1799 c2 = self._parse_value(s2)
1800 self._check_content(s1, c1.elts[0], '{}')
1801 self._check_content(s1, c1.elts[1], '{1, }')
1802 self._check_content(s1, c1.elts[2], '{1, 2,}')
1803 self._check_content(s2, c2.keys[1], 'f ()')
1804 self._check_content(s2, c2.values[1], 'g ()')
1805
1806 def test_comprehensions(self):
1807 s = dedent('''
1808 x = [{x for x, y in stuff
1809 if cond.x} for stuff in things]
1810 ''').strip()
1811 cmp = self._parse_value(s)
1812 self._check_end_pos(cmp, 2, 37)
1813 self._check_content(s, cmp.generators[0].iter, 'things')
1814 self._check_content(s, cmp.elt.generators[0].iter, 'stuff')
1815 self._check_content(s, cmp.elt.generators[0].ifs[0], 'cond.x')
1816 self._check_content(s, cmp.elt.generators[0].target, 'x, y')
1817
1818 def test_yield_await(self):
1819 s = dedent('''
1820 async def f():
1821 yield x
1822 await y
1823 ''').strip()
1824 fdef = ast.parse(s).body[0]
1825 self._check_content(s, fdef.body[0].value, 'yield x')
1826 self._check_content(s, fdef.body[1].value, 'await y')
1827
1828 def test_source_segment_multi(self):
1829 s_orig = dedent('''
1830 x = (
1831 a, b,
1832 ) + ()
1833 ''').strip()
1834 s_tuple = dedent('''
1835 (
1836 a, b,
1837 )
1838 ''').strip()
1839 binop = self._parse_value(s_orig)
1840 self.assertEqual(ast.get_source_segment(s_orig, binop.left), s_tuple)
1841
1842 def test_source_segment_padded(self):
1843 s_orig = dedent('''
1844 class C:
1845 def fun(self) -> None:
1846 "Đ–Đ–Đ–Đ–Đ–"
1847 ''').strip()
1848 s_method = ' def fun(self) -> None:\n' \
1849 ' "Đ–Đ–Đ–Đ–Đ–"'
1850 cdef = ast.parse(s_orig).body[0]
1851 self.assertEqual(ast.get_source_segment(s_orig, cdef.body[0], padded=True),
1852 s_method)
1853
1854 def test_source_segment_endings(self):
1855 s = 'v = 1\r\nw = 1\nx = 1\n\ry = 1\rz = 1\r\n'
1856 v, w, x, y, z = ast.parse(s).body
1857 self._check_content(s, v, 'v = 1')
1858 self._check_content(s, w, 'w = 1')
1859 self._check_content(s, x, 'x = 1')
1860 self._check_content(s, y, 'y = 1')
1861 self._check_content(s, z, 'z = 1')
1862
1863 def test_source_segment_tabs(self):
1864 s = dedent('''
1865 class C:
1866 \t\f def fun(self) -> None:
1867 \t\f pass
1868 ''').strip()
1869 s_method = ' \t\f def fun(self) -> None:\n' \
1870 ' \t\f pass'
1871
1872 cdef = ast.parse(s).body[0]
1873 self.assertEqual(ast.get_source_segment(s, cdef.body[0], padded=True), s_method)
1874
Irit Katriele6578a22020-05-18 19:14:12 +01001875 def test_source_segment_missing_info(self):
1876 s = 'v = 1\r\nw = 1\nx = 1\n\ry = 1\r\n'
1877 v, w, x, y = ast.parse(s).body
1878 del v.lineno
1879 del w.end_lineno
1880 del x.col_offset
1881 del y.end_col_offset
1882 self.assertIsNone(ast.get_source_segment(s, v))
1883 self.assertIsNone(ast.get_source_segment(s, w))
1884 self.assertIsNone(ast.get_source_segment(s, x))
1885 self.assertIsNone(ast.get_source_segment(s, y))
Ivan Levkivskyi9932a222019-01-22 11:18:22 +00001886
Serhiy Storchakac3ea41e2019-08-26 10:13:19 +03001887class NodeVisitorTests(unittest.TestCase):
1888 def test_old_constant_nodes(self):
1889 class Visitor(ast.NodeVisitor):
1890 def visit_Num(self, node):
1891 log.append((node.lineno, 'Num', node.n))
1892 def visit_Str(self, node):
1893 log.append((node.lineno, 'Str', node.s))
1894 def visit_Bytes(self, node):
1895 log.append((node.lineno, 'Bytes', node.s))
1896 def visit_NameConstant(self, node):
1897 log.append((node.lineno, 'NameConstant', node.value))
1898 def visit_Ellipsis(self, node):
1899 log.append((node.lineno, 'Ellipsis', ...))
1900 mod = ast.parse(dedent('''\
1901 i = 42
1902 f = 4.25
1903 c = 4.25j
1904 s = 'string'
1905 b = b'bytes'
1906 t = True
1907 n = None
1908 e = ...
1909 '''))
1910 visitor = Visitor()
1911 log = []
1912 with warnings.catch_warnings(record=True) as wlog:
1913 warnings.filterwarnings('always', '', DeprecationWarning)
1914 visitor.visit(mod)
1915 self.assertEqual(log, [
1916 (1, 'Num', 42),
1917 (2, 'Num', 4.25),
1918 (3, 'Num', 4.25j),
1919 (4, 'Str', 'string'),
1920 (5, 'Bytes', b'bytes'),
1921 (6, 'NameConstant', True),
1922 (7, 'NameConstant', None),
1923 (8, 'Ellipsis', ...),
1924 ])
1925 self.assertEqual([str(w.message) for w in wlog], [
1926 'visit_Num is deprecated; add visit_Constant',
1927 'visit_Num is deprecated; add visit_Constant',
1928 'visit_Num is deprecated; add visit_Constant',
1929 'visit_Str is deprecated; add visit_Constant',
1930 'visit_Bytes is deprecated; add visit_Constant',
1931 'visit_NameConstant is deprecated; add visit_Constant',
1932 'visit_NameConstant is deprecated; add visit_Constant',
1933 'visit_Ellipsis is deprecated; add visit_Constant',
1934 ])
1935
1936
Neal Norwitzee9b10a2008-03-31 05:29:39 +00001937def main():
1938 if __name__ != '__main__':
Martin v. Löwis49c5da12006-03-01 22:49:05 +00001939 return
Neal Norwitzee9b10a2008-03-31 05:29:39 +00001940 if sys.argv[1:] == ['-g']:
1941 for statements, kind in ((exec_tests, "exec"), (single_tests, "single"),
1942 (eval_tests, "eval")):
1943 print(kind+"_results = [")
Victor Stinnerf0891962016-02-08 17:15:21 +01001944 for statement in statements:
1945 tree = ast.parse(statement, "?", kind)
1946 print("%r," % (to_tuple(tree),))
Neal Norwitzee9b10a2008-03-31 05:29:39 +00001947 print("]")
1948 print("main()")
1949 raise SystemExit
Brett Cannon3e9a9ae2013-06-12 21:25:59 -04001950 unittest.main()
Tim Peters400cbc32006-02-28 18:44:41 +00001951
Guido van Rossumdcfcd142019-01-31 03:40:27 -08001952#### EVERYTHING BELOW IS GENERATED BY python Lib/test/test_ast.py -g #####
Tim Peters400cbc32006-02-28 18:44:41 +00001953exec_results = [
Serhiy Storchaka850a8852020-01-10 10:12:55 +02001954('Module', [('Expr', (1, 0, 1, 4), ('Constant', (1, 0, 1, 4), None, None))], []),
1955('Module', [('Expr', (1, 0, 1, 18), ('Constant', (1, 0, 1, 18), 'module docstring', None))], []),
1956('Module', [('FunctionDef', (1, 0, 1, 13), 'f', ('arguments', [], [], None, [], [], None, []), [('Pass', (1, 9, 1, 13))], [], None, None)], []),
1957('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)], []),
1958('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)], []),
1959('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)], []),
1960('Module', [('FunctionDef', (1, 0, 1, 18), 'f', ('arguments', [], [], ('arg', (1, 7, 1, 11), 'args', None, None), [], [], None, []), [('Pass', (1, 14, 1, 18))], [], None, None)], []),
1961('Module', [('FunctionDef', (1, 0, 1, 21), 'f', ('arguments', [], [], None, [], [], ('arg', (1, 8, 1, 14), 'kwargs', None, None), []), [('Pass', (1, 17, 1, 21))], [], None, None)], []),
1962('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)], []),
1963('Module', [('ClassDef', (1, 0, 1, 12), 'C', [], [], [('Pass', (1, 8, 1, 12))], [])], []),
1964('Module', [('ClassDef', (1, 0, 1, 32), 'C', [], [], [('Expr', (1, 9, 1, 32), ('Constant', (1, 9, 1, 32), 'docstring for class C', None))], [])], []),
1965('Module', [('ClassDef', (1, 0, 1, 21), 'C', [('Name', (1, 8, 1, 14), 'object', ('Load',))], [], [('Pass', (1, 17, 1, 21))], [])], []),
1966('Module', [('FunctionDef', (1, 0, 1, 16), 'f', ('arguments', [], [], None, [], [], None, []), [('Return', (1, 8, 1, 16), ('Constant', (1, 15, 1, 16), 1, None))], [], None, None)], []),
1967('Module', [('Delete', (1, 0, 1, 5), [('Name', (1, 4, 1, 5), 'v', ('Del',))])], []),
1968('Module', [('Assign', (1, 0, 1, 5), [('Name', (1, 0, 1, 1), 'v', ('Store',))], ('Constant', (1, 4, 1, 5), 1, None), None)], []),
1969('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)], []),
1970('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)], []),
1971('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)], []),
1972('Module', [('AugAssign', (1, 0, 1, 6), ('Name', (1, 0, 1, 1), 'v', ('Store',)), ('Add',), ('Constant', (1, 5, 1, 6), 1, None))], []),
1973('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)], []),
1974('Module', [('While', (1, 0, 1, 12), ('Name', (1, 6, 1, 7), 'v', ('Load',)), [('Pass', (1, 8, 1, 12))], [])], []),
1975('Module', [('If', (1, 0, 1, 9), ('Name', (1, 3, 1, 4), 'v', ('Load',)), [('Pass', (1, 5, 1, 9))], [])], []),
1976('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))], [])])], []),
1977('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))])])], []),
1978('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)], []),
1979('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)], []),
1980('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)], []),
1981('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))])], [], [])], []),
1982('Module', [('Try', (1, 0, 4, 6), [('Pass', (2, 2, 2, 6))], [], [], [('Pass', (4, 2, 4, 6))])], []),
1983('Module', [('Assert', (1, 0, 1, 8), ('Name', (1, 7, 1, 8), 'v', ('Load',)), None)], []),
1984('Module', [('Import', (1, 0, 1, 10), [('alias', 'sys', None)])], []),
1985('Module', [('ImportFrom', (1, 0, 1, 17), 'sys', [('alias', 'v', None)], 0)], []),
1986('Module', [('Global', (1, 0, 1, 8), ['v'])], []),
1987('Module', [('Expr', (1, 0, 1, 1), ('Constant', (1, 0, 1, 1), 1, None))], []),
1988('Module', [('Pass', (1, 0, 1, 4))], []),
1989('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)], []),
1990('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)], []),
1991('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)], []),
1992('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)], []),
1993('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)], []),
1994('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)]))], []),
1995('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)]))], []),
1996('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)]))], []),
1997('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)]))], []),
1998('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)]))], []),
1999('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)], []),
2000('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)], []),
2001('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)], []),
2002('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)]))], []),
2003('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)]))], []),
2004('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)], []),
2005('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)], []),
2006('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)], []),
2007('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)], [])])], []),
2008('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 +01002009('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 +02002010('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)))], []),
2011('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)], []),
2012('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)], []),
2013('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)], []),
2014('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)], []),
2015('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)], []),
2016('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)], []),
2017('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)], []),
2018('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)], []),
2019('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)], []),
2020('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 +00002021]
2022single_results = [
Serhiy Storchaka850a8852020-01-10 10:12:55 +02002023('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 +00002024]
2025eval_results = [
Serhiy Storchaka850a8852020-01-10 10:12:55 +02002026('Expression', ('Constant', (1, 0, 1, 4), None, None)),
2027('Expression', ('BoolOp', (1, 0, 1, 7), ('And',), [('Name', (1, 0, 1, 1), 'a', ('Load',)), ('Name', (1, 6, 1, 7), 'b', ('Load',))])),
2028('Expression', ('BinOp', (1, 0, 1, 5), ('Name', (1, 0, 1, 1), 'a', ('Load',)), ('Add',), ('Name', (1, 4, 1, 5), 'b', ('Load',)))),
2029('Expression', ('UnaryOp', (1, 0, 1, 5), ('Not',), ('Name', (1, 4, 1, 5), 'v', ('Load',)))),
2030('Expression', ('Lambda', (1, 0, 1, 11), ('arguments', [], [], None, [], [], None, []), ('Constant', (1, 7, 1, 11), None, None))),
2031('Expression', ('Dict', (1, 0, 1, 7), [('Constant', (1, 2, 1, 3), 1, None)], [('Constant', (1, 4, 1, 5), 2, None)])),
2032('Expression', ('Dict', (1, 0, 1, 2), [], [])),
2033('Expression', ('Set', (1, 0, 1, 7), [('Constant', (1, 1, 1, 5), None, None)])),
2034('Expression', ('Dict', (1, 0, 5, 6), [('Constant', (2, 6, 2, 7), 1, None)], [('Constant', (4, 10, 4, 11), 2, None)])),
2035('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)])),
2036('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)])),
2037('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)])),
2038('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)])),
2039('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)])),
2040('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)])),
2041('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)])),
2042('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)])),
2043('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)])),
2044('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)])),
2045('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)])),
2046('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 +01002047('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 +02002048('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',))], [])),
2049('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)])], [])),
2050('Expression', ('Constant', (1, 0, 1, 2), 10, None)),
2051('Expression', ('Constant', (1, 0, 1, 8), 'string', None)),
2052('Expression', ('Attribute', (1, 0, 1, 3), ('Name', (1, 0, 1, 1), 'a', ('Load',)), 'b', ('Load',))),
Serhiy Storchaka13d52c22020-03-10 18:52:34 +02002053('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 +02002054('Expression', ('Name', (1, 0, 1, 1), 'v', ('Load',))),
2055('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',))),
2056('Expression', ('List', (1, 0, 1, 2), [], ('Load',))),
2057('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',))),
2058('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',))),
2059('Expression', ('Tuple', (1, 0, 1, 2), [], ('Load',))),
Serhiy Storchaka13d52c22020-03-10 18:52:34 +02002060('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 +00002061]
Neal Norwitzee9b10a2008-03-31 05:29:39 +00002062main()