blob: 6f86eb954ec55ae6b9e6a34b021093c0ae3364d9 [file] [log] [blame]
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001import ast
2import dis
Benjamin Peterson832bfe22011-08-09 16:15:04 -05003import os
4import sys
5import unittest
Serhiy Storchakac3ea41e2019-08-26 10:13:19 +03006import warnings
Benjamin Peterson9ed37432012-07-08 11:13:36 -07007import weakref
Ivan Levkivskyi9932a222019-01-22 11:18:22 +00008from textwrap import dedent
Benjamin Peterson9ed37432012-07-08 11:13:36 -07009
10from test import support
Tim Peters400cbc32006-02-28 18:44:41 +000011
12def to_tuple(t):
Guido van Rossum3172c5d2007-10-16 18:12:55 +000013 if t is None or isinstance(t, (str, int, complex)):
Tim Peters400cbc32006-02-28 18:44:41 +000014 return t
15 elif isinstance(t, list):
16 return [to_tuple(e) for e in t]
17 result = [t.__class__.__name__]
Martin v. Löwis49c5da12006-03-01 22:49:05 +000018 if hasattr(t, 'lineno') and hasattr(t, 'col_offset'):
19 result.append((t.lineno, t.col_offset))
Serhiy Storchaka850a8852020-01-10 10:12:55 +020020 if hasattr(t, 'end_lineno') and hasattr(t, 'end_col_offset'):
21 result[-1] += (t.end_lineno, t.end_col_offset)
Tim Peters400cbc32006-02-28 18:44:41 +000022 if t._fields is None:
23 return tuple(result)
24 for f in t._fields:
25 result.append(to_tuple(getattr(t, f)))
26 return tuple(result)
27
Neal Norwitzee9b10a2008-03-31 05:29:39 +000028
Tim Peters400cbc32006-02-28 18:44:41 +000029# These tests are compiled through "exec"
Ezio Melotti85a86292013-08-17 16:57:41 +030030# There should be at least one test per statement
Tim Peters400cbc32006-02-28 18:44:41 +000031exec_tests = [
Benjamin Peterson6ccfe852011-06-27 17:46:06 -050032 # None
33 "None",
INADA Naokicb41b272017-02-23 00:31:59 +090034 # Module docstring
35 "'module docstring'",
Tim Peters400cbc32006-02-28 18:44:41 +000036 # FunctionDef
37 "def f(): pass",
INADA Naokicb41b272017-02-23 00:31:59 +090038 # FunctionDef with docstring
39 "def f(): 'function docstring'",
Benjamin Peterson6ccfe852011-06-27 17:46:06 -050040 # FunctionDef with arg
41 "def f(a): pass",
42 # FunctionDef with arg and default value
43 "def f(a=0): pass",
44 # FunctionDef with varargs
45 "def f(*args): pass",
46 # FunctionDef with kwargs
47 "def f(**kwargs): pass",
INADA Naokicb41b272017-02-23 00:31:59 +090048 # FunctionDef with all kind of args and docstring
49 "def f(a, b=1, c=None, d=[], e={}, *args, f=42, **kwargs): 'doc for f()'",
Tim Peters400cbc32006-02-28 18:44:41 +000050 # ClassDef
51 "class C:pass",
INADA Naokicb41b272017-02-23 00:31:59 +090052 # ClassDef with docstring
53 "class C: 'docstring for class C'",
Benjamin Peterson6ccfe852011-06-27 17:46:06 -050054 # ClassDef, new style class
55 "class C(object): pass",
Tim Peters400cbc32006-02-28 18:44:41 +000056 # Return
57 "def f():return 1",
58 # Delete
59 "del v",
60 # Assign
61 "v = 1",
Serhiy Storchakab619b092018-11-27 09:40:29 +020062 "a,b = c",
63 "(a,b) = c",
64 "[a,b] = c",
Tim Peters400cbc32006-02-28 18:44:41 +000065 # AugAssign
66 "v += 1",
Tim Peters400cbc32006-02-28 18:44:41 +000067 # For
68 "for v in v:pass",
69 # While
70 "while v:pass",
71 # If
72 "if v:pass",
Lysandros Nikolaou025a6022019-12-12 22:40:21 +010073 # If-Elif
74 "if a:\n pass\nelif b:\n pass",
Lysandros Nikolaou5936a4c2019-12-14 11:24:57 +010075 # If-Elif-Else
76 "if a:\n pass\nelif b:\n pass\nelse:\n pass",
Benjamin Petersonaeabd5f2011-05-27 15:02:03 -050077 # With
78 "with x as y: pass",
79 "with x as y, z as q: pass",
Tim Peters400cbc32006-02-28 18:44:41 +000080 # Raise
Collin Winter828f04a2007-08-31 00:04:24 +000081 "raise Exception('string')",
Tim Peters400cbc32006-02-28 18:44:41 +000082 # TryExcept
83 "try:\n pass\nexcept Exception:\n pass",
84 # TryFinally
85 "try:\n pass\nfinally:\n pass",
86 # Assert
87 "assert v",
88 # Import
89 "import sys",
90 # ImportFrom
91 "from sys import v",
Tim Peters400cbc32006-02-28 18:44:41 +000092 # Global
93 "global v",
94 # Expr
95 "1",
96 # Pass,
97 "pass",
98 # Break
Yury Selivanovb3d53132015-09-01 16:10:49 -040099 "for v in v:break",
Tim Peters400cbc32006-02-28 18:44:41 +0000100 # Continue
Yury Selivanovb3d53132015-09-01 16:10:49 -0400101 "for v in v:continue",
Benjamin Peterson2e4b0e12009-09-11 22:36:20 +0000102 # for statements with naked tuples (see http://bugs.python.org/issue6704)
103 "for a,b in c: pass",
Serhiy Storchakab619b092018-11-27 09:40:29 +0200104 "for (a,b) in c: pass",
105 "for [a,b] in c: pass",
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500106 # Multiline generator expression (test for .lineno & .col_offset)
107 """(
108 (
109 Aa
110 ,
111 Bb
112 )
113 for
114 Aa
115 ,
116 Bb in Cc
117 )""",
118 # dictcomp
119 "{a : b for w in x for m in p if g}",
120 # dictcomp with naked tuple
121 "{a : b for v,w in x}",
122 # setcomp
123 "{r for l in x if g}",
124 # setcomp with naked tuple
125 "{r for l,m in x}",
Yury Selivanov75445082015-05-11 22:57:16 -0400126 # AsyncFunctionDef
INADA Naokicb41b272017-02-23 00:31:59 +0900127 "async def f():\n 'async function'\n await something()",
Yury Selivanov75445082015-05-11 22:57:16 -0400128 # AsyncFor
129 "async def f():\n async for e in i: 1\n else: 2",
130 # AsyncWith
131 "async def f():\n async with a as b: 1",
Yury Selivanovb3d53132015-09-01 16:10:49 -0400132 # PEP 448: Additional Unpacking Generalizations
133 "{**{1:2}, 2:3}",
134 "{*{1, 2}, 3}",
Yury Selivanov52c4e7c2016-09-09 10:36:01 -0700135 # Asynchronous comprehensions
136 "async def f():\n [i async for b in c]",
Serhiy Storchaka95b6acf2018-10-30 13:16:02 +0200137 # Decorated FunctionDef
Serhiy Storchaka26ae9f62019-10-26 16:46:05 +0300138 "@deco1\n@deco2()\n@deco3(1)\ndef f(): pass",
Serhiy Storchaka95b6acf2018-10-30 13:16:02 +0200139 # Decorated AsyncFunctionDef
Serhiy Storchaka26ae9f62019-10-26 16:46:05 +0300140 "@deco1\n@deco2()\n@deco3(1)\nasync def f(): pass",
Serhiy Storchaka95b6acf2018-10-30 13:16:02 +0200141 # Decorated ClassDef
Serhiy Storchaka26ae9f62019-10-26 16:46:05 +0300142 "@deco1\n@deco2()\n@deco3(1)\nclass C: pass",
Serhiy Storchakab619b092018-11-27 09:40:29 +0200143 # Decorator with generator argument
144 "@deco(a for a in b)\ndef f(): pass",
Lysandros Nikolaoud2e10982020-02-08 00:36:32 +0100145 # Decorator with attribute
146 "@a.b.c\ndef f(): pass",
Pablo Galindo0c9258a2019-03-18 13:51:53 +0000147 # Simple assignment expression
148 "(a := 1)",
Pablo Galindo2f58a842019-05-31 14:09:49 +0100149 # Positional-only arguments
150 "def f(a, /,): pass",
151 "def f(a, /, c, d, e): pass",
152 "def f(a, /, c, *, d, e): pass",
153 "def f(a, /, c, *, d, e, **kwargs): pass",
154 # Positional-only arguments with defaults
155 "def f(a=1, /,): pass",
156 "def f(a=1, /, b=2, c=4): pass",
157 "def f(a=1, /, b=2, *, c=4): pass",
158 "def f(a=1, /, b=2, *, c): pass",
159 "def f(a=1, /, b=2, *, c=4, **kwargs): pass",
160 "def f(a=1, /, b=2, *, c, **kwargs): pass",
Pablo Galindo0c9258a2019-03-18 13:51:53 +0000161
Tim Peters400cbc32006-02-28 18:44:41 +0000162]
163
164# These are compiled through "single"
165# because of overlap with "eval", it just tests what
166# can't be tested with "eval"
167single_tests = [
168 "1+2"
169]
170
171# These are compiled through "eval"
172# It should test all expressions
173eval_tests = [
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500174 # None
175 "None",
Tim Peters400cbc32006-02-28 18:44:41 +0000176 # BoolOp
177 "a and b",
178 # BinOp
179 "a + b",
180 # UnaryOp
181 "not v",
182 # Lambda
183 "lambda:None",
184 # Dict
185 "{ 1:2 }",
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500186 # Empty dict
187 "{}",
188 # Set
189 "{None,}",
190 # Multiline dict (test for .lineno & .col_offset)
191 """{
192 1
193 :
194 2
195 }""",
Tim Peters400cbc32006-02-28 18:44:41 +0000196 # ListComp
197 "[a for b in c if d]",
198 # GeneratorExp
199 "(a for b in c if d)",
Serhiy Storchakab619b092018-11-27 09:40:29 +0200200 # Comprehensions with multiple for targets
201 "[(a,b) for a,b in c]",
202 "[(a,b) for (a,b) in c]",
203 "[(a,b) for [a,b] in c]",
204 "{(a,b) for a,b in c}",
205 "{(a,b) for (a,b) in c}",
206 "{(a,b) for [a,b] in c}",
207 "((a,b) for a,b in c)",
208 "((a,b) for (a,b) in c)",
209 "((a,b) for [a,b] in c)",
Tim Peters400cbc32006-02-28 18:44:41 +0000210 # Yield - yield expressions can't work outside a function
211 #
212 # Compare
213 "1 < 2 < 3",
214 # Call
215 "f(1,2,c=3,*d,**e)",
Lysandros Nikolaou50d4f122019-12-18 01:20:55 +0100216 # Call with multi-character starred
217 "f(*[0, 1])",
Serhiy Storchakab619b092018-11-27 09:40:29 +0200218 # Call with a generator argument
219 "f(a for a in b)",
Tim Peters400cbc32006-02-28 18:44:41 +0000220 # Num
Guido van Rossume2a383d2007-01-15 16:59:06 +0000221 "10",
Tim Peters400cbc32006-02-28 18:44:41 +0000222 # Str
223 "'string'",
224 # Attribute
225 "a.b",
226 # Subscript
227 "a[b:c]",
228 # Name
229 "v",
230 # List
231 "[1,2,3]",
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500232 # Empty list
233 "[]",
Tim Peters400cbc32006-02-28 18:44:41 +0000234 # Tuple
Martin v. Löwis49c5da12006-03-01 22:49:05 +0000235 "1,2,3",
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500236 # Tuple
237 "(1,2,3)",
238 # Empty tuple
239 "()",
Martin v. Löwis49c5da12006-03-01 22:49:05 +0000240 # Combination
241 "a.b.c.d(a.b[1:2])",
242
Tim Peters400cbc32006-02-28 18:44:41 +0000243]
244
245# TODO: expr_context, slice, boolop, operator, unaryop, cmpop, comprehension
246# excepthandler, arguments, keywords, alias
247
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000248class AST_Tests(unittest.TestCase):
Tim Peters400cbc32006-02-28 18:44:41 +0000249
Batuhan TaĹźkaya397b96f2020-03-01 23:12:17 +0300250 def _is_ast_node(self, name, node):
251 if not isinstance(node, type):
252 return False
253 if "ast" not in node.__module__:
254 return False
255 return name != 'AST' and name[0].isupper()
256
Benjamin Peterson7a66fc22015-02-02 10:51:20 -0500257 def _assertTrueorder(self, ast_node, parent_pos):
Georg Brandl0c77a822008-06-10 16:37:50 +0000258 if not isinstance(ast_node, ast.AST) or ast_node._fields is None:
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000259 return
Georg Brandl0c77a822008-06-10 16:37:50 +0000260 if isinstance(ast_node, (ast.expr, ast.stmt, ast.excepthandler)):
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000261 node_pos = (ast_node.lineno, ast_node.col_offset)
Serhiy Storchaka95b6acf2018-10-30 13:16:02 +0200262 self.assertGreaterEqual(node_pos, parent_pos)
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000263 parent_pos = (ast_node.lineno, ast_node.col_offset)
264 for name in ast_node._fields:
265 value = getattr(ast_node, name)
266 if isinstance(value, list):
Serhiy Storchaka95b6acf2018-10-30 13:16:02 +0200267 first_pos = parent_pos
268 if value and name == 'decorator_list':
269 first_pos = (value[0].lineno, value[0].col_offset)
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000270 for child in value:
Serhiy Storchaka95b6acf2018-10-30 13:16:02 +0200271 self._assertTrueorder(child, first_pos)
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000272 elif value is not None:
Benjamin Peterson7a66fc22015-02-02 10:51:20 -0500273 self._assertTrueorder(value, parent_pos)
Tim Peters5ddfe412006-03-01 23:02:57 +0000274
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500275 def test_AST_objects(self):
276 x = ast.AST()
277 self.assertEqual(x._fields, ())
Benjamin Peterson7e0dbfb2012-03-12 09:46:44 -0700278 x.foobar = 42
279 self.assertEqual(x.foobar, 42)
280 self.assertEqual(x.__dict__["foobar"], 42)
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500281
282 with self.assertRaises(AttributeError):
283 x.vararg
284
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500285 with self.assertRaises(TypeError):
Serhiy Storchakabace59d2020-03-22 20:33:34 +0200286 # "ast.AST constructor takes 0 positional arguments"
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500287 ast.AST(2)
288
Benjamin Peterson9ed37432012-07-08 11:13:36 -0700289 def test_AST_garbage_collection(self):
290 class X:
291 pass
292 a = ast.AST()
293 a.x = X()
294 a.x.a = a
295 ref = weakref.ref(a.x)
296 del a
297 support.gc_collect()
298 self.assertIsNone(ref())
299
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000300 def test_snippets(self):
301 for input, output, kind in ((exec_tests, exec_results, "exec"),
302 (single_tests, single_results, "single"),
303 (eval_tests, eval_results, "eval")):
304 for i, o in zip(input, output):
Yury Selivanovb3d53132015-09-01 16:10:49 -0400305 with self.subTest(action="parsing", input=i):
306 ast_tree = compile(i, "?", kind, ast.PyCF_ONLY_AST)
307 self.assertEqual(to_tuple(ast_tree), o)
308 self._assertTrueorder(ast_tree, (0, 0))
Victor Stinner15a30952016-02-08 22:45:06 +0100309 with self.subTest(action="compiling", input=i, kind=kind):
310 compile(ast_tree, "?", kind)
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000311
Pablo Galindo0c9258a2019-03-18 13:51:53 +0000312 def test_ast_validation(self):
313 # compile() is the only function that calls PyAST_Validate
314 snippets_to_validate = exec_tests + single_tests + eval_tests
315 for snippet in snippets_to_validate:
316 tree = ast.parse(snippet)
317 compile(tree, '<string>', 'exec')
318
Benjamin Peterson78565b22009-06-28 19:19:51 +0000319 def test_slice(self):
320 slc = ast.parse("x[::]").body[0].value.slice
321 self.assertIsNone(slc.upper)
322 self.assertIsNone(slc.lower)
323 self.assertIsNone(slc.step)
324
325 def test_from_import(self):
326 im = ast.parse("from . import y").body[0]
327 self.assertIsNone(im.module)
328
Benjamin Petersona4e4e352012-03-22 08:19:04 -0400329 def test_non_interned_future_from_ast(self):
330 mod = ast.parse("from __future__ import division")
331 self.assertIsInstance(mod.body[0], ast.ImportFrom)
332 mod.body[0].module = " __future__ ".strip()
333 compile(mod, "<test>", "exec")
334
Benjamin Petersona0dfa822009-11-13 02:25:08 +0000335 def test_base_classes(self):
336 self.assertTrue(issubclass(ast.For, ast.stmt))
337 self.assertTrue(issubclass(ast.Name, ast.expr))
338 self.assertTrue(issubclass(ast.stmt, ast.AST))
339 self.assertTrue(issubclass(ast.expr, ast.AST))
340 self.assertTrue(issubclass(ast.comprehension, ast.AST))
341 self.assertTrue(issubclass(ast.Gt, ast.AST))
342
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500343 def test_field_attr_existence(self):
344 for name, item in ast.__dict__.items():
Batuhan TaĹźkaya397b96f2020-03-01 23:12:17 +0300345 if self._is_ast_node(name, item):
Serhiy Storchaka13d52c22020-03-10 18:52:34 +0200346 if name == 'Index':
347 # Index(value) just returns value now.
348 # The argument is required.
349 continue
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500350 x = item()
351 if isinstance(x, ast.AST):
352 self.assertEqual(type(x._fields), tuple)
353
354 def test_arguments(self):
355 x = ast.arguments()
Pablo Galindocd6e83b2019-07-15 01:32:18 +0200356 self.assertEqual(x._fields, ('posonlyargs', 'args', 'vararg', 'kwonlyargs',
357 'kw_defaults', 'kwarg', 'defaults'))
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500358
359 with self.assertRaises(AttributeError):
Serhiy Storchakab7e95252020-03-10 00:07:47 +0200360 x.args
361 self.assertIsNone(x.vararg)
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500362
Pablo Galindo8c77b8c2019-04-29 13:36:57 +0100363 x = ast.arguments(*range(1, 8))
Serhiy Storchakab7e95252020-03-10 00:07:47 +0200364 self.assertEqual(x.args, 2)
Pablo Galindo8c77b8c2019-04-29 13:36:57 +0100365 self.assertEqual(x.vararg, 3)
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500366
367 def test_field_attr_writable(self):
368 x = ast.Num()
369 # We can assign to _fields
370 x._fields = 666
371 self.assertEqual(x._fields, 666)
372
373 def test_classattrs(self):
374 x = ast.Num()
Guido van Rossum10f8ce62019-03-13 13:00:46 -0700375 self.assertEqual(x._fields, ('value', 'kind'))
Serhiy Storchaka3f228112018-09-27 17:42:37 +0300376
377 with self.assertRaises(AttributeError):
378 x.value
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500379
380 with self.assertRaises(AttributeError):
381 x.n
382
383 x = ast.Num(42)
Serhiy Storchaka3f228112018-09-27 17:42:37 +0300384 self.assertEqual(x.value, 42)
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500385 self.assertEqual(x.n, 42)
386
387 with self.assertRaises(AttributeError):
388 x.lineno
389
390 with self.assertRaises(AttributeError):
391 x.foobar
392
393 x = ast.Num(lineno=2)
394 self.assertEqual(x.lineno, 2)
395
396 x = ast.Num(42, lineno=0)
397 self.assertEqual(x.lineno, 0)
Guido van Rossum10f8ce62019-03-13 13:00:46 -0700398 self.assertEqual(x._fields, ('value', 'kind'))
Serhiy Storchaka3f228112018-09-27 17:42:37 +0300399 self.assertEqual(x.value, 42)
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500400 self.assertEqual(x.n, 42)
401
Guido van Rossum10f8ce62019-03-13 13:00:46 -0700402 self.assertRaises(TypeError, ast.Num, 1, None, 2)
403 self.assertRaises(TypeError, ast.Num, 1, None, 2, lineno=0)
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500404
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")
Serhiy Storchakabace59d2020-03-22 20:33:34 +0200576 self.assertIn("but got <ast.expr", str(cm.exception))
Benjamin Peterson5b066812010-11-20 01:38:49 +0000577
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
Batuhan TaĹźkaya0ac59f92020-03-19 14:32:28 +0300585 def test_invalid_constant(self):
586 for invalid_constant in int, (1, 2, int), frozenset((1, 2, int)):
587 e = ast.Expression(body=ast.Constant(invalid_constant))
588 ast.fix_missing_locations(e)
589 with self.assertRaisesRegex(
590 TypeError, "invalid type in Constant: type"
591 ):
592 compile(e, "<test>", "eval")
593
Mark Dickinsonded35ae2012-11-25 14:36:26 +0000594 def test_empty_yield_from(self):
595 # Issue 16546: yield from value is not optional.
596 empty_yield_from = ast.parse("def f():\n yield from g()")
597 empty_yield_from.body[0].body[0].value.value = None
598 with self.assertRaises(ValueError) as cm:
599 compile(empty_yield_from, "<test>", "exec")
600 self.assertIn("field value is required", str(cm.exception))
601
Oren Milman7dc46d82017-09-30 20:16:24 +0300602 @support.cpython_only
603 def test_issue31592(self):
604 # There shouldn't be an assertion failure in case of a bad
605 # unicodedata.normalize().
606 import unicodedata
607 def bad_normalize(*args):
608 return None
609 with support.swap_attr(unicodedata, 'normalize', bad_normalize):
610 self.assertRaises(TypeError, ast.parse, '\u03D5')
611
Carl Friedrich Bolz-Tereick110a47c2019-07-08 23:17:56 +0200612 def test_issue18374_binop_col_offset(self):
613 tree = ast.parse('4+5+6+7')
614 parent_binop = tree.body[0].value
615 child_binop = parent_binop.left
616 grandchild_binop = child_binop.left
617 self.assertEqual(parent_binop.col_offset, 0)
618 self.assertEqual(parent_binop.end_col_offset, 7)
619 self.assertEqual(child_binop.col_offset, 0)
620 self.assertEqual(child_binop.end_col_offset, 5)
621 self.assertEqual(grandchild_binop.col_offset, 0)
622 self.assertEqual(grandchild_binop.end_col_offset, 3)
623
624 tree = ast.parse('4+5-\\\n 6-7')
625 parent_binop = tree.body[0].value
626 child_binop = parent_binop.left
627 grandchild_binop = child_binop.left
628 self.assertEqual(parent_binop.col_offset, 0)
629 self.assertEqual(parent_binop.lineno, 1)
630 self.assertEqual(parent_binop.end_col_offset, 4)
631 self.assertEqual(parent_binop.end_lineno, 2)
632
633 self.assertEqual(child_binop.col_offset, 0)
Carl Friedrich Bolz-Tereick430a9f42019-07-09 14:20:01 +0200634 self.assertEqual(child_binop.lineno, 1)
Carl Friedrich Bolz-Tereick110a47c2019-07-08 23:17:56 +0200635 self.assertEqual(child_binop.end_col_offset, 2)
Carl Friedrich Bolz-Tereick430a9f42019-07-09 14:20:01 +0200636 self.assertEqual(child_binop.end_lineno, 2)
Carl Friedrich Bolz-Tereick110a47c2019-07-08 23:17:56 +0200637
638 self.assertEqual(grandchild_binop.col_offset, 0)
Carl Friedrich Bolz-Tereick430a9f42019-07-09 14:20:01 +0200639 self.assertEqual(grandchild_binop.lineno, 1)
Carl Friedrich Bolz-Tereick110a47c2019-07-08 23:17:56 +0200640 self.assertEqual(grandchild_binop.end_col_offset, 3)
Carl Friedrich Bolz-Tereick430a9f42019-07-09 14:20:01 +0200641 self.assertEqual(grandchild_binop.end_lineno, 1)
Georg Brandl0c77a822008-06-10 16:37:50 +0000642
Lysandros Nikolaoud2e10982020-02-08 00:36:32 +0100643 def test_issue39579_dotted_name_end_col_offset(self):
644 tree = ast.parse('@a.b.c\ndef f(): pass')
645 attr_b = tree.body[0].decorator_list[0].value
646 self.assertEqual(attr_b.end_col_offset, 4)
647
Batuhan TaĹźkaya4ab362c2020-03-16 11:12:53 +0300648 def test_ast_asdl_signature(self):
649 self.assertEqual(ast.withitem.__doc__, "withitem(expr context_expr, expr? optional_vars)")
650 self.assertEqual(ast.GtE.__doc__, "GtE")
651 self.assertEqual(ast.Name.__doc__, "Name(identifier id, expr_context ctx)")
652 self.assertEqual(ast.cmpop.__doc__, "cmpop = Eq | NotEq | Lt | LtE | Gt | GtE | Is | IsNot | In | NotIn")
653 expressions = [f" | {node.__doc__}" for node in ast.expr.__subclasses__()]
654 expressions[0] = f"expr = {ast.expr.__subclasses__()[0].__doc__}"
655 self.assertCountEqual(ast.expr.__doc__.split("\n"), expressions)
656
657
Georg Brandl0c77a822008-06-10 16:37:50 +0000658class ASTHelpers_Test(unittest.TestCase):
Guido van Rossum10f8ce62019-03-13 13:00:46 -0700659 maxDiff = None
Georg Brandl0c77a822008-06-10 16:37:50 +0000660
661 def test_parse(self):
662 a = ast.parse('foo(1 + 1)')
663 b = compile('foo(1 + 1)', '<unknown>', 'exec', ast.PyCF_ONLY_AST)
664 self.assertEqual(ast.dump(a), ast.dump(b))
665
Benjamin Peterson2e2c9032012-09-02 14:23:15 -0400666 def test_parse_in_error(self):
667 try:
668 1/0
669 except Exception:
Benjamin Petersonbd0df502012-09-02 15:04:51 -0400670 with self.assertRaises(SyntaxError) as e:
671 ast.literal_eval(r"'\U'")
672 self.assertIsNotNone(e.exception.__context__)
Benjamin Peterson2e2c9032012-09-02 14:23:15 -0400673
Georg Brandl0c77a822008-06-10 16:37:50 +0000674 def test_dump(self):
675 node = ast.parse('spam(eggs, "and cheese")')
676 self.assertEqual(ast.dump(node),
677 "Module(body=[Expr(value=Call(func=Name(id='spam', ctx=Load()), "
Serhiy Storchakab7e95252020-03-10 00:07:47 +0200678 "args=[Name(id='eggs', ctx=Load()), Constant(value='and cheese')], "
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800679 "keywords=[]))], type_ignores=[])"
Georg Brandl0c77a822008-06-10 16:37:50 +0000680 )
681 self.assertEqual(ast.dump(node, annotate_fields=False),
682 "Module([Expr(Call(Name('spam', Load()), [Name('eggs', Load()), "
Serhiy Storchakab7e95252020-03-10 00:07:47 +0200683 "Constant('and cheese')], []))], [])"
Georg Brandl0c77a822008-06-10 16:37:50 +0000684 )
685 self.assertEqual(ast.dump(node, include_attributes=True),
686 "Module(body=[Expr(value=Call(func=Name(id='spam', ctx=Load(), "
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000687 "lineno=1, col_offset=0, end_lineno=1, end_col_offset=4), "
688 "args=[Name(id='eggs', ctx=Load(), lineno=1, col_offset=5, "
Serhiy Storchakab7e95252020-03-10 00:07:47 +0200689 "end_lineno=1, end_col_offset=9), Constant(value='and cheese', "
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000690 "lineno=1, col_offset=11, end_lineno=1, end_col_offset=23)], keywords=[], "
691 "lineno=1, col_offset=0, end_lineno=1, end_col_offset=24), "
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800692 "lineno=1, col_offset=0, end_lineno=1, end_col_offset=24)], type_ignores=[])"
Georg Brandl0c77a822008-06-10 16:37:50 +0000693 )
694
Serhiy Storchaka850573b2019-09-09 19:33:13 +0300695 def test_dump_indent(self):
696 node = ast.parse('spam(eggs, "and cheese")')
697 self.assertEqual(ast.dump(node, indent=3), """\
698Module(
699 body=[
700 Expr(
701 value=Call(
702 func=Name(id='spam', ctx=Load()),
703 args=[
704 Name(id='eggs', ctx=Load()),
Serhiy Storchakab7e95252020-03-10 00:07:47 +0200705 Constant(value='and cheese')],
Serhiy Storchaka850573b2019-09-09 19:33:13 +0300706 keywords=[]))],
707 type_ignores=[])""")
708 self.assertEqual(ast.dump(node, annotate_fields=False, indent='\t'), """\
709Module(
710\t[
711\t\tExpr(
712\t\t\tCall(
713\t\t\t\tName('spam', Load()),
714\t\t\t\t[
715\t\t\t\t\tName('eggs', Load()),
Serhiy Storchakab7e95252020-03-10 00:07:47 +0200716\t\t\t\t\tConstant('and cheese')],
Serhiy Storchaka850573b2019-09-09 19:33:13 +0300717\t\t\t\t[]))],
718\t[])""")
719 self.assertEqual(ast.dump(node, include_attributes=True, indent=3), """\
720Module(
721 body=[
722 Expr(
723 value=Call(
724 func=Name(
725 id='spam',
726 ctx=Load(),
727 lineno=1,
728 col_offset=0,
729 end_lineno=1,
730 end_col_offset=4),
731 args=[
732 Name(
733 id='eggs',
734 ctx=Load(),
735 lineno=1,
736 col_offset=5,
737 end_lineno=1,
738 end_col_offset=9),
739 Constant(
740 value='and cheese',
Serhiy Storchaka850573b2019-09-09 19:33:13 +0300741 lineno=1,
742 col_offset=11,
743 end_lineno=1,
744 end_col_offset=23)],
745 keywords=[],
746 lineno=1,
747 col_offset=0,
748 end_lineno=1,
749 end_col_offset=24),
750 lineno=1,
751 col_offset=0,
752 end_lineno=1,
753 end_col_offset=24)],
754 type_ignores=[])""")
755
Serhiy Storchakae64f9482019-08-29 09:30:23 +0300756 def test_dump_incomplete(self):
757 node = ast.Raise(lineno=3, col_offset=4)
758 self.assertEqual(ast.dump(node),
759 "Raise()"
760 )
761 self.assertEqual(ast.dump(node, include_attributes=True),
762 "Raise(lineno=3, col_offset=4)"
763 )
764 node = ast.Raise(exc=ast.Name(id='e', ctx=ast.Load()), lineno=3, col_offset=4)
765 self.assertEqual(ast.dump(node),
766 "Raise(exc=Name(id='e', ctx=Load()))"
767 )
768 self.assertEqual(ast.dump(node, annotate_fields=False),
769 "Raise(Name('e', Load()))"
770 )
771 self.assertEqual(ast.dump(node, include_attributes=True),
772 "Raise(exc=Name(id='e', ctx=Load()), lineno=3, col_offset=4)"
773 )
774 self.assertEqual(ast.dump(node, annotate_fields=False, include_attributes=True),
775 "Raise(Name('e', Load()), lineno=3, col_offset=4)"
776 )
777 node = ast.Raise(cause=ast.Name(id='e', ctx=ast.Load()))
778 self.assertEqual(ast.dump(node),
779 "Raise(cause=Name(id='e', ctx=Load()))"
780 )
781 self.assertEqual(ast.dump(node, annotate_fields=False),
782 "Raise(cause=Name('e', Load()))"
783 )
784
Georg Brandl0c77a822008-06-10 16:37:50 +0000785 def test_copy_location(self):
786 src = ast.parse('1 + 1', mode='eval')
787 src.body.right = ast.copy_location(ast.Num(2), src.body.right)
788 self.assertEqual(ast.dump(src, include_attributes=True),
Serhiy Storchakab7e95252020-03-10 00:07:47 +0200789 'Expression(body=BinOp(left=Constant(value=1, lineno=1, col_offset=0, '
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000790 'end_lineno=1, end_col_offset=1), op=Add(), right=Constant(value=2, '
791 'lineno=1, col_offset=4, end_lineno=1, end_col_offset=5), lineno=1, '
792 'col_offset=0, end_lineno=1, end_col_offset=5))'
Georg Brandl0c77a822008-06-10 16:37:50 +0000793 )
794
795 def test_fix_missing_locations(self):
796 src = ast.parse('write("spam")')
797 src.body.append(ast.Expr(ast.Call(ast.Name('spam', ast.Load()),
Benjamin Peterson025e9eb2015-05-05 20:16:41 -0400798 [ast.Str('eggs')], [])))
Georg Brandl0c77a822008-06-10 16:37:50 +0000799 self.assertEqual(src, ast.fix_missing_locations(src))
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000800 self.maxDiff = None
Georg Brandl0c77a822008-06-10 16:37:50 +0000801 self.assertEqual(ast.dump(src, include_attributes=True),
802 "Module(body=[Expr(value=Call(func=Name(id='write', ctx=Load(), "
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000803 "lineno=1, col_offset=0, end_lineno=1, end_col_offset=5), "
Serhiy Storchakab7e95252020-03-10 00:07:47 +0200804 "args=[Constant(value='spam', lineno=1, col_offset=6, end_lineno=1, "
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000805 "end_col_offset=12)], keywords=[], lineno=1, col_offset=0, end_lineno=1, "
806 "end_col_offset=13), lineno=1, col_offset=0, end_lineno=1, "
807 "end_col_offset=13), Expr(value=Call(func=Name(id='spam', ctx=Load(), "
808 "lineno=1, col_offset=0, end_lineno=1, end_col_offset=0), "
809 "args=[Constant(value='eggs', lineno=1, col_offset=0, end_lineno=1, "
810 "end_col_offset=0)], keywords=[], lineno=1, col_offset=0, end_lineno=1, "
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800811 "end_col_offset=0), lineno=1, col_offset=0, end_lineno=1, end_col_offset=0)], "
812 "type_ignores=[])"
Georg Brandl0c77a822008-06-10 16:37:50 +0000813 )
814
815 def test_increment_lineno(self):
816 src = ast.parse('1 + 1', mode='eval')
817 self.assertEqual(ast.increment_lineno(src, n=3), src)
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 Brandl0c77a822008-06-10 16:37:50 +0000823 )
Georg Brandl619e7ba2011-01-09 07:38:51 +0000824 # issue10869: do not increment lineno of root twice
Georg Brandlefb69022011-01-09 07:50:48 +0000825 src = ast.parse('1 + 1', mode='eval')
Georg Brandl619e7ba2011-01-09 07:38:51 +0000826 self.assertEqual(ast.increment_lineno(src.body, n=3), src.body)
827 self.assertEqual(ast.dump(src, include_attributes=True),
Serhiy Storchakab7e95252020-03-10 00:07:47 +0200828 'Expression(body=BinOp(left=Constant(value=1, lineno=4, col_offset=0, '
829 'end_lineno=4, end_col_offset=1), op=Add(), right=Constant(value=1, '
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000830 'lineno=4, col_offset=4, end_lineno=4, end_col_offset=5), lineno=4, '
831 'col_offset=0, end_lineno=4, end_col_offset=5))'
Georg Brandl619e7ba2011-01-09 07:38:51 +0000832 )
Georg Brandl0c77a822008-06-10 16:37:50 +0000833
834 def test_iter_fields(self):
835 node = ast.parse('foo()', mode='eval')
836 d = dict(ast.iter_fields(node.body))
837 self.assertEqual(d.pop('func').id, 'foo')
Benjamin Peterson025e9eb2015-05-05 20:16:41 -0400838 self.assertEqual(d, {'keywords': [], 'args': []})
Georg Brandl0c77a822008-06-10 16:37:50 +0000839
840 def test_iter_child_nodes(self):
841 node = ast.parse("spam(23, 42, eggs='leek')", mode='eval')
842 self.assertEqual(len(list(ast.iter_child_nodes(node.body))), 4)
843 iterator = ast.iter_child_nodes(node.body)
844 self.assertEqual(next(iterator).id, 'spam')
Serhiy Storchaka3f228112018-09-27 17:42:37 +0300845 self.assertEqual(next(iterator).value, 23)
846 self.assertEqual(next(iterator).value, 42)
Georg Brandl0c77a822008-06-10 16:37:50 +0000847 self.assertEqual(ast.dump(next(iterator)),
Serhiy Storchakab7e95252020-03-10 00:07:47 +0200848 "keyword(arg='eggs', value=Constant(value='leek'))"
Georg Brandl0c77a822008-06-10 16:37:50 +0000849 )
850
851 def test_get_docstring(self):
Serhiy Storchaka08f127a2018-06-15 11:05:15 +0300852 node = ast.parse('"""line one\n line two"""')
853 self.assertEqual(ast.get_docstring(node),
854 'line one\nline two')
855
856 node = ast.parse('class foo:\n """line one\n line two"""')
857 self.assertEqual(ast.get_docstring(node.body[0]),
858 'line one\nline two')
859
Georg Brandl0c77a822008-06-10 16:37:50 +0000860 node = ast.parse('def foo():\n """line one\n line two"""')
861 self.assertEqual(ast.get_docstring(node.body[0]),
862 'line one\nline two')
863
Yury Selivanov2f07a662015-07-23 08:54:35 +0300864 node = ast.parse('async def foo():\n """spam\n ham"""')
865 self.assertEqual(ast.get_docstring(node.body[0]), 'spam\nham')
Serhiy Storchaka08f127a2018-06-15 11:05:15 +0300866
867 def test_get_docstring_none(self):
Matthias Bussonnier41cea702017-02-23 22:44:19 -0800868 self.assertIsNone(ast.get_docstring(ast.parse('')))
Serhiy Storchaka08f127a2018-06-15 11:05:15 +0300869 node = ast.parse('x = "not docstring"')
870 self.assertIsNone(ast.get_docstring(node))
871 node = ast.parse('def foo():\n pass')
872 self.assertIsNone(ast.get_docstring(node))
873
874 node = ast.parse('class foo:\n pass')
875 self.assertIsNone(ast.get_docstring(node.body[0]))
876 node = ast.parse('class foo:\n x = "not docstring"')
877 self.assertIsNone(ast.get_docstring(node.body[0]))
878 node = ast.parse('class foo:\n def bar(self): pass')
879 self.assertIsNone(ast.get_docstring(node.body[0]))
880
881 node = ast.parse('def foo():\n pass')
882 self.assertIsNone(ast.get_docstring(node.body[0]))
883 node = ast.parse('def foo():\n x = "not docstring"')
884 self.assertIsNone(ast.get_docstring(node.body[0]))
885
886 node = ast.parse('async def foo():\n pass')
887 self.assertIsNone(ast.get_docstring(node.body[0]))
888 node = ast.parse('async def foo():\n x = "not docstring"')
889 self.assertIsNone(ast.get_docstring(node.body[0]))
Yury Selivanov2f07a662015-07-23 08:54:35 +0300890
Anthony Sottile995d9b92019-01-12 20:05:13 -0800891 def test_multi_line_docstring_col_offset_and_lineno_issue16806(self):
892 node = ast.parse(
893 '"""line one\nline two"""\n\n'
894 'def foo():\n """line one\n line two"""\n\n'
895 ' def bar():\n """line one\n line two"""\n'
896 ' """line one\n line two"""\n'
897 '"""line one\nline two"""\n\n'
898 )
899 self.assertEqual(node.body[0].col_offset, 0)
900 self.assertEqual(node.body[0].lineno, 1)
901 self.assertEqual(node.body[1].body[0].col_offset, 2)
902 self.assertEqual(node.body[1].body[0].lineno, 5)
903 self.assertEqual(node.body[1].body[1].body[0].col_offset, 4)
904 self.assertEqual(node.body[1].body[1].body[0].lineno, 9)
905 self.assertEqual(node.body[1].body[2].col_offset, 2)
906 self.assertEqual(node.body[1].body[2].lineno, 11)
907 self.assertEqual(node.body[2].col_offset, 0)
908 self.assertEqual(node.body[2].lineno, 13)
909
Lysandros Nikolaou025a6022019-12-12 22:40:21 +0100910 def test_elif_stmt_start_position(self):
911 node = ast.parse('if a:\n pass\nelif b:\n pass\n')
912 elif_stmt = node.body[0].orelse[0]
913 self.assertEqual(elif_stmt.lineno, 3)
914 self.assertEqual(elif_stmt.col_offset, 0)
915
Lysandros Nikolaou5936a4c2019-12-14 11:24:57 +0100916 def test_elif_stmt_start_position_with_else(self):
917 node = ast.parse('if a:\n pass\nelif b:\n pass\nelse:\n pass\n')
918 elif_stmt = node.body[0].orelse[0]
919 self.assertEqual(elif_stmt.lineno, 3)
920 self.assertEqual(elif_stmt.col_offset, 0)
921
Lysandros Nikolaou50d4f122019-12-18 01:20:55 +0100922 def test_starred_expr_end_position_within_call(self):
923 node = ast.parse('f(*[0, 1])')
924 starred_expr = node.body[0].value.args[0]
925 self.assertEqual(starred_expr.end_lineno, 1)
926 self.assertEqual(starred_expr.end_col_offset, 9)
927
Georg Brandl0c77a822008-06-10 16:37:50 +0000928 def test_literal_eval(self):
929 self.assertEqual(ast.literal_eval('[1, 2, 3]'), [1, 2, 3])
930 self.assertEqual(ast.literal_eval('{"foo": 42}'), {"foo": 42})
931 self.assertEqual(ast.literal_eval('(True, False, None)'), (True, False, None))
Benjamin Peterson3e742892010-07-11 12:59:24 +0000932 self.assertEqual(ast.literal_eval('{1, 2, 3}'), {1, 2, 3})
Benjamin Peterson5ef96e52010-07-11 23:06:06 +0000933 self.assertEqual(ast.literal_eval('b"hi"'), b"hi")
Raymond Hettinger4fcf5c12020-01-02 22:21:18 -0700934 self.assertEqual(ast.literal_eval('set()'), set())
Georg Brandl0c77a822008-06-10 16:37:50 +0000935 self.assertRaises(ValueError, ast.literal_eval, 'foo()')
Serhiy Storchakad8ac4d12018-01-04 11:15:39 +0200936 self.assertEqual(ast.literal_eval('6'), 6)
937 self.assertEqual(ast.literal_eval('+6'), 6)
Raymond Hettingerbc959732010-10-08 00:47:45 +0000938 self.assertEqual(ast.literal_eval('-6'), -6)
Raymond Hettingerbc959732010-10-08 00:47:45 +0000939 self.assertEqual(ast.literal_eval('3.25'), 3.25)
Serhiy Storchakad8ac4d12018-01-04 11:15:39 +0200940 self.assertEqual(ast.literal_eval('+3.25'), 3.25)
941 self.assertEqual(ast.literal_eval('-3.25'), -3.25)
942 self.assertEqual(repr(ast.literal_eval('-0.0')), '-0.0')
943 self.assertRaises(ValueError, ast.literal_eval, '++6')
944 self.assertRaises(ValueError, ast.literal_eval, '+True')
945 self.assertRaises(ValueError, ast.literal_eval, '2+3')
Georg Brandl0c77a822008-06-10 16:37:50 +0000946
Serhiy Storchakad8ac4d12018-01-04 11:15:39 +0200947 def test_literal_eval_complex(self):
948 # Issue #4907
949 self.assertEqual(ast.literal_eval('6j'), 6j)
950 self.assertEqual(ast.literal_eval('-6j'), -6j)
951 self.assertEqual(ast.literal_eval('6.75j'), 6.75j)
952 self.assertEqual(ast.literal_eval('-6.75j'), -6.75j)
953 self.assertEqual(ast.literal_eval('3+6j'), 3+6j)
954 self.assertEqual(ast.literal_eval('-3+6j'), -3+6j)
955 self.assertEqual(ast.literal_eval('3-6j'), 3-6j)
956 self.assertEqual(ast.literal_eval('-3-6j'), -3-6j)
957 self.assertEqual(ast.literal_eval('3.25+6.75j'), 3.25+6.75j)
958 self.assertEqual(ast.literal_eval('-3.25+6.75j'), -3.25+6.75j)
959 self.assertEqual(ast.literal_eval('3.25-6.75j'), 3.25-6.75j)
960 self.assertEqual(ast.literal_eval('-3.25-6.75j'), -3.25-6.75j)
961 self.assertEqual(ast.literal_eval('(3+6j)'), 3+6j)
962 self.assertRaises(ValueError, ast.literal_eval, '-6j+3')
963 self.assertRaises(ValueError, ast.literal_eval, '-6j+3j')
964 self.assertRaises(ValueError, ast.literal_eval, '3+-6j')
965 self.assertRaises(ValueError, ast.literal_eval, '3+(0+6j)')
966 self.assertRaises(ValueError, ast.literal_eval, '-(3+6j)')
Benjamin Peterson058e31e2009-01-16 03:54:08 +0000967
Amaury Forgeot d'Arc58e87612011-11-22 21:51:55 +0100968 def test_bad_integer(self):
969 # issue13436: Bad error message with invalid numeric values
970 body = [ast.ImportFrom(module='time',
971 names=[ast.alias(name='sleep')],
972 level=None,
973 lineno=None, col_offset=None)]
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800974 mod = ast.Module(body, [])
Amaury Forgeot d'Arc58e87612011-11-22 21:51:55 +0100975 with self.assertRaises(ValueError) as cm:
976 compile(mod, 'test', 'exec')
977 self.assertIn("invalid integer value: None", str(cm.exception))
978
Berker Peksag0a5bd512016-04-29 19:50:02 +0300979 def test_level_as_none(self):
980 body = [ast.ImportFrom(module='time',
981 names=[ast.alias(name='sleep')],
982 level=None,
983 lineno=0, col_offset=0)]
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800984 mod = ast.Module(body, [])
Berker Peksag0a5bd512016-04-29 19:50:02 +0300985 code = compile(mod, 'test', 'exec')
986 ns = {}
987 exec(code, ns)
988 self.assertIn('sleep', ns)
989
Georg Brandl0c77a822008-06-10 16:37:50 +0000990
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500991class ASTValidatorTests(unittest.TestCase):
992
993 def mod(self, mod, msg=None, mode="exec", *, exc=ValueError):
994 mod.lineno = mod.col_offset = 0
995 ast.fix_missing_locations(mod)
Serhiy Storchaka3f228112018-09-27 17:42:37 +0300996 if msg is None:
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500997 compile(mod, "<test>", mode)
Serhiy Storchaka3f228112018-09-27 17:42:37 +0300998 else:
999 with self.assertRaises(exc) as cm:
1000 compile(mod, "<test>", mode)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001001 self.assertIn(msg, str(cm.exception))
1002
1003 def expr(self, node, msg=None, *, exc=ValueError):
Guido van Rossumdcfcd142019-01-31 03:40:27 -08001004 mod = ast.Module([ast.Expr(node)], [])
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001005 self.mod(mod, msg, exc=exc)
1006
1007 def stmt(self, stmt, msg=None):
Guido van Rossumdcfcd142019-01-31 03:40:27 -08001008 mod = ast.Module([stmt], [])
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001009 self.mod(mod, msg)
1010
1011 def test_module(self):
1012 m = ast.Interactive([ast.Expr(ast.Name("x", ast.Store()))])
1013 self.mod(m, "must have Load context", "single")
1014 m = ast.Expression(ast.Name("x", ast.Store()))
1015 self.mod(m, "must have Load context", "eval")
1016
1017 def _check_arguments(self, fac, check):
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01001018 def arguments(args=None, posonlyargs=None, vararg=None,
Benjamin Petersoncda75be2013-03-18 10:48:58 -07001019 kwonlyargs=None, kwarg=None,
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001020 defaults=None, kw_defaults=None):
1021 if args is None:
1022 args = []
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01001023 if posonlyargs is None:
1024 posonlyargs = []
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001025 if kwonlyargs is None:
1026 kwonlyargs = []
1027 if defaults is None:
1028 defaults = []
1029 if kw_defaults is None:
1030 kw_defaults = []
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01001031 args = ast.arguments(args, posonlyargs, vararg, kwonlyargs,
1032 kw_defaults, kwarg, defaults)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001033 return fac(args)
1034 args = [ast.arg("x", ast.Name("x", ast.Store()))]
1035 check(arguments(args=args), "must have Load context")
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01001036 check(arguments(posonlyargs=args), "must have Load context")
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001037 check(arguments(kwonlyargs=args), "must have Load context")
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001038 check(arguments(defaults=[ast.Num(3)]),
1039 "more positional defaults than args")
1040 check(arguments(kw_defaults=[ast.Num(4)]),
1041 "length of kwonlyargs is not the same as kw_defaults")
1042 args = [ast.arg("x", ast.Name("x", ast.Load()))]
1043 check(arguments(args=args, defaults=[ast.Name("x", ast.Store())]),
1044 "must have Load context")
1045 args = [ast.arg("a", ast.Name("x", ast.Load())),
1046 ast.arg("b", ast.Name("y", ast.Load()))]
1047 check(arguments(kwonlyargs=args,
1048 kw_defaults=[None, ast.Name("x", ast.Store())]),
1049 "must have Load context")
1050
1051 def test_funcdef(self):
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01001052 a = ast.arguments([], [], None, [], [], None, [])
Serhiy Storchaka73cbe7a2018-05-29 12:04:55 +03001053 f = ast.FunctionDef("x", a, [], [], None)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001054 self.stmt(f, "empty body on FunctionDef")
1055 f = ast.FunctionDef("x", a, [ast.Pass()], [ast.Name("x", ast.Store())],
Serhiy Storchaka73cbe7a2018-05-29 12:04:55 +03001056 None)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001057 self.stmt(f, "must have Load context")
1058 f = ast.FunctionDef("x", a, [ast.Pass()], [],
Serhiy Storchaka73cbe7a2018-05-29 12:04:55 +03001059 ast.Name("x", ast.Store()))
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001060 self.stmt(f, "must have Load context")
1061 def fac(args):
Serhiy Storchaka73cbe7a2018-05-29 12:04:55 +03001062 return ast.FunctionDef("x", args, [ast.Pass()], [], None)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001063 self._check_arguments(fac, self.stmt)
1064
1065 def test_classdef(self):
Benjamin Peterson025e9eb2015-05-05 20:16:41 -04001066 def cls(bases=None, keywords=None, body=None, decorator_list=None):
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001067 if bases is None:
1068 bases = []
1069 if keywords is None:
1070 keywords = []
1071 if body is None:
1072 body = [ast.Pass()]
1073 if decorator_list is None:
1074 decorator_list = []
Benjamin Peterson025e9eb2015-05-05 20:16:41 -04001075 return ast.ClassDef("myclass", bases, keywords,
Serhiy Storchaka73cbe7a2018-05-29 12:04:55 +03001076 body, decorator_list)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001077 self.stmt(cls(bases=[ast.Name("x", ast.Store())]),
1078 "must have Load context")
1079 self.stmt(cls(keywords=[ast.keyword("x", ast.Name("x", ast.Store()))]),
1080 "must have Load context")
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001081 self.stmt(cls(body=[]), "empty body on ClassDef")
1082 self.stmt(cls(body=[None]), "None disallowed")
1083 self.stmt(cls(decorator_list=[ast.Name("x", ast.Store())]),
1084 "must have Load context")
1085
1086 def test_delete(self):
1087 self.stmt(ast.Delete([]), "empty targets on Delete")
1088 self.stmt(ast.Delete([None]), "None disallowed")
1089 self.stmt(ast.Delete([ast.Name("x", ast.Load())]),
1090 "must have Del context")
1091
1092 def test_assign(self):
1093 self.stmt(ast.Assign([], ast.Num(3)), "empty targets on Assign")
1094 self.stmt(ast.Assign([None], ast.Num(3)), "None disallowed")
1095 self.stmt(ast.Assign([ast.Name("x", ast.Load())], ast.Num(3)),
1096 "must have Store context")
1097 self.stmt(ast.Assign([ast.Name("x", ast.Store())],
1098 ast.Name("y", ast.Store())),
1099 "must have Load context")
1100
1101 def test_augassign(self):
1102 aug = ast.AugAssign(ast.Name("x", ast.Load()), ast.Add(),
1103 ast.Name("y", ast.Load()))
1104 self.stmt(aug, "must have Store context")
1105 aug = ast.AugAssign(ast.Name("x", ast.Store()), ast.Add(),
1106 ast.Name("y", ast.Store()))
1107 self.stmt(aug, "must have Load context")
1108
1109 def test_for(self):
1110 x = ast.Name("x", ast.Store())
1111 y = ast.Name("y", ast.Load())
1112 p = ast.Pass()
1113 self.stmt(ast.For(x, y, [], []), "empty body on For")
1114 self.stmt(ast.For(ast.Name("x", ast.Load()), y, [p], []),
1115 "must have Store context")
1116 self.stmt(ast.For(x, ast.Name("y", ast.Store()), [p], []),
1117 "must have Load context")
1118 e = ast.Expr(ast.Name("x", ast.Store()))
1119 self.stmt(ast.For(x, y, [e], []), "must have Load context")
1120 self.stmt(ast.For(x, y, [p], [e]), "must have Load context")
1121
1122 def test_while(self):
1123 self.stmt(ast.While(ast.Num(3), [], []), "empty body on While")
1124 self.stmt(ast.While(ast.Name("x", ast.Store()), [ast.Pass()], []),
1125 "must have Load context")
1126 self.stmt(ast.While(ast.Num(3), [ast.Pass()],
1127 [ast.Expr(ast.Name("x", ast.Store()))]),
1128 "must have Load context")
1129
1130 def test_if(self):
1131 self.stmt(ast.If(ast.Num(3), [], []), "empty body on If")
1132 i = ast.If(ast.Name("x", ast.Store()), [ast.Pass()], [])
1133 self.stmt(i, "must have Load context")
1134 i = ast.If(ast.Num(3), [ast.Expr(ast.Name("x", ast.Store()))], [])
1135 self.stmt(i, "must have Load context")
1136 i = ast.If(ast.Num(3), [ast.Pass()],
1137 [ast.Expr(ast.Name("x", ast.Store()))])
1138 self.stmt(i, "must have Load context")
1139
1140 def test_with(self):
1141 p = ast.Pass()
1142 self.stmt(ast.With([], [p]), "empty items on With")
1143 i = ast.withitem(ast.Num(3), None)
1144 self.stmt(ast.With([i], []), "empty body on With")
1145 i = ast.withitem(ast.Name("x", ast.Store()), None)
1146 self.stmt(ast.With([i], [p]), "must have Load context")
1147 i = ast.withitem(ast.Num(3), ast.Name("x", ast.Load()))
1148 self.stmt(ast.With([i], [p]), "must have Store context")
1149
1150 def test_raise(self):
1151 r = ast.Raise(None, ast.Num(3))
1152 self.stmt(r, "Raise with cause but no exception")
1153 r = ast.Raise(ast.Name("x", ast.Store()), None)
1154 self.stmt(r, "must have Load context")
1155 r = ast.Raise(ast.Num(4), ast.Name("x", ast.Store()))
1156 self.stmt(r, "must have Load context")
1157
1158 def test_try(self):
1159 p = ast.Pass()
1160 t = ast.Try([], [], [], [p])
1161 self.stmt(t, "empty body on Try")
1162 t = ast.Try([ast.Expr(ast.Name("x", ast.Store()))], [], [], [p])
1163 self.stmt(t, "must have Load context")
1164 t = ast.Try([p], [], [], [])
1165 self.stmt(t, "Try has neither except handlers nor finalbody")
1166 t = ast.Try([p], [], [p], [p])
1167 self.stmt(t, "Try has orelse but no except handlers")
1168 t = ast.Try([p], [ast.ExceptHandler(None, "x", [])], [], [])
1169 self.stmt(t, "empty body on ExceptHandler")
1170 e = [ast.ExceptHandler(ast.Name("x", ast.Store()), "y", [p])]
1171 self.stmt(ast.Try([p], e, [], []), "must have Load context")
1172 e = [ast.ExceptHandler(None, "x", [p])]
1173 t = ast.Try([p], e, [ast.Expr(ast.Name("x", ast.Store()))], [p])
1174 self.stmt(t, "must have Load context")
1175 t = ast.Try([p], e, [p], [ast.Expr(ast.Name("x", ast.Store()))])
1176 self.stmt(t, "must have Load context")
1177
1178 def test_assert(self):
1179 self.stmt(ast.Assert(ast.Name("x", ast.Store()), None),
1180 "must have Load context")
1181 assrt = ast.Assert(ast.Name("x", ast.Load()),
1182 ast.Name("y", ast.Store()))
1183 self.stmt(assrt, "must have Load context")
1184
1185 def test_import(self):
1186 self.stmt(ast.Import([]), "empty names on Import")
1187
1188 def test_importfrom(self):
1189 imp = ast.ImportFrom(None, [ast.alias("x", None)], -42)
Serhiy Storchaka7de28402016-06-27 23:40:43 +03001190 self.stmt(imp, "Negative ImportFrom level")
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001191 self.stmt(ast.ImportFrom(None, [], 0), "empty names on ImportFrom")
1192
1193 def test_global(self):
1194 self.stmt(ast.Global([]), "empty names on Global")
1195
1196 def test_nonlocal(self):
1197 self.stmt(ast.Nonlocal([]), "empty names on Nonlocal")
1198
1199 def test_expr(self):
1200 e = ast.Expr(ast.Name("x", ast.Store()))
1201 self.stmt(e, "must have Load context")
1202
1203 def test_boolop(self):
1204 b = ast.BoolOp(ast.And(), [])
1205 self.expr(b, "less than 2 values")
1206 b = ast.BoolOp(ast.And(), [ast.Num(3)])
1207 self.expr(b, "less than 2 values")
1208 b = ast.BoolOp(ast.And(), [ast.Num(4), None])
1209 self.expr(b, "None disallowed")
1210 b = ast.BoolOp(ast.And(), [ast.Num(4), ast.Name("x", ast.Store())])
1211 self.expr(b, "must have Load context")
1212
1213 def test_unaryop(self):
1214 u = ast.UnaryOp(ast.Not(), ast.Name("x", ast.Store()))
1215 self.expr(u, "must have Load context")
1216
1217 def test_lambda(self):
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01001218 a = ast.arguments([], [], None, [], [], None, [])
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001219 self.expr(ast.Lambda(a, ast.Name("x", ast.Store())),
1220 "must have Load context")
1221 def fac(args):
1222 return ast.Lambda(args, ast.Name("x", ast.Load()))
1223 self._check_arguments(fac, self.expr)
1224
1225 def test_ifexp(self):
1226 l = ast.Name("x", ast.Load())
1227 s = ast.Name("y", ast.Store())
1228 for args in (s, l, l), (l, s, l), (l, l, s):
Benjamin Peterson71ce8972011-08-09 16:17:12 -05001229 self.expr(ast.IfExp(*args), "must have Load context")
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001230
1231 def test_dict(self):
1232 d = ast.Dict([], [ast.Name("x", ast.Load())])
1233 self.expr(d, "same number of keys as values")
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001234 d = ast.Dict([ast.Name("x", ast.Load())], [None])
1235 self.expr(d, "None disallowed")
1236
1237 def test_set(self):
1238 self.expr(ast.Set([None]), "None disallowed")
1239 s = ast.Set([ast.Name("x", ast.Store())])
1240 self.expr(s, "must have Load context")
1241
1242 def _check_comprehension(self, fac):
1243 self.expr(fac([]), "comprehension with no generators")
1244 g = ast.comprehension(ast.Name("x", ast.Load()),
Yury Selivanov52c4e7c2016-09-09 10:36:01 -07001245 ast.Name("x", ast.Load()), [], 0)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001246 self.expr(fac([g]), "must have Store context")
1247 g = ast.comprehension(ast.Name("x", ast.Store()),
Yury Selivanov52c4e7c2016-09-09 10:36:01 -07001248 ast.Name("x", ast.Store()), [], 0)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001249 self.expr(fac([g]), "must have Load context")
1250 x = ast.Name("x", ast.Store())
1251 y = ast.Name("y", ast.Load())
Yury Selivanov52c4e7c2016-09-09 10:36:01 -07001252 g = ast.comprehension(x, y, [None], 0)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001253 self.expr(fac([g]), "None disallowed")
Yury Selivanov52c4e7c2016-09-09 10:36:01 -07001254 g = ast.comprehension(x, y, [ast.Name("x", ast.Store())], 0)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001255 self.expr(fac([g]), "must have Load context")
1256
1257 def _simple_comp(self, fac):
1258 g = ast.comprehension(ast.Name("x", ast.Store()),
Yury Selivanov52c4e7c2016-09-09 10:36:01 -07001259 ast.Name("x", ast.Load()), [], 0)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001260 self.expr(fac(ast.Name("x", ast.Store()), [g]),
1261 "must have Load context")
1262 def wrap(gens):
1263 return fac(ast.Name("x", ast.Store()), gens)
1264 self._check_comprehension(wrap)
1265
1266 def test_listcomp(self):
1267 self._simple_comp(ast.ListComp)
1268
1269 def test_setcomp(self):
1270 self._simple_comp(ast.SetComp)
1271
1272 def test_generatorexp(self):
1273 self._simple_comp(ast.GeneratorExp)
1274
1275 def test_dictcomp(self):
1276 g = ast.comprehension(ast.Name("y", ast.Store()),
Yury Selivanov52c4e7c2016-09-09 10:36:01 -07001277 ast.Name("p", ast.Load()), [], 0)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001278 c = ast.DictComp(ast.Name("x", ast.Store()),
1279 ast.Name("y", ast.Load()), [g])
1280 self.expr(c, "must have Load context")
1281 c = ast.DictComp(ast.Name("x", ast.Load()),
1282 ast.Name("y", ast.Store()), [g])
1283 self.expr(c, "must have Load context")
1284 def factory(comps):
1285 k = ast.Name("x", ast.Load())
1286 v = ast.Name("y", ast.Load())
1287 return ast.DictComp(k, v, comps)
1288 self._check_comprehension(factory)
1289
1290 def test_yield(self):
Benjamin Peterson527c6222012-01-14 08:58:23 -05001291 self.expr(ast.Yield(ast.Name("x", ast.Store())), "must have Load")
1292 self.expr(ast.YieldFrom(ast.Name("x", ast.Store())), "must have Load")
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001293
1294 def test_compare(self):
1295 left = ast.Name("x", ast.Load())
1296 comp = ast.Compare(left, [ast.In()], [])
1297 self.expr(comp, "no comparators")
1298 comp = ast.Compare(left, [ast.In()], [ast.Num(4), ast.Num(5)])
1299 self.expr(comp, "different number of comparators and operands")
1300 comp = ast.Compare(ast.Num("blah"), [ast.In()], [left])
Serhiy Storchaka3f228112018-09-27 17:42:37 +03001301 self.expr(comp)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001302 comp = ast.Compare(left, [ast.In()], [ast.Num("blah")])
Serhiy Storchaka3f228112018-09-27 17:42:37 +03001303 self.expr(comp)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001304
1305 def test_call(self):
1306 func = ast.Name("x", ast.Load())
1307 args = [ast.Name("y", ast.Load())]
1308 keywords = [ast.keyword("w", ast.Name("z", ast.Load()))]
Benjamin Peterson025e9eb2015-05-05 20:16:41 -04001309 call = ast.Call(ast.Name("x", ast.Store()), args, keywords)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001310 self.expr(call, "must have Load context")
Benjamin Peterson025e9eb2015-05-05 20:16:41 -04001311 call = ast.Call(func, [None], keywords)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001312 self.expr(call, "None disallowed")
1313 bad_keywords = [ast.keyword("w", ast.Name("z", ast.Store()))]
Benjamin Peterson025e9eb2015-05-05 20:16:41 -04001314 call = ast.Call(func, args, bad_keywords)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001315 self.expr(call, "must have Load context")
1316
1317 def test_num(self):
1318 class subint(int):
1319 pass
1320 class subfloat(float):
1321 pass
1322 class subcomplex(complex):
1323 pass
Serhiy Storchaka3f228112018-09-27 17:42:37 +03001324 for obj in "0", "hello":
1325 self.expr(ast.Num(obj))
1326 for obj in subint(), subfloat(), subcomplex():
1327 self.expr(ast.Num(obj), "invalid type", exc=TypeError)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001328
1329 def test_attribute(self):
1330 attr = ast.Attribute(ast.Name("x", ast.Store()), "y", ast.Load())
1331 self.expr(attr, "must have Load context")
1332
1333 def test_subscript(self):
Serhiy Storchaka13d52c22020-03-10 18:52:34 +02001334 sub = ast.Subscript(ast.Name("x", ast.Store()), ast.Num(3),
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001335 ast.Load())
1336 self.expr(sub, "must have Load context")
1337 x = ast.Name("x", ast.Load())
Serhiy Storchaka13d52c22020-03-10 18:52:34 +02001338 sub = ast.Subscript(x, ast.Name("y", ast.Store()),
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001339 ast.Load())
1340 self.expr(sub, "must have Load context")
1341 s = ast.Name("x", ast.Store())
1342 for args in (s, None, None), (None, s, None), (None, None, s):
1343 sl = ast.Slice(*args)
1344 self.expr(ast.Subscript(x, sl, ast.Load()),
1345 "must have Load context")
Serhiy Storchaka13d52c22020-03-10 18:52:34 +02001346 sl = ast.Tuple([], ast.Load())
1347 self.expr(ast.Subscript(x, sl, ast.Load()))
1348 sl = ast.Tuple([s], ast.Load())
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001349 self.expr(ast.Subscript(x, sl, ast.Load()), "must have Load context")
1350
1351 def test_starred(self):
1352 left = ast.List([ast.Starred(ast.Name("x", ast.Load()), ast.Store())],
1353 ast.Store())
1354 assign = ast.Assign([left], ast.Num(4))
1355 self.stmt(assign, "must have Store context")
1356
1357 def _sequence(self, fac):
1358 self.expr(fac([None], ast.Load()), "None disallowed")
1359 self.expr(fac([ast.Name("x", ast.Store())], ast.Load()),
1360 "must have Load context")
1361
1362 def test_list(self):
1363 self._sequence(ast.List)
1364
1365 def test_tuple(self):
1366 self._sequence(ast.Tuple)
1367
Benjamin Peterson442f2092012-12-06 17:41:04 -05001368 def test_nameconstant(self):
Serhiy Storchaka3f228112018-09-27 17:42:37 +03001369 self.expr(ast.NameConstant(4))
Benjamin Peterson442f2092012-12-06 17:41:04 -05001370
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001371 def test_stdlib_validates(self):
1372 stdlib = os.path.dirname(ast.__file__)
1373 tests = [fn for fn in os.listdir(stdlib) if fn.endswith(".py")]
1374 tests.extend(["test/test_grammar.py", "test/test_unpack_ex.py"])
1375 for module in tests:
Serhiy Storchaka3bcbedc2019-01-18 07:47:48 +02001376 with self.subTest(module):
1377 fn = os.path.join(stdlib, module)
1378 with open(fn, "r", encoding="utf-8") as fp:
1379 source = fp.read()
1380 mod = ast.parse(source, fn)
1381 compile(mod, fn, "exec")
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001382
1383
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001384class ConstantTests(unittest.TestCase):
1385 """Tests on the ast.Constant node type."""
1386
1387 def compile_constant(self, value):
1388 tree = ast.parse("x = 123")
1389
1390 node = tree.body[0].value
1391 new_node = ast.Constant(value=value)
1392 ast.copy_location(new_node, node)
1393 tree.body[0].value = new_node
1394
1395 code = compile(tree, "<string>", "exec")
1396
1397 ns = {}
1398 exec(code, ns)
1399 return ns['x']
1400
Victor Stinnerbe59d142016-01-27 00:39:12 +01001401 def test_validation(self):
1402 with self.assertRaises(TypeError) as cm:
1403 self.compile_constant([1, 2, 3])
1404 self.assertEqual(str(cm.exception),
1405 "got an invalid type in Constant: list")
1406
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001407 def test_singletons(self):
1408 for const in (None, False, True, Ellipsis, b'', frozenset()):
1409 with self.subTest(const=const):
1410 value = self.compile_constant(const)
1411 self.assertIs(value, const)
1412
1413 def test_values(self):
1414 nested_tuple = (1,)
1415 nested_frozenset = frozenset({1})
1416 for level in range(3):
1417 nested_tuple = (nested_tuple, 2)
1418 nested_frozenset = frozenset({nested_frozenset, 2})
1419 values = (123, 123.0, 123j,
1420 "unicode", b'bytes',
1421 tuple("tuple"), frozenset("frozenset"),
1422 nested_tuple, nested_frozenset)
1423 for value in values:
1424 with self.subTest(value=value):
1425 result = self.compile_constant(value)
1426 self.assertEqual(result, value)
1427
1428 def test_assign_to_constant(self):
1429 tree = ast.parse("x = 1")
1430
1431 target = tree.body[0].targets[0]
1432 new_target = ast.Constant(value=1)
1433 ast.copy_location(new_target, target)
1434 tree.body[0].targets[0] = new_target
1435
1436 with self.assertRaises(ValueError) as cm:
1437 compile(tree, "string", "exec")
1438 self.assertEqual(str(cm.exception),
1439 "expression which can't be assigned "
1440 "to in Store context")
1441
1442 def test_get_docstring(self):
1443 tree = ast.parse("'docstring'\nx = 1")
1444 self.assertEqual(ast.get_docstring(tree), 'docstring')
1445
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001446 def get_load_const(self, tree):
1447 # Compile to bytecode, disassemble and get parameter of LOAD_CONST
1448 # instructions
1449 co = compile(tree, '<string>', 'exec')
1450 consts = []
1451 for instr in dis.get_instructions(co):
1452 if instr.opname == 'LOAD_CONST':
1453 consts.append(instr.argval)
1454 return consts
1455
1456 @support.cpython_only
1457 def test_load_const(self):
1458 consts = [None,
1459 True, False,
1460 124,
1461 2.0,
1462 3j,
1463 "unicode",
1464 b'bytes',
1465 (1, 2, 3)]
1466
Victor Stinnera2724092016-02-08 18:17:58 +01001467 code = '\n'.join(['x={!r}'.format(const) for const in consts])
1468 code += '\nx = ...'
1469 consts.extend((Ellipsis, None))
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001470
1471 tree = ast.parse(code)
Victor Stinnera2724092016-02-08 18:17:58 +01001472 self.assertEqual(self.get_load_const(tree),
1473 consts)
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001474
1475 # Replace expression nodes with constants
Victor Stinnera2724092016-02-08 18:17:58 +01001476 for assign, const in zip(tree.body, consts):
1477 assert isinstance(assign, ast.Assign), ast.dump(assign)
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001478 new_node = ast.Constant(value=const)
Victor Stinnera2724092016-02-08 18:17:58 +01001479 ast.copy_location(new_node, assign.value)
1480 assign.value = new_node
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001481
Victor Stinnera2724092016-02-08 18:17:58 +01001482 self.assertEqual(self.get_load_const(tree),
1483 consts)
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001484
1485 def test_literal_eval(self):
1486 tree = ast.parse("1 + 2")
1487 binop = tree.body[0].value
1488
1489 new_left = ast.Constant(value=10)
1490 ast.copy_location(new_left, binop.left)
1491 binop.left = new_left
1492
Serhiy Storchakad8ac4d12018-01-04 11:15:39 +02001493 new_right = ast.Constant(value=20j)
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001494 ast.copy_location(new_right, binop.right)
1495 binop.right = new_right
1496
Serhiy Storchakad8ac4d12018-01-04 11:15:39 +02001497 self.assertEqual(ast.literal_eval(binop), 10+20j)
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001498
Guido van Rossum10f8ce62019-03-13 13:00:46 -07001499 def test_string_kind(self):
1500 c = ast.parse('"x"', mode='eval').body
1501 self.assertEqual(c.value, "x")
1502 self.assertEqual(c.kind, None)
1503
1504 c = ast.parse('u"x"', mode='eval').body
1505 self.assertEqual(c.value, "x")
1506 self.assertEqual(c.kind, "u")
1507
1508 c = ast.parse('r"x"', mode='eval').body
1509 self.assertEqual(c.value, "x")
1510 self.assertEqual(c.kind, None)
1511
1512 c = ast.parse('b"x"', mode='eval').body
1513 self.assertEqual(c.value, b"x")
1514 self.assertEqual(c.kind, None)
1515
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001516
Ivan Levkivskyi9932a222019-01-22 11:18:22 +00001517class EndPositionTests(unittest.TestCase):
1518 """Tests for end position of AST nodes.
1519
1520 Testing end positions of nodes requires a bit of extra care
1521 because of how LL parsers work.
1522 """
1523 def _check_end_pos(self, ast_node, end_lineno, end_col_offset):
1524 self.assertEqual(ast_node.end_lineno, end_lineno)
1525 self.assertEqual(ast_node.end_col_offset, end_col_offset)
1526
1527 def _check_content(self, source, ast_node, content):
1528 self.assertEqual(ast.get_source_segment(source, ast_node), content)
1529
1530 def _parse_value(self, s):
1531 # Use duck-typing to support both single expression
1532 # and a right hand side of an assignment statement.
1533 return ast.parse(s).body[0].value
1534
1535 def test_lambda(self):
1536 s = 'lambda x, *y: None'
1537 lam = self._parse_value(s)
1538 self._check_content(s, lam.body, 'None')
1539 self._check_content(s, lam.args.args[0], 'x')
1540 self._check_content(s, lam.args.vararg, 'y')
1541
1542 def test_func_def(self):
1543 s = dedent('''
1544 def func(x: int,
1545 *args: str,
1546 z: float = 0,
1547 **kwargs: Any) -> bool:
1548 return True
1549 ''').strip()
1550 fdef = ast.parse(s).body[0]
1551 self._check_end_pos(fdef, 5, 15)
1552 self._check_content(s, fdef.body[0], 'return True')
1553 self._check_content(s, fdef.args.args[0], 'x: int')
1554 self._check_content(s, fdef.args.args[0].annotation, 'int')
1555 self._check_content(s, fdef.args.kwarg, 'kwargs: Any')
1556 self._check_content(s, fdef.args.kwarg.annotation, 'Any')
1557
1558 def test_call(self):
1559 s = 'func(x, y=2, **kw)'
1560 call = self._parse_value(s)
1561 self._check_content(s, call.func, 'func')
1562 self._check_content(s, call.keywords[0].value, '2')
1563 self._check_content(s, call.keywords[1].value, 'kw')
1564
1565 def test_call_noargs(self):
1566 s = 'x[0]()'
1567 call = self._parse_value(s)
1568 self._check_content(s, call.func, 'x[0]')
1569 self._check_end_pos(call, 1, 6)
1570
1571 def test_class_def(self):
1572 s = dedent('''
1573 class C(A, B):
1574 x: int = 0
1575 ''').strip()
1576 cdef = ast.parse(s).body[0]
1577 self._check_end_pos(cdef, 2, 14)
1578 self._check_content(s, cdef.bases[1], 'B')
1579 self._check_content(s, cdef.body[0], 'x: int = 0')
1580
1581 def test_class_kw(self):
1582 s = 'class S(metaclass=abc.ABCMeta): pass'
1583 cdef = ast.parse(s).body[0]
1584 self._check_content(s, cdef.keywords[0].value, 'abc.ABCMeta')
1585
1586 def test_multi_line_str(self):
1587 s = dedent('''
1588 x = """Some multi-line text.
1589
1590 It goes on starting from same indent."""
1591 ''').strip()
1592 assign = ast.parse(s).body[0]
1593 self._check_end_pos(assign, 3, 40)
1594 self._check_end_pos(assign.value, 3, 40)
1595
1596 def test_continued_str(self):
1597 s = dedent('''
1598 x = "first part" \\
1599 "second part"
1600 ''').strip()
1601 assign = ast.parse(s).body[0]
1602 self._check_end_pos(assign, 2, 13)
1603 self._check_end_pos(assign.value, 2, 13)
1604
1605 def test_suites(self):
1606 # We intentionally put these into the same string to check
1607 # that empty lines are not part of the suite.
1608 s = dedent('''
1609 while True:
1610 pass
1611
1612 if one():
1613 x = None
1614 elif other():
1615 y = None
1616 else:
1617 z = None
1618
1619 for x, y in stuff:
1620 assert True
1621
1622 try:
1623 raise RuntimeError
1624 except TypeError as e:
1625 pass
1626
1627 pass
1628 ''').strip()
1629 mod = ast.parse(s)
1630 while_loop = mod.body[0]
1631 if_stmt = mod.body[1]
1632 for_loop = mod.body[2]
1633 try_stmt = mod.body[3]
1634 pass_stmt = mod.body[4]
1635
1636 self._check_end_pos(while_loop, 2, 8)
1637 self._check_end_pos(if_stmt, 9, 12)
1638 self._check_end_pos(for_loop, 12, 15)
1639 self._check_end_pos(try_stmt, 17, 8)
1640 self._check_end_pos(pass_stmt, 19, 4)
1641
1642 self._check_content(s, while_loop.test, 'True')
1643 self._check_content(s, if_stmt.body[0], 'x = None')
1644 self._check_content(s, if_stmt.orelse[0].test, 'other()')
1645 self._check_content(s, for_loop.target, 'x, y')
1646 self._check_content(s, try_stmt.body[0], 'raise RuntimeError')
1647 self._check_content(s, try_stmt.handlers[0].type, 'TypeError')
1648
1649 def test_fstring(self):
1650 s = 'x = f"abc {x + y} abc"'
1651 fstr = self._parse_value(s)
1652 binop = fstr.values[1].value
1653 self._check_content(s, binop, 'x + y')
1654
1655 def test_fstring_multi_line(self):
1656 s = dedent('''
1657 f"""Some multi-line text.
1658 {
1659 arg_one
1660 +
1661 arg_two
1662 }
1663 It goes on..."""
1664 ''').strip()
1665 fstr = self._parse_value(s)
1666 binop = fstr.values[1].value
1667 self._check_end_pos(binop, 5, 7)
1668 self._check_content(s, binop.left, 'arg_one')
1669 self._check_content(s, binop.right, 'arg_two')
1670
1671 def test_import_from_multi_line(self):
1672 s = dedent('''
1673 from x.y.z import (
1674 a, b, c as c
1675 )
1676 ''').strip()
1677 imp = ast.parse(s).body[0]
1678 self._check_end_pos(imp, 3, 1)
1679
1680 def test_slices(self):
1681 s1 = 'f()[1, 2] [0]'
1682 s2 = 'x[ a.b: c.d]'
1683 sm = dedent('''
1684 x[ a.b: f () ,
1685 g () : c.d
1686 ]
1687 ''').strip()
1688 i1, i2, im = map(self._parse_value, (s1, s2, sm))
1689 self._check_content(s1, i1.value, 'f()[1, 2]')
Serhiy Storchaka13d52c22020-03-10 18:52:34 +02001690 self._check_content(s1, i1.value.slice, '1, 2')
Ivan Levkivskyi9932a222019-01-22 11:18:22 +00001691 self._check_content(s2, i2.slice.lower, 'a.b')
1692 self._check_content(s2, i2.slice.upper, 'c.d')
Serhiy Storchaka13d52c22020-03-10 18:52:34 +02001693 self._check_content(sm, im.slice.elts[0].upper, 'f ()')
1694 self._check_content(sm, im.slice.elts[1].lower, 'g ()')
Ivan Levkivskyi9932a222019-01-22 11:18:22 +00001695 self._check_end_pos(im, 3, 3)
1696
1697 def test_binop(self):
1698 s = dedent('''
1699 (1 * 2 + (3 ) +
1700 4
1701 )
1702 ''').strip()
1703 binop = self._parse_value(s)
1704 self._check_end_pos(binop, 2, 6)
1705 self._check_content(s, binop.right, '4')
1706 self._check_content(s, binop.left, '1 * 2 + (3 )')
1707 self._check_content(s, binop.left.right, '3')
1708
1709 def test_boolop(self):
1710 s = dedent('''
1711 if (one_condition and
1712 (other_condition or yet_another_one)):
1713 pass
1714 ''').strip()
1715 bop = ast.parse(s).body[0].test
1716 self._check_end_pos(bop, 2, 44)
1717 self._check_content(s, bop.values[1],
1718 'other_condition or yet_another_one')
1719
1720 def test_tuples(self):
1721 s1 = 'x = () ;'
1722 s2 = 'x = 1 , ;'
1723 s3 = 'x = (1 , 2 ) ;'
1724 sm = dedent('''
1725 x = (
1726 a, b,
1727 )
1728 ''').strip()
1729 t1, t2, t3, tm = map(self._parse_value, (s1, s2, s3, sm))
1730 self._check_content(s1, t1, '()')
1731 self._check_content(s2, t2, '1 ,')
1732 self._check_content(s3, t3, '(1 , 2 )')
1733 self._check_end_pos(tm, 3, 1)
1734
1735 def test_attribute_spaces(self):
1736 s = 'func(x. y .z)'
1737 call = self._parse_value(s)
1738 self._check_content(s, call, s)
1739 self._check_content(s, call.args[0], 'x. y .z')
1740
Serhiy Storchaka6e619c42020-02-12 22:37:49 +02001741 def test_redundant_parenthesis(self):
1742 s = '( ( ( a + b ) ) )'
1743 v = ast.parse(s).body[0].value
1744 self.assertEqual(type(v).__name__, 'BinOp')
1745 self._check_content(s, v, 'a + b')
1746 s2 = 'await ' + s
1747 v = ast.parse(s2).body[0].value.value
1748 self.assertEqual(type(v).__name__, 'BinOp')
1749 self._check_content(s2, v, 'a + b')
1750
1751 def test_trailers_with_redundant_parenthesis(self):
1752 tests = (
1753 ('( ( ( a ) ) ) ( )', 'Call'),
1754 ('( ( ( a ) ) ) ( b )', 'Call'),
1755 ('( ( ( a ) ) ) [ b ]', 'Subscript'),
1756 ('( ( ( a ) ) ) . b', 'Attribute'),
1757 )
1758 for s, t in tests:
1759 with self.subTest(s):
1760 v = ast.parse(s).body[0].value
1761 self.assertEqual(type(v).__name__, t)
1762 self._check_content(s, v, s)
1763 s2 = 'await ' + s
1764 v = ast.parse(s2).body[0].value.value
1765 self.assertEqual(type(v).__name__, t)
1766 self._check_content(s2, v, s)
1767
Ivan Levkivskyi9932a222019-01-22 11:18:22 +00001768 def test_displays(self):
1769 s1 = '[{}, {1, }, {1, 2,} ]'
1770 s2 = '{a: b, f (): g () ,}'
1771 c1 = self._parse_value(s1)
1772 c2 = self._parse_value(s2)
1773 self._check_content(s1, c1.elts[0], '{}')
1774 self._check_content(s1, c1.elts[1], '{1, }')
1775 self._check_content(s1, c1.elts[2], '{1, 2,}')
1776 self._check_content(s2, c2.keys[1], 'f ()')
1777 self._check_content(s2, c2.values[1], 'g ()')
1778
1779 def test_comprehensions(self):
1780 s = dedent('''
1781 x = [{x for x, y in stuff
1782 if cond.x} for stuff in things]
1783 ''').strip()
1784 cmp = self._parse_value(s)
1785 self._check_end_pos(cmp, 2, 37)
1786 self._check_content(s, cmp.generators[0].iter, 'things')
1787 self._check_content(s, cmp.elt.generators[0].iter, 'stuff')
1788 self._check_content(s, cmp.elt.generators[0].ifs[0], 'cond.x')
1789 self._check_content(s, cmp.elt.generators[0].target, 'x, y')
1790
1791 def test_yield_await(self):
1792 s = dedent('''
1793 async def f():
1794 yield x
1795 await y
1796 ''').strip()
1797 fdef = ast.parse(s).body[0]
1798 self._check_content(s, fdef.body[0].value, 'yield x')
1799 self._check_content(s, fdef.body[1].value, 'await y')
1800
1801 def test_source_segment_multi(self):
1802 s_orig = dedent('''
1803 x = (
1804 a, b,
1805 ) + ()
1806 ''').strip()
1807 s_tuple = dedent('''
1808 (
1809 a, b,
1810 )
1811 ''').strip()
1812 binop = self._parse_value(s_orig)
1813 self.assertEqual(ast.get_source_segment(s_orig, binop.left), s_tuple)
1814
1815 def test_source_segment_padded(self):
1816 s_orig = dedent('''
1817 class C:
1818 def fun(self) -> None:
1819 "Đ–Đ–Đ–Đ–Đ–"
1820 ''').strip()
1821 s_method = ' def fun(self) -> None:\n' \
1822 ' "Đ–Đ–Đ–Đ–Đ–"'
1823 cdef = ast.parse(s_orig).body[0]
1824 self.assertEqual(ast.get_source_segment(s_orig, cdef.body[0], padded=True),
1825 s_method)
1826
1827 def test_source_segment_endings(self):
1828 s = 'v = 1\r\nw = 1\nx = 1\n\ry = 1\rz = 1\r\n'
1829 v, w, x, y, z = ast.parse(s).body
1830 self._check_content(s, v, 'v = 1')
1831 self._check_content(s, w, 'w = 1')
1832 self._check_content(s, x, 'x = 1')
1833 self._check_content(s, y, 'y = 1')
1834 self._check_content(s, z, 'z = 1')
1835
1836 def test_source_segment_tabs(self):
1837 s = dedent('''
1838 class C:
1839 \t\f def fun(self) -> None:
1840 \t\f pass
1841 ''').strip()
1842 s_method = ' \t\f def fun(self) -> None:\n' \
1843 ' \t\f pass'
1844
1845 cdef = ast.parse(s).body[0]
1846 self.assertEqual(ast.get_source_segment(s, cdef.body[0], padded=True), s_method)
1847
1848
Serhiy Storchakac3ea41e2019-08-26 10:13:19 +03001849class NodeVisitorTests(unittest.TestCase):
1850 def test_old_constant_nodes(self):
1851 class Visitor(ast.NodeVisitor):
1852 def visit_Num(self, node):
1853 log.append((node.lineno, 'Num', node.n))
1854 def visit_Str(self, node):
1855 log.append((node.lineno, 'Str', node.s))
1856 def visit_Bytes(self, node):
1857 log.append((node.lineno, 'Bytes', node.s))
1858 def visit_NameConstant(self, node):
1859 log.append((node.lineno, 'NameConstant', node.value))
1860 def visit_Ellipsis(self, node):
1861 log.append((node.lineno, 'Ellipsis', ...))
1862 mod = ast.parse(dedent('''\
1863 i = 42
1864 f = 4.25
1865 c = 4.25j
1866 s = 'string'
1867 b = b'bytes'
1868 t = True
1869 n = None
1870 e = ...
1871 '''))
1872 visitor = Visitor()
1873 log = []
1874 with warnings.catch_warnings(record=True) as wlog:
1875 warnings.filterwarnings('always', '', DeprecationWarning)
1876 visitor.visit(mod)
1877 self.assertEqual(log, [
1878 (1, 'Num', 42),
1879 (2, 'Num', 4.25),
1880 (3, 'Num', 4.25j),
1881 (4, 'Str', 'string'),
1882 (5, 'Bytes', b'bytes'),
1883 (6, 'NameConstant', True),
1884 (7, 'NameConstant', None),
1885 (8, 'Ellipsis', ...),
1886 ])
1887 self.assertEqual([str(w.message) for w in wlog], [
1888 'visit_Num is deprecated; add visit_Constant',
1889 'visit_Num is deprecated; add visit_Constant',
1890 'visit_Num is deprecated; add visit_Constant',
1891 'visit_Str is deprecated; add visit_Constant',
1892 'visit_Bytes is deprecated; add visit_Constant',
1893 'visit_NameConstant is deprecated; add visit_Constant',
1894 'visit_NameConstant is deprecated; add visit_Constant',
1895 'visit_Ellipsis is deprecated; add visit_Constant',
1896 ])
1897
1898
Neal Norwitzee9b10a2008-03-31 05:29:39 +00001899def main():
1900 if __name__ != '__main__':
Martin v. Löwis49c5da12006-03-01 22:49:05 +00001901 return
Neal Norwitzee9b10a2008-03-31 05:29:39 +00001902 if sys.argv[1:] == ['-g']:
1903 for statements, kind in ((exec_tests, "exec"), (single_tests, "single"),
1904 (eval_tests, "eval")):
1905 print(kind+"_results = [")
Victor Stinnerf0891962016-02-08 17:15:21 +01001906 for statement in statements:
1907 tree = ast.parse(statement, "?", kind)
1908 print("%r," % (to_tuple(tree),))
Neal Norwitzee9b10a2008-03-31 05:29:39 +00001909 print("]")
1910 print("main()")
1911 raise SystemExit
Brett Cannon3e9a9ae2013-06-12 21:25:59 -04001912 unittest.main()
Tim Peters400cbc32006-02-28 18:44:41 +00001913
Guido van Rossumdcfcd142019-01-31 03:40:27 -08001914#### EVERYTHING BELOW IS GENERATED BY python Lib/test/test_ast.py -g #####
Tim Peters400cbc32006-02-28 18:44:41 +00001915exec_results = [
Serhiy Storchaka850a8852020-01-10 10:12:55 +02001916('Module', [('Expr', (1, 0, 1, 4), ('Constant', (1, 0, 1, 4), None, None))], []),
1917('Module', [('Expr', (1, 0, 1, 18), ('Constant', (1, 0, 1, 18), 'module docstring', None))], []),
1918('Module', [('FunctionDef', (1, 0, 1, 13), 'f', ('arguments', [], [], None, [], [], None, []), [('Pass', (1, 9, 1, 13))], [], None, None)], []),
1919('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)], []),
1920('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)], []),
1921('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)], []),
1922('Module', [('FunctionDef', (1, 0, 1, 18), 'f', ('arguments', [], [], ('arg', (1, 7, 1, 11), 'args', None, None), [], [], None, []), [('Pass', (1, 14, 1, 18))], [], None, None)], []),
1923('Module', [('FunctionDef', (1, 0, 1, 21), 'f', ('arguments', [], [], None, [], [], ('arg', (1, 8, 1, 14), 'kwargs', None, None), []), [('Pass', (1, 17, 1, 21))], [], None, None)], []),
1924('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)], []),
1925('Module', [('ClassDef', (1, 0, 1, 12), 'C', [], [], [('Pass', (1, 8, 1, 12))], [])], []),
1926('Module', [('ClassDef', (1, 0, 1, 32), 'C', [], [], [('Expr', (1, 9, 1, 32), ('Constant', (1, 9, 1, 32), 'docstring for class C', None))], [])], []),
1927('Module', [('ClassDef', (1, 0, 1, 21), 'C', [('Name', (1, 8, 1, 14), 'object', ('Load',))], [], [('Pass', (1, 17, 1, 21))], [])], []),
1928('Module', [('FunctionDef', (1, 0, 1, 16), 'f', ('arguments', [], [], None, [], [], None, []), [('Return', (1, 8, 1, 16), ('Constant', (1, 15, 1, 16), 1, None))], [], None, None)], []),
1929('Module', [('Delete', (1, 0, 1, 5), [('Name', (1, 4, 1, 5), 'v', ('Del',))])], []),
1930('Module', [('Assign', (1, 0, 1, 5), [('Name', (1, 0, 1, 1), 'v', ('Store',))], ('Constant', (1, 4, 1, 5), 1, None), None)], []),
1931('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)], []),
1932('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)], []),
1933('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)], []),
1934('Module', [('AugAssign', (1, 0, 1, 6), ('Name', (1, 0, 1, 1), 'v', ('Store',)), ('Add',), ('Constant', (1, 5, 1, 6), 1, None))], []),
1935('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)], []),
1936('Module', [('While', (1, 0, 1, 12), ('Name', (1, 6, 1, 7), 'v', ('Load',)), [('Pass', (1, 8, 1, 12))], [])], []),
1937('Module', [('If', (1, 0, 1, 9), ('Name', (1, 3, 1, 4), 'v', ('Load',)), [('Pass', (1, 5, 1, 9))], [])], []),
1938('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))], [])])], []),
1939('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))])])], []),
1940('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)], []),
1941('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)], []),
1942('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)], []),
1943('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))])], [], [])], []),
1944('Module', [('Try', (1, 0, 4, 6), [('Pass', (2, 2, 2, 6))], [], [], [('Pass', (4, 2, 4, 6))])], []),
1945('Module', [('Assert', (1, 0, 1, 8), ('Name', (1, 7, 1, 8), 'v', ('Load',)), None)], []),
1946('Module', [('Import', (1, 0, 1, 10), [('alias', 'sys', None)])], []),
1947('Module', [('ImportFrom', (1, 0, 1, 17), 'sys', [('alias', 'v', None)], 0)], []),
1948('Module', [('Global', (1, 0, 1, 8), ['v'])], []),
1949('Module', [('Expr', (1, 0, 1, 1), ('Constant', (1, 0, 1, 1), 1, None))], []),
1950('Module', [('Pass', (1, 0, 1, 4))], []),
1951('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)], []),
1952('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)], []),
1953('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)], []),
1954('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)], []),
1955('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)], []),
1956('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)]))], []),
1957('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)]))], []),
1958('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)]))], []),
1959('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)]))], []),
1960('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)]))], []),
1961('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)], []),
1962('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)], []),
1963('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)], []),
1964('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)]))], []),
1965('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)]))], []),
1966('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)], []),
1967('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)], []),
1968('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)], []),
1969('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)], [])])], []),
1970('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 +01001971('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 +02001972('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)))], []),
1973('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)], []),
1974('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)], []),
1975('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)], []),
1976('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)], []),
1977('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)], []),
1978('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)], []),
1979('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)], []),
1980('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)], []),
1981('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)], []),
1982('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 +00001983]
1984single_results = [
Serhiy Storchaka850a8852020-01-10 10:12:55 +02001985('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 +00001986]
1987eval_results = [
Serhiy Storchaka850a8852020-01-10 10:12:55 +02001988('Expression', ('Constant', (1, 0, 1, 4), None, None)),
1989('Expression', ('BoolOp', (1, 0, 1, 7), ('And',), [('Name', (1, 0, 1, 1), 'a', ('Load',)), ('Name', (1, 6, 1, 7), 'b', ('Load',))])),
1990('Expression', ('BinOp', (1, 0, 1, 5), ('Name', (1, 0, 1, 1), 'a', ('Load',)), ('Add',), ('Name', (1, 4, 1, 5), 'b', ('Load',)))),
1991('Expression', ('UnaryOp', (1, 0, 1, 5), ('Not',), ('Name', (1, 4, 1, 5), 'v', ('Load',)))),
1992('Expression', ('Lambda', (1, 0, 1, 11), ('arguments', [], [], None, [], [], None, []), ('Constant', (1, 7, 1, 11), None, None))),
1993('Expression', ('Dict', (1, 0, 1, 7), [('Constant', (1, 2, 1, 3), 1, None)], [('Constant', (1, 4, 1, 5), 2, None)])),
1994('Expression', ('Dict', (1, 0, 1, 2), [], [])),
1995('Expression', ('Set', (1, 0, 1, 7), [('Constant', (1, 1, 1, 5), None, None)])),
1996('Expression', ('Dict', (1, 0, 5, 6), [('Constant', (2, 6, 2, 7), 1, None)], [('Constant', (4, 10, 4, 11), 2, None)])),
1997('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)])),
1998('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)])),
1999('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)])),
2000('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)])),
2001('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)])),
2002('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)])),
2003('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)])),
2004('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)])),
2005('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)])),
2006('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)])),
2007('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)])),
2008('Expression', ('Compare', (1, 0, 1, 9), ('Constant', (1, 0, 1, 1), 1, None), [('Lt',), ('Lt',)], [('Constant', (1, 4, 1, 5), 2, None), ('Constant', (1, 8, 1, 9), 3, None)])),
Pablo Galindo168660b2020-04-02 00:47:39 +01002009('Expression', ('Call', (1, 0, 1, 17), ('Name', (1, 0, 1, 1), 'f', ('Load',)), [('Constant', (1, 2, 1, 3), 1, None), ('Constant', (1, 4, 1, 5), 2, None), ('Starred', (1, 10, 1, 12), ('Name', (1, 11, 1, 12), 'd', ('Load',)), ('Load',))], [('keyword', (1, 6, 1, 7), 'c', ('Constant', (1, 8, 1, 9), 3, None)), ('keyword', (1, 13, 1, 16), None, ('Name', (1, 15, 1, 16), 'e', ('Load',)))])),
Serhiy Storchaka850a8852020-01-10 10:12:55 +02002010('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',))], [])),
2011('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)])], [])),
2012('Expression', ('Constant', (1, 0, 1, 2), 10, None)),
2013('Expression', ('Constant', (1, 0, 1, 8), 'string', None)),
2014('Expression', ('Attribute', (1, 0, 1, 3), ('Name', (1, 0, 1, 1), 'a', ('Load',)), 'b', ('Load',))),
Serhiy Storchaka13d52c22020-03-10 18:52:34 +02002015('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 +02002016('Expression', ('Name', (1, 0, 1, 1), 'v', ('Load',))),
2017('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',))),
2018('Expression', ('List', (1, 0, 1, 2), [], ('Load',))),
2019('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',))),
2020('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',))),
2021('Expression', ('Tuple', (1, 0, 1, 2), [], ('Load',))),
Serhiy Storchaka13d52c22020-03-10 18:52:34 +02002022('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 +00002023]
Neal Norwitzee9b10a2008-03-31 05:29:39 +00002024main()