blob: 66f83841ce3417ffec21c0431bf4abf64de5c603 [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):
286 # "_ast.AST constructor takes 0 positional arguments"
287 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
Serhiy Storchaka3f228112018-09-27 17:42:37 +0300405 self.assertEqual(ast.Num(42).n, 42)
406 self.assertEqual(ast.Num(4.25).n, 4.25)
407 self.assertEqual(ast.Num(4.25j).n, 4.25j)
408 self.assertEqual(ast.Str('42').s, '42')
409 self.assertEqual(ast.Bytes(b'42').s, b'42')
410 self.assertIs(ast.NameConstant(True).value, True)
411 self.assertIs(ast.NameConstant(False).value, False)
412 self.assertIs(ast.NameConstant(None).value, None)
413
414 self.assertEqual(ast.Constant(42).value, 42)
415 self.assertEqual(ast.Constant(4.25).value, 4.25)
416 self.assertEqual(ast.Constant(4.25j).value, 4.25j)
417 self.assertEqual(ast.Constant('42').value, '42')
418 self.assertEqual(ast.Constant(b'42').value, b'42')
419 self.assertIs(ast.Constant(True).value, True)
420 self.assertIs(ast.Constant(False).value, False)
421 self.assertIs(ast.Constant(None).value, None)
422 self.assertIs(ast.Constant(...).value, ...)
423
424 def test_realtype(self):
425 self.assertEqual(type(ast.Num(42)), ast.Constant)
426 self.assertEqual(type(ast.Num(4.25)), ast.Constant)
427 self.assertEqual(type(ast.Num(4.25j)), ast.Constant)
428 self.assertEqual(type(ast.Str('42')), ast.Constant)
429 self.assertEqual(type(ast.Bytes(b'42')), ast.Constant)
430 self.assertEqual(type(ast.NameConstant(True)), ast.Constant)
431 self.assertEqual(type(ast.NameConstant(False)), ast.Constant)
432 self.assertEqual(type(ast.NameConstant(None)), ast.Constant)
433 self.assertEqual(type(ast.Ellipsis()), ast.Constant)
434
435 def test_isinstance(self):
436 self.assertTrue(isinstance(ast.Num(42), ast.Num))
437 self.assertTrue(isinstance(ast.Num(4.2), ast.Num))
438 self.assertTrue(isinstance(ast.Num(4.2j), ast.Num))
439 self.assertTrue(isinstance(ast.Str('42'), ast.Str))
440 self.assertTrue(isinstance(ast.Bytes(b'42'), ast.Bytes))
441 self.assertTrue(isinstance(ast.NameConstant(True), ast.NameConstant))
442 self.assertTrue(isinstance(ast.NameConstant(False), ast.NameConstant))
443 self.assertTrue(isinstance(ast.NameConstant(None), ast.NameConstant))
444 self.assertTrue(isinstance(ast.Ellipsis(), ast.Ellipsis))
445
446 self.assertTrue(isinstance(ast.Constant(42), ast.Num))
447 self.assertTrue(isinstance(ast.Constant(4.2), ast.Num))
448 self.assertTrue(isinstance(ast.Constant(4.2j), ast.Num))
449 self.assertTrue(isinstance(ast.Constant('42'), ast.Str))
450 self.assertTrue(isinstance(ast.Constant(b'42'), ast.Bytes))
451 self.assertTrue(isinstance(ast.Constant(True), ast.NameConstant))
452 self.assertTrue(isinstance(ast.Constant(False), ast.NameConstant))
453 self.assertTrue(isinstance(ast.Constant(None), ast.NameConstant))
454 self.assertTrue(isinstance(ast.Constant(...), ast.Ellipsis))
455
456 self.assertFalse(isinstance(ast.Str('42'), ast.Num))
457 self.assertFalse(isinstance(ast.Num(42), ast.Str))
458 self.assertFalse(isinstance(ast.Str('42'), ast.Bytes))
459 self.assertFalse(isinstance(ast.Num(42), ast.NameConstant))
460 self.assertFalse(isinstance(ast.Num(42), ast.Ellipsis))
Anthony Sottile74176222019-01-18 11:30:28 -0800461 self.assertFalse(isinstance(ast.NameConstant(True), ast.Num))
462 self.assertFalse(isinstance(ast.NameConstant(False), ast.Num))
Serhiy Storchaka3f228112018-09-27 17:42:37 +0300463
464 self.assertFalse(isinstance(ast.Constant('42'), ast.Num))
465 self.assertFalse(isinstance(ast.Constant(42), ast.Str))
466 self.assertFalse(isinstance(ast.Constant('42'), ast.Bytes))
467 self.assertFalse(isinstance(ast.Constant(42), ast.NameConstant))
468 self.assertFalse(isinstance(ast.Constant(42), ast.Ellipsis))
Anthony Sottile74176222019-01-18 11:30:28 -0800469 self.assertFalse(isinstance(ast.Constant(True), ast.Num))
470 self.assertFalse(isinstance(ast.Constant(False), ast.Num))
Serhiy Storchaka3f228112018-09-27 17:42:37 +0300471
472 self.assertFalse(isinstance(ast.Constant(), ast.Num))
473 self.assertFalse(isinstance(ast.Constant(), ast.Str))
474 self.assertFalse(isinstance(ast.Constant(), ast.Bytes))
475 self.assertFalse(isinstance(ast.Constant(), ast.NameConstant))
476 self.assertFalse(isinstance(ast.Constant(), ast.Ellipsis))
477
Serhiy Storchaka6015cc52018-10-28 13:43:03 +0200478 class S(str): pass
479 self.assertTrue(isinstance(ast.Constant(S('42')), ast.Str))
480 self.assertFalse(isinstance(ast.Constant(S('42')), ast.Num))
481
Serhiy Storchaka3f228112018-09-27 17:42:37 +0300482 def test_subclasses(self):
483 class N(ast.Num):
484 def __init__(self, *args, **kwargs):
485 super().__init__(*args, **kwargs)
486 self.z = 'spam'
487 class N2(ast.Num):
488 pass
489
490 n = N(42)
491 self.assertEqual(n.n, 42)
492 self.assertEqual(n.z, 'spam')
493 self.assertEqual(type(n), N)
494 self.assertTrue(isinstance(n, N))
495 self.assertTrue(isinstance(n, ast.Num))
496 self.assertFalse(isinstance(n, N2))
497 self.assertFalse(isinstance(ast.Num(42), N))
498 n = N(n=42)
499 self.assertEqual(n.n, 42)
500 self.assertEqual(type(n), N)
501
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500502 def test_module(self):
503 body = [ast.Num(42)]
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800504 x = ast.Module(body, [])
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500505 self.assertEqual(x.body, body)
506
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000507 def test_nodeclasses(self):
Florent Xicluna992d9e02011-11-11 19:35:42 +0100508 # Zero arguments constructor explicitly allowed
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500509 x = ast.BinOp()
510 self.assertEqual(x._fields, ('left', 'op', 'right'))
511
512 # Random attribute allowed too
513 x.foobarbaz = 5
514 self.assertEqual(x.foobarbaz, 5)
515
516 n1 = ast.Num(1)
517 n3 = ast.Num(3)
518 addop = ast.Add()
519 x = ast.BinOp(n1, addop, n3)
520 self.assertEqual(x.left, n1)
521 self.assertEqual(x.op, addop)
522 self.assertEqual(x.right, n3)
Benjamin Peterson68b543a2011-06-27 17:51:18 -0500523
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500524 x = ast.BinOp(1, 2, 3)
525 self.assertEqual(x.left, 1)
526 self.assertEqual(x.op, 2)
527 self.assertEqual(x.right, 3)
528
Georg Brandl0c77a822008-06-10 16:37:50 +0000529 x = ast.BinOp(1, 2, 3, lineno=0)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000530 self.assertEqual(x.left, 1)
531 self.assertEqual(x.op, 2)
532 self.assertEqual(x.right, 3)
533 self.assertEqual(x.lineno, 0)
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000534
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500535 # node raises exception when given too many arguments
536 self.assertRaises(TypeError, ast.BinOp, 1, 2, 3, 4)
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500537 # node raises exception when given too many arguments
538 self.assertRaises(TypeError, ast.BinOp, 1, 2, 3, 4, lineno=0)
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000539
540 # can set attributes through kwargs too
Georg Brandl0c77a822008-06-10 16:37:50 +0000541 x = ast.BinOp(left=1, op=2, right=3, lineno=0)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000542 self.assertEqual(x.left, 1)
543 self.assertEqual(x.op, 2)
544 self.assertEqual(x.right, 3)
545 self.assertEqual(x.lineno, 0)
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000546
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500547 # Random kwargs also allowed
548 x = ast.BinOp(1, 2, 3, foobarbaz=42)
549 self.assertEqual(x.foobarbaz, 42)
550
551 def test_no_fields(self):
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000552 # this used to fail because Sub._fields was None
Georg Brandl0c77a822008-06-10 16:37:50 +0000553 x = ast.Sub()
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500554 self.assertEqual(x._fields, ())
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000555
556 def test_pickling(self):
557 import pickle
558 mods = [pickle]
559 try:
560 import cPickle
561 mods.append(cPickle)
562 except ImportError:
563 pass
564 protocols = [0, 1, 2]
565 for mod in mods:
566 for protocol in protocols:
567 for ast in (compile(i, "?", "exec", 0x400) for i in exec_tests):
568 ast2 = mod.loads(mod.dumps(ast, protocol))
Ezio Melottib3aedd42010-11-20 19:04:17 +0000569 self.assertEqual(to_tuple(ast2), to_tuple(ast))
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000570
Benjamin Peterson5b066812010-11-20 01:38:49 +0000571 def test_invalid_sum(self):
572 pos = dict(lineno=2, col_offset=3)
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800573 m = ast.Module([ast.Expr(ast.expr(**pos), **pos)], [])
Benjamin Peterson5b066812010-11-20 01:38:49 +0000574 with self.assertRaises(TypeError) as cm:
575 compile(m, "<test>", "exec")
576 self.assertIn("but got <_ast.expr", str(cm.exception))
577
Min ho Kimc4cacc82019-07-31 08:16:13 +1000578 def test_invalid_identifier(self):
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800579 m = ast.Module([ast.Expr(ast.Name(42, ast.Load()))], [])
Benjamin Peterson2193d2b2011-07-22 10:50:23 -0500580 ast.fix_missing_locations(m)
581 with self.assertRaises(TypeError) as cm:
582 compile(m, "<test>", "exec")
583 self.assertIn("identifier must be of type str", str(cm.exception))
584
Mark Dickinsonded35ae2012-11-25 14:36:26 +0000585 def test_empty_yield_from(self):
586 # Issue 16546: yield from value is not optional.
587 empty_yield_from = ast.parse("def f():\n yield from g()")
588 empty_yield_from.body[0].body[0].value.value = None
589 with self.assertRaises(ValueError) as cm:
590 compile(empty_yield_from, "<test>", "exec")
591 self.assertIn("field value is required", str(cm.exception))
592
Oren Milman7dc46d82017-09-30 20:16:24 +0300593 @support.cpython_only
594 def test_issue31592(self):
595 # There shouldn't be an assertion failure in case of a bad
596 # unicodedata.normalize().
597 import unicodedata
598 def bad_normalize(*args):
599 return None
600 with support.swap_attr(unicodedata, 'normalize', bad_normalize):
601 self.assertRaises(TypeError, ast.parse, '\u03D5')
602
Carl Friedrich Bolz-Tereick110a47c2019-07-08 23:17:56 +0200603 def test_issue18374_binop_col_offset(self):
604 tree = ast.parse('4+5+6+7')
605 parent_binop = tree.body[0].value
606 child_binop = parent_binop.left
607 grandchild_binop = child_binop.left
608 self.assertEqual(parent_binop.col_offset, 0)
609 self.assertEqual(parent_binop.end_col_offset, 7)
610 self.assertEqual(child_binop.col_offset, 0)
611 self.assertEqual(child_binop.end_col_offset, 5)
612 self.assertEqual(grandchild_binop.col_offset, 0)
613 self.assertEqual(grandchild_binop.end_col_offset, 3)
614
615 tree = ast.parse('4+5-\\\n 6-7')
616 parent_binop = tree.body[0].value
617 child_binop = parent_binop.left
618 grandchild_binop = child_binop.left
619 self.assertEqual(parent_binop.col_offset, 0)
620 self.assertEqual(parent_binop.lineno, 1)
621 self.assertEqual(parent_binop.end_col_offset, 4)
622 self.assertEqual(parent_binop.end_lineno, 2)
623
624 self.assertEqual(child_binop.col_offset, 0)
Carl Friedrich Bolz-Tereick430a9f42019-07-09 14:20:01 +0200625 self.assertEqual(child_binop.lineno, 1)
Carl Friedrich Bolz-Tereick110a47c2019-07-08 23:17:56 +0200626 self.assertEqual(child_binop.end_col_offset, 2)
Carl Friedrich Bolz-Tereick430a9f42019-07-09 14:20:01 +0200627 self.assertEqual(child_binop.end_lineno, 2)
Carl Friedrich Bolz-Tereick110a47c2019-07-08 23:17:56 +0200628
629 self.assertEqual(grandchild_binop.col_offset, 0)
Carl Friedrich Bolz-Tereick430a9f42019-07-09 14:20:01 +0200630 self.assertEqual(grandchild_binop.lineno, 1)
Carl Friedrich Bolz-Tereick110a47c2019-07-08 23:17:56 +0200631 self.assertEqual(grandchild_binop.end_col_offset, 3)
Carl Friedrich Bolz-Tereick430a9f42019-07-09 14:20:01 +0200632 self.assertEqual(grandchild_binop.end_lineno, 1)
Georg Brandl0c77a822008-06-10 16:37:50 +0000633
Lysandros Nikolaoud2e10982020-02-08 00:36:32 +0100634 def test_issue39579_dotted_name_end_col_offset(self):
635 tree = ast.parse('@a.b.c\ndef f(): pass')
636 attr_b = tree.body[0].decorator_list[0].value
637 self.assertEqual(attr_b.end_col_offset, 4)
638
Batuhan TaĹźkaya4ab362c2020-03-16 11:12:53 +0300639 def test_ast_asdl_signature(self):
640 self.assertEqual(ast.withitem.__doc__, "withitem(expr context_expr, expr? optional_vars)")
641 self.assertEqual(ast.GtE.__doc__, "GtE")
642 self.assertEqual(ast.Name.__doc__, "Name(identifier id, expr_context ctx)")
643 self.assertEqual(ast.cmpop.__doc__, "cmpop = Eq | NotEq | Lt | LtE | Gt | GtE | Is | IsNot | In | NotIn")
644 expressions = [f" | {node.__doc__}" for node in ast.expr.__subclasses__()]
645 expressions[0] = f"expr = {ast.expr.__subclasses__()[0].__doc__}"
646 self.assertCountEqual(ast.expr.__doc__.split("\n"), expressions)
647
648
Georg Brandl0c77a822008-06-10 16:37:50 +0000649class ASTHelpers_Test(unittest.TestCase):
Guido van Rossum10f8ce62019-03-13 13:00:46 -0700650 maxDiff = None
Georg Brandl0c77a822008-06-10 16:37:50 +0000651
652 def test_parse(self):
653 a = ast.parse('foo(1 + 1)')
654 b = compile('foo(1 + 1)', '<unknown>', 'exec', ast.PyCF_ONLY_AST)
655 self.assertEqual(ast.dump(a), ast.dump(b))
656
Benjamin Peterson2e2c9032012-09-02 14:23:15 -0400657 def test_parse_in_error(self):
658 try:
659 1/0
660 except Exception:
Benjamin Petersonbd0df502012-09-02 15:04:51 -0400661 with self.assertRaises(SyntaxError) as e:
662 ast.literal_eval(r"'\U'")
663 self.assertIsNotNone(e.exception.__context__)
Benjamin Peterson2e2c9032012-09-02 14:23:15 -0400664
Georg Brandl0c77a822008-06-10 16:37:50 +0000665 def test_dump(self):
666 node = ast.parse('spam(eggs, "and cheese")')
667 self.assertEqual(ast.dump(node),
668 "Module(body=[Expr(value=Call(func=Name(id='spam', ctx=Load()), "
Serhiy Storchakab7e95252020-03-10 00:07:47 +0200669 "args=[Name(id='eggs', ctx=Load()), Constant(value='and cheese')], "
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800670 "keywords=[]))], type_ignores=[])"
Georg Brandl0c77a822008-06-10 16:37:50 +0000671 )
672 self.assertEqual(ast.dump(node, annotate_fields=False),
673 "Module([Expr(Call(Name('spam', Load()), [Name('eggs', Load()), "
Serhiy Storchakab7e95252020-03-10 00:07:47 +0200674 "Constant('and cheese')], []))], [])"
Georg Brandl0c77a822008-06-10 16:37:50 +0000675 )
676 self.assertEqual(ast.dump(node, include_attributes=True),
677 "Module(body=[Expr(value=Call(func=Name(id='spam', ctx=Load(), "
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000678 "lineno=1, col_offset=0, end_lineno=1, end_col_offset=4), "
679 "args=[Name(id='eggs', ctx=Load(), lineno=1, col_offset=5, "
Serhiy Storchakab7e95252020-03-10 00:07:47 +0200680 "end_lineno=1, end_col_offset=9), Constant(value='and cheese', "
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000681 "lineno=1, col_offset=11, end_lineno=1, end_col_offset=23)], keywords=[], "
682 "lineno=1, col_offset=0, end_lineno=1, end_col_offset=24), "
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800683 "lineno=1, col_offset=0, end_lineno=1, end_col_offset=24)], type_ignores=[])"
Georg Brandl0c77a822008-06-10 16:37:50 +0000684 )
685
Serhiy Storchaka850573b2019-09-09 19:33:13 +0300686 def test_dump_indent(self):
687 node = ast.parse('spam(eggs, "and cheese")')
688 self.assertEqual(ast.dump(node, indent=3), """\
689Module(
690 body=[
691 Expr(
692 value=Call(
693 func=Name(id='spam', ctx=Load()),
694 args=[
695 Name(id='eggs', ctx=Load()),
Serhiy Storchakab7e95252020-03-10 00:07:47 +0200696 Constant(value='and cheese')],
Serhiy Storchaka850573b2019-09-09 19:33:13 +0300697 keywords=[]))],
698 type_ignores=[])""")
699 self.assertEqual(ast.dump(node, annotate_fields=False, indent='\t'), """\
700Module(
701\t[
702\t\tExpr(
703\t\t\tCall(
704\t\t\t\tName('spam', Load()),
705\t\t\t\t[
706\t\t\t\t\tName('eggs', Load()),
Serhiy Storchakab7e95252020-03-10 00:07:47 +0200707\t\t\t\t\tConstant('and cheese')],
Serhiy Storchaka850573b2019-09-09 19:33:13 +0300708\t\t\t\t[]))],
709\t[])""")
710 self.assertEqual(ast.dump(node, include_attributes=True, indent=3), """\
711Module(
712 body=[
713 Expr(
714 value=Call(
715 func=Name(
716 id='spam',
717 ctx=Load(),
718 lineno=1,
719 col_offset=0,
720 end_lineno=1,
721 end_col_offset=4),
722 args=[
723 Name(
724 id='eggs',
725 ctx=Load(),
726 lineno=1,
727 col_offset=5,
728 end_lineno=1,
729 end_col_offset=9),
730 Constant(
731 value='and cheese',
Serhiy Storchaka850573b2019-09-09 19:33:13 +0300732 lineno=1,
733 col_offset=11,
734 end_lineno=1,
735 end_col_offset=23)],
736 keywords=[],
737 lineno=1,
738 col_offset=0,
739 end_lineno=1,
740 end_col_offset=24),
741 lineno=1,
742 col_offset=0,
743 end_lineno=1,
744 end_col_offset=24)],
745 type_ignores=[])""")
746
Serhiy Storchakae64f9482019-08-29 09:30:23 +0300747 def test_dump_incomplete(self):
748 node = ast.Raise(lineno=3, col_offset=4)
749 self.assertEqual(ast.dump(node),
750 "Raise()"
751 )
752 self.assertEqual(ast.dump(node, include_attributes=True),
753 "Raise(lineno=3, col_offset=4)"
754 )
755 node = ast.Raise(exc=ast.Name(id='e', ctx=ast.Load()), lineno=3, col_offset=4)
756 self.assertEqual(ast.dump(node),
757 "Raise(exc=Name(id='e', ctx=Load()))"
758 )
759 self.assertEqual(ast.dump(node, annotate_fields=False),
760 "Raise(Name('e', Load()))"
761 )
762 self.assertEqual(ast.dump(node, include_attributes=True),
763 "Raise(exc=Name(id='e', ctx=Load()), lineno=3, col_offset=4)"
764 )
765 self.assertEqual(ast.dump(node, annotate_fields=False, include_attributes=True),
766 "Raise(Name('e', Load()), lineno=3, col_offset=4)"
767 )
768 node = ast.Raise(cause=ast.Name(id='e', ctx=ast.Load()))
769 self.assertEqual(ast.dump(node),
770 "Raise(cause=Name(id='e', ctx=Load()))"
771 )
772 self.assertEqual(ast.dump(node, annotate_fields=False),
773 "Raise(cause=Name('e', Load()))"
774 )
775
Georg Brandl0c77a822008-06-10 16:37:50 +0000776 def test_copy_location(self):
777 src = ast.parse('1 + 1', mode='eval')
778 src.body.right = ast.copy_location(ast.Num(2), src.body.right)
779 self.assertEqual(ast.dump(src, include_attributes=True),
Serhiy Storchakab7e95252020-03-10 00:07:47 +0200780 'Expression(body=BinOp(left=Constant(value=1, lineno=1, col_offset=0, '
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000781 'end_lineno=1, end_col_offset=1), op=Add(), right=Constant(value=2, '
782 'lineno=1, col_offset=4, end_lineno=1, end_col_offset=5), lineno=1, '
783 'col_offset=0, end_lineno=1, end_col_offset=5))'
Georg Brandl0c77a822008-06-10 16:37:50 +0000784 )
785
786 def test_fix_missing_locations(self):
787 src = ast.parse('write("spam")')
788 src.body.append(ast.Expr(ast.Call(ast.Name('spam', ast.Load()),
Benjamin Peterson025e9eb2015-05-05 20:16:41 -0400789 [ast.Str('eggs')], [])))
Georg Brandl0c77a822008-06-10 16:37:50 +0000790 self.assertEqual(src, ast.fix_missing_locations(src))
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000791 self.maxDiff = None
Georg Brandl0c77a822008-06-10 16:37:50 +0000792 self.assertEqual(ast.dump(src, include_attributes=True),
793 "Module(body=[Expr(value=Call(func=Name(id='write', ctx=Load(), "
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000794 "lineno=1, col_offset=0, end_lineno=1, end_col_offset=5), "
Serhiy Storchakab7e95252020-03-10 00:07:47 +0200795 "args=[Constant(value='spam', lineno=1, col_offset=6, end_lineno=1, "
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000796 "end_col_offset=12)], keywords=[], lineno=1, col_offset=0, end_lineno=1, "
797 "end_col_offset=13), lineno=1, col_offset=0, end_lineno=1, "
798 "end_col_offset=13), Expr(value=Call(func=Name(id='spam', ctx=Load(), "
799 "lineno=1, col_offset=0, end_lineno=1, end_col_offset=0), "
800 "args=[Constant(value='eggs', lineno=1, col_offset=0, end_lineno=1, "
801 "end_col_offset=0)], keywords=[], lineno=1, col_offset=0, end_lineno=1, "
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800802 "end_col_offset=0), lineno=1, col_offset=0, end_lineno=1, end_col_offset=0)], "
803 "type_ignores=[])"
Georg Brandl0c77a822008-06-10 16:37:50 +0000804 )
805
806 def test_increment_lineno(self):
807 src = ast.parse('1 + 1', mode='eval')
808 self.assertEqual(ast.increment_lineno(src, n=3), src)
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=4, col_offset=0, '
811 'end_lineno=4, end_col_offset=1), op=Add(), right=Constant(value=1, '
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000812 'lineno=4, col_offset=4, end_lineno=4, end_col_offset=5), lineno=4, '
813 'col_offset=0, end_lineno=4, end_col_offset=5))'
Georg Brandl0c77a822008-06-10 16:37:50 +0000814 )
Georg Brandl619e7ba2011-01-09 07:38:51 +0000815 # issue10869: do not increment lineno of root twice
Georg Brandlefb69022011-01-09 07:50:48 +0000816 src = ast.parse('1 + 1', mode='eval')
Georg Brandl619e7ba2011-01-09 07:38:51 +0000817 self.assertEqual(ast.increment_lineno(src.body, n=3), src.body)
818 self.assertEqual(ast.dump(src, include_attributes=True),
Serhiy Storchakab7e95252020-03-10 00:07:47 +0200819 'Expression(body=BinOp(left=Constant(value=1, lineno=4, col_offset=0, '
820 'end_lineno=4, end_col_offset=1), op=Add(), right=Constant(value=1, '
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000821 'lineno=4, col_offset=4, end_lineno=4, end_col_offset=5), lineno=4, '
822 'col_offset=0, end_lineno=4, end_col_offset=5))'
Georg Brandl619e7ba2011-01-09 07:38:51 +0000823 )
Georg Brandl0c77a822008-06-10 16:37:50 +0000824
825 def test_iter_fields(self):
826 node = ast.parse('foo()', mode='eval')
827 d = dict(ast.iter_fields(node.body))
828 self.assertEqual(d.pop('func').id, 'foo')
Benjamin Peterson025e9eb2015-05-05 20:16:41 -0400829 self.assertEqual(d, {'keywords': [], 'args': []})
Georg Brandl0c77a822008-06-10 16:37:50 +0000830
831 def test_iter_child_nodes(self):
832 node = ast.parse("spam(23, 42, eggs='leek')", mode='eval')
833 self.assertEqual(len(list(ast.iter_child_nodes(node.body))), 4)
834 iterator = ast.iter_child_nodes(node.body)
835 self.assertEqual(next(iterator).id, 'spam')
Serhiy Storchaka3f228112018-09-27 17:42:37 +0300836 self.assertEqual(next(iterator).value, 23)
837 self.assertEqual(next(iterator).value, 42)
Georg Brandl0c77a822008-06-10 16:37:50 +0000838 self.assertEqual(ast.dump(next(iterator)),
Serhiy Storchakab7e95252020-03-10 00:07:47 +0200839 "keyword(arg='eggs', value=Constant(value='leek'))"
Georg Brandl0c77a822008-06-10 16:37:50 +0000840 )
841
842 def test_get_docstring(self):
Serhiy Storchaka08f127a2018-06-15 11:05:15 +0300843 node = ast.parse('"""line one\n line two"""')
844 self.assertEqual(ast.get_docstring(node),
845 'line one\nline two')
846
847 node = ast.parse('class foo:\n """line one\n line two"""')
848 self.assertEqual(ast.get_docstring(node.body[0]),
849 'line one\nline two')
850
Georg Brandl0c77a822008-06-10 16:37:50 +0000851 node = ast.parse('def foo():\n """line one\n line two"""')
852 self.assertEqual(ast.get_docstring(node.body[0]),
853 'line one\nline two')
854
Yury Selivanov2f07a662015-07-23 08:54:35 +0300855 node = ast.parse('async def foo():\n """spam\n ham"""')
856 self.assertEqual(ast.get_docstring(node.body[0]), 'spam\nham')
Serhiy Storchaka08f127a2018-06-15 11:05:15 +0300857
858 def test_get_docstring_none(self):
Matthias Bussonnier41cea702017-02-23 22:44:19 -0800859 self.assertIsNone(ast.get_docstring(ast.parse('')))
Serhiy Storchaka08f127a2018-06-15 11:05:15 +0300860 node = ast.parse('x = "not docstring"')
861 self.assertIsNone(ast.get_docstring(node))
862 node = ast.parse('def foo():\n pass')
863 self.assertIsNone(ast.get_docstring(node))
864
865 node = ast.parse('class foo:\n pass')
866 self.assertIsNone(ast.get_docstring(node.body[0]))
867 node = ast.parse('class foo:\n x = "not docstring"')
868 self.assertIsNone(ast.get_docstring(node.body[0]))
869 node = ast.parse('class foo:\n def bar(self): pass')
870 self.assertIsNone(ast.get_docstring(node.body[0]))
871
872 node = ast.parse('def foo():\n pass')
873 self.assertIsNone(ast.get_docstring(node.body[0]))
874 node = ast.parse('def foo():\n x = "not docstring"')
875 self.assertIsNone(ast.get_docstring(node.body[0]))
876
877 node = ast.parse('async def foo():\n pass')
878 self.assertIsNone(ast.get_docstring(node.body[0]))
879 node = ast.parse('async def foo():\n x = "not docstring"')
880 self.assertIsNone(ast.get_docstring(node.body[0]))
Yury Selivanov2f07a662015-07-23 08:54:35 +0300881
Anthony Sottile995d9b92019-01-12 20:05:13 -0800882 def test_multi_line_docstring_col_offset_and_lineno_issue16806(self):
883 node = ast.parse(
884 '"""line one\nline two"""\n\n'
885 'def foo():\n """line one\n line two"""\n\n'
886 ' def bar():\n """line one\n line two"""\n'
887 ' """line one\n line two"""\n'
888 '"""line one\nline two"""\n\n'
889 )
890 self.assertEqual(node.body[0].col_offset, 0)
891 self.assertEqual(node.body[0].lineno, 1)
892 self.assertEqual(node.body[1].body[0].col_offset, 2)
893 self.assertEqual(node.body[1].body[0].lineno, 5)
894 self.assertEqual(node.body[1].body[1].body[0].col_offset, 4)
895 self.assertEqual(node.body[1].body[1].body[0].lineno, 9)
896 self.assertEqual(node.body[1].body[2].col_offset, 2)
897 self.assertEqual(node.body[1].body[2].lineno, 11)
898 self.assertEqual(node.body[2].col_offset, 0)
899 self.assertEqual(node.body[2].lineno, 13)
900
Lysandros Nikolaou025a6022019-12-12 22:40:21 +0100901 def test_elif_stmt_start_position(self):
902 node = ast.parse('if a:\n pass\nelif b:\n pass\n')
903 elif_stmt = node.body[0].orelse[0]
904 self.assertEqual(elif_stmt.lineno, 3)
905 self.assertEqual(elif_stmt.col_offset, 0)
906
Lysandros Nikolaou5936a4c2019-12-14 11:24:57 +0100907 def test_elif_stmt_start_position_with_else(self):
908 node = ast.parse('if a:\n pass\nelif b:\n pass\nelse:\n pass\n')
909 elif_stmt = node.body[0].orelse[0]
910 self.assertEqual(elif_stmt.lineno, 3)
911 self.assertEqual(elif_stmt.col_offset, 0)
912
Lysandros Nikolaou50d4f122019-12-18 01:20:55 +0100913 def test_starred_expr_end_position_within_call(self):
914 node = ast.parse('f(*[0, 1])')
915 starred_expr = node.body[0].value.args[0]
916 self.assertEqual(starred_expr.end_lineno, 1)
917 self.assertEqual(starred_expr.end_col_offset, 9)
918
Georg Brandl0c77a822008-06-10 16:37:50 +0000919 def test_literal_eval(self):
920 self.assertEqual(ast.literal_eval('[1, 2, 3]'), [1, 2, 3])
921 self.assertEqual(ast.literal_eval('{"foo": 42}'), {"foo": 42})
922 self.assertEqual(ast.literal_eval('(True, False, None)'), (True, False, None))
Benjamin Peterson3e742892010-07-11 12:59:24 +0000923 self.assertEqual(ast.literal_eval('{1, 2, 3}'), {1, 2, 3})
Benjamin Peterson5ef96e52010-07-11 23:06:06 +0000924 self.assertEqual(ast.literal_eval('b"hi"'), b"hi")
Raymond Hettinger4fcf5c12020-01-02 22:21:18 -0700925 self.assertEqual(ast.literal_eval('set()'), set())
Georg Brandl0c77a822008-06-10 16:37:50 +0000926 self.assertRaises(ValueError, ast.literal_eval, 'foo()')
Serhiy Storchakad8ac4d12018-01-04 11:15:39 +0200927 self.assertEqual(ast.literal_eval('6'), 6)
928 self.assertEqual(ast.literal_eval('+6'), 6)
Raymond Hettingerbc959732010-10-08 00:47:45 +0000929 self.assertEqual(ast.literal_eval('-6'), -6)
Raymond Hettingerbc959732010-10-08 00:47:45 +0000930 self.assertEqual(ast.literal_eval('3.25'), 3.25)
Serhiy Storchakad8ac4d12018-01-04 11:15:39 +0200931 self.assertEqual(ast.literal_eval('+3.25'), 3.25)
932 self.assertEqual(ast.literal_eval('-3.25'), -3.25)
933 self.assertEqual(repr(ast.literal_eval('-0.0')), '-0.0')
934 self.assertRaises(ValueError, ast.literal_eval, '++6')
935 self.assertRaises(ValueError, ast.literal_eval, '+True')
936 self.assertRaises(ValueError, ast.literal_eval, '2+3')
Georg Brandl0c77a822008-06-10 16:37:50 +0000937
Serhiy Storchakad8ac4d12018-01-04 11:15:39 +0200938 def test_literal_eval_complex(self):
939 # Issue #4907
940 self.assertEqual(ast.literal_eval('6j'), 6j)
941 self.assertEqual(ast.literal_eval('-6j'), -6j)
942 self.assertEqual(ast.literal_eval('6.75j'), 6.75j)
943 self.assertEqual(ast.literal_eval('-6.75j'), -6.75j)
944 self.assertEqual(ast.literal_eval('3+6j'), 3+6j)
945 self.assertEqual(ast.literal_eval('-3+6j'), -3+6j)
946 self.assertEqual(ast.literal_eval('3-6j'), 3-6j)
947 self.assertEqual(ast.literal_eval('-3-6j'), -3-6j)
948 self.assertEqual(ast.literal_eval('3.25+6.75j'), 3.25+6.75j)
949 self.assertEqual(ast.literal_eval('-3.25+6.75j'), -3.25+6.75j)
950 self.assertEqual(ast.literal_eval('3.25-6.75j'), 3.25-6.75j)
951 self.assertEqual(ast.literal_eval('-3.25-6.75j'), -3.25-6.75j)
952 self.assertEqual(ast.literal_eval('(3+6j)'), 3+6j)
953 self.assertRaises(ValueError, ast.literal_eval, '-6j+3')
954 self.assertRaises(ValueError, ast.literal_eval, '-6j+3j')
955 self.assertRaises(ValueError, ast.literal_eval, '3+-6j')
956 self.assertRaises(ValueError, ast.literal_eval, '3+(0+6j)')
957 self.assertRaises(ValueError, ast.literal_eval, '-(3+6j)')
Benjamin Peterson058e31e2009-01-16 03:54:08 +0000958
Amaury Forgeot d'Arc58e87612011-11-22 21:51:55 +0100959 def test_bad_integer(self):
960 # issue13436: Bad error message with invalid numeric values
961 body = [ast.ImportFrom(module='time',
962 names=[ast.alias(name='sleep')],
963 level=None,
964 lineno=None, col_offset=None)]
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800965 mod = ast.Module(body, [])
Amaury Forgeot d'Arc58e87612011-11-22 21:51:55 +0100966 with self.assertRaises(ValueError) as cm:
967 compile(mod, 'test', 'exec')
968 self.assertIn("invalid integer value: None", str(cm.exception))
969
Berker Peksag0a5bd512016-04-29 19:50:02 +0300970 def test_level_as_none(self):
971 body = [ast.ImportFrom(module='time',
972 names=[ast.alias(name='sleep')],
973 level=None,
974 lineno=0, col_offset=0)]
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800975 mod = ast.Module(body, [])
Berker Peksag0a5bd512016-04-29 19:50:02 +0300976 code = compile(mod, 'test', 'exec')
977 ns = {}
978 exec(code, ns)
979 self.assertIn('sleep', ns)
980
Georg Brandl0c77a822008-06-10 16:37:50 +0000981
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500982class ASTValidatorTests(unittest.TestCase):
983
984 def mod(self, mod, msg=None, mode="exec", *, exc=ValueError):
985 mod.lineno = mod.col_offset = 0
986 ast.fix_missing_locations(mod)
Serhiy Storchaka3f228112018-09-27 17:42:37 +0300987 if msg is None:
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500988 compile(mod, "<test>", mode)
Serhiy Storchaka3f228112018-09-27 17:42:37 +0300989 else:
990 with self.assertRaises(exc) as cm:
991 compile(mod, "<test>", mode)
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500992 self.assertIn(msg, str(cm.exception))
993
994 def expr(self, node, msg=None, *, exc=ValueError):
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800995 mod = ast.Module([ast.Expr(node)], [])
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500996 self.mod(mod, msg, exc=exc)
997
998 def stmt(self, stmt, msg=None):
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800999 mod = ast.Module([stmt], [])
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001000 self.mod(mod, msg)
1001
1002 def test_module(self):
1003 m = ast.Interactive([ast.Expr(ast.Name("x", ast.Store()))])
1004 self.mod(m, "must have Load context", "single")
1005 m = ast.Expression(ast.Name("x", ast.Store()))
1006 self.mod(m, "must have Load context", "eval")
1007
1008 def _check_arguments(self, fac, check):
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01001009 def arguments(args=None, posonlyargs=None, vararg=None,
Benjamin Petersoncda75be2013-03-18 10:48:58 -07001010 kwonlyargs=None, kwarg=None,
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001011 defaults=None, kw_defaults=None):
1012 if args is None:
1013 args = []
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01001014 if posonlyargs is None:
1015 posonlyargs = []
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001016 if kwonlyargs is None:
1017 kwonlyargs = []
1018 if defaults is None:
1019 defaults = []
1020 if kw_defaults is None:
1021 kw_defaults = []
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01001022 args = ast.arguments(args, posonlyargs, vararg, kwonlyargs,
1023 kw_defaults, kwarg, defaults)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001024 return fac(args)
1025 args = [ast.arg("x", ast.Name("x", ast.Store()))]
1026 check(arguments(args=args), "must have Load context")
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01001027 check(arguments(posonlyargs=args), "must have Load context")
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001028 check(arguments(kwonlyargs=args), "must have Load context")
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001029 check(arguments(defaults=[ast.Num(3)]),
1030 "more positional defaults than args")
1031 check(arguments(kw_defaults=[ast.Num(4)]),
1032 "length of kwonlyargs is not the same as kw_defaults")
1033 args = [ast.arg("x", ast.Name("x", ast.Load()))]
1034 check(arguments(args=args, defaults=[ast.Name("x", ast.Store())]),
1035 "must have Load context")
1036 args = [ast.arg("a", ast.Name("x", ast.Load())),
1037 ast.arg("b", ast.Name("y", ast.Load()))]
1038 check(arguments(kwonlyargs=args,
1039 kw_defaults=[None, ast.Name("x", ast.Store())]),
1040 "must have Load context")
1041
1042 def test_funcdef(self):
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01001043 a = ast.arguments([], [], None, [], [], None, [])
Serhiy Storchaka73cbe7a2018-05-29 12:04:55 +03001044 f = ast.FunctionDef("x", a, [], [], None)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001045 self.stmt(f, "empty body on FunctionDef")
1046 f = ast.FunctionDef("x", a, [ast.Pass()], [ast.Name("x", ast.Store())],
Serhiy Storchaka73cbe7a2018-05-29 12:04:55 +03001047 None)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001048 self.stmt(f, "must have Load context")
1049 f = ast.FunctionDef("x", a, [ast.Pass()], [],
Serhiy Storchaka73cbe7a2018-05-29 12:04:55 +03001050 ast.Name("x", ast.Store()))
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001051 self.stmt(f, "must have Load context")
1052 def fac(args):
Serhiy Storchaka73cbe7a2018-05-29 12:04:55 +03001053 return ast.FunctionDef("x", args, [ast.Pass()], [], None)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001054 self._check_arguments(fac, self.stmt)
1055
1056 def test_classdef(self):
Benjamin Peterson025e9eb2015-05-05 20:16:41 -04001057 def cls(bases=None, keywords=None, body=None, decorator_list=None):
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001058 if bases is None:
1059 bases = []
1060 if keywords is None:
1061 keywords = []
1062 if body is None:
1063 body = [ast.Pass()]
1064 if decorator_list is None:
1065 decorator_list = []
Benjamin Peterson025e9eb2015-05-05 20:16:41 -04001066 return ast.ClassDef("myclass", bases, keywords,
Serhiy Storchaka73cbe7a2018-05-29 12:04:55 +03001067 body, decorator_list)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001068 self.stmt(cls(bases=[ast.Name("x", ast.Store())]),
1069 "must have Load context")
1070 self.stmt(cls(keywords=[ast.keyword("x", ast.Name("x", ast.Store()))]),
1071 "must have Load context")
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001072 self.stmt(cls(body=[]), "empty body on ClassDef")
1073 self.stmt(cls(body=[None]), "None disallowed")
1074 self.stmt(cls(decorator_list=[ast.Name("x", ast.Store())]),
1075 "must have Load context")
1076
1077 def test_delete(self):
1078 self.stmt(ast.Delete([]), "empty targets on Delete")
1079 self.stmt(ast.Delete([None]), "None disallowed")
1080 self.stmt(ast.Delete([ast.Name("x", ast.Load())]),
1081 "must have Del context")
1082
1083 def test_assign(self):
1084 self.stmt(ast.Assign([], ast.Num(3)), "empty targets on Assign")
1085 self.stmt(ast.Assign([None], ast.Num(3)), "None disallowed")
1086 self.stmt(ast.Assign([ast.Name("x", ast.Load())], ast.Num(3)),
1087 "must have Store context")
1088 self.stmt(ast.Assign([ast.Name("x", ast.Store())],
1089 ast.Name("y", ast.Store())),
1090 "must have Load context")
1091
1092 def test_augassign(self):
1093 aug = ast.AugAssign(ast.Name("x", ast.Load()), ast.Add(),
1094 ast.Name("y", ast.Load()))
1095 self.stmt(aug, "must have Store context")
1096 aug = ast.AugAssign(ast.Name("x", ast.Store()), ast.Add(),
1097 ast.Name("y", ast.Store()))
1098 self.stmt(aug, "must have Load context")
1099
1100 def test_for(self):
1101 x = ast.Name("x", ast.Store())
1102 y = ast.Name("y", ast.Load())
1103 p = ast.Pass()
1104 self.stmt(ast.For(x, y, [], []), "empty body on For")
1105 self.stmt(ast.For(ast.Name("x", ast.Load()), y, [p], []),
1106 "must have Store context")
1107 self.stmt(ast.For(x, ast.Name("y", ast.Store()), [p], []),
1108 "must have Load context")
1109 e = ast.Expr(ast.Name("x", ast.Store()))
1110 self.stmt(ast.For(x, y, [e], []), "must have Load context")
1111 self.stmt(ast.For(x, y, [p], [e]), "must have Load context")
1112
1113 def test_while(self):
1114 self.stmt(ast.While(ast.Num(3), [], []), "empty body on While")
1115 self.stmt(ast.While(ast.Name("x", ast.Store()), [ast.Pass()], []),
1116 "must have Load context")
1117 self.stmt(ast.While(ast.Num(3), [ast.Pass()],
1118 [ast.Expr(ast.Name("x", ast.Store()))]),
1119 "must have Load context")
1120
1121 def test_if(self):
1122 self.stmt(ast.If(ast.Num(3), [], []), "empty body on If")
1123 i = ast.If(ast.Name("x", ast.Store()), [ast.Pass()], [])
1124 self.stmt(i, "must have Load context")
1125 i = ast.If(ast.Num(3), [ast.Expr(ast.Name("x", ast.Store()))], [])
1126 self.stmt(i, "must have Load context")
1127 i = ast.If(ast.Num(3), [ast.Pass()],
1128 [ast.Expr(ast.Name("x", ast.Store()))])
1129 self.stmt(i, "must have Load context")
1130
1131 def test_with(self):
1132 p = ast.Pass()
1133 self.stmt(ast.With([], [p]), "empty items on With")
1134 i = ast.withitem(ast.Num(3), None)
1135 self.stmt(ast.With([i], []), "empty body on With")
1136 i = ast.withitem(ast.Name("x", ast.Store()), None)
1137 self.stmt(ast.With([i], [p]), "must have Load context")
1138 i = ast.withitem(ast.Num(3), ast.Name("x", ast.Load()))
1139 self.stmt(ast.With([i], [p]), "must have Store context")
1140
1141 def test_raise(self):
1142 r = ast.Raise(None, ast.Num(3))
1143 self.stmt(r, "Raise with cause but no exception")
1144 r = ast.Raise(ast.Name("x", ast.Store()), None)
1145 self.stmt(r, "must have Load context")
1146 r = ast.Raise(ast.Num(4), ast.Name("x", ast.Store()))
1147 self.stmt(r, "must have Load context")
1148
1149 def test_try(self):
1150 p = ast.Pass()
1151 t = ast.Try([], [], [], [p])
1152 self.stmt(t, "empty body on Try")
1153 t = ast.Try([ast.Expr(ast.Name("x", ast.Store()))], [], [], [p])
1154 self.stmt(t, "must have Load context")
1155 t = ast.Try([p], [], [], [])
1156 self.stmt(t, "Try has neither except handlers nor finalbody")
1157 t = ast.Try([p], [], [p], [p])
1158 self.stmt(t, "Try has orelse but no except handlers")
1159 t = ast.Try([p], [ast.ExceptHandler(None, "x", [])], [], [])
1160 self.stmt(t, "empty body on ExceptHandler")
1161 e = [ast.ExceptHandler(ast.Name("x", ast.Store()), "y", [p])]
1162 self.stmt(ast.Try([p], e, [], []), "must have Load context")
1163 e = [ast.ExceptHandler(None, "x", [p])]
1164 t = ast.Try([p], e, [ast.Expr(ast.Name("x", ast.Store()))], [p])
1165 self.stmt(t, "must have Load context")
1166 t = ast.Try([p], e, [p], [ast.Expr(ast.Name("x", ast.Store()))])
1167 self.stmt(t, "must have Load context")
1168
1169 def test_assert(self):
1170 self.stmt(ast.Assert(ast.Name("x", ast.Store()), None),
1171 "must have Load context")
1172 assrt = ast.Assert(ast.Name("x", ast.Load()),
1173 ast.Name("y", ast.Store()))
1174 self.stmt(assrt, "must have Load context")
1175
1176 def test_import(self):
1177 self.stmt(ast.Import([]), "empty names on Import")
1178
1179 def test_importfrom(self):
1180 imp = ast.ImportFrom(None, [ast.alias("x", None)], -42)
Serhiy Storchaka7de28402016-06-27 23:40:43 +03001181 self.stmt(imp, "Negative ImportFrom level")
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001182 self.stmt(ast.ImportFrom(None, [], 0), "empty names on ImportFrom")
1183
1184 def test_global(self):
1185 self.stmt(ast.Global([]), "empty names on Global")
1186
1187 def test_nonlocal(self):
1188 self.stmt(ast.Nonlocal([]), "empty names on Nonlocal")
1189
1190 def test_expr(self):
1191 e = ast.Expr(ast.Name("x", ast.Store()))
1192 self.stmt(e, "must have Load context")
1193
1194 def test_boolop(self):
1195 b = ast.BoolOp(ast.And(), [])
1196 self.expr(b, "less than 2 values")
1197 b = ast.BoolOp(ast.And(), [ast.Num(3)])
1198 self.expr(b, "less than 2 values")
1199 b = ast.BoolOp(ast.And(), [ast.Num(4), None])
1200 self.expr(b, "None disallowed")
1201 b = ast.BoolOp(ast.And(), [ast.Num(4), ast.Name("x", ast.Store())])
1202 self.expr(b, "must have Load context")
1203
1204 def test_unaryop(self):
1205 u = ast.UnaryOp(ast.Not(), ast.Name("x", ast.Store()))
1206 self.expr(u, "must have Load context")
1207
1208 def test_lambda(self):
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01001209 a = ast.arguments([], [], None, [], [], None, [])
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001210 self.expr(ast.Lambda(a, ast.Name("x", ast.Store())),
1211 "must have Load context")
1212 def fac(args):
1213 return ast.Lambda(args, ast.Name("x", ast.Load()))
1214 self._check_arguments(fac, self.expr)
1215
1216 def test_ifexp(self):
1217 l = ast.Name("x", ast.Load())
1218 s = ast.Name("y", ast.Store())
1219 for args in (s, l, l), (l, s, l), (l, l, s):
Benjamin Peterson71ce8972011-08-09 16:17:12 -05001220 self.expr(ast.IfExp(*args), "must have Load context")
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001221
1222 def test_dict(self):
1223 d = ast.Dict([], [ast.Name("x", ast.Load())])
1224 self.expr(d, "same number of keys as values")
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001225 d = ast.Dict([ast.Name("x", ast.Load())], [None])
1226 self.expr(d, "None disallowed")
1227
1228 def test_set(self):
1229 self.expr(ast.Set([None]), "None disallowed")
1230 s = ast.Set([ast.Name("x", ast.Store())])
1231 self.expr(s, "must have Load context")
1232
1233 def _check_comprehension(self, fac):
1234 self.expr(fac([]), "comprehension with no generators")
1235 g = ast.comprehension(ast.Name("x", ast.Load()),
Yury Selivanov52c4e7c2016-09-09 10:36:01 -07001236 ast.Name("x", ast.Load()), [], 0)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001237 self.expr(fac([g]), "must have Store context")
1238 g = ast.comprehension(ast.Name("x", ast.Store()),
Yury Selivanov52c4e7c2016-09-09 10:36:01 -07001239 ast.Name("x", ast.Store()), [], 0)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001240 self.expr(fac([g]), "must have Load context")
1241 x = ast.Name("x", ast.Store())
1242 y = ast.Name("y", ast.Load())
Yury Selivanov52c4e7c2016-09-09 10:36:01 -07001243 g = ast.comprehension(x, y, [None], 0)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001244 self.expr(fac([g]), "None disallowed")
Yury Selivanov52c4e7c2016-09-09 10:36:01 -07001245 g = ast.comprehension(x, y, [ast.Name("x", ast.Store())], 0)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001246 self.expr(fac([g]), "must have Load context")
1247
1248 def _simple_comp(self, fac):
1249 g = ast.comprehension(ast.Name("x", ast.Store()),
Yury Selivanov52c4e7c2016-09-09 10:36:01 -07001250 ast.Name("x", ast.Load()), [], 0)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001251 self.expr(fac(ast.Name("x", ast.Store()), [g]),
1252 "must have Load context")
1253 def wrap(gens):
1254 return fac(ast.Name("x", ast.Store()), gens)
1255 self._check_comprehension(wrap)
1256
1257 def test_listcomp(self):
1258 self._simple_comp(ast.ListComp)
1259
1260 def test_setcomp(self):
1261 self._simple_comp(ast.SetComp)
1262
1263 def test_generatorexp(self):
1264 self._simple_comp(ast.GeneratorExp)
1265
1266 def test_dictcomp(self):
1267 g = ast.comprehension(ast.Name("y", ast.Store()),
Yury Selivanov52c4e7c2016-09-09 10:36:01 -07001268 ast.Name("p", ast.Load()), [], 0)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001269 c = ast.DictComp(ast.Name("x", ast.Store()),
1270 ast.Name("y", ast.Load()), [g])
1271 self.expr(c, "must have Load context")
1272 c = ast.DictComp(ast.Name("x", ast.Load()),
1273 ast.Name("y", ast.Store()), [g])
1274 self.expr(c, "must have Load context")
1275 def factory(comps):
1276 k = ast.Name("x", ast.Load())
1277 v = ast.Name("y", ast.Load())
1278 return ast.DictComp(k, v, comps)
1279 self._check_comprehension(factory)
1280
1281 def test_yield(self):
Benjamin Peterson527c6222012-01-14 08:58:23 -05001282 self.expr(ast.Yield(ast.Name("x", ast.Store())), "must have Load")
1283 self.expr(ast.YieldFrom(ast.Name("x", ast.Store())), "must have Load")
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001284
1285 def test_compare(self):
1286 left = ast.Name("x", ast.Load())
1287 comp = ast.Compare(left, [ast.In()], [])
1288 self.expr(comp, "no comparators")
1289 comp = ast.Compare(left, [ast.In()], [ast.Num(4), ast.Num(5)])
1290 self.expr(comp, "different number of comparators and operands")
1291 comp = ast.Compare(ast.Num("blah"), [ast.In()], [left])
Serhiy Storchaka3f228112018-09-27 17:42:37 +03001292 self.expr(comp)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001293 comp = ast.Compare(left, [ast.In()], [ast.Num("blah")])
Serhiy Storchaka3f228112018-09-27 17:42:37 +03001294 self.expr(comp)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001295
1296 def test_call(self):
1297 func = ast.Name("x", ast.Load())
1298 args = [ast.Name("y", ast.Load())]
1299 keywords = [ast.keyword("w", ast.Name("z", ast.Load()))]
Benjamin Peterson025e9eb2015-05-05 20:16:41 -04001300 call = ast.Call(ast.Name("x", ast.Store()), args, keywords)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001301 self.expr(call, "must have Load context")
Benjamin Peterson025e9eb2015-05-05 20:16:41 -04001302 call = ast.Call(func, [None], keywords)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001303 self.expr(call, "None disallowed")
1304 bad_keywords = [ast.keyword("w", ast.Name("z", ast.Store()))]
Benjamin Peterson025e9eb2015-05-05 20:16:41 -04001305 call = ast.Call(func, args, bad_keywords)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001306 self.expr(call, "must have Load context")
1307
1308 def test_num(self):
1309 class subint(int):
1310 pass
1311 class subfloat(float):
1312 pass
1313 class subcomplex(complex):
1314 pass
Serhiy Storchaka3f228112018-09-27 17:42:37 +03001315 for obj in "0", "hello":
1316 self.expr(ast.Num(obj))
1317 for obj in subint(), subfloat(), subcomplex():
1318 self.expr(ast.Num(obj), "invalid type", exc=TypeError)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001319
1320 def test_attribute(self):
1321 attr = ast.Attribute(ast.Name("x", ast.Store()), "y", ast.Load())
1322 self.expr(attr, "must have Load context")
1323
1324 def test_subscript(self):
Serhiy Storchaka13d52c22020-03-10 18:52:34 +02001325 sub = ast.Subscript(ast.Name("x", ast.Store()), ast.Num(3),
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001326 ast.Load())
1327 self.expr(sub, "must have Load context")
1328 x = ast.Name("x", ast.Load())
Serhiy Storchaka13d52c22020-03-10 18:52:34 +02001329 sub = ast.Subscript(x, ast.Name("y", ast.Store()),
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001330 ast.Load())
1331 self.expr(sub, "must have Load context")
1332 s = ast.Name("x", ast.Store())
1333 for args in (s, None, None), (None, s, None), (None, None, s):
1334 sl = ast.Slice(*args)
1335 self.expr(ast.Subscript(x, sl, ast.Load()),
1336 "must have Load context")
Serhiy Storchaka13d52c22020-03-10 18:52:34 +02001337 sl = ast.Tuple([], ast.Load())
1338 self.expr(ast.Subscript(x, sl, ast.Load()))
1339 sl = ast.Tuple([s], ast.Load())
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001340 self.expr(ast.Subscript(x, sl, ast.Load()), "must have Load context")
1341
1342 def test_starred(self):
1343 left = ast.List([ast.Starred(ast.Name("x", ast.Load()), ast.Store())],
1344 ast.Store())
1345 assign = ast.Assign([left], ast.Num(4))
1346 self.stmt(assign, "must have Store context")
1347
1348 def _sequence(self, fac):
1349 self.expr(fac([None], ast.Load()), "None disallowed")
1350 self.expr(fac([ast.Name("x", ast.Store())], ast.Load()),
1351 "must have Load context")
1352
1353 def test_list(self):
1354 self._sequence(ast.List)
1355
1356 def test_tuple(self):
1357 self._sequence(ast.Tuple)
1358
Benjamin Peterson442f2092012-12-06 17:41:04 -05001359 def test_nameconstant(self):
Serhiy Storchaka3f228112018-09-27 17:42:37 +03001360 self.expr(ast.NameConstant(4))
Benjamin Peterson442f2092012-12-06 17:41:04 -05001361
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001362 def test_stdlib_validates(self):
1363 stdlib = os.path.dirname(ast.__file__)
1364 tests = [fn for fn in os.listdir(stdlib) if fn.endswith(".py")]
1365 tests.extend(["test/test_grammar.py", "test/test_unpack_ex.py"])
1366 for module in tests:
Serhiy Storchaka3bcbedc2019-01-18 07:47:48 +02001367 with self.subTest(module):
1368 fn = os.path.join(stdlib, module)
1369 with open(fn, "r", encoding="utf-8") as fp:
1370 source = fp.read()
1371 mod = ast.parse(source, fn)
1372 compile(mod, fn, "exec")
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001373
1374
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001375class ConstantTests(unittest.TestCase):
1376 """Tests on the ast.Constant node type."""
1377
1378 def compile_constant(self, value):
1379 tree = ast.parse("x = 123")
1380
1381 node = tree.body[0].value
1382 new_node = ast.Constant(value=value)
1383 ast.copy_location(new_node, node)
1384 tree.body[0].value = new_node
1385
1386 code = compile(tree, "<string>", "exec")
1387
1388 ns = {}
1389 exec(code, ns)
1390 return ns['x']
1391
Victor Stinnerbe59d142016-01-27 00:39:12 +01001392 def test_validation(self):
1393 with self.assertRaises(TypeError) as cm:
1394 self.compile_constant([1, 2, 3])
1395 self.assertEqual(str(cm.exception),
1396 "got an invalid type in Constant: list")
1397
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001398 def test_singletons(self):
1399 for const in (None, False, True, Ellipsis, b'', frozenset()):
1400 with self.subTest(const=const):
1401 value = self.compile_constant(const)
1402 self.assertIs(value, const)
1403
1404 def test_values(self):
1405 nested_tuple = (1,)
1406 nested_frozenset = frozenset({1})
1407 for level in range(3):
1408 nested_tuple = (nested_tuple, 2)
1409 nested_frozenset = frozenset({nested_frozenset, 2})
1410 values = (123, 123.0, 123j,
1411 "unicode", b'bytes',
1412 tuple("tuple"), frozenset("frozenset"),
1413 nested_tuple, nested_frozenset)
1414 for value in values:
1415 with self.subTest(value=value):
1416 result = self.compile_constant(value)
1417 self.assertEqual(result, value)
1418
1419 def test_assign_to_constant(self):
1420 tree = ast.parse("x = 1")
1421
1422 target = tree.body[0].targets[0]
1423 new_target = ast.Constant(value=1)
1424 ast.copy_location(new_target, target)
1425 tree.body[0].targets[0] = new_target
1426
1427 with self.assertRaises(ValueError) as cm:
1428 compile(tree, "string", "exec")
1429 self.assertEqual(str(cm.exception),
1430 "expression which can't be assigned "
1431 "to in Store context")
1432
1433 def test_get_docstring(self):
1434 tree = ast.parse("'docstring'\nx = 1")
1435 self.assertEqual(ast.get_docstring(tree), 'docstring')
1436
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001437 def get_load_const(self, tree):
1438 # Compile to bytecode, disassemble and get parameter of LOAD_CONST
1439 # instructions
1440 co = compile(tree, '<string>', 'exec')
1441 consts = []
1442 for instr in dis.get_instructions(co):
1443 if instr.opname == 'LOAD_CONST':
1444 consts.append(instr.argval)
1445 return consts
1446
1447 @support.cpython_only
1448 def test_load_const(self):
1449 consts = [None,
1450 True, False,
1451 124,
1452 2.0,
1453 3j,
1454 "unicode",
1455 b'bytes',
1456 (1, 2, 3)]
1457
Victor Stinnera2724092016-02-08 18:17:58 +01001458 code = '\n'.join(['x={!r}'.format(const) for const in consts])
1459 code += '\nx = ...'
1460 consts.extend((Ellipsis, None))
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001461
1462 tree = ast.parse(code)
Victor Stinnera2724092016-02-08 18:17:58 +01001463 self.assertEqual(self.get_load_const(tree),
1464 consts)
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001465
1466 # Replace expression nodes with constants
Victor Stinnera2724092016-02-08 18:17:58 +01001467 for assign, const in zip(tree.body, consts):
1468 assert isinstance(assign, ast.Assign), ast.dump(assign)
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001469 new_node = ast.Constant(value=const)
Victor Stinnera2724092016-02-08 18:17:58 +01001470 ast.copy_location(new_node, assign.value)
1471 assign.value = new_node
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001472
Victor Stinnera2724092016-02-08 18:17:58 +01001473 self.assertEqual(self.get_load_const(tree),
1474 consts)
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001475
1476 def test_literal_eval(self):
1477 tree = ast.parse("1 + 2")
1478 binop = tree.body[0].value
1479
1480 new_left = ast.Constant(value=10)
1481 ast.copy_location(new_left, binop.left)
1482 binop.left = new_left
1483
Serhiy Storchakad8ac4d12018-01-04 11:15:39 +02001484 new_right = ast.Constant(value=20j)
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001485 ast.copy_location(new_right, binop.right)
1486 binop.right = new_right
1487
Serhiy Storchakad8ac4d12018-01-04 11:15:39 +02001488 self.assertEqual(ast.literal_eval(binop), 10+20j)
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001489
Guido van Rossum10f8ce62019-03-13 13:00:46 -07001490 def test_string_kind(self):
1491 c = ast.parse('"x"', mode='eval').body
1492 self.assertEqual(c.value, "x")
1493 self.assertEqual(c.kind, None)
1494
1495 c = ast.parse('u"x"', mode='eval').body
1496 self.assertEqual(c.value, "x")
1497 self.assertEqual(c.kind, "u")
1498
1499 c = ast.parse('r"x"', mode='eval').body
1500 self.assertEqual(c.value, "x")
1501 self.assertEqual(c.kind, None)
1502
1503 c = ast.parse('b"x"', mode='eval').body
1504 self.assertEqual(c.value, b"x")
1505 self.assertEqual(c.kind, None)
1506
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001507
Ivan Levkivskyi9932a222019-01-22 11:18:22 +00001508class EndPositionTests(unittest.TestCase):
1509 """Tests for end position of AST nodes.
1510
1511 Testing end positions of nodes requires a bit of extra care
1512 because of how LL parsers work.
1513 """
1514 def _check_end_pos(self, ast_node, end_lineno, end_col_offset):
1515 self.assertEqual(ast_node.end_lineno, end_lineno)
1516 self.assertEqual(ast_node.end_col_offset, end_col_offset)
1517
1518 def _check_content(self, source, ast_node, content):
1519 self.assertEqual(ast.get_source_segment(source, ast_node), content)
1520
1521 def _parse_value(self, s):
1522 # Use duck-typing to support both single expression
1523 # and a right hand side of an assignment statement.
1524 return ast.parse(s).body[0].value
1525
1526 def test_lambda(self):
1527 s = 'lambda x, *y: None'
1528 lam = self._parse_value(s)
1529 self._check_content(s, lam.body, 'None')
1530 self._check_content(s, lam.args.args[0], 'x')
1531 self._check_content(s, lam.args.vararg, 'y')
1532
1533 def test_func_def(self):
1534 s = dedent('''
1535 def func(x: int,
1536 *args: str,
1537 z: float = 0,
1538 **kwargs: Any) -> bool:
1539 return True
1540 ''').strip()
1541 fdef = ast.parse(s).body[0]
1542 self._check_end_pos(fdef, 5, 15)
1543 self._check_content(s, fdef.body[0], 'return True')
1544 self._check_content(s, fdef.args.args[0], 'x: int')
1545 self._check_content(s, fdef.args.args[0].annotation, 'int')
1546 self._check_content(s, fdef.args.kwarg, 'kwargs: Any')
1547 self._check_content(s, fdef.args.kwarg.annotation, 'Any')
1548
1549 def test_call(self):
1550 s = 'func(x, y=2, **kw)'
1551 call = self._parse_value(s)
1552 self._check_content(s, call.func, 'func')
1553 self._check_content(s, call.keywords[0].value, '2')
1554 self._check_content(s, call.keywords[1].value, 'kw')
1555
1556 def test_call_noargs(self):
1557 s = 'x[0]()'
1558 call = self._parse_value(s)
1559 self._check_content(s, call.func, 'x[0]')
1560 self._check_end_pos(call, 1, 6)
1561
1562 def test_class_def(self):
1563 s = dedent('''
1564 class C(A, B):
1565 x: int = 0
1566 ''').strip()
1567 cdef = ast.parse(s).body[0]
1568 self._check_end_pos(cdef, 2, 14)
1569 self._check_content(s, cdef.bases[1], 'B')
1570 self._check_content(s, cdef.body[0], 'x: int = 0')
1571
1572 def test_class_kw(self):
1573 s = 'class S(metaclass=abc.ABCMeta): pass'
1574 cdef = ast.parse(s).body[0]
1575 self._check_content(s, cdef.keywords[0].value, 'abc.ABCMeta')
1576
1577 def test_multi_line_str(self):
1578 s = dedent('''
1579 x = """Some multi-line text.
1580
1581 It goes on starting from same indent."""
1582 ''').strip()
1583 assign = ast.parse(s).body[0]
1584 self._check_end_pos(assign, 3, 40)
1585 self._check_end_pos(assign.value, 3, 40)
1586
1587 def test_continued_str(self):
1588 s = dedent('''
1589 x = "first part" \\
1590 "second part"
1591 ''').strip()
1592 assign = ast.parse(s).body[0]
1593 self._check_end_pos(assign, 2, 13)
1594 self._check_end_pos(assign.value, 2, 13)
1595
1596 def test_suites(self):
1597 # We intentionally put these into the same string to check
1598 # that empty lines are not part of the suite.
1599 s = dedent('''
1600 while True:
1601 pass
1602
1603 if one():
1604 x = None
1605 elif other():
1606 y = None
1607 else:
1608 z = None
1609
1610 for x, y in stuff:
1611 assert True
1612
1613 try:
1614 raise RuntimeError
1615 except TypeError as e:
1616 pass
1617
1618 pass
1619 ''').strip()
1620 mod = ast.parse(s)
1621 while_loop = mod.body[0]
1622 if_stmt = mod.body[1]
1623 for_loop = mod.body[2]
1624 try_stmt = mod.body[3]
1625 pass_stmt = mod.body[4]
1626
1627 self._check_end_pos(while_loop, 2, 8)
1628 self._check_end_pos(if_stmt, 9, 12)
1629 self._check_end_pos(for_loop, 12, 15)
1630 self._check_end_pos(try_stmt, 17, 8)
1631 self._check_end_pos(pass_stmt, 19, 4)
1632
1633 self._check_content(s, while_loop.test, 'True')
1634 self._check_content(s, if_stmt.body[0], 'x = None')
1635 self._check_content(s, if_stmt.orelse[0].test, 'other()')
1636 self._check_content(s, for_loop.target, 'x, y')
1637 self._check_content(s, try_stmt.body[0], 'raise RuntimeError')
1638 self._check_content(s, try_stmt.handlers[0].type, 'TypeError')
1639
1640 def test_fstring(self):
1641 s = 'x = f"abc {x + y} abc"'
1642 fstr = self._parse_value(s)
1643 binop = fstr.values[1].value
1644 self._check_content(s, binop, 'x + y')
1645
1646 def test_fstring_multi_line(self):
1647 s = dedent('''
1648 f"""Some multi-line text.
1649 {
1650 arg_one
1651 +
1652 arg_two
1653 }
1654 It goes on..."""
1655 ''').strip()
1656 fstr = self._parse_value(s)
1657 binop = fstr.values[1].value
1658 self._check_end_pos(binop, 5, 7)
1659 self._check_content(s, binop.left, 'arg_one')
1660 self._check_content(s, binop.right, 'arg_two')
1661
1662 def test_import_from_multi_line(self):
1663 s = dedent('''
1664 from x.y.z import (
1665 a, b, c as c
1666 )
1667 ''').strip()
1668 imp = ast.parse(s).body[0]
1669 self._check_end_pos(imp, 3, 1)
1670
1671 def test_slices(self):
1672 s1 = 'f()[1, 2] [0]'
1673 s2 = 'x[ a.b: c.d]'
1674 sm = dedent('''
1675 x[ a.b: f () ,
1676 g () : c.d
1677 ]
1678 ''').strip()
1679 i1, i2, im = map(self._parse_value, (s1, s2, sm))
1680 self._check_content(s1, i1.value, 'f()[1, 2]')
Serhiy Storchaka13d52c22020-03-10 18:52:34 +02001681 self._check_content(s1, i1.value.slice, '1, 2')
Ivan Levkivskyi9932a222019-01-22 11:18:22 +00001682 self._check_content(s2, i2.slice.lower, 'a.b')
1683 self._check_content(s2, i2.slice.upper, 'c.d')
Serhiy Storchaka13d52c22020-03-10 18:52:34 +02001684 self._check_content(sm, im.slice.elts[0].upper, 'f ()')
1685 self._check_content(sm, im.slice.elts[1].lower, 'g ()')
Ivan Levkivskyi9932a222019-01-22 11:18:22 +00001686 self._check_end_pos(im, 3, 3)
1687
1688 def test_binop(self):
1689 s = dedent('''
1690 (1 * 2 + (3 ) +
1691 4
1692 )
1693 ''').strip()
1694 binop = self._parse_value(s)
1695 self._check_end_pos(binop, 2, 6)
1696 self._check_content(s, binop.right, '4')
1697 self._check_content(s, binop.left, '1 * 2 + (3 )')
1698 self._check_content(s, binop.left.right, '3')
1699
1700 def test_boolop(self):
1701 s = dedent('''
1702 if (one_condition and
1703 (other_condition or yet_another_one)):
1704 pass
1705 ''').strip()
1706 bop = ast.parse(s).body[0].test
1707 self._check_end_pos(bop, 2, 44)
1708 self._check_content(s, bop.values[1],
1709 'other_condition or yet_another_one')
1710
1711 def test_tuples(self):
1712 s1 = 'x = () ;'
1713 s2 = 'x = 1 , ;'
1714 s3 = 'x = (1 , 2 ) ;'
1715 sm = dedent('''
1716 x = (
1717 a, b,
1718 )
1719 ''').strip()
1720 t1, t2, t3, tm = map(self._parse_value, (s1, s2, s3, sm))
1721 self._check_content(s1, t1, '()')
1722 self._check_content(s2, t2, '1 ,')
1723 self._check_content(s3, t3, '(1 , 2 )')
1724 self._check_end_pos(tm, 3, 1)
1725
1726 def test_attribute_spaces(self):
1727 s = 'func(x. y .z)'
1728 call = self._parse_value(s)
1729 self._check_content(s, call, s)
1730 self._check_content(s, call.args[0], 'x. y .z')
1731
Serhiy Storchaka6e619c42020-02-12 22:37:49 +02001732 def test_redundant_parenthesis(self):
1733 s = '( ( ( a + b ) ) )'
1734 v = ast.parse(s).body[0].value
1735 self.assertEqual(type(v).__name__, 'BinOp')
1736 self._check_content(s, v, 'a + b')
1737 s2 = 'await ' + s
1738 v = ast.parse(s2).body[0].value.value
1739 self.assertEqual(type(v).__name__, 'BinOp')
1740 self._check_content(s2, v, 'a + b')
1741
1742 def test_trailers_with_redundant_parenthesis(self):
1743 tests = (
1744 ('( ( ( a ) ) ) ( )', 'Call'),
1745 ('( ( ( a ) ) ) ( b )', 'Call'),
1746 ('( ( ( a ) ) ) [ b ]', 'Subscript'),
1747 ('( ( ( a ) ) ) . b', 'Attribute'),
1748 )
1749 for s, t in tests:
1750 with self.subTest(s):
1751 v = ast.parse(s).body[0].value
1752 self.assertEqual(type(v).__name__, t)
1753 self._check_content(s, v, s)
1754 s2 = 'await ' + s
1755 v = ast.parse(s2).body[0].value.value
1756 self.assertEqual(type(v).__name__, t)
1757 self._check_content(s2, v, s)
1758
Ivan Levkivskyi9932a222019-01-22 11:18:22 +00001759 def test_displays(self):
1760 s1 = '[{}, {1, }, {1, 2,} ]'
1761 s2 = '{a: b, f (): g () ,}'
1762 c1 = self._parse_value(s1)
1763 c2 = self._parse_value(s2)
1764 self._check_content(s1, c1.elts[0], '{}')
1765 self._check_content(s1, c1.elts[1], '{1, }')
1766 self._check_content(s1, c1.elts[2], '{1, 2,}')
1767 self._check_content(s2, c2.keys[1], 'f ()')
1768 self._check_content(s2, c2.values[1], 'g ()')
1769
1770 def test_comprehensions(self):
1771 s = dedent('''
1772 x = [{x for x, y in stuff
1773 if cond.x} for stuff in things]
1774 ''').strip()
1775 cmp = self._parse_value(s)
1776 self._check_end_pos(cmp, 2, 37)
1777 self._check_content(s, cmp.generators[0].iter, 'things')
1778 self._check_content(s, cmp.elt.generators[0].iter, 'stuff')
1779 self._check_content(s, cmp.elt.generators[0].ifs[0], 'cond.x')
1780 self._check_content(s, cmp.elt.generators[0].target, 'x, y')
1781
1782 def test_yield_await(self):
1783 s = dedent('''
1784 async def f():
1785 yield x
1786 await y
1787 ''').strip()
1788 fdef = ast.parse(s).body[0]
1789 self._check_content(s, fdef.body[0].value, 'yield x')
1790 self._check_content(s, fdef.body[1].value, 'await y')
1791
1792 def test_source_segment_multi(self):
1793 s_orig = dedent('''
1794 x = (
1795 a, b,
1796 ) + ()
1797 ''').strip()
1798 s_tuple = dedent('''
1799 (
1800 a, b,
1801 )
1802 ''').strip()
1803 binop = self._parse_value(s_orig)
1804 self.assertEqual(ast.get_source_segment(s_orig, binop.left), s_tuple)
1805
1806 def test_source_segment_padded(self):
1807 s_orig = dedent('''
1808 class C:
1809 def fun(self) -> None:
1810 "Đ–Đ–Đ–Đ–Đ–"
1811 ''').strip()
1812 s_method = ' def fun(self) -> None:\n' \
1813 ' "Đ–Đ–Đ–Đ–Đ–"'
1814 cdef = ast.parse(s_orig).body[0]
1815 self.assertEqual(ast.get_source_segment(s_orig, cdef.body[0], padded=True),
1816 s_method)
1817
1818 def test_source_segment_endings(self):
1819 s = 'v = 1\r\nw = 1\nx = 1\n\ry = 1\rz = 1\r\n'
1820 v, w, x, y, z = ast.parse(s).body
1821 self._check_content(s, v, 'v = 1')
1822 self._check_content(s, w, 'w = 1')
1823 self._check_content(s, x, 'x = 1')
1824 self._check_content(s, y, 'y = 1')
1825 self._check_content(s, z, 'z = 1')
1826
1827 def test_source_segment_tabs(self):
1828 s = dedent('''
1829 class C:
1830 \t\f def fun(self) -> None:
1831 \t\f pass
1832 ''').strip()
1833 s_method = ' \t\f def fun(self) -> None:\n' \
1834 ' \t\f pass'
1835
1836 cdef = ast.parse(s).body[0]
1837 self.assertEqual(ast.get_source_segment(s, cdef.body[0], padded=True), s_method)
1838
1839
Serhiy Storchakac3ea41e2019-08-26 10:13:19 +03001840class NodeVisitorTests(unittest.TestCase):
1841 def test_old_constant_nodes(self):
1842 class Visitor(ast.NodeVisitor):
1843 def visit_Num(self, node):
1844 log.append((node.lineno, 'Num', node.n))
1845 def visit_Str(self, node):
1846 log.append((node.lineno, 'Str', node.s))
1847 def visit_Bytes(self, node):
1848 log.append((node.lineno, 'Bytes', node.s))
1849 def visit_NameConstant(self, node):
1850 log.append((node.lineno, 'NameConstant', node.value))
1851 def visit_Ellipsis(self, node):
1852 log.append((node.lineno, 'Ellipsis', ...))
1853 mod = ast.parse(dedent('''\
1854 i = 42
1855 f = 4.25
1856 c = 4.25j
1857 s = 'string'
1858 b = b'bytes'
1859 t = True
1860 n = None
1861 e = ...
1862 '''))
1863 visitor = Visitor()
1864 log = []
1865 with warnings.catch_warnings(record=True) as wlog:
1866 warnings.filterwarnings('always', '', DeprecationWarning)
1867 visitor.visit(mod)
1868 self.assertEqual(log, [
1869 (1, 'Num', 42),
1870 (2, 'Num', 4.25),
1871 (3, 'Num', 4.25j),
1872 (4, 'Str', 'string'),
1873 (5, 'Bytes', b'bytes'),
1874 (6, 'NameConstant', True),
1875 (7, 'NameConstant', None),
1876 (8, 'Ellipsis', ...),
1877 ])
1878 self.assertEqual([str(w.message) for w in wlog], [
1879 'visit_Num is deprecated; add visit_Constant',
1880 'visit_Num is deprecated; add visit_Constant',
1881 'visit_Num is deprecated; add visit_Constant',
1882 'visit_Str is deprecated; add visit_Constant',
1883 'visit_Bytes is deprecated; add visit_Constant',
1884 'visit_NameConstant is deprecated; add visit_Constant',
1885 'visit_NameConstant is deprecated; add visit_Constant',
1886 'visit_Ellipsis is deprecated; add visit_Constant',
1887 ])
1888
1889
Neal Norwitzee9b10a2008-03-31 05:29:39 +00001890def main():
1891 if __name__ != '__main__':
Martin v. Löwis49c5da12006-03-01 22:49:05 +00001892 return
Neal Norwitzee9b10a2008-03-31 05:29:39 +00001893 if sys.argv[1:] == ['-g']:
1894 for statements, kind in ((exec_tests, "exec"), (single_tests, "single"),
1895 (eval_tests, "eval")):
1896 print(kind+"_results = [")
Victor Stinnerf0891962016-02-08 17:15:21 +01001897 for statement in statements:
1898 tree = ast.parse(statement, "?", kind)
1899 print("%r," % (to_tuple(tree),))
Neal Norwitzee9b10a2008-03-31 05:29:39 +00001900 print("]")
1901 print("main()")
1902 raise SystemExit
Brett Cannon3e9a9ae2013-06-12 21:25:59 -04001903 unittest.main()
Tim Peters400cbc32006-02-28 18:44:41 +00001904
Guido van Rossumdcfcd142019-01-31 03:40:27 -08001905#### EVERYTHING BELOW IS GENERATED BY python Lib/test/test_ast.py -g #####
Tim Peters400cbc32006-02-28 18:44:41 +00001906exec_results = [
Serhiy Storchaka850a8852020-01-10 10:12:55 +02001907('Module', [('Expr', (1, 0, 1, 4), ('Constant', (1, 0, 1, 4), None, None))], []),
1908('Module', [('Expr', (1, 0, 1, 18), ('Constant', (1, 0, 1, 18), 'module docstring', None))], []),
1909('Module', [('FunctionDef', (1, 0, 1, 13), 'f', ('arguments', [], [], None, [], [], None, []), [('Pass', (1, 9, 1, 13))], [], None, None)], []),
1910('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)], []),
1911('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)], []),
1912('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)], []),
1913('Module', [('FunctionDef', (1, 0, 1, 18), 'f', ('arguments', [], [], ('arg', (1, 7, 1, 11), 'args', None, None), [], [], None, []), [('Pass', (1, 14, 1, 18))], [], None, None)], []),
1914('Module', [('FunctionDef', (1, 0, 1, 21), 'f', ('arguments', [], [], None, [], [], ('arg', (1, 8, 1, 14), 'kwargs', None, None), []), [('Pass', (1, 17, 1, 21))], [], None, None)], []),
1915('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)], []),
1916('Module', [('ClassDef', (1, 0, 1, 12), 'C', [], [], [('Pass', (1, 8, 1, 12))], [])], []),
1917('Module', [('ClassDef', (1, 0, 1, 32), 'C', [], [], [('Expr', (1, 9, 1, 32), ('Constant', (1, 9, 1, 32), 'docstring for class C', None))], [])], []),
1918('Module', [('ClassDef', (1, 0, 1, 21), 'C', [('Name', (1, 8, 1, 14), 'object', ('Load',))], [], [('Pass', (1, 17, 1, 21))], [])], []),
1919('Module', [('FunctionDef', (1, 0, 1, 16), 'f', ('arguments', [], [], None, [], [], None, []), [('Return', (1, 8, 1, 16), ('Constant', (1, 15, 1, 16), 1, None))], [], None, None)], []),
1920('Module', [('Delete', (1, 0, 1, 5), [('Name', (1, 4, 1, 5), 'v', ('Del',))])], []),
1921('Module', [('Assign', (1, 0, 1, 5), [('Name', (1, 0, 1, 1), 'v', ('Store',))], ('Constant', (1, 4, 1, 5), 1, None), None)], []),
1922('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)], []),
1923('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)], []),
1924('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)], []),
1925('Module', [('AugAssign', (1, 0, 1, 6), ('Name', (1, 0, 1, 1), 'v', ('Store',)), ('Add',), ('Constant', (1, 5, 1, 6), 1, None))], []),
1926('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)], []),
1927('Module', [('While', (1, 0, 1, 12), ('Name', (1, 6, 1, 7), 'v', ('Load',)), [('Pass', (1, 8, 1, 12))], [])], []),
1928('Module', [('If', (1, 0, 1, 9), ('Name', (1, 3, 1, 4), 'v', ('Load',)), [('Pass', (1, 5, 1, 9))], [])], []),
1929('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))], [])])], []),
1930('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))])])], []),
1931('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)], []),
1932('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)], []),
1933('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)], []),
1934('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))])], [], [])], []),
1935('Module', [('Try', (1, 0, 4, 6), [('Pass', (2, 2, 2, 6))], [], [], [('Pass', (4, 2, 4, 6))])], []),
1936('Module', [('Assert', (1, 0, 1, 8), ('Name', (1, 7, 1, 8), 'v', ('Load',)), None)], []),
1937('Module', [('Import', (1, 0, 1, 10), [('alias', 'sys', None)])], []),
1938('Module', [('ImportFrom', (1, 0, 1, 17), 'sys', [('alias', 'v', None)], 0)], []),
1939('Module', [('Global', (1, 0, 1, 8), ['v'])], []),
1940('Module', [('Expr', (1, 0, 1, 1), ('Constant', (1, 0, 1, 1), 1, None))], []),
1941('Module', [('Pass', (1, 0, 1, 4))], []),
1942('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)], []),
1943('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)], []),
1944('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)], []),
1945('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)], []),
1946('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)], []),
1947('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)]))], []),
1948('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)]))], []),
1949('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)]))], []),
1950('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)]))], []),
1951('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)]))], []),
1952('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)], []),
1953('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)], []),
1954('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)], []),
1955('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)]))], []),
1956('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)]))], []),
1957('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)], []),
1958('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)], []),
1959('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)], []),
1960('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)], [])])], []),
1961('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 +01001962('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 +02001963('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)))], []),
1964('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)], []),
1965('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)], []),
1966('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)], []),
1967('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)], []),
1968('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)], []),
1969('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)], []),
1970('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)], []),
1971('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)], []),
1972('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)], []),
1973('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 +00001974]
1975single_results = [
Serhiy Storchaka850a8852020-01-10 10:12:55 +02001976('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 +00001977]
1978eval_results = [
Serhiy Storchaka850a8852020-01-10 10:12:55 +02001979('Expression', ('Constant', (1, 0, 1, 4), None, None)),
1980('Expression', ('BoolOp', (1, 0, 1, 7), ('And',), [('Name', (1, 0, 1, 1), 'a', ('Load',)), ('Name', (1, 6, 1, 7), 'b', ('Load',))])),
1981('Expression', ('BinOp', (1, 0, 1, 5), ('Name', (1, 0, 1, 1), 'a', ('Load',)), ('Add',), ('Name', (1, 4, 1, 5), 'b', ('Load',)))),
1982('Expression', ('UnaryOp', (1, 0, 1, 5), ('Not',), ('Name', (1, 4, 1, 5), 'v', ('Load',)))),
1983('Expression', ('Lambda', (1, 0, 1, 11), ('arguments', [], [], None, [], [], None, []), ('Constant', (1, 7, 1, 11), None, None))),
1984('Expression', ('Dict', (1, 0, 1, 7), [('Constant', (1, 2, 1, 3), 1, None)], [('Constant', (1, 4, 1, 5), 2, None)])),
1985('Expression', ('Dict', (1, 0, 1, 2), [], [])),
1986('Expression', ('Set', (1, 0, 1, 7), [('Constant', (1, 1, 1, 5), None, None)])),
1987('Expression', ('Dict', (1, 0, 5, 6), [('Constant', (2, 6, 2, 7), 1, None)], [('Constant', (4, 10, 4, 11), 2, None)])),
1988('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)])),
1989('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)])),
1990('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)])),
1991('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)])),
1992('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)])),
1993('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)])),
1994('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)])),
1995('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)])),
1996('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)])),
1997('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)])),
1998('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)])),
1999('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)])),
2000('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', 'c', ('Constant', (1, 8, 1, 9), 3, None)), ('keyword', None, ('Name', (1, 15, 1, 16), 'e', ('Load',)))])),
2001('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',))], [])),
2002('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)])], [])),
2003('Expression', ('Constant', (1, 0, 1, 2), 10, None)),
2004('Expression', ('Constant', (1, 0, 1, 8), 'string', None)),
2005('Expression', ('Attribute', (1, 0, 1, 3), ('Name', (1, 0, 1, 1), 'a', ('Load',)), 'b', ('Load',))),
Serhiy Storchaka13d52c22020-03-10 18:52:34 +02002006('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 +02002007('Expression', ('Name', (1, 0, 1, 1), 'v', ('Load',))),
2008('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',))),
2009('Expression', ('List', (1, 0, 1, 2), [], ('Load',))),
2010('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',))),
2011('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',))),
2012('Expression', ('Tuple', (1, 0, 1, 2), [], ('Load',))),
Serhiy Storchaka13d52c22020-03-10 18:52:34 +02002013('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 +00002014]
Neal Norwitzee9b10a2008-03-31 05:29:39 +00002015main()