blob: a3b366ec35da125e8dc5f5b9dcd4ab3283a4f86c [file] [log] [blame]
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001import ast
2import dis
Benjamin Peterson832bfe22011-08-09 16:15:04 -05003import os
4import sys
5import unittest
Serhiy Storchakac3ea41e2019-08-26 10:13:19 +03006import warnings
Benjamin Peterson9ed37432012-07-08 11:13:36 -07007import weakref
Ivan Levkivskyi9932a222019-01-22 11:18:22 +00008from textwrap import dedent
Benjamin Peterson9ed37432012-07-08 11:13:36 -07009
10from test import support
Tim Peters400cbc32006-02-28 18:44:41 +000011
12def to_tuple(t):
Guido van Rossum3172c5d2007-10-16 18:12:55 +000013 if t is None or isinstance(t, (str, int, complex)):
Tim Peters400cbc32006-02-28 18:44:41 +000014 return t
15 elif isinstance(t, list):
16 return [to_tuple(e) for e in t]
17 result = [t.__class__.__name__]
Martin v. Löwis49c5da12006-03-01 22:49:05 +000018 if hasattr(t, 'lineno') and hasattr(t, 'col_offset'):
19 result.append((t.lineno, t.col_offset))
Serhiy Storchaka850a8852020-01-10 10:12:55 +020020 if hasattr(t, 'end_lineno') and hasattr(t, 'end_col_offset'):
21 result[-1] += (t.end_lineno, t.end_col_offset)
Tim Peters400cbc32006-02-28 18:44:41 +000022 if t._fields is None:
23 return tuple(result)
24 for f in t._fields:
25 result.append(to_tuple(getattr(t, f)))
26 return tuple(result)
27
Neal Norwitzee9b10a2008-03-31 05:29:39 +000028
Tim Peters400cbc32006-02-28 18:44:41 +000029# These tests are compiled through "exec"
Ezio Melotti85a86292013-08-17 16:57:41 +030030# There should be at least one test per statement
Tim Peters400cbc32006-02-28 18:44:41 +000031exec_tests = [
Benjamin Peterson6ccfe852011-06-27 17:46:06 -050032 # None
33 "None",
INADA Naokicb41b272017-02-23 00:31:59 +090034 # Module docstring
35 "'module docstring'",
Tim Peters400cbc32006-02-28 18:44:41 +000036 # FunctionDef
37 "def f(): pass",
INADA Naokicb41b272017-02-23 00:31:59 +090038 # FunctionDef with docstring
39 "def f(): 'function docstring'",
Benjamin Peterson6ccfe852011-06-27 17:46:06 -050040 # FunctionDef with arg
41 "def f(a): pass",
42 # FunctionDef with arg and default value
43 "def f(a=0): pass",
44 # FunctionDef with varargs
45 "def f(*args): pass",
46 # FunctionDef with kwargs
47 "def f(**kwargs): pass",
INADA Naokicb41b272017-02-23 00:31:59 +090048 # FunctionDef with all kind of args and docstring
49 "def f(a, b=1, c=None, d=[], e={}, *args, f=42, **kwargs): 'doc for f()'",
Tim Peters400cbc32006-02-28 18:44:41 +000050 # ClassDef
51 "class C:pass",
INADA Naokicb41b272017-02-23 00:31:59 +090052 # ClassDef with docstring
53 "class C: 'docstring for class C'",
Benjamin Peterson6ccfe852011-06-27 17:46:06 -050054 # ClassDef, new style class
55 "class C(object): pass",
Tim Peters400cbc32006-02-28 18:44:41 +000056 # Return
57 "def f():return 1",
58 # Delete
59 "del v",
60 # Assign
61 "v = 1",
Serhiy Storchakab619b092018-11-27 09:40:29 +020062 "a,b = c",
63 "(a,b) = c",
64 "[a,b] = c",
Tim Peters400cbc32006-02-28 18:44:41 +000065 # AugAssign
66 "v += 1",
Tim Peters400cbc32006-02-28 18:44:41 +000067 # For
68 "for v in v:pass",
69 # While
70 "while v:pass",
71 # If
72 "if v:pass",
Lysandros Nikolaou025a6022019-12-12 22:40:21 +010073 # If-Elif
74 "if a:\n pass\nelif b:\n pass",
Lysandros Nikolaou5936a4c2019-12-14 11:24:57 +010075 # If-Elif-Else
76 "if a:\n pass\nelif b:\n pass\nelse:\n pass",
Benjamin Petersonaeabd5f2011-05-27 15:02:03 -050077 # With
78 "with x as y: pass",
79 "with x as y, z as q: pass",
Tim Peters400cbc32006-02-28 18:44:41 +000080 # Raise
Collin Winter828f04a2007-08-31 00:04:24 +000081 "raise Exception('string')",
Tim Peters400cbc32006-02-28 18:44:41 +000082 # TryExcept
83 "try:\n pass\nexcept Exception:\n pass",
84 # TryFinally
85 "try:\n pass\nfinally:\n pass",
86 # Assert
87 "assert v",
88 # Import
89 "import sys",
90 # ImportFrom
91 "from sys import v",
Tim Peters400cbc32006-02-28 18:44:41 +000092 # Global
93 "global v",
94 # Expr
95 "1",
96 # Pass,
97 "pass",
98 # Break
Yury Selivanovb3d53132015-09-01 16:10:49 -040099 "for v in v:break",
Tim Peters400cbc32006-02-28 18:44:41 +0000100 # Continue
Yury Selivanovb3d53132015-09-01 16:10:49 -0400101 "for v in v:continue",
Benjamin Peterson2e4b0e12009-09-11 22:36:20 +0000102 # for statements with naked tuples (see http://bugs.python.org/issue6704)
103 "for a,b in c: pass",
Serhiy Storchakab619b092018-11-27 09:40:29 +0200104 "for (a,b) in c: pass",
105 "for [a,b] in c: pass",
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500106 # Multiline generator expression (test for .lineno & .col_offset)
107 """(
108 (
109 Aa
110 ,
111 Bb
112 )
113 for
114 Aa
115 ,
116 Bb in Cc
117 )""",
118 # dictcomp
119 "{a : b for w in x for m in p if g}",
120 # dictcomp with naked tuple
121 "{a : b for v,w in x}",
122 # setcomp
123 "{r for l in x if g}",
124 # setcomp with naked tuple
125 "{r for l,m in x}",
Yury Selivanov75445082015-05-11 22:57:16 -0400126 # AsyncFunctionDef
INADA Naokicb41b272017-02-23 00:31:59 +0900127 "async def f():\n 'async function'\n await something()",
Yury Selivanov75445082015-05-11 22:57:16 -0400128 # AsyncFor
129 "async def f():\n async for e in i: 1\n else: 2",
130 # AsyncWith
131 "async def f():\n async with a as b: 1",
Yury Selivanovb3d53132015-09-01 16:10:49 -0400132 # PEP 448: Additional Unpacking Generalizations
133 "{**{1:2}, 2:3}",
134 "{*{1, 2}, 3}",
Yury Selivanov52c4e7c2016-09-09 10:36:01 -0700135 # Asynchronous comprehensions
136 "async def f():\n [i async for b in c]",
Serhiy Storchaka95b6acf2018-10-30 13:16:02 +0200137 # Decorated FunctionDef
Serhiy Storchaka26ae9f62019-10-26 16:46:05 +0300138 "@deco1\n@deco2()\n@deco3(1)\ndef f(): pass",
Serhiy Storchaka95b6acf2018-10-30 13:16:02 +0200139 # Decorated AsyncFunctionDef
Serhiy Storchaka26ae9f62019-10-26 16:46:05 +0300140 "@deco1\n@deco2()\n@deco3(1)\nasync def f(): pass",
Serhiy Storchaka95b6acf2018-10-30 13:16:02 +0200141 # Decorated ClassDef
Serhiy Storchaka26ae9f62019-10-26 16:46:05 +0300142 "@deco1\n@deco2()\n@deco3(1)\nclass C: pass",
Serhiy Storchakab619b092018-11-27 09:40:29 +0200143 # Decorator with generator argument
144 "@deco(a for a in b)\ndef f(): pass",
Lysandros Nikolaoud2e10982020-02-08 00:36:32 +0100145 # Decorator with attribute
146 "@a.b.c\ndef f(): pass",
Pablo Galindo0c9258a2019-03-18 13:51:53 +0000147 # Simple assignment expression
148 "(a := 1)",
Pablo Galindo2f58a842019-05-31 14:09:49 +0100149 # Positional-only arguments
150 "def f(a, /,): pass",
151 "def f(a, /, c, d, e): pass",
152 "def f(a, /, c, *, d, e): pass",
153 "def f(a, /, c, *, d, e, **kwargs): pass",
154 # Positional-only arguments with defaults
155 "def f(a=1, /,): pass",
156 "def f(a=1, /, b=2, c=4): pass",
157 "def f(a=1, /, b=2, *, c=4): pass",
158 "def f(a=1, /, b=2, *, c): pass",
159 "def f(a=1, /, b=2, *, c=4, **kwargs): pass",
160 "def f(a=1, /, b=2, *, c, **kwargs): pass",
Pablo Galindo0c9258a2019-03-18 13:51:53 +0000161
Tim Peters400cbc32006-02-28 18:44:41 +0000162]
163
164# These are compiled through "single"
165# because of overlap with "eval", it just tests what
166# can't be tested with "eval"
167single_tests = [
168 "1+2"
169]
170
171# These are compiled through "eval"
172# It should test all expressions
173eval_tests = [
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500174 # None
175 "None",
Tim Peters400cbc32006-02-28 18:44:41 +0000176 # BoolOp
177 "a and b",
178 # BinOp
179 "a + b",
180 # UnaryOp
181 "not v",
182 # Lambda
183 "lambda:None",
184 # Dict
185 "{ 1:2 }",
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500186 # Empty dict
187 "{}",
188 # Set
189 "{None,}",
190 # Multiline dict (test for .lineno & .col_offset)
191 """{
192 1
193 :
194 2
195 }""",
Tim Peters400cbc32006-02-28 18:44:41 +0000196 # ListComp
197 "[a for b in c if d]",
198 # GeneratorExp
199 "(a for b in c if d)",
Serhiy Storchakab619b092018-11-27 09:40:29 +0200200 # Comprehensions with multiple for targets
201 "[(a,b) for a,b in c]",
202 "[(a,b) for (a,b) in c]",
203 "[(a,b) for [a,b] in c]",
204 "{(a,b) for a,b in c}",
205 "{(a,b) for (a,b) in c}",
206 "{(a,b) for [a,b] in c}",
207 "((a,b) for a,b in c)",
208 "((a,b) for (a,b) in c)",
209 "((a,b) for [a,b] in c)",
Tim Peters400cbc32006-02-28 18:44:41 +0000210 # Yield - yield expressions can't work outside a function
211 #
212 # Compare
213 "1 < 2 < 3",
214 # Call
215 "f(1,2,c=3,*d,**e)",
Lysandros Nikolaou50d4f122019-12-18 01:20:55 +0100216 # Call with multi-character starred
217 "f(*[0, 1])",
Serhiy Storchakab619b092018-11-27 09:40:29 +0200218 # Call with a generator argument
219 "f(a for a in b)",
Tim Peters400cbc32006-02-28 18:44:41 +0000220 # Num
Guido van Rossume2a383d2007-01-15 16:59:06 +0000221 "10",
Tim Peters400cbc32006-02-28 18:44:41 +0000222 # Str
223 "'string'",
224 # Attribute
225 "a.b",
226 # Subscript
227 "a[b:c]",
228 # Name
229 "v",
230 # List
231 "[1,2,3]",
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500232 # Empty list
233 "[]",
Tim Peters400cbc32006-02-28 18:44:41 +0000234 # Tuple
Martin v. Löwis49c5da12006-03-01 22:49:05 +0000235 "1,2,3",
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500236 # Tuple
237 "(1,2,3)",
238 # Empty tuple
239 "()",
Martin v. Löwis49c5da12006-03-01 22:49:05 +0000240 # Combination
241 "a.b.c.d(a.b[1:2])",
242
Tim Peters400cbc32006-02-28 18:44:41 +0000243]
244
245# TODO: expr_context, slice, boolop, operator, unaryop, cmpop, comprehension
246# excepthandler, arguments, keywords, alias
247
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000248class AST_Tests(unittest.TestCase):
Tim Peters400cbc32006-02-28 18:44:41 +0000249
Batuhan TaĹźkaya397b96f2020-03-01 23:12:17 +0300250 def _is_ast_node(self, name, node):
251 if not isinstance(node, type):
252 return False
253 if "ast" not in node.__module__:
254 return False
255 return name != 'AST' and name[0].isupper()
256
Benjamin Peterson7a66fc22015-02-02 10:51:20 -0500257 def _assertTrueorder(self, ast_node, parent_pos):
Georg Brandl0c77a822008-06-10 16:37:50 +0000258 if not isinstance(ast_node, ast.AST) or ast_node._fields is None:
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000259 return
Georg Brandl0c77a822008-06-10 16:37:50 +0000260 if isinstance(ast_node, (ast.expr, ast.stmt, ast.excepthandler)):
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000261 node_pos = (ast_node.lineno, ast_node.col_offset)
Serhiy Storchaka95b6acf2018-10-30 13:16:02 +0200262 self.assertGreaterEqual(node_pos, parent_pos)
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000263 parent_pos = (ast_node.lineno, ast_node.col_offset)
264 for name in ast_node._fields:
265 value = getattr(ast_node, name)
266 if isinstance(value, list):
Serhiy Storchaka95b6acf2018-10-30 13:16:02 +0200267 first_pos = parent_pos
268 if value and name == 'decorator_list':
269 first_pos = (value[0].lineno, value[0].col_offset)
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000270 for child in value:
Serhiy Storchaka95b6acf2018-10-30 13:16:02 +0200271 self._assertTrueorder(child, first_pos)
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000272 elif value is not None:
Benjamin Peterson7a66fc22015-02-02 10:51:20 -0500273 self._assertTrueorder(value, parent_pos)
Tim Peters5ddfe412006-03-01 23:02:57 +0000274
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500275 def test_AST_objects(self):
276 x = ast.AST()
277 self.assertEqual(x._fields, ())
Benjamin Peterson7e0dbfb2012-03-12 09:46:44 -0700278 x.foobar = 42
279 self.assertEqual(x.foobar, 42)
280 self.assertEqual(x.__dict__["foobar"], 42)
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500281
282 with self.assertRaises(AttributeError):
283 x.vararg
284
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500285 with self.assertRaises(TypeError):
Serhiy Storchakabace59d2020-03-22 20:33:34 +0200286 # "ast.AST constructor takes 0 positional arguments"
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500287 ast.AST(2)
288
Benjamin Peterson9ed37432012-07-08 11:13:36 -0700289 def test_AST_garbage_collection(self):
290 class X:
291 pass
292 a = ast.AST()
293 a.x = X()
294 a.x.a = a
295 ref = weakref.ref(a.x)
296 del a
297 support.gc_collect()
298 self.assertIsNone(ref())
299
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000300 def test_snippets(self):
301 for input, output, kind in ((exec_tests, exec_results, "exec"),
302 (single_tests, single_results, "single"),
303 (eval_tests, eval_results, "eval")):
304 for i, o in zip(input, output):
Yury Selivanovb3d53132015-09-01 16:10:49 -0400305 with self.subTest(action="parsing", input=i):
306 ast_tree = compile(i, "?", kind, ast.PyCF_ONLY_AST)
307 self.assertEqual(to_tuple(ast_tree), o)
308 self._assertTrueorder(ast_tree, (0, 0))
Victor Stinner15a30952016-02-08 22:45:06 +0100309 with self.subTest(action="compiling", input=i, kind=kind):
310 compile(ast_tree, "?", kind)
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000311
Pablo Galindo0c9258a2019-03-18 13:51:53 +0000312 def test_ast_validation(self):
313 # compile() is the only function that calls PyAST_Validate
314 snippets_to_validate = exec_tests + single_tests + eval_tests
315 for snippet in snippets_to_validate:
316 tree = ast.parse(snippet)
317 compile(tree, '<string>', 'exec')
318
Benjamin Peterson78565b22009-06-28 19:19:51 +0000319 def test_slice(self):
320 slc = ast.parse("x[::]").body[0].value.slice
321 self.assertIsNone(slc.upper)
322 self.assertIsNone(slc.lower)
323 self.assertIsNone(slc.step)
324
325 def test_from_import(self):
326 im = ast.parse("from . import y").body[0]
327 self.assertIsNone(im.module)
328
Benjamin Petersona4e4e352012-03-22 08:19:04 -0400329 def test_non_interned_future_from_ast(self):
330 mod = ast.parse("from __future__ import division")
331 self.assertIsInstance(mod.body[0], ast.ImportFrom)
332 mod.body[0].module = " __future__ ".strip()
333 compile(mod, "<test>", "exec")
334
Benjamin Petersona0dfa822009-11-13 02:25:08 +0000335 def test_base_classes(self):
336 self.assertTrue(issubclass(ast.For, ast.stmt))
337 self.assertTrue(issubclass(ast.Name, ast.expr))
338 self.assertTrue(issubclass(ast.stmt, ast.AST))
339 self.assertTrue(issubclass(ast.expr, ast.AST))
340 self.assertTrue(issubclass(ast.comprehension, ast.AST))
341 self.assertTrue(issubclass(ast.Gt, ast.AST))
342
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500343 def test_field_attr_existence(self):
344 for name, item in ast.__dict__.items():
Batuhan TaĹźkaya397b96f2020-03-01 23:12:17 +0300345 if self._is_ast_node(name, item):
Serhiy Storchaka13d52c22020-03-10 18:52:34 +0200346 if name == 'Index':
347 # Index(value) just returns value now.
348 # The argument is required.
349 continue
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500350 x = item()
351 if isinstance(x, ast.AST):
352 self.assertEqual(type(x._fields), tuple)
353
354 def test_arguments(self):
355 x = ast.arguments()
Pablo Galindocd6e83b2019-07-15 01:32:18 +0200356 self.assertEqual(x._fields, ('posonlyargs', 'args', 'vararg', 'kwonlyargs',
357 'kw_defaults', 'kwarg', 'defaults'))
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500358
359 with self.assertRaises(AttributeError):
Serhiy Storchakab7e95252020-03-10 00:07:47 +0200360 x.args
361 self.assertIsNone(x.vararg)
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500362
Pablo Galindo8c77b8c2019-04-29 13:36:57 +0100363 x = ast.arguments(*range(1, 8))
Serhiy Storchakab7e95252020-03-10 00:07:47 +0200364 self.assertEqual(x.args, 2)
Pablo Galindo8c77b8c2019-04-29 13:36:57 +0100365 self.assertEqual(x.vararg, 3)
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500366
367 def test_field_attr_writable(self):
368 x = ast.Num()
369 # We can assign to _fields
370 x._fields = 666
371 self.assertEqual(x._fields, 666)
372
373 def test_classattrs(self):
374 x = ast.Num()
Guido van Rossum10f8ce62019-03-13 13:00:46 -0700375 self.assertEqual(x._fields, ('value', 'kind'))
Serhiy Storchaka3f228112018-09-27 17:42:37 +0300376
377 with self.assertRaises(AttributeError):
378 x.value
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500379
380 with self.assertRaises(AttributeError):
381 x.n
382
383 x = ast.Num(42)
Serhiy Storchaka3f228112018-09-27 17:42:37 +0300384 self.assertEqual(x.value, 42)
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500385 self.assertEqual(x.n, 42)
386
387 with self.assertRaises(AttributeError):
388 x.lineno
389
390 with self.assertRaises(AttributeError):
391 x.foobar
392
393 x = ast.Num(lineno=2)
394 self.assertEqual(x.lineno, 2)
395
396 x = ast.Num(42, lineno=0)
397 self.assertEqual(x.lineno, 0)
Guido van Rossum10f8ce62019-03-13 13:00:46 -0700398 self.assertEqual(x._fields, ('value', 'kind'))
Serhiy Storchaka3f228112018-09-27 17:42:37 +0300399 self.assertEqual(x.value, 42)
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500400 self.assertEqual(x.n, 42)
401
Guido van Rossum10f8ce62019-03-13 13:00:46 -0700402 self.assertRaises(TypeError, ast.Num, 1, None, 2)
403 self.assertRaises(TypeError, ast.Num, 1, None, 2, lineno=0)
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500404
Rémi Lapeyrec73914a2020-05-24 23:12:57 +0200405 # Arbitrary keyword arguments are supported
406 self.assertEqual(ast.Constant(1, foo='bar').foo, 'bar')
407 self.assertEqual(ast.Num(1, foo='bar').foo, 'bar')
408
409 with self.assertRaisesRegex(TypeError, "Num got multiple values for argument 'n'"):
410 ast.Num(1, n=2)
411 with self.assertRaisesRegex(TypeError, "Constant got multiple values for argument 'value'"):
412 ast.Constant(1, value=2)
413
Serhiy Storchaka3f228112018-09-27 17:42:37 +0300414 self.assertEqual(ast.Num(42).n, 42)
415 self.assertEqual(ast.Num(4.25).n, 4.25)
416 self.assertEqual(ast.Num(4.25j).n, 4.25j)
417 self.assertEqual(ast.Str('42').s, '42')
418 self.assertEqual(ast.Bytes(b'42').s, b'42')
419 self.assertIs(ast.NameConstant(True).value, True)
420 self.assertIs(ast.NameConstant(False).value, False)
421 self.assertIs(ast.NameConstant(None).value, None)
422
423 self.assertEqual(ast.Constant(42).value, 42)
424 self.assertEqual(ast.Constant(4.25).value, 4.25)
425 self.assertEqual(ast.Constant(4.25j).value, 4.25j)
426 self.assertEqual(ast.Constant('42').value, '42')
427 self.assertEqual(ast.Constant(b'42').value, b'42')
428 self.assertIs(ast.Constant(True).value, True)
429 self.assertIs(ast.Constant(False).value, False)
430 self.assertIs(ast.Constant(None).value, None)
431 self.assertIs(ast.Constant(...).value, ...)
432
433 def test_realtype(self):
434 self.assertEqual(type(ast.Num(42)), ast.Constant)
435 self.assertEqual(type(ast.Num(4.25)), ast.Constant)
436 self.assertEqual(type(ast.Num(4.25j)), ast.Constant)
437 self.assertEqual(type(ast.Str('42')), ast.Constant)
438 self.assertEqual(type(ast.Bytes(b'42')), ast.Constant)
439 self.assertEqual(type(ast.NameConstant(True)), ast.Constant)
440 self.assertEqual(type(ast.NameConstant(False)), ast.Constant)
441 self.assertEqual(type(ast.NameConstant(None)), ast.Constant)
442 self.assertEqual(type(ast.Ellipsis()), ast.Constant)
443
444 def test_isinstance(self):
445 self.assertTrue(isinstance(ast.Num(42), ast.Num))
446 self.assertTrue(isinstance(ast.Num(4.2), ast.Num))
447 self.assertTrue(isinstance(ast.Num(4.2j), ast.Num))
448 self.assertTrue(isinstance(ast.Str('42'), ast.Str))
449 self.assertTrue(isinstance(ast.Bytes(b'42'), ast.Bytes))
450 self.assertTrue(isinstance(ast.NameConstant(True), ast.NameConstant))
451 self.assertTrue(isinstance(ast.NameConstant(False), ast.NameConstant))
452 self.assertTrue(isinstance(ast.NameConstant(None), ast.NameConstant))
453 self.assertTrue(isinstance(ast.Ellipsis(), ast.Ellipsis))
454
455 self.assertTrue(isinstance(ast.Constant(42), ast.Num))
456 self.assertTrue(isinstance(ast.Constant(4.2), ast.Num))
457 self.assertTrue(isinstance(ast.Constant(4.2j), ast.Num))
458 self.assertTrue(isinstance(ast.Constant('42'), ast.Str))
459 self.assertTrue(isinstance(ast.Constant(b'42'), ast.Bytes))
460 self.assertTrue(isinstance(ast.Constant(True), ast.NameConstant))
461 self.assertTrue(isinstance(ast.Constant(False), ast.NameConstant))
462 self.assertTrue(isinstance(ast.Constant(None), ast.NameConstant))
463 self.assertTrue(isinstance(ast.Constant(...), ast.Ellipsis))
464
465 self.assertFalse(isinstance(ast.Str('42'), ast.Num))
466 self.assertFalse(isinstance(ast.Num(42), ast.Str))
467 self.assertFalse(isinstance(ast.Str('42'), ast.Bytes))
468 self.assertFalse(isinstance(ast.Num(42), ast.NameConstant))
469 self.assertFalse(isinstance(ast.Num(42), ast.Ellipsis))
Anthony Sottile74176222019-01-18 11:30:28 -0800470 self.assertFalse(isinstance(ast.NameConstant(True), ast.Num))
471 self.assertFalse(isinstance(ast.NameConstant(False), ast.Num))
Serhiy Storchaka3f228112018-09-27 17:42:37 +0300472
473 self.assertFalse(isinstance(ast.Constant('42'), ast.Num))
474 self.assertFalse(isinstance(ast.Constant(42), ast.Str))
475 self.assertFalse(isinstance(ast.Constant('42'), ast.Bytes))
476 self.assertFalse(isinstance(ast.Constant(42), ast.NameConstant))
477 self.assertFalse(isinstance(ast.Constant(42), ast.Ellipsis))
Anthony Sottile74176222019-01-18 11:30:28 -0800478 self.assertFalse(isinstance(ast.Constant(True), ast.Num))
479 self.assertFalse(isinstance(ast.Constant(False), ast.Num))
Serhiy Storchaka3f228112018-09-27 17:42:37 +0300480
481 self.assertFalse(isinstance(ast.Constant(), ast.Num))
482 self.assertFalse(isinstance(ast.Constant(), ast.Str))
483 self.assertFalse(isinstance(ast.Constant(), ast.Bytes))
484 self.assertFalse(isinstance(ast.Constant(), ast.NameConstant))
485 self.assertFalse(isinstance(ast.Constant(), ast.Ellipsis))
486
Serhiy Storchaka6015cc52018-10-28 13:43:03 +0200487 class S(str): pass
488 self.assertTrue(isinstance(ast.Constant(S('42')), ast.Str))
489 self.assertFalse(isinstance(ast.Constant(S('42')), ast.Num))
490
Serhiy Storchaka3f228112018-09-27 17:42:37 +0300491 def test_subclasses(self):
492 class N(ast.Num):
493 def __init__(self, *args, **kwargs):
494 super().__init__(*args, **kwargs)
495 self.z = 'spam'
496 class N2(ast.Num):
497 pass
498
499 n = N(42)
500 self.assertEqual(n.n, 42)
501 self.assertEqual(n.z, 'spam')
502 self.assertEqual(type(n), N)
503 self.assertTrue(isinstance(n, N))
504 self.assertTrue(isinstance(n, ast.Num))
505 self.assertFalse(isinstance(n, N2))
506 self.assertFalse(isinstance(ast.Num(42), N))
507 n = N(n=42)
508 self.assertEqual(n.n, 42)
509 self.assertEqual(type(n), N)
510
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500511 def test_module(self):
512 body = [ast.Num(42)]
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800513 x = ast.Module(body, [])
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500514 self.assertEqual(x.body, body)
515
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000516 def test_nodeclasses(self):
Florent Xicluna992d9e02011-11-11 19:35:42 +0100517 # Zero arguments constructor explicitly allowed
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500518 x = ast.BinOp()
519 self.assertEqual(x._fields, ('left', 'op', 'right'))
520
521 # Random attribute allowed too
522 x.foobarbaz = 5
523 self.assertEqual(x.foobarbaz, 5)
524
525 n1 = ast.Num(1)
526 n3 = ast.Num(3)
527 addop = ast.Add()
528 x = ast.BinOp(n1, addop, n3)
529 self.assertEqual(x.left, n1)
530 self.assertEqual(x.op, addop)
531 self.assertEqual(x.right, n3)
Benjamin Peterson68b543a2011-06-27 17:51:18 -0500532
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500533 x = ast.BinOp(1, 2, 3)
534 self.assertEqual(x.left, 1)
535 self.assertEqual(x.op, 2)
536 self.assertEqual(x.right, 3)
537
Georg Brandl0c77a822008-06-10 16:37:50 +0000538 x = ast.BinOp(1, 2, 3, lineno=0)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000539 self.assertEqual(x.left, 1)
540 self.assertEqual(x.op, 2)
541 self.assertEqual(x.right, 3)
542 self.assertEqual(x.lineno, 0)
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000543
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500544 # node raises exception when given too many arguments
545 self.assertRaises(TypeError, ast.BinOp, 1, 2, 3, 4)
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500546 # node raises exception when given too many arguments
547 self.assertRaises(TypeError, ast.BinOp, 1, 2, 3, 4, lineno=0)
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000548
549 # can set attributes through kwargs too
Georg Brandl0c77a822008-06-10 16:37:50 +0000550 x = ast.BinOp(left=1, op=2, right=3, lineno=0)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000551 self.assertEqual(x.left, 1)
552 self.assertEqual(x.op, 2)
553 self.assertEqual(x.right, 3)
554 self.assertEqual(x.lineno, 0)
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000555
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500556 # Random kwargs also allowed
557 x = ast.BinOp(1, 2, 3, foobarbaz=42)
558 self.assertEqual(x.foobarbaz, 42)
559
560 def test_no_fields(self):
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000561 # this used to fail because Sub._fields was None
Georg Brandl0c77a822008-06-10 16:37:50 +0000562 x = ast.Sub()
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500563 self.assertEqual(x._fields, ())
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000564
565 def test_pickling(self):
566 import pickle
567 mods = [pickle]
568 try:
569 import cPickle
570 mods.append(cPickle)
571 except ImportError:
572 pass
573 protocols = [0, 1, 2]
574 for mod in mods:
575 for protocol in protocols:
576 for ast in (compile(i, "?", "exec", 0x400) for i in exec_tests):
577 ast2 = mod.loads(mod.dumps(ast, protocol))
Ezio Melottib3aedd42010-11-20 19:04:17 +0000578 self.assertEqual(to_tuple(ast2), to_tuple(ast))
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000579
Benjamin Peterson5b066812010-11-20 01:38:49 +0000580 def test_invalid_sum(self):
581 pos = dict(lineno=2, col_offset=3)
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800582 m = ast.Module([ast.Expr(ast.expr(**pos), **pos)], [])
Benjamin Peterson5b066812010-11-20 01:38:49 +0000583 with self.assertRaises(TypeError) as cm:
584 compile(m, "<test>", "exec")
Serhiy Storchakabace59d2020-03-22 20:33:34 +0200585 self.assertIn("but got <ast.expr", str(cm.exception))
Benjamin Peterson5b066812010-11-20 01:38:49 +0000586
Min ho Kimc4cacc82019-07-31 08:16:13 +1000587 def test_invalid_identifier(self):
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800588 m = ast.Module([ast.Expr(ast.Name(42, ast.Load()))], [])
Benjamin Peterson2193d2b2011-07-22 10:50:23 -0500589 ast.fix_missing_locations(m)
590 with self.assertRaises(TypeError) as cm:
591 compile(m, "<test>", "exec")
592 self.assertIn("identifier must be of type str", str(cm.exception))
593
Batuhan TaĹźkaya0ac59f92020-03-19 14:32:28 +0300594 def test_invalid_constant(self):
595 for invalid_constant in int, (1, 2, int), frozenset((1, 2, int)):
596 e = ast.Expression(body=ast.Constant(invalid_constant))
597 ast.fix_missing_locations(e)
598 with self.assertRaisesRegex(
599 TypeError, "invalid type in Constant: type"
600 ):
601 compile(e, "<test>", "eval")
602
Mark Dickinsonded35ae2012-11-25 14:36:26 +0000603 def test_empty_yield_from(self):
604 # Issue 16546: yield from value is not optional.
605 empty_yield_from = ast.parse("def f():\n yield from g()")
606 empty_yield_from.body[0].body[0].value.value = None
607 with self.assertRaises(ValueError) as cm:
608 compile(empty_yield_from, "<test>", "exec")
Batuhan Taskaya091951a2020-05-06 17:29:32 +0300609 self.assertIn("field 'value' is required", str(cm.exception))
Mark Dickinsonded35ae2012-11-25 14:36:26 +0000610
Oren Milman7dc46d82017-09-30 20:16:24 +0300611 @support.cpython_only
612 def test_issue31592(self):
613 # There shouldn't be an assertion failure in case of a bad
614 # unicodedata.normalize().
615 import unicodedata
616 def bad_normalize(*args):
617 return None
618 with support.swap_attr(unicodedata, 'normalize', bad_normalize):
619 self.assertRaises(TypeError, ast.parse, '\u03D5')
620
Carl Friedrich Bolz-Tereick110a47c2019-07-08 23:17:56 +0200621 def test_issue18374_binop_col_offset(self):
622 tree = ast.parse('4+5+6+7')
623 parent_binop = tree.body[0].value
624 child_binop = parent_binop.left
625 grandchild_binop = child_binop.left
626 self.assertEqual(parent_binop.col_offset, 0)
627 self.assertEqual(parent_binop.end_col_offset, 7)
628 self.assertEqual(child_binop.col_offset, 0)
629 self.assertEqual(child_binop.end_col_offset, 5)
630 self.assertEqual(grandchild_binop.col_offset, 0)
631 self.assertEqual(grandchild_binop.end_col_offset, 3)
632
633 tree = ast.parse('4+5-\\\n 6-7')
634 parent_binop = tree.body[0].value
635 child_binop = parent_binop.left
636 grandchild_binop = child_binop.left
637 self.assertEqual(parent_binop.col_offset, 0)
638 self.assertEqual(parent_binop.lineno, 1)
639 self.assertEqual(parent_binop.end_col_offset, 4)
640 self.assertEqual(parent_binop.end_lineno, 2)
641
642 self.assertEqual(child_binop.col_offset, 0)
Carl Friedrich Bolz-Tereick430a9f42019-07-09 14:20:01 +0200643 self.assertEqual(child_binop.lineno, 1)
Carl Friedrich Bolz-Tereick110a47c2019-07-08 23:17:56 +0200644 self.assertEqual(child_binop.end_col_offset, 2)
Carl Friedrich Bolz-Tereick430a9f42019-07-09 14:20:01 +0200645 self.assertEqual(child_binop.end_lineno, 2)
Carl Friedrich Bolz-Tereick110a47c2019-07-08 23:17:56 +0200646
647 self.assertEqual(grandchild_binop.col_offset, 0)
Carl Friedrich Bolz-Tereick430a9f42019-07-09 14:20:01 +0200648 self.assertEqual(grandchild_binop.lineno, 1)
Carl Friedrich Bolz-Tereick110a47c2019-07-08 23:17:56 +0200649 self.assertEqual(grandchild_binop.end_col_offset, 3)
Carl Friedrich Bolz-Tereick430a9f42019-07-09 14:20:01 +0200650 self.assertEqual(grandchild_binop.end_lineno, 1)
Georg Brandl0c77a822008-06-10 16:37:50 +0000651
Lysandros Nikolaoud2e10982020-02-08 00:36:32 +0100652 def test_issue39579_dotted_name_end_col_offset(self):
653 tree = ast.parse('@a.b.c\ndef f(): pass')
654 attr_b = tree.body[0].decorator_list[0].value
655 self.assertEqual(attr_b.end_col_offset, 4)
656
Batuhan TaĹźkaya4ab362c2020-03-16 11:12:53 +0300657 def test_ast_asdl_signature(self):
658 self.assertEqual(ast.withitem.__doc__, "withitem(expr context_expr, expr? optional_vars)")
659 self.assertEqual(ast.GtE.__doc__, "GtE")
660 self.assertEqual(ast.Name.__doc__, "Name(identifier id, expr_context ctx)")
661 self.assertEqual(ast.cmpop.__doc__, "cmpop = Eq | NotEq | Lt | LtE | Gt | GtE | Is | IsNot | In | NotIn")
662 expressions = [f" | {node.__doc__}" for node in ast.expr.__subclasses__()]
663 expressions[0] = f"expr = {ast.expr.__subclasses__()[0].__doc__}"
664 self.assertCountEqual(ast.expr.__doc__.split("\n"), expressions)
665
Shantanuc116c942020-05-27 13:30:38 -0700666 def test_issue40614_feature_version(self):
667 ast.parse('f"{x=}"', feature_version=(3, 8))
668 with self.assertRaises(SyntaxError):
669 ast.parse('f"{x=}"', feature_version=(3, 7))
670
Batuhan TaĹźkaya4ab362c2020-03-16 11:12:53 +0300671
Georg Brandl0c77a822008-06-10 16:37:50 +0000672class ASTHelpers_Test(unittest.TestCase):
Guido van Rossum10f8ce62019-03-13 13:00:46 -0700673 maxDiff = None
Georg Brandl0c77a822008-06-10 16:37:50 +0000674
675 def test_parse(self):
676 a = ast.parse('foo(1 + 1)')
677 b = compile('foo(1 + 1)', '<unknown>', 'exec', ast.PyCF_ONLY_AST)
678 self.assertEqual(ast.dump(a), ast.dump(b))
679
Benjamin Peterson2e2c9032012-09-02 14:23:15 -0400680 def test_parse_in_error(self):
681 try:
682 1/0
683 except Exception:
Benjamin Petersonbd0df502012-09-02 15:04:51 -0400684 with self.assertRaises(SyntaxError) as e:
685 ast.literal_eval(r"'\U'")
686 self.assertIsNotNone(e.exception.__context__)
Benjamin Peterson2e2c9032012-09-02 14:23:15 -0400687
Georg Brandl0c77a822008-06-10 16:37:50 +0000688 def test_dump(self):
689 node = ast.parse('spam(eggs, "and cheese")')
690 self.assertEqual(ast.dump(node),
691 "Module(body=[Expr(value=Call(func=Name(id='spam', ctx=Load()), "
Serhiy Storchakab7e95252020-03-10 00:07:47 +0200692 "args=[Name(id='eggs', ctx=Load()), Constant(value='and cheese')], "
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800693 "keywords=[]))], type_ignores=[])"
Georg Brandl0c77a822008-06-10 16:37:50 +0000694 )
695 self.assertEqual(ast.dump(node, annotate_fields=False),
696 "Module([Expr(Call(Name('spam', Load()), [Name('eggs', Load()), "
Serhiy Storchakab7e95252020-03-10 00:07:47 +0200697 "Constant('and cheese')], []))], [])"
Georg Brandl0c77a822008-06-10 16:37:50 +0000698 )
699 self.assertEqual(ast.dump(node, include_attributes=True),
700 "Module(body=[Expr(value=Call(func=Name(id='spam', ctx=Load(), "
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000701 "lineno=1, col_offset=0, end_lineno=1, end_col_offset=4), "
702 "args=[Name(id='eggs', ctx=Load(), lineno=1, col_offset=5, "
Serhiy Storchakab7e95252020-03-10 00:07:47 +0200703 "end_lineno=1, end_col_offset=9), Constant(value='and cheese', "
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000704 "lineno=1, col_offset=11, end_lineno=1, end_col_offset=23)], keywords=[], "
705 "lineno=1, col_offset=0, end_lineno=1, end_col_offset=24), "
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800706 "lineno=1, col_offset=0, end_lineno=1, end_col_offset=24)], type_ignores=[])"
Georg Brandl0c77a822008-06-10 16:37:50 +0000707 )
708
Serhiy Storchaka850573b2019-09-09 19:33:13 +0300709 def test_dump_indent(self):
710 node = ast.parse('spam(eggs, "and cheese")')
711 self.assertEqual(ast.dump(node, indent=3), """\
712Module(
713 body=[
714 Expr(
715 value=Call(
716 func=Name(id='spam', ctx=Load()),
717 args=[
718 Name(id='eggs', ctx=Load()),
Serhiy Storchakab7e95252020-03-10 00:07:47 +0200719 Constant(value='and cheese')],
Serhiy Storchaka850573b2019-09-09 19:33:13 +0300720 keywords=[]))],
721 type_ignores=[])""")
722 self.assertEqual(ast.dump(node, annotate_fields=False, indent='\t'), """\
723Module(
724\t[
725\t\tExpr(
726\t\t\tCall(
727\t\t\t\tName('spam', Load()),
728\t\t\t\t[
729\t\t\t\t\tName('eggs', Load()),
Serhiy Storchakab7e95252020-03-10 00:07:47 +0200730\t\t\t\t\tConstant('and cheese')],
Serhiy Storchaka850573b2019-09-09 19:33:13 +0300731\t\t\t\t[]))],
732\t[])""")
733 self.assertEqual(ast.dump(node, include_attributes=True, indent=3), """\
734Module(
735 body=[
736 Expr(
737 value=Call(
738 func=Name(
739 id='spam',
740 ctx=Load(),
741 lineno=1,
742 col_offset=0,
743 end_lineno=1,
744 end_col_offset=4),
745 args=[
746 Name(
747 id='eggs',
748 ctx=Load(),
749 lineno=1,
750 col_offset=5,
751 end_lineno=1,
752 end_col_offset=9),
753 Constant(
754 value='and cheese',
Serhiy Storchaka850573b2019-09-09 19:33:13 +0300755 lineno=1,
756 col_offset=11,
757 end_lineno=1,
758 end_col_offset=23)],
759 keywords=[],
760 lineno=1,
761 col_offset=0,
762 end_lineno=1,
763 end_col_offset=24),
764 lineno=1,
765 col_offset=0,
766 end_lineno=1,
767 end_col_offset=24)],
768 type_ignores=[])""")
769
Serhiy Storchakae64f9482019-08-29 09:30:23 +0300770 def test_dump_incomplete(self):
771 node = ast.Raise(lineno=3, col_offset=4)
772 self.assertEqual(ast.dump(node),
773 "Raise()"
774 )
775 self.assertEqual(ast.dump(node, include_attributes=True),
776 "Raise(lineno=3, col_offset=4)"
777 )
778 node = ast.Raise(exc=ast.Name(id='e', ctx=ast.Load()), lineno=3, col_offset=4)
779 self.assertEqual(ast.dump(node),
780 "Raise(exc=Name(id='e', ctx=Load()))"
781 )
782 self.assertEqual(ast.dump(node, annotate_fields=False),
783 "Raise(Name('e', Load()))"
784 )
785 self.assertEqual(ast.dump(node, include_attributes=True),
786 "Raise(exc=Name(id='e', ctx=Load()), lineno=3, col_offset=4)"
787 )
788 self.assertEqual(ast.dump(node, annotate_fields=False, include_attributes=True),
789 "Raise(Name('e', Load()), lineno=3, col_offset=4)"
790 )
791 node = ast.Raise(cause=ast.Name(id='e', ctx=ast.Load()))
792 self.assertEqual(ast.dump(node),
793 "Raise(cause=Name(id='e', ctx=Load()))"
794 )
795 self.assertEqual(ast.dump(node, annotate_fields=False),
796 "Raise(cause=Name('e', Load()))"
797 )
798
Georg Brandl0c77a822008-06-10 16:37:50 +0000799 def test_copy_location(self):
800 src = ast.parse('1 + 1', mode='eval')
801 src.body.right = ast.copy_location(ast.Num(2), src.body.right)
802 self.assertEqual(ast.dump(src, include_attributes=True),
Serhiy Storchakab7e95252020-03-10 00:07:47 +0200803 'Expression(body=BinOp(left=Constant(value=1, lineno=1, col_offset=0, '
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000804 'end_lineno=1, end_col_offset=1), op=Add(), right=Constant(value=2, '
805 'lineno=1, col_offset=4, end_lineno=1, end_col_offset=5), lineno=1, '
806 'col_offset=0, end_lineno=1, end_col_offset=5))'
Georg Brandl0c77a822008-06-10 16:37:50 +0000807 )
808
809 def test_fix_missing_locations(self):
810 src = ast.parse('write("spam")')
811 src.body.append(ast.Expr(ast.Call(ast.Name('spam', ast.Load()),
Benjamin Peterson025e9eb2015-05-05 20:16:41 -0400812 [ast.Str('eggs')], [])))
Georg Brandl0c77a822008-06-10 16:37:50 +0000813 self.assertEqual(src, ast.fix_missing_locations(src))
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000814 self.maxDiff = None
Georg Brandl0c77a822008-06-10 16:37:50 +0000815 self.assertEqual(ast.dump(src, include_attributes=True),
816 "Module(body=[Expr(value=Call(func=Name(id='write', ctx=Load(), "
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000817 "lineno=1, col_offset=0, end_lineno=1, end_col_offset=5), "
Serhiy Storchakab7e95252020-03-10 00:07:47 +0200818 "args=[Constant(value='spam', lineno=1, col_offset=6, end_lineno=1, "
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000819 "end_col_offset=12)], keywords=[], lineno=1, col_offset=0, end_lineno=1, "
820 "end_col_offset=13), lineno=1, col_offset=0, end_lineno=1, "
821 "end_col_offset=13), Expr(value=Call(func=Name(id='spam', ctx=Load(), "
822 "lineno=1, col_offset=0, end_lineno=1, end_col_offset=0), "
823 "args=[Constant(value='eggs', lineno=1, col_offset=0, end_lineno=1, "
824 "end_col_offset=0)], keywords=[], lineno=1, col_offset=0, end_lineno=1, "
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800825 "end_col_offset=0), lineno=1, col_offset=0, end_lineno=1, end_col_offset=0)], "
826 "type_ignores=[])"
Georg Brandl0c77a822008-06-10 16:37:50 +0000827 )
828
829 def test_increment_lineno(self):
830 src = ast.parse('1 + 1', mode='eval')
831 self.assertEqual(ast.increment_lineno(src, n=3), src)
832 self.assertEqual(ast.dump(src, include_attributes=True),
Serhiy Storchakab7e95252020-03-10 00:07:47 +0200833 'Expression(body=BinOp(left=Constant(value=1, lineno=4, col_offset=0, '
834 'end_lineno=4, end_col_offset=1), op=Add(), right=Constant(value=1, '
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000835 'lineno=4, col_offset=4, end_lineno=4, end_col_offset=5), lineno=4, '
836 'col_offset=0, end_lineno=4, end_col_offset=5))'
Georg Brandl0c77a822008-06-10 16:37:50 +0000837 )
Georg Brandl619e7ba2011-01-09 07:38:51 +0000838 # issue10869: do not increment lineno of root twice
Georg Brandlefb69022011-01-09 07:50:48 +0000839 src = ast.parse('1 + 1', mode='eval')
Georg Brandl619e7ba2011-01-09 07:38:51 +0000840 self.assertEqual(ast.increment_lineno(src.body, n=3), src.body)
841 self.assertEqual(ast.dump(src, include_attributes=True),
Serhiy Storchakab7e95252020-03-10 00:07:47 +0200842 'Expression(body=BinOp(left=Constant(value=1, lineno=4, col_offset=0, '
843 'end_lineno=4, end_col_offset=1), op=Add(), right=Constant(value=1, '
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000844 'lineno=4, col_offset=4, end_lineno=4, end_col_offset=5), lineno=4, '
845 'col_offset=0, end_lineno=4, end_col_offset=5))'
Georg Brandl619e7ba2011-01-09 07:38:51 +0000846 )
Georg Brandl0c77a822008-06-10 16:37:50 +0000847
848 def test_iter_fields(self):
849 node = ast.parse('foo()', mode='eval')
850 d = dict(ast.iter_fields(node.body))
851 self.assertEqual(d.pop('func').id, 'foo')
Benjamin Peterson025e9eb2015-05-05 20:16:41 -0400852 self.assertEqual(d, {'keywords': [], 'args': []})
Georg Brandl0c77a822008-06-10 16:37:50 +0000853
854 def test_iter_child_nodes(self):
855 node = ast.parse("spam(23, 42, eggs='leek')", mode='eval')
856 self.assertEqual(len(list(ast.iter_child_nodes(node.body))), 4)
857 iterator = ast.iter_child_nodes(node.body)
858 self.assertEqual(next(iterator).id, 'spam')
Serhiy Storchaka3f228112018-09-27 17:42:37 +0300859 self.assertEqual(next(iterator).value, 23)
860 self.assertEqual(next(iterator).value, 42)
Georg Brandl0c77a822008-06-10 16:37:50 +0000861 self.assertEqual(ast.dump(next(iterator)),
Serhiy Storchakab7e95252020-03-10 00:07:47 +0200862 "keyword(arg='eggs', value=Constant(value='leek'))"
Georg Brandl0c77a822008-06-10 16:37:50 +0000863 )
864
865 def test_get_docstring(self):
Serhiy Storchaka08f127a2018-06-15 11:05:15 +0300866 node = ast.parse('"""line one\n line two"""')
867 self.assertEqual(ast.get_docstring(node),
868 'line one\nline two')
869
870 node = ast.parse('class foo:\n """line one\n line two"""')
871 self.assertEqual(ast.get_docstring(node.body[0]),
872 'line one\nline two')
873
Georg Brandl0c77a822008-06-10 16:37:50 +0000874 node = ast.parse('def foo():\n """line one\n line two"""')
875 self.assertEqual(ast.get_docstring(node.body[0]),
876 'line one\nline two')
877
Yury Selivanov2f07a662015-07-23 08:54:35 +0300878 node = ast.parse('async def foo():\n """spam\n ham"""')
879 self.assertEqual(ast.get_docstring(node.body[0]), 'spam\nham')
Serhiy Storchaka08f127a2018-06-15 11:05:15 +0300880
881 def test_get_docstring_none(self):
Matthias Bussonnier41cea702017-02-23 22:44:19 -0800882 self.assertIsNone(ast.get_docstring(ast.parse('')))
Serhiy Storchaka08f127a2018-06-15 11:05:15 +0300883 node = ast.parse('x = "not docstring"')
884 self.assertIsNone(ast.get_docstring(node))
885 node = ast.parse('def foo():\n pass')
886 self.assertIsNone(ast.get_docstring(node))
887
888 node = ast.parse('class foo:\n pass')
889 self.assertIsNone(ast.get_docstring(node.body[0]))
890 node = ast.parse('class foo:\n x = "not docstring"')
891 self.assertIsNone(ast.get_docstring(node.body[0]))
892 node = ast.parse('class foo:\n def bar(self): pass')
893 self.assertIsNone(ast.get_docstring(node.body[0]))
894
895 node = ast.parse('def foo():\n pass')
896 self.assertIsNone(ast.get_docstring(node.body[0]))
897 node = ast.parse('def foo():\n x = "not docstring"')
898 self.assertIsNone(ast.get_docstring(node.body[0]))
899
900 node = ast.parse('async def foo():\n pass')
901 self.assertIsNone(ast.get_docstring(node.body[0]))
902 node = ast.parse('async def foo():\n x = "not docstring"')
903 self.assertIsNone(ast.get_docstring(node.body[0]))
Yury Selivanov2f07a662015-07-23 08:54:35 +0300904
Anthony Sottile995d9b92019-01-12 20:05:13 -0800905 def test_multi_line_docstring_col_offset_and_lineno_issue16806(self):
906 node = ast.parse(
907 '"""line one\nline two"""\n\n'
908 'def foo():\n """line one\n line two"""\n\n'
909 ' def bar():\n """line one\n line two"""\n'
910 ' """line one\n line two"""\n'
911 '"""line one\nline two"""\n\n'
912 )
913 self.assertEqual(node.body[0].col_offset, 0)
914 self.assertEqual(node.body[0].lineno, 1)
915 self.assertEqual(node.body[1].body[0].col_offset, 2)
916 self.assertEqual(node.body[1].body[0].lineno, 5)
917 self.assertEqual(node.body[1].body[1].body[0].col_offset, 4)
918 self.assertEqual(node.body[1].body[1].body[0].lineno, 9)
919 self.assertEqual(node.body[1].body[2].col_offset, 2)
920 self.assertEqual(node.body[1].body[2].lineno, 11)
921 self.assertEqual(node.body[2].col_offset, 0)
922 self.assertEqual(node.body[2].lineno, 13)
923
Lysandros Nikolaou025a6022019-12-12 22:40:21 +0100924 def test_elif_stmt_start_position(self):
925 node = ast.parse('if a:\n pass\nelif b:\n pass\n')
926 elif_stmt = node.body[0].orelse[0]
927 self.assertEqual(elif_stmt.lineno, 3)
928 self.assertEqual(elif_stmt.col_offset, 0)
929
Lysandros Nikolaou5936a4c2019-12-14 11:24:57 +0100930 def test_elif_stmt_start_position_with_else(self):
931 node = ast.parse('if a:\n pass\nelif b:\n pass\nelse:\n pass\n')
932 elif_stmt = node.body[0].orelse[0]
933 self.assertEqual(elif_stmt.lineno, 3)
934 self.assertEqual(elif_stmt.col_offset, 0)
935
Lysandros Nikolaou50d4f122019-12-18 01:20:55 +0100936 def test_starred_expr_end_position_within_call(self):
937 node = ast.parse('f(*[0, 1])')
938 starred_expr = node.body[0].value.args[0]
939 self.assertEqual(starred_expr.end_lineno, 1)
940 self.assertEqual(starred_expr.end_col_offset, 9)
941
Georg Brandl0c77a822008-06-10 16:37:50 +0000942 def test_literal_eval(self):
943 self.assertEqual(ast.literal_eval('[1, 2, 3]'), [1, 2, 3])
944 self.assertEqual(ast.literal_eval('{"foo": 42}'), {"foo": 42})
945 self.assertEqual(ast.literal_eval('(True, False, None)'), (True, False, None))
Benjamin Peterson3e742892010-07-11 12:59:24 +0000946 self.assertEqual(ast.literal_eval('{1, 2, 3}'), {1, 2, 3})
Benjamin Peterson5ef96e52010-07-11 23:06:06 +0000947 self.assertEqual(ast.literal_eval('b"hi"'), b"hi")
Raymond Hettinger4fcf5c12020-01-02 22:21:18 -0700948 self.assertEqual(ast.literal_eval('set()'), set())
Georg Brandl0c77a822008-06-10 16:37:50 +0000949 self.assertRaises(ValueError, ast.literal_eval, 'foo()')
Serhiy Storchakad8ac4d12018-01-04 11:15:39 +0200950 self.assertEqual(ast.literal_eval('6'), 6)
951 self.assertEqual(ast.literal_eval('+6'), 6)
Raymond Hettingerbc959732010-10-08 00:47:45 +0000952 self.assertEqual(ast.literal_eval('-6'), -6)
Raymond Hettingerbc959732010-10-08 00:47:45 +0000953 self.assertEqual(ast.literal_eval('3.25'), 3.25)
Serhiy Storchakad8ac4d12018-01-04 11:15:39 +0200954 self.assertEqual(ast.literal_eval('+3.25'), 3.25)
955 self.assertEqual(ast.literal_eval('-3.25'), -3.25)
956 self.assertEqual(repr(ast.literal_eval('-0.0')), '-0.0')
957 self.assertRaises(ValueError, ast.literal_eval, '++6')
958 self.assertRaises(ValueError, ast.literal_eval, '+True')
959 self.assertRaises(ValueError, ast.literal_eval, '2+3')
Georg Brandl0c77a822008-06-10 16:37:50 +0000960
Serhiy Storchakad8ac4d12018-01-04 11:15:39 +0200961 def test_literal_eval_complex(self):
962 # Issue #4907
963 self.assertEqual(ast.literal_eval('6j'), 6j)
964 self.assertEqual(ast.literal_eval('-6j'), -6j)
965 self.assertEqual(ast.literal_eval('6.75j'), 6.75j)
966 self.assertEqual(ast.literal_eval('-6.75j'), -6.75j)
967 self.assertEqual(ast.literal_eval('3+6j'), 3+6j)
968 self.assertEqual(ast.literal_eval('-3+6j'), -3+6j)
969 self.assertEqual(ast.literal_eval('3-6j'), 3-6j)
970 self.assertEqual(ast.literal_eval('-3-6j'), -3-6j)
971 self.assertEqual(ast.literal_eval('3.25+6.75j'), 3.25+6.75j)
972 self.assertEqual(ast.literal_eval('-3.25+6.75j'), -3.25+6.75j)
973 self.assertEqual(ast.literal_eval('3.25-6.75j'), 3.25-6.75j)
974 self.assertEqual(ast.literal_eval('-3.25-6.75j'), -3.25-6.75j)
975 self.assertEqual(ast.literal_eval('(3+6j)'), 3+6j)
976 self.assertRaises(ValueError, ast.literal_eval, '-6j+3')
977 self.assertRaises(ValueError, ast.literal_eval, '-6j+3j')
978 self.assertRaises(ValueError, ast.literal_eval, '3+-6j')
979 self.assertRaises(ValueError, ast.literal_eval, '3+(0+6j)')
980 self.assertRaises(ValueError, ast.literal_eval, '-(3+6j)')
Benjamin Peterson058e31e2009-01-16 03:54:08 +0000981
Curtis Bucherc21c5122020-05-05 12:40:56 -0700982 def test_literal_eval_malformed_dict_nodes(self):
983 malformed = ast.Dict(keys=[ast.Constant(1), ast.Constant(2)], values=[ast.Constant(3)])
984 self.assertRaises(ValueError, ast.literal_eval, malformed)
985 malformed = ast.Dict(keys=[ast.Constant(1)], values=[ast.Constant(2), ast.Constant(3)])
986 self.assertRaises(ValueError, ast.literal_eval, malformed)
987
Amaury Forgeot d'Arc58e87612011-11-22 21:51:55 +0100988 def test_bad_integer(self):
989 # issue13436: Bad error message with invalid numeric values
990 body = [ast.ImportFrom(module='time',
991 names=[ast.alias(name='sleep')],
992 level=None,
993 lineno=None, col_offset=None)]
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800994 mod = ast.Module(body, [])
Amaury Forgeot d'Arc58e87612011-11-22 21:51:55 +0100995 with self.assertRaises(ValueError) as cm:
996 compile(mod, 'test', 'exec')
997 self.assertIn("invalid integer value: None", str(cm.exception))
998
Berker Peksag0a5bd512016-04-29 19:50:02 +0300999 def test_level_as_none(self):
1000 body = [ast.ImportFrom(module='time',
1001 names=[ast.alias(name='sleep')],
1002 level=None,
1003 lineno=0, col_offset=0)]
Guido van Rossumdcfcd142019-01-31 03:40:27 -08001004 mod = ast.Module(body, [])
Berker Peksag0a5bd512016-04-29 19:50:02 +03001005 code = compile(mod, 'test', 'exec')
1006 ns = {}
1007 exec(code, ns)
1008 self.assertIn('sleep', ns)
1009
Georg Brandl0c77a822008-06-10 16:37:50 +00001010
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001011class ASTValidatorTests(unittest.TestCase):
1012
1013 def mod(self, mod, msg=None, mode="exec", *, exc=ValueError):
1014 mod.lineno = mod.col_offset = 0
1015 ast.fix_missing_locations(mod)
Serhiy Storchaka3f228112018-09-27 17:42:37 +03001016 if msg is None:
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001017 compile(mod, "<test>", mode)
Serhiy Storchaka3f228112018-09-27 17:42:37 +03001018 else:
1019 with self.assertRaises(exc) as cm:
1020 compile(mod, "<test>", mode)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001021 self.assertIn(msg, str(cm.exception))
1022
1023 def expr(self, node, msg=None, *, exc=ValueError):
Guido van Rossumdcfcd142019-01-31 03:40:27 -08001024 mod = ast.Module([ast.Expr(node)], [])
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001025 self.mod(mod, msg, exc=exc)
1026
1027 def stmt(self, stmt, msg=None):
Guido van Rossumdcfcd142019-01-31 03:40:27 -08001028 mod = ast.Module([stmt], [])
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001029 self.mod(mod, msg)
1030
1031 def test_module(self):
1032 m = ast.Interactive([ast.Expr(ast.Name("x", ast.Store()))])
1033 self.mod(m, "must have Load context", "single")
1034 m = ast.Expression(ast.Name("x", ast.Store()))
1035 self.mod(m, "must have Load context", "eval")
1036
1037 def _check_arguments(self, fac, check):
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01001038 def arguments(args=None, posonlyargs=None, vararg=None,
Benjamin Petersoncda75be2013-03-18 10:48:58 -07001039 kwonlyargs=None, kwarg=None,
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001040 defaults=None, kw_defaults=None):
1041 if args is None:
1042 args = []
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01001043 if posonlyargs is None:
1044 posonlyargs = []
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001045 if kwonlyargs is None:
1046 kwonlyargs = []
1047 if defaults is None:
1048 defaults = []
1049 if kw_defaults is None:
1050 kw_defaults = []
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01001051 args = ast.arguments(args, posonlyargs, vararg, kwonlyargs,
1052 kw_defaults, kwarg, defaults)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001053 return fac(args)
1054 args = [ast.arg("x", ast.Name("x", ast.Store()))]
1055 check(arguments(args=args), "must have Load context")
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01001056 check(arguments(posonlyargs=args), "must have Load context")
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001057 check(arguments(kwonlyargs=args), "must have Load context")
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001058 check(arguments(defaults=[ast.Num(3)]),
1059 "more positional defaults than args")
1060 check(arguments(kw_defaults=[ast.Num(4)]),
1061 "length of kwonlyargs is not the same as kw_defaults")
1062 args = [ast.arg("x", ast.Name("x", ast.Load()))]
1063 check(arguments(args=args, defaults=[ast.Name("x", ast.Store())]),
1064 "must have Load context")
1065 args = [ast.arg("a", ast.Name("x", ast.Load())),
1066 ast.arg("b", ast.Name("y", ast.Load()))]
1067 check(arguments(kwonlyargs=args,
1068 kw_defaults=[None, ast.Name("x", ast.Store())]),
1069 "must have Load context")
1070
1071 def test_funcdef(self):
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01001072 a = ast.arguments([], [], None, [], [], None, [])
Serhiy Storchaka73cbe7a2018-05-29 12:04:55 +03001073 f = ast.FunctionDef("x", a, [], [], None)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001074 self.stmt(f, "empty body on FunctionDef")
1075 f = ast.FunctionDef("x", a, [ast.Pass()], [ast.Name("x", ast.Store())],
Serhiy Storchaka73cbe7a2018-05-29 12:04:55 +03001076 None)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001077 self.stmt(f, "must have Load context")
1078 f = ast.FunctionDef("x", a, [ast.Pass()], [],
Serhiy Storchaka73cbe7a2018-05-29 12:04:55 +03001079 ast.Name("x", ast.Store()))
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001080 self.stmt(f, "must have Load context")
1081 def fac(args):
Serhiy Storchaka73cbe7a2018-05-29 12:04:55 +03001082 return ast.FunctionDef("x", args, [ast.Pass()], [], None)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001083 self._check_arguments(fac, self.stmt)
1084
1085 def test_classdef(self):
Benjamin Peterson025e9eb2015-05-05 20:16:41 -04001086 def cls(bases=None, keywords=None, body=None, decorator_list=None):
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001087 if bases is None:
1088 bases = []
1089 if keywords is None:
1090 keywords = []
1091 if body is None:
1092 body = [ast.Pass()]
1093 if decorator_list is None:
1094 decorator_list = []
Benjamin Peterson025e9eb2015-05-05 20:16:41 -04001095 return ast.ClassDef("myclass", bases, keywords,
Serhiy Storchaka73cbe7a2018-05-29 12:04:55 +03001096 body, decorator_list)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001097 self.stmt(cls(bases=[ast.Name("x", ast.Store())]),
1098 "must have Load context")
1099 self.stmt(cls(keywords=[ast.keyword("x", ast.Name("x", ast.Store()))]),
1100 "must have Load context")
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001101 self.stmt(cls(body=[]), "empty body on ClassDef")
1102 self.stmt(cls(body=[None]), "None disallowed")
1103 self.stmt(cls(decorator_list=[ast.Name("x", ast.Store())]),
1104 "must have Load context")
1105
1106 def test_delete(self):
1107 self.stmt(ast.Delete([]), "empty targets on Delete")
1108 self.stmt(ast.Delete([None]), "None disallowed")
1109 self.stmt(ast.Delete([ast.Name("x", ast.Load())]),
1110 "must have Del context")
1111
1112 def test_assign(self):
1113 self.stmt(ast.Assign([], ast.Num(3)), "empty targets on Assign")
1114 self.stmt(ast.Assign([None], ast.Num(3)), "None disallowed")
1115 self.stmt(ast.Assign([ast.Name("x", ast.Load())], ast.Num(3)),
1116 "must have Store context")
1117 self.stmt(ast.Assign([ast.Name("x", ast.Store())],
1118 ast.Name("y", ast.Store())),
1119 "must have Load context")
1120
1121 def test_augassign(self):
1122 aug = ast.AugAssign(ast.Name("x", ast.Load()), ast.Add(),
1123 ast.Name("y", ast.Load()))
1124 self.stmt(aug, "must have Store context")
1125 aug = ast.AugAssign(ast.Name("x", ast.Store()), ast.Add(),
1126 ast.Name("y", ast.Store()))
1127 self.stmt(aug, "must have Load context")
1128
1129 def test_for(self):
1130 x = ast.Name("x", ast.Store())
1131 y = ast.Name("y", ast.Load())
1132 p = ast.Pass()
1133 self.stmt(ast.For(x, y, [], []), "empty body on For")
1134 self.stmt(ast.For(ast.Name("x", ast.Load()), y, [p], []),
1135 "must have Store context")
1136 self.stmt(ast.For(x, ast.Name("y", ast.Store()), [p], []),
1137 "must have Load context")
1138 e = ast.Expr(ast.Name("x", ast.Store()))
1139 self.stmt(ast.For(x, y, [e], []), "must have Load context")
1140 self.stmt(ast.For(x, y, [p], [e]), "must have Load context")
1141
1142 def test_while(self):
1143 self.stmt(ast.While(ast.Num(3), [], []), "empty body on While")
1144 self.stmt(ast.While(ast.Name("x", ast.Store()), [ast.Pass()], []),
1145 "must have Load context")
1146 self.stmt(ast.While(ast.Num(3), [ast.Pass()],
1147 [ast.Expr(ast.Name("x", ast.Store()))]),
1148 "must have Load context")
1149
1150 def test_if(self):
1151 self.stmt(ast.If(ast.Num(3), [], []), "empty body on If")
1152 i = ast.If(ast.Name("x", ast.Store()), [ast.Pass()], [])
1153 self.stmt(i, "must have Load context")
1154 i = ast.If(ast.Num(3), [ast.Expr(ast.Name("x", ast.Store()))], [])
1155 self.stmt(i, "must have Load context")
1156 i = ast.If(ast.Num(3), [ast.Pass()],
1157 [ast.Expr(ast.Name("x", ast.Store()))])
1158 self.stmt(i, "must have Load context")
1159
1160 def test_with(self):
1161 p = ast.Pass()
1162 self.stmt(ast.With([], [p]), "empty items on With")
1163 i = ast.withitem(ast.Num(3), None)
1164 self.stmt(ast.With([i], []), "empty body on With")
1165 i = ast.withitem(ast.Name("x", ast.Store()), None)
1166 self.stmt(ast.With([i], [p]), "must have Load context")
1167 i = ast.withitem(ast.Num(3), ast.Name("x", ast.Load()))
1168 self.stmt(ast.With([i], [p]), "must have Store context")
1169
1170 def test_raise(self):
1171 r = ast.Raise(None, ast.Num(3))
1172 self.stmt(r, "Raise with cause but no exception")
1173 r = ast.Raise(ast.Name("x", ast.Store()), None)
1174 self.stmt(r, "must have Load context")
1175 r = ast.Raise(ast.Num(4), ast.Name("x", ast.Store()))
1176 self.stmt(r, "must have Load context")
1177
1178 def test_try(self):
1179 p = ast.Pass()
1180 t = ast.Try([], [], [], [p])
1181 self.stmt(t, "empty body on Try")
1182 t = ast.Try([ast.Expr(ast.Name("x", ast.Store()))], [], [], [p])
1183 self.stmt(t, "must have Load context")
1184 t = ast.Try([p], [], [], [])
1185 self.stmt(t, "Try has neither except handlers nor finalbody")
1186 t = ast.Try([p], [], [p], [p])
1187 self.stmt(t, "Try has orelse but no except handlers")
1188 t = ast.Try([p], [ast.ExceptHandler(None, "x", [])], [], [])
1189 self.stmt(t, "empty body on ExceptHandler")
1190 e = [ast.ExceptHandler(ast.Name("x", ast.Store()), "y", [p])]
1191 self.stmt(ast.Try([p], e, [], []), "must have Load context")
1192 e = [ast.ExceptHandler(None, "x", [p])]
1193 t = ast.Try([p], e, [ast.Expr(ast.Name("x", ast.Store()))], [p])
1194 self.stmt(t, "must have Load context")
1195 t = ast.Try([p], e, [p], [ast.Expr(ast.Name("x", ast.Store()))])
1196 self.stmt(t, "must have Load context")
1197
1198 def test_assert(self):
1199 self.stmt(ast.Assert(ast.Name("x", ast.Store()), None),
1200 "must have Load context")
1201 assrt = ast.Assert(ast.Name("x", ast.Load()),
1202 ast.Name("y", ast.Store()))
1203 self.stmt(assrt, "must have Load context")
1204
1205 def test_import(self):
1206 self.stmt(ast.Import([]), "empty names on Import")
1207
1208 def test_importfrom(self):
1209 imp = ast.ImportFrom(None, [ast.alias("x", None)], -42)
Serhiy Storchaka7de28402016-06-27 23:40:43 +03001210 self.stmt(imp, "Negative ImportFrom level")
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001211 self.stmt(ast.ImportFrom(None, [], 0), "empty names on ImportFrom")
1212
1213 def test_global(self):
1214 self.stmt(ast.Global([]), "empty names on Global")
1215
1216 def test_nonlocal(self):
1217 self.stmt(ast.Nonlocal([]), "empty names on Nonlocal")
1218
1219 def test_expr(self):
1220 e = ast.Expr(ast.Name("x", ast.Store()))
1221 self.stmt(e, "must have Load context")
1222
1223 def test_boolop(self):
1224 b = ast.BoolOp(ast.And(), [])
1225 self.expr(b, "less than 2 values")
1226 b = ast.BoolOp(ast.And(), [ast.Num(3)])
1227 self.expr(b, "less than 2 values")
1228 b = ast.BoolOp(ast.And(), [ast.Num(4), None])
1229 self.expr(b, "None disallowed")
1230 b = ast.BoolOp(ast.And(), [ast.Num(4), ast.Name("x", ast.Store())])
1231 self.expr(b, "must have Load context")
1232
1233 def test_unaryop(self):
1234 u = ast.UnaryOp(ast.Not(), ast.Name("x", ast.Store()))
1235 self.expr(u, "must have Load context")
1236
1237 def test_lambda(self):
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01001238 a = ast.arguments([], [], None, [], [], None, [])
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001239 self.expr(ast.Lambda(a, ast.Name("x", ast.Store())),
1240 "must have Load context")
1241 def fac(args):
1242 return ast.Lambda(args, ast.Name("x", ast.Load()))
1243 self._check_arguments(fac, self.expr)
1244
1245 def test_ifexp(self):
1246 l = ast.Name("x", ast.Load())
1247 s = ast.Name("y", ast.Store())
1248 for args in (s, l, l), (l, s, l), (l, l, s):
Benjamin Peterson71ce8972011-08-09 16:17:12 -05001249 self.expr(ast.IfExp(*args), "must have Load context")
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001250
1251 def test_dict(self):
1252 d = ast.Dict([], [ast.Name("x", ast.Load())])
1253 self.expr(d, "same number of keys as values")
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001254 d = ast.Dict([ast.Name("x", ast.Load())], [None])
1255 self.expr(d, "None disallowed")
1256
1257 def test_set(self):
1258 self.expr(ast.Set([None]), "None disallowed")
1259 s = ast.Set([ast.Name("x", ast.Store())])
1260 self.expr(s, "must have Load context")
1261
1262 def _check_comprehension(self, fac):
1263 self.expr(fac([]), "comprehension with no generators")
1264 g = ast.comprehension(ast.Name("x", ast.Load()),
Yury Selivanov52c4e7c2016-09-09 10:36:01 -07001265 ast.Name("x", ast.Load()), [], 0)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001266 self.expr(fac([g]), "must have Store context")
1267 g = ast.comprehension(ast.Name("x", ast.Store()),
Yury Selivanov52c4e7c2016-09-09 10:36:01 -07001268 ast.Name("x", ast.Store()), [], 0)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001269 self.expr(fac([g]), "must have Load context")
1270 x = ast.Name("x", ast.Store())
1271 y = ast.Name("y", ast.Load())
Yury Selivanov52c4e7c2016-09-09 10:36:01 -07001272 g = ast.comprehension(x, y, [None], 0)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001273 self.expr(fac([g]), "None disallowed")
Yury Selivanov52c4e7c2016-09-09 10:36:01 -07001274 g = ast.comprehension(x, y, [ast.Name("x", ast.Store())], 0)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001275 self.expr(fac([g]), "must have Load context")
1276
1277 def _simple_comp(self, fac):
1278 g = ast.comprehension(ast.Name("x", ast.Store()),
Yury Selivanov52c4e7c2016-09-09 10:36:01 -07001279 ast.Name("x", ast.Load()), [], 0)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001280 self.expr(fac(ast.Name("x", ast.Store()), [g]),
1281 "must have Load context")
1282 def wrap(gens):
1283 return fac(ast.Name("x", ast.Store()), gens)
1284 self._check_comprehension(wrap)
1285
1286 def test_listcomp(self):
1287 self._simple_comp(ast.ListComp)
1288
1289 def test_setcomp(self):
1290 self._simple_comp(ast.SetComp)
1291
1292 def test_generatorexp(self):
1293 self._simple_comp(ast.GeneratorExp)
1294
1295 def test_dictcomp(self):
1296 g = ast.comprehension(ast.Name("y", ast.Store()),
Yury Selivanov52c4e7c2016-09-09 10:36:01 -07001297 ast.Name("p", ast.Load()), [], 0)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001298 c = ast.DictComp(ast.Name("x", ast.Store()),
1299 ast.Name("y", ast.Load()), [g])
1300 self.expr(c, "must have Load context")
1301 c = ast.DictComp(ast.Name("x", ast.Load()),
1302 ast.Name("y", ast.Store()), [g])
1303 self.expr(c, "must have Load context")
1304 def factory(comps):
1305 k = ast.Name("x", ast.Load())
1306 v = ast.Name("y", ast.Load())
1307 return ast.DictComp(k, v, comps)
1308 self._check_comprehension(factory)
1309
1310 def test_yield(self):
Benjamin Peterson527c6222012-01-14 08:58:23 -05001311 self.expr(ast.Yield(ast.Name("x", ast.Store())), "must have Load")
1312 self.expr(ast.YieldFrom(ast.Name("x", ast.Store())), "must have Load")
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001313
1314 def test_compare(self):
1315 left = ast.Name("x", ast.Load())
1316 comp = ast.Compare(left, [ast.In()], [])
1317 self.expr(comp, "no comparators")
1318 comp = ast.Compare(left, [ast.In()], [ast.Num(4), ast.Num(5)])
1319 self.expr(comp, "different number of comparators and operands")
1320 comp = ast.Compare(ast.Num("blah"), [ast.In()], [left])
Serhiy Storchaka3f228112018-09-27 17:42:37 +03001321 self.expr(comp)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001322 comp = ast.Compare(left, [ast.In()], [ast.Num("blah")])
Serhiy Storchaka3f228112018-09-27 17:42:37 +03001323 self.expr(comp)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001324
1325 def test_call(self):
1326 func = ast.Name("x", ast.Load())
1327 args = [ast.Name("y", ast.Load())]
1328 keywords = [ast.keyword("w", ast.Name("z", ast.Load()))]
Benjamin Peterson025e9eb2015-05-05 20:16:41 -04001329 call = ast.Call(ast.Name("x", ast.Store()), args, keywords)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001330 self.expr(call, "must have Load context")
Benjamin Peterson025e9eb2015-05-05 20:16:41 -04001331 call = ast.Call(func, [None], keywords)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001332 self.expr(call, "None disallowed")
1333 bad_keywords = [ast.keyword("w", ast.Name("z", ast.Store()))]
Benjamin Peterson025e9eb2015-05-05 20:16:41 -04001334 call = ast.Call(func, args, bad_keywords)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001335 self.expr(call, "must have Load context")
1336
1337 def test_num(self):
1338 class subint(int):
1339 pass
1340 class subfloat(float):
1341 pass
1342 class subcomplex(complex):
1343 pass
Serhiy Storchaka3f228112018-09-27 17:42:37 +03001344 for obj in "0", "hello":
1345 self.expr(ast.Num(obj))
1346 for obj in subint(), subfloat(), subcomplex():
1347 self.expr(ast.Num(obj), "invalid type", exc=TypeError)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001348
1349 def test_attribute(self):
1350 attr = ast.Attribute(ast.Name("x", ast.Store()), "y", ast.Load())
1351 self.expr(attr, "must have Load context")
1352
1353 def test_subscript(self):
Serhiy Storchaka13d52c22020-03-10 18:52:34 +02001354 sub = ast.Subscript(ast.Name("x", ast.Store()), ast.Num(3),
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001355 ast.Load())
1356 self.expr(sub, "must have Load context")
1357 x = ast.Name("x", ast.Load())
Serhiy Storchaka13d52c22020-03-10 18:52:34 +02001358 sub = ast.Subscript(x, ast.Name("y", ast.Store()),
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001359 ast.Load())
1360 self.expr(sub, "must have Load context")
1361 s = ast.Name("x", ast.Store())
1362 for args in (s, None, None), (None, s, None), (None, None, s):
1363 sl = ast.Slice(*args)
1364 self.expr(ast.Subscript(x, sl, ast.Load()),
1365 "must have Load context")
Serhiy Storchaka13d52c22020-03-10 18:52:34 +02001366 sl = ast.Tuple([], ast.Load())
1367 self.expr(ast.Subscript(x, sl, ast.Load()))
1368 sl = ast.Tuple([s], ast.Load())
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001369 self.expr(ast.Subscript(x, sl, ast.Load()), "must have Load context")
1370
1371 def test_starred(self):
1372 left = ast.List([ast.Starred(ast.Name("x", ast.Load()), ast.Store())],
1373 ast.Store())
1374 assign = ast.Assign([left], ast.Num(4))
1375 self.stmt(assign, "must have Store context")
1376
1377 def _sequence(self, fac):
1378 self.expr(fac([None], ast.Load()), "None disallowed")
1379 self.expr(fac([ast.Name("x", ast.Store())], ast.Load()),
1380 "must have Load context")
1381
1382 def test_list(self):
1383 self._sequence(ast.List)
1384
1385 def test_tuple(self):
1386 self._sequence(ast.Tuple)
1387
Benjamin Peterson442f2092012-12-06 17:41:04 -05001388 def test_nameconstant(self):
Serhiy Storchaka3f228112018-09-27 17:42:37 +03001389 self.expr(ast.NameConstant(4))
Benjamin Peterson442f2092012-12-06 17:41:04 -05001390
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001391 def test_stdlib_validates(self):
1392 stdlib = os.path.dirname(ast.__file__)
1393 tests = [fn for fn in os.listdir(stdlib) if fn.endswith(".py")]
1394 tests.extend(["test/test_grammar.py", "test/test_unpack_ex.py"])
1395 for module in tests:
Serhiy Storchaka3bcbedc2019-01-18 07:47:48 +02001396 with self.subTest(module):
1397 fn = os.path.join(stdlib, module)
1398 with open(fn, "r", encoding="utf-8") as fp:
1399 source = fp.read()
1400 mod = ast.parse(source, fn)
1401 compile(mod, fn, "exec")
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001402
1403
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001404class ConstantTests(unittest.TestCase):
1405 """Tests on the ast.Constant node type."""
1406
1407 def compile_constant(self, value):
1408 tree = ast.parse("x = 123")
1409
1410 node = tree.body[0].value
1411 new_node = ast.Constant(value=value)
1412 ast.copy_location(new_node, node)
1413 tree.body[0].value = new_node
1414
1415 code = compile(tree, "<string>", "exec")
1416
1417 ns = {}
1418 exec(code, ns)
1419 return ns['x']
1420
Victor Stinnerbe59d142016-01-27 00:39:12 +01001421 def test_validation(self):
1422 with self.assertRaises(TypeError) as cm:
1423 self.compile_constant([1, 2, 3])
1424 self.assertEqual(str(cm.exception),
1425 "got an invalid type in Constant: list")
1426
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001427 def test_singletons(self):
1428 for const in (None, False, True, Ellipsis, b'', frozenset()):
1429 with self.subTest(const=const):
1430 value = self.compile_constant(const)
1431 self.assertIs(value, const)
1432
1433 def test_values(self):
1434 nested_tuple = (1,)
1435 nested_frozenset = frozenset({1})
1436 for level in range(3):
1437 nested_tuple = (nested_tuple, 2)
1438 nested_frozenset = frozenset({nested_frozenset, 2})
1439 values = (123, 123.0, 123j,
1440 "unicode", b'bytes',
1441 tuple("tuple"), frozenset("frozenset"),
1442 nested_tuple, nested_frozenset)
1443 for value in values:
1444 with self.subTest(value=value):
1445 result = self.compile_constant(value)
1446 self.assertEqual(result, value)
1447
1448 def test_assign_to_constant(self):
1449 tree = ast.parse("x = 1")
1450
1451 target = tree.body[0].targets[0]
1452 new_target = ast.Constant(value=1)
1453 ast.copy_location(new_target, target)
1454 tree.body[0].targets[0] = new_target
1455
1456 with self.assertRaises(ValueError) as cm:
1457 compile(tree, "string", "exec")
1458 self.assertEqual(str(cm.exception),
1459 "expression which can't be assigned "
1460 "to in Store context")
1461
1462 def test_get_docstring(self):
1463 tree = ast.parse("'docstring'\nx = 1")
1464 self.assertEqual(ast.get_docstring(tree), 'docstring')
1465
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001466 def get_load_const(self, tree):
1467 # Compile to bytecode, disassemble and get parameter of LOAD_CONST
1468 # instructions
1469 co = compile(tree, '<string>', 'exec')
1470 consts = []
1471 for instr in dis.get_instructions(co):
1472 if instr.opname == 'LOAD_CONST':
1473 consts.append(instr.argval)
1474 return consts
1475
1476 @support.cpython_only
1477 def test_load_const(self):
1478 consts = [None,
1479 True, False,
1480 124,
1481 2.0,
1482 3j,
1483 "unicode",
1484 b'bytes',
1485 (1, 2, 3)]
1486
Victor Stinnera2724092016-02-08 18:17:58 +01001487 code = '\n'.join(['x={!r}'.format(const) for const in consts])
1488 code += '\nx = ...'
1489 consts.extend((Ellipsis, None))
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001490
1491 tree = ast.parse(code)
Victor Stinnera2724092016-02-08 18:17:58 +01001492 self.assertEqual(self.get_load_const(tree),
1493 consts)
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001494
1495 # Replace expression nodes with constants
Victor Stinnera2724092016-02-08 18:17:58 +01001496 for assign, const in zip(tree.body, consts):
1497 assert isinstance(assign, ast.Assign), ast.dump(assign)
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001498 new_node = ast.Constant(value=const)
Victor Stinnera2724092016-02-08 18:17:58 +01001499 ast.copy_location(new_node, assign.value)
1500 assign.value = new_node
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001501
Victor Stinnera2724092016-02-08 18:17:58 +01001502 self.assertEqual(self.get_load_const(tree),
1503 consts)
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001504
1505 def test_literal_eval(self):
1506 tree = ast.parse("1 + 2")
1507 binop = tree.body[0].value
1508
1509 new_left = ast.Constant(value=10)
1510 ast.copy_location(new_left, binop.left)
1511 binop.left = new_left
1512
Serhiy Storchakad8ac4d12018-01-04 11:15:39 +02001513 new_right = ast.Constant(value=20j)
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001514 ast.copy_location(new_right, binop.right)
1515 binop.right = new_right
1516
Serhiy Storchakad8ac4d12018-01-04 11:15:39 +02001517 self.assertEqual(ast.literal_eval(binop), 10+20j)
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001518
Guido van Rossum10f8ce62019-03-13 13:00:46 -07001519 def test_string_kind(self):
1520 c = ast.parse('"x"', mode='eval').body
1521 self.assertEqual(c.value, "x")
1522 self.assertEqual(c.kind, None)
1523
1524 c = ast.parse('u"x"', mode='eval').body
1525 self.assertEqual(c.value, "x")
1526 self.assertEqual(c.kind, "u")
1527
1528 c = ast.parse('r"x"', mode='eval').body
1529 self.assertEqual(c.value, "x")
1530 self.assertEqual(c.kind, None)
1531
1532 c = ast.parse('b"x"', mode='eval').body
1533 self.assertEqual(c.value, b"x")
1534 self.assertEqual(c.kind, None)
1535
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001536
Ivan Levkivskyi9932a222019-01-22 11:18:22 +00001537class EndPositionTests(unittest.TestCase):
1538 """Tests for end position of AST nodes.
1539
1540 Testing end positions of nodes requires a bit of extra care
1541 because of how LL parsers work.
1542 """
1543 def _check_end_pos(self, ast_node, end_lineno, end_col_offset):
1544 self.assertEqual(ast_node.end_lineno, end_lineno)
1545 self.assertEqual(ast_node.end_col_offset, end_col_offset)
1546
1547 def _check_content(self, source, ast_node, content):
1548 self.assertEqual(ast.get_source_segment(source, ast_node), content)
1549
1550 def _parse_value(self, s):
1551 # Use duck-typing to support both single expression
1552 # and a right hand side of an assignment statement.
1553 return ast.parse(s).body[0].value
1554
1555 def test_lambda(self):
1556 s = 'lambda x, *y: None'
1557 lam = self._parse_value(s)
1558 self._check_content(s, lam.body, 'None')
1559 self._check_content(s, lam.args.args[0], 'x')
1560 self._check_content(s, lam.args.vararg, 'y')
1561
1562 def test_func_def(self):
1563 s = dedent('''
1564 def func(x: int,
1565 *args: str,
1566 z: float = 0,
1567 **kwargs: Any) -> bool:
1568 return True
1569 ''').strip()
1570 fdef = ast.parse(s).body[0]
1571 self._check_end_pos(fdef, 5, 15)
1572 self._check_content(s, fdef.body[0], 'return True')
1573 self._check_content(s, fdef.args.args[0], 'x: int')
1574 self._check_content(s, fdef.args.args[0].annotation, 'int')
1575 self._check_content(s, fdef.args.kwarg, 'kwargs: Any')
1576 self._check_content(s, fdef.args.kwarg.annotation, 'Any')
1577
1578 def test_call(self):
1579 s = 'func(x, y=2, **kw)'
1580 call = self._parse_value(s)
1581 self._check_content(s, call.func, 'func')
1582 self._check_content(s, call.keywords[0].value, '2')
1583 self._check_content(s, call.keywords[1].value, 'kw')
1584
1585 def test_call_noargs(self):
1586 s = 'x[0]()'
1587 call = self._parse_value(s)
1588 self._check_content(s, call.func, 'x[0]')
1589 self._check_end_pos(call, 1, 6)
1590
1591 def test_class_def(self):
1592 s = dedent('''
1593 class C(A, B):
1594 x: int = 0
1595 ''').strip()
1596 cdef = ast.parse(s).body[0]
1597 self._check_end_pos(cdef, 2, 14)
1598 self._check_content(s, cdef.bases[1], 'B')
1599 self._check_content(s, cdef.body[0], 'x: int = 0')
1600
1601 def test_class_kw(self):
1602 s = 'class S(metaclass=abc.ABCMeta): pass'
1603 cdef = ast.parse(s).body[0]
1604 self._check_content(s, cdef.keywords[0].value, 'abc.ABCMeta')
1605
1606 def test_multi_line_str(self):
1607 s = dedent('''
1608 x = """Some multi-line text.
1609
1610 It goes on starting from same indent."""
1611 ''').strip()
1612 assign = ast.parse(s).body[0]
1613 self._check_end_pos(assign, 3, 40)
1614 self._check_end_pos(assign.value, 3, 40)
1615
1616 def test_continued_str(self):
1617 s = dedent('''
1618 x = "first part" \\
1619 "second part"
1620 ''').strip()
1621 assign = ast.parse(s).body[0]
1622 self._check_end_pos(assign, 2, 13)
1623 self._check_end_pos(assign.value, 2, 13)
1624
1625 def test_suites(self):
1626 # We intentionally put these into the same string to check
1627 # that empty lines are not part of the suite.
1628 s = dedent('''
1629 while True:
1630 pass
1631
1632 if one():
1633 x = None
1634 elif other():
1635 y = None
1636 else:
1637 z = None
1638
1639 for x, y in stuff:
1640 assert True
1641
1642 try:
1643 raise RuntimeError
1644 except TypeError as e:
1645 pass
1646
1647 pass
1648 ''').strip()
1649 mod = ast.parse(s)
1650 while_loop = mod.body[0]
1651 if_stmt = mod.body[1]
1652 for_loop = mod.body[2]
1653 try_stmt = mod.body[3]
1654 pass_stmt = mod.body[4]
1655
1656 self._check_end_pos(while_loop, 2, 8)
1657 self._check_end_pos(if_stmt, 9, 12)
1658 self._check_end_pos(for_loop, 12, 15)
1659 self._check_end_pos(try_stmt, 17, 8)
1660 self._check_end_pos(pass_stmt, 19, 4)
1661
1662 self._check_content(s, while_loop.test, 'True')
1663 self._check_content(s, if_stmt.body[0], 'x = None')
1664 self._check_content(s, if_stmt.orelse[0].test, 'other()')
1665 self._check_content(s, for_loop.target, 'x, y')
1666 self._check_content(s, try_stmt.body[0], 'raise RuntimeError')
1667 self._check_content(s, try_stmt.handlers[0].type, 'TypeError')
1668
1669 def test_fstring(self):
1670 s = 'x = f"abc {x + y} abc"'
1671 fstr = self._parse_value(s)
1672 binop = fstr.values[1].value
1673 self._check_content(s, binop, 'x + y')
1674
1675 def test_fstring_multi_line(self):
1676 s = dedent('''
1677 f"""Some multi-line text.
1678 {
1679 arg_one
1680 +
1681 arg_two
1682 }
1683 It goes on..."""
1684 ''').strip()
1685 fstr = self._parse_value(s)
1686 binop = fstr.values[1].value
1687 self._check_end_pos(binop, 5, 7)
1688 self._check_content(s, binop.left, 'arg_one')
1689 self._check_content(s, binop.right, 'arg_two')
1690
1691 def test_import_from_multi_line(self):
1692 s = dedent('''
1693 from x.y.z import (
1694 a, b, c as c
1695 )
1696 ''').strip()
1697 imp = ast.parse(s).body[0]
1698 self._check_end_pos(imp, 3, 1)
1699
1700 def test_slices(self):
1701 s1 = 'f()[1, 2] [0]'
1702 s2 = 'x[ a.b: c.d]'
1703 sm = dedent('''
1704 x[ a.b: f () ,
1705 g () : c.d
1706 ]
1707 ''').strip()
1708 i1, i2, im = map(self._parse_value, (s1, s2, sm))
1709 self._check_content(s1, i1.value, 'f()[1, 2]')
Serhiy Storchaka13d52c22020-03-10 18:52:34 +02001710 self._check_content(s1, i1.value.slice, '1, 2')
Ivan Levkivskyi9932a222019-01-22 11:18:22 +00001711 self._check_content(s2, i2.slice.lower, 'a.b')
1712 self._check_content(s2, i2.slice.upper, 'c.d')
Serhiy Storchaka13d52c22020-03-10 18:52:34 +02001713 self._check_content(sm, im.slice.elts[0].upper, 'f ()')
1714 self._check_content(sm, im.slice.elts[1].lower, 'g ()')
Ivan Levkivskyi9932a222019-01-22 11:18:22 +00001715 self._check_end_pos(im, 3, 3)
1716
1717 def test_binop(self):
1718 s = dedent('''
1719 (1 * 2 + (3 ) +
1720 4
1721 )
1722 ''').strip()
1723 binop = self._parse_value(s)
1724 self._check_end_pos(binop, 2, 6)
1725 self._check_content(s, binop.right, '4')
1726 self._check_content(s, binop.left, '1 * 2 + (3 )')
1727 self._check_content(s, binop.left.right, '3')
1728
1729 def test_boolop(self):
1730 s = dedent('''
1731 if (one_condition and
1732 (other_condition or yet_another_one)):
1733 pass
1734 ''').strip()
1735 bop = ast.parse(s).body[0].test
1736 self._check_end_pos(bop, 2, 44)
1737 self._check_content(s, bop.values[1],
1738 'other_condition or yet_another_one')
1739
1740 def test_tuples(self):
1741 s1 = 'x = () ;'
1742 s2 = 'x = 1 , ;'
1743 s3 = 'x = (1 , 2 ) ;'
1744 sm = dedent('''
1745 x = (
1746 a, b,
1747 )
1748 ''').strip()
1749 t1, t2, t3, tm = map(self._parse_value, (s1, s2, s3, sm))
1750 self._check_content(s1, t1, '()')
1751 self._check_content(s2, t2, '1 ,')
1752 self._check_content(s3, t3, '(1 , 2 )')
1753 self._check_end_pos(tm, 3, 1)
1754
1755 def test_attribute_spaces(self):
1756 s = 'func(x. y .z)'
1757 call = self._parse_value(s)
1758 self._check_content(s, call, s)
1759 self._check_content(s, call.args[0], 'x. y .z')
1760
Serhiy Storchaka6e619c42020-02-12 22:37:49 +02001761 def test_redundant_parenthesis(self):
1762 s = '( ( ( a + b ) ) )'
1763 v = ast.parse(s).body[0].value
1764 self.assertEqual(type(v).__name__, 'BinOp')
1765 self._check_content(s, v, 'a + b')
1766 s2 = 'await ' + s
1767 v = ast.parse(s2).body[0].value.value
1768 self.assertEqual(type(v).__name__, 'BinOp')
1769 self._check_content(s2, v, 'a + b')
1770
1771 def test_trailers_with_redundant_parenthesis(self):
1772 tests = (
1773 ('( ( ( a ) ) ) ( )', 'Call'),
1774 ('( ( ( a ) ) ) ( b )', 'Call'),
1775 ('( ( ( a ) ) ) [ b ]', 'Subscript'),
1776 ('( ( ( a ) ) ) . b', 'Attribute'),
1777 )
1778 for s, t in tests:
1779 with self.subTest(s):
1780 v = ast.parse(s).body[0].value
1781 self.assertEqual(type(v).__name__, t)
1782 self._check_content(s, v, s)
1783 s2 = 'await ' + s
1784 v = ast.parse(s2).body[0].value.value
1785 self.assertEqual(type(v).__name__, t)
1786 self._check_content(s2, v, s)
1787
Ivan Levkivskyi9932a222019-01-22 11:18:22 +00001788 def test_displays(self):
1789 s1 = '[{}, {1, }, {1, 2,} ]'
1790 s2 = '{a: b, f (): g () ,}'
1791 c1 = self._parse_value(s1)
1792 c2 = self._parse_value(s2)
1793 self._check_content(s1, c1.elts[0], '{}')
1794 self._check_content(s1, c1.elts[1], '{1, }')
1795 self._check_content(s1, c1.elts[2], '{1, 2,}')
1796 self._check_content(s2, c2.keys[1], 'f ()')
1797 self._check_content(s2, c2.values[1], 'g ()')
1798
1799 def test_comprehensions(self):
1800 s = dedent('''
1801 x = [{x for x, y in stuff
1802 if cond.x} for stuff in things]
1803 ''').strip()
1804 cmp = self._parse_value(s)
1805 self._check_end_pos(cmp, 2, 37)
1806 self._check_content(s, cmp.generators[0].iter, 'things')
1807 self._check_content(s, cmp.elt.generators[0].iter, 'stuff')
1808 self._check_content(s, cmp.elt.generators[0].ifs[0], 'cond.x')
1809 self._check_content(s, cmp.elt.generators[0].target, 'x, y')
1810
1811 def test_yield_await(self):
1812 s = dedent('''
1813 async def f():
1814 yield x
1815 await y
1816 ''').strip()
1817 fdef = ast.parse(s).body[0]
1818 self._check_content(s, fdef.body[0].value, 'yield x')
1819 self._check_content(s, fdef.body[1].value, 'await y')
1820
1821 def test_source_segment_multi(self):
1822 s_orig = dedent('''
1823 x = (
1824 a, b,
1825 ) + ()
1826 ''').strip()
1827 s_tuple = dedent('''
1828 (
1829 a, b,
1830 )
1831 ''').strip()
1832 binop = self._parse_value(s_orig)
1833 self.assertEqual(ast.get_source_segment(s_orig, binop.left), s_tuple)
1834
1835 def test_source_segment_padded(self):
1836 s_orig = dedent('''
1837 class C:
1838 def fun(self) -> None:
1839 "Đ–Đ–Đ–Đ–Đ–"
1840 ''').strip()
1841 s_method = ' def fun(self) -> None:\n' \
1842 ' "Đ–Đ–Đ–Đ–Đ–"'
1843 cdef = ast.parse(s_orig).body[0]
1844 self.assertEqual(ast.get_source_segment(s_orig, cdef.body[0], padded=True),
1845 s_method)
1846
1847 def test_source_segment_endings(self):
1848 s = 'v = 1\r\nw = 1\nx = 1\n\ry = 1\rz = 1\r\n'
1849 v, w, x, y, z = ast.parse(s).body
1850 self._check_content(s, v, 'v = 1')
1851 self._check_content(s, w, 'w = 1')
1852 self._check_content(s, x, 'x = 1')
1853 self._check_content(s, y, 'y = 1')
1854 self._check_content(s, z, 'z = 1')
1855
1856 def test_source_segment_tabs(self):
1857 s = dedent('''
1858 class C:
1859 \t\f def fun(self) -> None:
1860 \t\f pass
1861 ''').strip()
1862 s_method = ' \t\f def fun(self) -> None:\n' \
1863 ' \t\f pass'
1864
1865 cdef = ast.parse(s).body[0]
1866 self.assertEqual(ast.get_source_segment(s, cdef.body[0], padded=True), s_method)
1867
Irit Katriele6578a22020-05-18 19:14:12 +01001868 def test_source_segment_missing_info(self):
1869 s = 'v = 1\r\nw = 1\nx = 1\n\ry = 1\r\n'
1870 v, w, x, y = ast.parse(s).body
1871 del v.lineno
1872 del w.end_lineno
1873 del x.col_offset
1874 del y.end_col_offset
1875 self.assertIsNone(ast.get_source_segment(s, v))
1876 self.assertIsNone(ast.get_source_segment(s, w))
1877 self.assertIsNone(ast.get_source_segment(s, x))
1878 self.assertIsNone(ast.get_source_segment(s, y))
Ivan Levkivskyi9932a222019-01-22 11:18:22 +00001879
Serhiy Storchakac3ea41e2019-08-26 10:13:19 +03001880class NodeVisitorTests(unittest.TestCase):
1881 def test_old_constant_nodes(self):
1882 class Visitor(ast.NodeVisitor):
1883 def visit_Num(self, node):
1884 log.append((node.lineno, 'Num', node.n))
1885 def visit_Str(self, node):
1886 log.append((node.lineno, 'Str', node.s))
1887 def visit_Bytes(self, node):
1888 log.append((node.lineno, 'Bytes', node.s))
1889 def visit_NameConstant(self, node):
1890 log.append((node.lineno, 'NameConstant', node.value))
1891 def visit_Ellipsis(self, node):
1892 log.append((node.lineno, 'Ellipsis', ...))
1893 mod = ast.parse(dedent('''\
1894 i = 42
1895 f = 4.25
1896 c = 4.25j
1897 s = 'string'
1898 b = b'bytes'
1899 t = True
1900 n = None
1901 e = ...
1902 '''))
1903 visitor = Visitor()
1904 log = []
1905 with warnings.catch_warnings(record=True) as wlog:
1906 warnings.filterwarnings('always', '', DeprecationWarning)
1907 visitor.visit(mod)
1908 self.assertEqual(log, [
1909 (1, 'Num', 42),
1910 (2, 'Num', 4.25),
1911 (3, 'Num', 4.25j),
1912 (4, 'Str', 'string'),
1913 (5, 'Bytes', b'bytes'),
1914 (6, 'NameConstant', True),
1915 (7, 'NameConstant', None),
1916 (8, 'Ellipsis', ...),
1917 ])
1918 self.assertEqual([str(w.message) for w in wlog], [
1919 'visit_Num is deprecated; add visit_Constant',
1920 'visit_Num is deprecated; add visit_Constant',
1921 'visit_Num is deprecated; add visit_Constant',
1922 'visit_Str is deprecated; add visit_Constant',
1923 'visit_Bytes is deprecated; add visit_Constant',
1924 'visit_NameConstant is deprecated; add visit_Constant',
1925 'visit_NameConstant is deprecated; add visit_Constant',
1926 'visit_Ellipsis is deprecated; add visit_Constant',
1927 ])
1928
1929
Neal Norwitzee9b10a2008-03-31 05:29:39 +00001930def main():
1931 if __name__ != '__main__':
Martin v. Löwis49c5da12006-03-01 22:49:05 +00001932 return
Neal Norwitzee9b10a2008-03-31 05:29:39 +00001933 if sys.argv[1:] == ['-g']:
1934 for statements, kind in ((exec_tests, "exec"), (single_tests, "single"),
1935 (eval_tests, "eval")):
1936 print(kind+"_results = [")
Victor Stinnerf0891962016-02-08 17:15:21 +01001937 for statement in statements:
1938 tree = ast.parse(statement, "?", kind)
1939 print("%r," % (to_tuple(tree),))
Neal Norwitzee9b10a2008-03-31 05:29:39 +00001940 print("]")
1941 print("main()")
1942 raise SystemExit
Brett Cannon3e9a9ae2013-06-12 21:25:59 -04001943 unittest.main()
Tim Peters400cbc32006-02-28 18:44:41 +00001944
Guido van Rossumdcfcd142019-01-31 03:40:27 -08001945#### EVERYTHING BELOW IS GENERATED BY python Lib/test/test_ast.py -g #####
Tim Peters400cbc32006-02-28 18:44:41 +00001946exec_results = [
Serhiy Storchaka850a8852020-01-10 10:12:55 +02001947('Module', [('Expr', (1, 0, 1, 4), ('Constant', (1, 0, 1, 4), None, None))], []),
1948('Module', [('Expr', (1, 0, 1, 18), ('Constant', (1, 0, 1, 18), 'module docstring', None))], []),
1949('Module', [('FunctionDef', (1, 0, 1, 13), 'f', ('arguments', [], [], None, [], [], None, []), [('Pass', (1, 9, 1, 13))], [], None, None)], []),
1950('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)], []),
1951('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)], []),
1952('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)], []),
1953('Module', [('FunctionDef', (1, 0, 1, 18), 'f', ('arguments', [], [], ('arg', (1, 7, 1, 11), 'args', None, None), [], [], None, []), [('Pass', (1, 14, 1, 18))], [], None, None)], []),
1954('Module', [('FunctionDef', (1, 0, 1, 21), 'f', ('arguments', [], [], None, [], [], ('arg', (1, 8, 1, 14), 'kwargs', None, None), []), [('Pass', (1, 17, 1, 21))], [], None, None)], []),
1955('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)], []),
1956('Module', [('ClassDef', (1, 0, 1, 12), 'C', [], [], [('Pass', (1, 8, 1, 12))], [])], []),
1957('Module', [('ClassDef', (1, 0, 1, 32), 'C', [], [], [('Expr', (1, 9, 1, 32), ('Constant', (1, 9, 1, 32), 'docstring for class C', None))], [])], []),
1958('Module', [('ClassDef', (1, 0, 1, 21), 'C', [('Name', (1, 8, 1, 14), 'object', ('Load',))], [], [('Pass', (1, 17, 1, 21))], [])], []),
1959('Module', [('FunctionDef', (1, 0, 1, 16), 'f', ('arguments', [], [], None, [], [], None, []), [('Return', (1, 8, 1, 16), ('Constant', (1, 15, 1, 16), 1, None))], [], None, None)], []),
1960('Module', [('Delete', (1, 0, 1, 5), [('Name', (1, 4, 1, 5), 'v', ('Del',))])], []),
1961('Module', [('Assign', (1, 0, 1, 5), [('Name', (1, 0, 1, 1), 'v', ('Store',))], ('Constant', (1, 4, 1, 5), 1, None), None)], []),
1962('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)], []),
1963('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)], []),
1964('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)], []),
1965('Module', [('AugAssign', (1, 0, 1, 6), ('Name', (1, 0, 1, 1), 'v', ('Store',)), ('Add',), ('Constant', (1, 5, 1, 6), 1, None))], []),
1966('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)], []),
1967('Module', [('While', (1, 0, 1, 12), ('Name', (1, 6, 1, 7), 'v', ('Load',)), [('Pass', (1, 8, 1, 12))], [])], []),
1968('Module', [('If', (1, 0, 1, 9), ('Name', (1, 3, 1, 4), 'v', ('Load',)), [('Pass', (1, 5, 1, 9))], [])], []),
1969('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))], [])])], []),
1970('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))])])], []),
1971('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)], []),
1972('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)], []),
1973('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)], []),
1974('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))])], [], [])], []),
1975('Module', [('Try', (1, 0, 4, 6), [('Pass', (2, 2, 2, 6))], [], [], [('Pass', (4, 2, 4, 6))])], []),
1976('Module', [('Assert', (1, 0, 1, 8), ('Name', (1, 7, 1, 8), 'v', ('Load',)), None)], []),
1977('Module', [('Import', (1, 0, 1, 10), [('alias', 'sys', None)])], []),
1978('Module', [('ImportFrom', (1, 0, 1, 17), 'sys', [('alias', 'v', None)], 0)], []),
1979('Module', [('Global', (1, 0, 1, 8), ['v'])], []),
1980('Module', [('Expr', (1, 0, 1, 1), ('Constant', (1, 0, 1, 1), 1, None))], []),
1981('Module', [('Pass', (1, 0, 1, 4))], []),
1982('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)], []),
1983('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)], []),
1984('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)], []),
1985('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)], []),
1986('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)], []),
1987('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)]))], []),
1988('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)]))], []),
1989('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)]))], []),
1990('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)]))], []),
1991('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)]))], []),
1992('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)], []),
1993('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)], []),
1994('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)], []),
1995('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)]))], []),
1996('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)]))], []),
1997('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)], []),
1998('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)], []),
1999('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)], []),
2000('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)], [])])], []),
2001('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 +01002002('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 +02002003('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)))], []),
2004('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)], []),
2005('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)], []),
2006('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)], []),
2007('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)], []),
2008('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)], []),
2009('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)], []),
2010('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)], []),
2011('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)], []),
2012('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)], []),
2013('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 +00002014]
2015single_results = [
Serhiy Storchaka850a8852020-01-10 10:12:55 +02002016('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 +00002017]
2018eval_results = [
Serhiy Storchaka850a8852020-01-10 10:12:55 +02002019('Expression', ('Constant', (1, 0, 1, 4), None, None)),
2020('Expression', ('BoolOp', (1, 0, 1, 7), ('And',), [('Name', (1, 0, 1, 1), 'a', ('Load',)), ('Name', (1, 6, 1, 7), 'b', ('Load',))])),
2021('Expression', ('BinOp', (1, 0, 1, 5), ('Name', (1, 0, 1, 1), 'a', ('Load',)), ('Add',), ('Name', (1, 4, 1, 5), 'b', ('Load',)))),
2022('Expression', ('UnaryOp', (1, 0, 1, 5), ('Not',), ('Name', (1, 4, 1, 5), 'v', ('Load',)))),
2023('Expression', ('Lambda', (1, 0, 1, 11), ('arguments', [], [], None, [], [], None, []), ('Constant', (1, 7, 1, 11), None, None))),
2024('Expression', ('Dict', (1, 0, 1, 7), [('Constant', (1, 2, 1, 3), 1, None)], [('Constant', (1, 4, 1, 5), 2, None)])),
2025('Expression', ('Dict', (1, 0, 1, 2), [], [])),
2026('Expression', ('Set', (1, 0, 1, 7), [('Constant', (1, 1, 1, 5), None, None)])),
2027('Expression', ('Dict', (1, 0, 5, 6), [('Constant', (2, 6, 2, 7), 1, None)], [('Constant', (4, 10, 4, 11), 2, None)])),
2028('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)])),
2029('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)])),
2030('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)])),
2031('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)])),
2032('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)])),
2033('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)])),
2034('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)])),
2035('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)])),
2036('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)])),
2037('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)])),
2038('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)])),
2039('Expression', ('Compare', (1, 0, 1, 9), ('Constant', (1, 0, 1, 1), 1, None), [('Lt',), ('Lt',)], [('Constant', (1, 4, 1, 5), 2, None), ('Constant', (1, 8, 1, 9), 3, None)])),
Pablo Galindo40cf35c2020-04-03 21:02:26 +01002040('Expression', ('Call', (1, 0, 1, 17), ('Name', (1, 0, 1, 1), 'f', ('Load',)), [('Constant', (1, 2, 1, 3), 1, None), ('Constant', (1, 4, 1, 5), 2, None), ('Starred', (1, 10, 1, 12), ('Name', (1, 11, 1, 12), 'd', ('Load',)), ('Load',))], [('keyword', (1, 6, 1, 9), 'c', ('Constant', (1, 8, 1, 9), 3, None)), ('keyword', (1, 13, 1, 16), None, ('Name', (1, 15, 1, 16), 'e', ('Load',)))])),
Serhiy Storchaka850a8852020-01-10 10:12:55 +02002041('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',))], [])),
2042('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)])], [])),
2043('Expression', ('Constant', (1, 0, 1, 2), 10, None)),
2044('Expression', ('Constant', (1, 0, 1, 8), 'string', None)),
2045('Expression', ('Attribute', (1, 0, 1, 3), ('Name', (1, 0, 1, 1), 'a', ('Load',)), 'b', ('Load',))),
Serhiy Storchaka13d52c22020-03-10 18:52:34 +02002046('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 +02002047('Expression', ('Name', (1, 0, 1, 1), 'v', ('Load',))),
2048('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',))),
2049('Expression', ('List', (1, 0, 1, 2), [], ('Load',))),
2050('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',))),
2051('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',))),
2052('Expression', ('Tuple', (1, 0, 1, 2), [], ('Load',))),
Serhiy Storchaka13d52c22020-03-10 18:52:34 +02002053('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 +00002054]
Neal Norwitzee9b10a2008-03-31 05:29:39 +00002055main()