blob: 3e9c8b55cdff421d38c3352cac5889f1c76c373b [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
666
Georg Brandl0c77a822008-06-10 16:37:50 +0000667class ASTHelpers_Test(unittest.TestCase):
Guido van Rossum10f8ce62019-03-13 13:00:46 -0700668 maxDiff = None
Georg Brandl0c77a822008-06-10 16:37:50 +0000669
670 def test_parse(self):
671 a = ast.parse('foo(1 + 1)')
672 b = compile('foo(1 + 1)', '<unknown>', 'exec', ast.PyCF_ONLY_AST)
673 self.assertEqual(ast.dump(a), ast.dump(b))
674
Benjamin Peterson2e2c9032012-09-02 14:23:15 -0400675 def test_parse_in_error(self):
676 try:
677 1/0
678 except Exception:
Benjamin Petersonbd0df502012-09-02 15:04:51 -0400679 with self.assertRaises(SyntaxError) as e:
680 ast.literal_eval(r"'\U'")
681 self.assertIsNotNone(e.exception.__context__)
Benjamin Peterson2e2c9032012-09-02 14:23:15 -0400682
Georg Brandl0c77a822008-06-10 16:37:50 +0000683 def test_dump(self):
684 node = ast.parse('spam(eggs, "and cheese")')
685 self.assertEqual(ast.dump(node),
686 "Module(body=[Expr(value=Call(func=Name(id='spam', ctx=Load()), "
Serhiy Storchakab7e95252020-03-10 00:07:47 +0200687 "args=[Name(id='eggs', ctx=Load()), Constant(value='and cheese')], "
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800688 "keywords=[]))], type_ignores=[])"
Georg Brandl0c77a822008-06-10 16:37:50 +0000689 )
690 self.assertEqual(ast.dump(node, annotate_fields=False),
691 "Module([Expr(Call(Name('spam', Load()), [Name('eggs', Load()), "
Serhiy Storchakab7e95252020-03-10 00:07:47 +0200692 "Constant('and cheese')], []))], [])"
Georg Brandl0c77a822008-06-10 16:37:50 +0000693 )
694 self.assertEqual(ast.dump(node, include_attributes=True),
695 "Module(body=[Expr(value=Call(func=Name(id='spam', ctx=Load(), "
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000696 "lineno=1, col_offset=0, end_lineno=1, end_col_offset=4), "
697 "args=[Name(id='eggs', ctx=Load(), lineno=1, col_offset=5, "
Serhiy Storchakab7e95252020-03-10 00:07:47 +0200698 "end_lineno=1, end_col_offset=9), Constant(value='and cheese', "
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000699 "lineno=1, col_offset=11, end_lineno=1, end_col_offset=23)], keywords=[], "
700 "lineno=1, col_offset=0, end_lineno=1, end_col_offset=24), "
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800701 "lineno=1, col_offset=0, end_lineno=1, end_col_offset=24)], type_ignores=[])"
Georg Brandl0c77a822008-06-10 16:37:50 +0000702 )
703
Serhiy Storchaka850573b2019-09-09 19:33:13 +0300704 def test_dump_indent(self):
705 node = ast.parse('spam(eggs, "and cheese")')
706 self.assertEqual(ast.dump(node, indent=3), """\
707Module(
708 body=[
709 Expr(
710 value=Call(
711 func=Name(id='spam', ctx=Load()),
712 args=[
713 Name(id='eggs', ctx=Load()),
Serhiy Storchakab7e95252020-03-10 00:07:47 +0200714 Constant(value='and cheese')],
Serhiy Storchaka850573b2019-09-09 19:33:13 +0300715 keywords=[]))],
716 type_ignores=[])""")
717 self.assertEqual(ast.dump(node, annotate_fields=False, indent='\t'), """\
718Module(
719\t[
720\t\tExpr(
721\t\t\tCall(
722\t\t\t\tName('spam', Load()),
723\t\t\t\t[
724\t\t\t\t\tName('eggs', Load()),
Serhiy Storchakab7e95252020-03-10 00:07:47 +0200725\t\t\t\t\tConstant('and cheese')],
Serhiy Storchaka850573b2019-09-09 19:33:13 +0300726\t\t\t\t[]))],
727\t[])""")
728 self.assertEqual(ast.dump(node, include_attributes=True, indent=3), """\
729Module(
730 body=[
731 Expr(
732 value=Call(
733 func=Name(
734 id='spam',
735 ctx=Load(),
736 lineno=1,
737 col_offset=0,
738 end_lineno=1,
739 end_col_offset=4),
740 args=[
741 Name(
742 id='eggs',
743 ctx=Load(),
744 lineno=1,
745 col_offset=5,
746 end_lineno=1,
747 end_col_offset=9),
748 Constant(
749 value='and cheese',
Serhiy Storchaka850573b2019-09-09 19:33:13 +0300750 lineno=1,
751 col_offset=11,
752 end_lineno=1,
753 end_col_offset=23)],
754 keywords=[],
755 lineno=1,
756 col_offset=0,
757 end_lineno=1,
758 end_col_offset=24),
759 lineno=1,
760 col_offset=0,
761 end_lineno=1,
762 end_col_offset=24)],
763 type_ignores=[])""")
764
Serhiy Storchakae64f9482019-08-29 09:30:23 +0300765 def test_dump_incomplete(self):
766 node = ast.Raise(lineno=3, col_offset=4)
767 self.assertEqual(ast.dump(node),
768 "Raise()"
769 )
770 self.assertEqual(ast.dump(node, include_attributes=True),
771 "Raise(lineno=3, col_offset=4)"
772 )
773 node = ast.Raise(exc=ast.Name(id='e', ctx=ast.Load()), lineno=3, col_offset=4)
774 self.assertEqual(ast.dump(node),
775 "Raise(exc=Name(id='e', ctx=Load()))"
776 )
777 self.assertEqual(ast.dump(node, annotate_fields=False),
778 "Raise(Name('e', Load()))"
779 )
780 self.assertEqual(ast.dump(node, include_attributes=True),
781 "Raise(exc=Name(id='e', ctx=Load()), lineno=3, col_offset=4)"
782 )
783 self.assertEqual(ast.dump(node, annotate_fields=False, include_attributes=True),
784 "Raise(Name('e', Load()), lineno=3, col_offset=4)"
785 )
786 node = ast.Raise(cause=ast.Name(id='e', ctx=ast.Load()))
787 self.assertEqual(ast.dump(node),
788 "Raise(cause=Name(id='e', ctx=Load()))"
789 )
790 self.assertEqual(ast.dump(node, annotate_fields=False),
791 "Raise(cause=Name('e', Load()))"
792 )
793
Georg Brandl0c77a822008-06-10 16:37:50 +0000794 def test_copy_location(self):
795 src = ast.parse('1 + 1', mode='eval')
796 src.body.right = ast.copy_location(ast.Num(2), src.body.right)
797 self.assertEqual(ast.dump(src, include_attributes=True),
Serhiy Storchakab7e95252020-03-10 00:07:47 +0200798 'Expression(body=BinOp(left=Constant(value=1, lineno=1, col_offset=0, '
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000799 'end_lineno=1, end_col_offset=1), op=Add(), right=Constant(value=2, '
800 'lineno=1, col_offset=4, end_lineno=1, end_col_offset=5), lineno=1, '
801 'col_offset=0, end_lineno=1, end_col_offset=5))'
Georg Brandl0c77a822008-06-10 16:37:50 +0000802 )
803
804 def test_fix_missing_locations(self):
805 src = ast.parse('write("spam")')
806 src.body.append(ast.Expr(ast.Call(ast.Name('spam', ast.Load()),
Benjamin Peterson025e9eb2015-05-05 20:16:41 -0400807 [ast.Str('eggs')], [])))
Georg Brandl0c77a822008-06-10 16:37:50 +0000808 self.assertEqual(src, ast.fix_missing_locations(src))
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000809 self.maxDiff = None
Georg Brandl0c77a822008-06-10 16:37:50 +0000810 self.assertEqual(ast.dump(src, include_attributes=True),
811 "Module(body=[Expr(value=Call(func=Name(id='write', ctx=Load(), "
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000812 "lineno=1, col_offset=0, end_lineno=1, end_col_offset=5), "
Serhiy Storchakab7e95252020-03-10 00:07:47 +0200813 "args=[Constant(value='spam', lineno=1, col_offset=6, end_lineno=1, "
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000814 "end_col_offset=12)], keywords=[], lineno=1, col_offset=0, end_lineno=1, "
815 "end_col_offset=13), lineno=1, col_offset=0, end_lineno=1, "
816 "end_col_offset=13), Expr(value=Call(func=Name(id='spam', ctx=Load(), "
817 "lineno=1, col_offset=0, end_lineno=1, end_col_offset=0), "
818 "args=[Constant(value='eggs', lineno=1, col_offset=0, end_lineno=1, "
819 "end_col_offset=0)], keywords=[], lineno=1, col_offset=0, end_lineno=1, "
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800820 "end_col_offset=0), lineno=1, col_offset=0, end_lineno=1, end_col_offset=0)], "
821 "type_ignores=[])"
Georg Brandl0c77a822008-06-10 16:37:50 +0000822 )
823
824 def test_increment_lineno(self):
825 src = ast.parse('1 + 1', mode='eval')
826 self.assertEqual(ast.increment_lineno(src, n=3), src)
827 self.assertEqual(ast.dump(src, include_attributes=True),
Serhiy Storchakab7e95252020-03-10 00:07:47 +0200828 'Expression(body=BinOp(left=Constant(value=1, lineno=4, col_offset=0, '
829 'end_lineno=4, end_col_offset=1), op=Add(), right=Constant(value=1, '
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000830 'lineno=4, col_offset=4, end_lineno=4, end_col_offset=5), lineno=4, '
831 'col_offset=0, end_lineno=4, end_col_offset=5))'
Georg Brandl0c77a822008-06-10 16:37:50 +0000832 )
Georg Brandl619e7ba2011-01-09 07:38:51 +0000833 # issue10869: do not increment lineno of root twice
Georg Brandlefb69022011-01-09 07:50:48 +0000834 src = ast.parse('1 + 1', mode='eval')
Georg Brandl619e7ba2011-01-09 07:38:51 +0000835 self.assertEqual(ast.increment_lineno(src.body, n=3), src.body)
836 self.assertEqual(ast.dump(src, include_attributes=True),
Serhiy Storchakab7e95252020-03-10 00:07:47 +0200837 'Expression(body=BinOp(left=Constant(value=1, lineno=4, col_offset=0, '
838 'end_lineno=4, end_col_offset=1), op=Add(), right=Constant(value=1, '
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000839 'lineno=4, col_offset=4, end_lineno=4, end_col_offset=5), lineno=4, '
840 'col_offset=0, end_lineno=4, end_col_offset=5))'
Georg Brandl619e7ba2011-01-09 07:38:51 +0000841 )
Georg Brandl0c77a822008-06-10 16:37:50 +0000842
843 def test_iter_fields(self):
844 node = ast.parse('foo()', mode='eval')
845 d = dict(ast.iter_fields(node.body))
846 self.assertEqual(d.pop('func').id, 'foo')
Benjamin Peterson025e9eb2015-05-05 20:16:41 -0400847 self.assertEqual(d, {'keywords': [], 'args': []})
Georg Brandl0c77a822008-06-10 16:37:50 +0000848
849 def test_iter_child_nodes(self):
850 node = ast.parse("spam(23, 42, eggs='leek')", mode='eval')
851 self.assertEqual(len(list(ast.iter_child_nodes(node.body))), 4)
852 iterator = ast.iter_child_nodes(node.body)
853 self.assertEqual(next(iterator).id, 'spam')
Serhiy Storchaka3f228112018-09-27 17:42:37 +0300854 self.assertEqual(next(iterator).value, 23)
855 self.assertEqual(next(iterator).value, 42)
Georg Brandl0c77a822008-06-10 16:37:50 +0000856 self.assertEqual(ast.dump(next(iterator)),
Serhiy Storchakab7e95252020-03-10 00:07:47 +0200857 "keyword(arg='eggs', value=Constant(value='leek'))"
Georg Brandl0c77a822008-06-10 16:37:50 +0000858 )
859
860 def test_get_docstring(self):
Serhiy Storchaka08f127a2018-06-15 11:05:15 +0300861 node = ast.parse('"""line one\n line two"""')
862 self.assertEqual(ast.get_docstring(node),
863 'line one\nline two')
864
865 node = ast.parse('class foo:\n """line one\n line two"""')
866 self.assertEqual(ast.get_docstring(node.body[0]),
867 'line one\nline two')
868
Georg Brandl0c77a822008-06-10 16:37:50 +0000869 node = ast.parse('def foo():\n """line one\n line two"""')
870 self.assertEqual(ast.get_docstring(node.body[0]),
871 'line one\nline two')
872
Yury Selivanov2f07a662015-07-23 08:54:35 +0300873 node = ast.parse('async def foo():\n """spam\n ham"""')
874 self.assertEqual(ast.get_docstring(node.body[0]), 'spam\nham')
Serhiy Storchaka08f127a2018-06-15 11:05:15 +0300875
876 def test_get_docstring_none(self):
Matthias Bussonnier41cea702017-02-23 22:44:19 -0800877 self.assertIsNone(ast.get_docstring(ast.parse('')))
Serhiy Storchaka08f127a2018-06-15 11:05:15 +0300878 node = ast.parse('x = "not docstring"')
879 self.assertIsNone(ast.get_docstring(node))
880 node = ast.parse('def foo():\n pass')
881 self.assertIsNone(ast.get_docstring(node))
882
883 node = ast.parse('class foo:\n pass')
884 self.assertIsNone(ast.get_docstring(node.body[0]))
885 node = ast.parse('class foo:\n x = "not docstring"')
886 self.assertIsNone(ast.get_docstring(node.body[0]))
887 node = ast.parse('class foo:\n def bar(self): pass')
888 self.assertIsNone(ast.get_docstring(node.body[0]))
889
890 node = ast.parse('def foo():\n pass')
891 self.assertIsNone(ast.get_docstring(node.body[0]))
892 node = ast.parse('def foo():\n x = "not docstring"')
893 self.assertIsNone(ast.get_docstring(node.body[0]))
894
895 node = ast.parse('async def foo():\n pass')
896 self.assertIsNone(ast.get_docstring(node.body[0]))
897 node = ast.parse('async def foo():\n x = "not docstring"')
898 self.assertIsNone(ast.get_docstring(node.body[0]))
Yury Selivanov2f07a662015-07-23 08:54:35 +0300899
Anthony Sottile995d9b92019-01-12 20:05:13 -0800900 def test_multi_line_docstring_col_offset_and_lineno_issue16806(self):
901 node = ast.parse(
902 '"""line one\nline two"""\n\n'
903 'def foo():\n """line one\n line two"""\n\n'
904 ' def bar():\n """line one\n line two"""\n'
905 ' """line one\n line two"""\n'
906 '"""line one\nline two"""\n\n'
907 )
908 self.assertEqual(node.body[0].col_offset, 0)
909 self.assertEqual(node.body[0].lineno, 1)
910 self.assertEqual(node.body[1].body[0].col_offset, 2)
911 self.assertEqual(node.body[1].body[0].lineno, 5)
912 self.assertEqual(node.body[1].body[1].body[0].col_offset, 4)
913 self.assertEqual(node.body[1].body[1].body[0].lineno, 9)
914 self.assertEqual(node.body[1].body[2].col_offset, 2)
915 self.assertEqual(node.body[1].body[2].lineno, 11)
916 self.assertEqual(node.body[2].col_offset, 0)
917 self.assertEqual(node.body[2].lineno, 13)
918
Lysandros Nikolaou025a6022019-12-12 22:40:21 +0100919 def test_elif_stmt_start_position(self):
920 node = ast.parse('if a:\n pass\nelif b:\n pass\n')
921 elif_stmt = node.body[0].orelse[0]
922 self.assertEqual(elif_stmt.lineno, 3)
923 self.assertEqual(elif_stmt.col_offset, 0)
924
Lysandros Nikolaou5936a4c2019-12-14 11:24:57 +0100925 def test_elif_stmt_start_position_with_else(self):
926 node = ast.parse('if a:\n pass\nelif b:\n pass\nelse:\n pass\n')
927 elif_stmt = node.body[0].orelse[0]
928 self.assertEqual(elif_stmt.lineno, 3)
929 self.assertEqual(elif_stmt.col_offset, 0)
930
Lysandros Nikolaou50d4f122019-12-18 01:20:55 +0100931 def test_starred_expr_end_position_within_call(self):
932 node = ast.parse('f(*[0, 1])')
933 starred_expr = node.body[0].value.args[0]
934 self.assertEqual(starred_expr.end_lineno, 1)
935 self.assertEqual(starred_expr.end_col_offset, 9)
936
Georg Brandl0c77a822008-06-10 16:37:50 +0000937 def test_literal_eval(self):
938 self.assertEqual(ast.literal_eval('[1, 2, 3]'), [1, 2, 3])
939 self.assertEqual(ast.literal_eval('{"foo": 42}'), {"foo": 42})
940 self.assertEqual(ast.literal_eval('(True, False, None)'), (True, False, None))
Benjamin Peterson3e742892010-07-11 12:59:24 +0000941 self.assertEqual(ast.literal_eval('{1, 2, 3}'), {1, 2, 3})
Benjamin Peterson5ef96e52010-07-11 23:06:06 +0000942 self.assertEqual(ast.literal_eval('b"hi"'), b"hi")
Raymond Hettinger4fcf5c12020-01-02 22:21:18 -0700943 self.assertEqual(ast.literal_eval('set()'), set())
Georg Brandl0c77a822008-06-10 16:37:50 +0000944 self.assertRaises(ValueError, ast.literal_eval, 'foo()')
Serhiy Storchakad8ac4d12018-01-04 11:15:39 +0200945 self.assertEqual(ast.literal_eval('6'), 6)
946 self.assertEqual(ast.literal_eval('+6'), 6)
Raymond Hettingerbc959732010-10-08 00:47:45 +0000947 self.assertEqual(ast.literal_eval('-6'), -6)
Raymond Hettingerbc959732010-10-08 00:47:45 +0000948 self.assertEqual(ast.literal_eval('3.25'), 3.25)
Serhiy Storchakad8ac4d12018-01-04 11:15:39 +0200949 self.assertEqual(ast.literal_eval('+3.25'), 3.25)
950 self.assertEqual(ast.literal_eval('-3.25'), -3.25)
951 self.assertEqual(repr(ast.literal_eval('-0.0')), '-0.0')
952 self.assertRaises(ValueError, ast.literal_eval, '++6')
953 self.assertRaises(ValueError, ast.literal_eval, '+True')
954 self.assertRaises(ValueError, ast.literal_eval, '2+3')
Georg Brandl0c77a822008-06-10 16:37:50 +0000955
Serhiy Storchakad8ac4d12018-01-04 11:15:39 +0200956 def test_literal_eval_complex(self):
957 # Issue #4907
958 self.assertEqual(ast.literal_eval('6j'), 6j)
959 self.assertEqual(ast.literal_eval('-6j'), -6j)
960 self.assertEqual(ast.literal_eval('6.75j'), 6.75j)
961 self.assertEqual(ast.literal_eval('-6.75j'), -6.75j)
962 self.assertEqual(ast.literal_eval('3+6j'), 3+6j)
963 self.assertEqual(ast.literal_eval('-3+6j'), -3+6j)
964 self.assertEqual(ast.literal_eval('3-6j'), 3-6j)
965 self.assertEqual(ast.literal_eval('-3-6j'), -3-6j)
966 self.assertEqual(ast.literal_eval('3.25+6.75j'), 3.25+6.75j)
967 self.assertEqual(ast.literal_eval('-3.25+6.75j'), -3.25+6.75j)
968 self.assertEqual(ast.literal_eval('3.25-6.75j'), 3.25-6.75j)
969 self.assertEqual(ast.literal_eval('-3.25-6.75j'), -3.25-6.75j)
970 self.assertEqual(ast.literal_eval('(3+6j)'), 3+6j)
971 self.assertRaises(ValueError, ast.literal_eval, '-6j+3')
972 self.assertRaises(ValueError, ast.literal_eval, '-6j+3j')
973 self.assertRaises(ValueError, ast.literal_eval, '3+-6j')
974 self.assertRaises(ValueError, ast.literal_eval, '3+(0+6j)')
975 self.assertRaises(ValueError, ast.literal_eval, '-(3+6j)')
Benjamin Peterson058e31e2009-01-16 03:54:08 +0000976
Curtis Bucherc21c5122020-05-05 12:40:56 -0700977 def test_literal_eval_malformed_dict_nodes(self):
978 malformed = ast.Dict(keys=[ast.Constant(1), ast.Constant(2)], values=[ast.Constant(3)])
979 self.assertRaises(ValueError, ast.literal_eval, malformed)
980 malformed = ast.Dict(keys=[ast.Constant(1)], values=[ast.Constant(2), ast.Constant(3)])
981 self.assertRaises(ValueError, ast.literal_eval, malformed)
982
Amaury Forgeot d'Arc58e87612011-11-22 21:51:55 +0100983 def test_bad_integer(self):
984 # issue13436: Bad error message with invalid numeric values
985 body = [ast.ImportFrom(module='time',
986 names=[ast.alias(name='sleep')],
987 level=None,
988 lineno=None, col_offset=None)]
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800989 mod = ast.Module(body, [])
Amaury Forgeot d'Arc58e87612011-11-22 21:51:55 +0100990 with self.assertRaises(ValueError) as cm:
991 compile(mod, 'test', 'exec')
992 self.assertIn("invalid integer value: None", str(cm.exception))
993
Berker Peksag0a5bd512016-04-29 19:50:02 +0300994 def test_level_as_none(self):
995 body = [ast.ImportFrom(module='time',
996 names=[ast.alias(name='sleep')],
997 level=None,
998 lineno=0, col_offset=0)]
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800999 mod = ast.Module(body, [])
Berker Peksag0a5bd512016-04-29 19:50:02 +03001000 code = compile(mod, 'test', 'exec')
1001 ns = {}
1002 exec(code, ns)
1003 self.assertIn('sleep', ns)
1004
Georg Brandl0c77a822008-06-10 16:37:50 +00001005
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001006class ASTValidatorTests(unittest.TestCase):
1007
1008 def mod(self, mod, msg=None, mode="exec", *, exc=ValueError):
1009 mod.lineno = mod.col_offset = 0
1010 ast.fix_missing_locations(mod)
Serhiy Storchaka3f228112018-09-27 17:42:37 +03001011 if msg is None:
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001012 compile(mod, "<test>", mode)
Serhiy Storchaka3f228112018-09-27 17:42:37 +03001013 else:
1014 with self.assertRaises(exc) as cm:
1015 compile(mod, "<test>", mode)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001016 self.assertIn(msg, str(cm.exception))
1017
1018 def expr(self, node, msg=None, *, exc=ValueError):
Guido van Rossumdcfcd142019-01-31 03:40:27 -08001019 mod = ast.Module([ast.Expr(node)], [])
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001020 self.mod(mod, msg, exc=exc)
1021
1022 def stmt(self, stmt, msg=None):
Guido van Rossumdcfcd142019-01-31 03:40:27 -08001023 mod = ast.Module([stmt], [])
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001024 self.mod(mod, msg)
1025
1026 def test_module(self):
1027 m = ast.Interactive([ast.Expr(ast.Name("x", ast.Store()))])
1028 self.mod(m, "must have Load context", "single")
1029 m = ast.Expression(ast.Name("x", ast.Store()))
1030 self.mod(m, "must have Load context", "eval")
1031
1032 def _check_arguments(self, fac, check):
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01001033 def arguments(args=None, posonlyargs=None, vararg=None,
Benjamin Petersoncda75be2013-03-18 10:48:58 -07001034 kwonlyargs=None, kwarg=None,
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001035 defaults=None, kw_defaults=None):
1036 if args is None:
1037 args = []
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01001038 if posonlyargs is None:
1039 posonlyargs = []
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001040 if kwonlyargs is None:
1041 kwonlyargs = []
1042 if defaults is None:
1043 defaults = []
1044 if kw_defaults is None:
1045 kw_defaults = []
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01001046 args = ast.arguments(args, posonlyargs, vararg, kwonlyargs,
1047 kw_defaults, kwarg, defaults)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001048 return fac(args)
1049 args = [ast.arg("x", ast.Name("x", ast.Store()))]
1050 check(arguments(args=args), "must have Load context")
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01001051 check(arguments(posonlyargs=args), "must have Load context")
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001052 check(arguments(kwonlyargs=args), "must have Load context")
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001053 check(arguments(defaults=[ast.Num(3)]),
1054 "more positional defaults than args")
1055 check(arguments(kw_defaults=[ast.Num(4)]),
1056 "length of kwonlyargs is not the same as kw_defaults")
1057 args = [ast.arg("x", ast.Name("x", ast.Load()))]
1058 check(arguments(args=args, defaults=[ast.Name("x", ast.Store())]),
1059 "must have Load context")
1060 args = [ast.arg("a", ast.Name("x", ast.Load())),
1061 ast.arg("b", ast.Name("y", ast.Load()))]
1062 check(arguments(kwonlyargs=args,
1063 kw_defaults=[None, ast.Name("x", ast.Store())]),
1064 "must have Load context")
1065
1066 def test_funcdef(self):
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01001067 a = ast.arguments([], [], None, [], [], None, [])
Serhiy Storchaka73cbe7a2018-05-29 12:04:55 +03001068 f = ast.FunctionDef("x", a, [], [], None)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001069 self.stmt(f, "empty body on FunctionDef")
1070 f = ast.FunctionDef("x", a, [ast.Pass()], [ast.Name("x", ast.Store())],
Serhiy Storchaka73cbe7a2018-05-29 12:04:55 +03001071 None)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001072 self.stmt(f, "must have Load context")
1073 f = ast.FunctionDef("x", a, [ast.Pass()], [],
Serhiy Storchaka73cbe7a2018-05-29 12:04:55 +03001074 ast.Name("x", ast.Store()))
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001075 self.stmt(f, "must have Load context")
1076 def fac(args):
Serhiy Storchaka73cbe7a2018-05-29 12:04:55 +03001077 return ast.FunctionDef("x", args, [ast.Pass()], [], None)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001078 self._check_arguments(fac, self.stmt)
1079
1080 def test_classdef(self):
Benjamin Peterson025e9eb2015-05-05 20:16:41 -04001081 def cls(bases=None, keywords=None, body=None, decorator_list=None):
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001082 if bases is None:
1083 bases = []
1084 if keywords is None:
1085 keywords = []
1086 if body is None:
1087 body = [ast.Pass()]
1088 if decorator_list is None:
1089 decorator_list = []
Benjamin Peterson025e9eb2015-05-05 20:16:41 -04001090 return ast.ClassDef("myclass", bases, keywords,
Serhiy Storchaka73cbe7a2018-05-29 12:04:55 +03001091 body, decorator_list)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001092 self.stmt(cls(bases=[ast.Name("x", ast.Store())]),
1093 "must have Load context")
1094 self.stmt(cls(keywords=[ast.keyword("x", ast.Name("x", ast.Store()))]),
1095 "must have Load context")
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001096 self.stmt(cls(body=[]), "empty body on ClassDef")
1097 self.stmt(cls(body=[None]), "None disallowed")
1098 self.stmt(cls(decorator_list=[ast.Name("x", ast.Store())]),
1099 "must have Load context")
1100
1101 def test_delete(self):
1102 self.stmt(ast.Delete([]), "empty targets on Delete")
1103 self.stmt(ast.Delete([None]), "None disallowed")
1104 self.stmt(ast.Delete([ast.Name("x", ast.Load())]),
1105 "must have Del context")
1106
1107 def test_assign(self):
1108 self.stmt(ast.Assign([], ast.Num(3)), "empty targets on Assign")
1109 self.stmt(ast.Assign([None], ast.Num(3)), "None disallowed")
1110 self.stmt(ast.Assign([ast.Name("x", ast.Load())], ast.Num(3)),
1111 "must have Store context")
1112 self.stmt(ast.Assign([ast.Name("x", ast.Store())],
1113 ast.Name("y", ast.Store())),
1114 "must have Load context")
1115
1116 def test_augassign(self):
1117 aug = ast.AugAssign(ast.Name("x", ast.Load()), ast.Add(),
1118 ast.Name("y", ast.Load()))
1119 self.stmt(aug, "must have Store context")
1120 aug = ast.AugAssign(ast.Name("x", ast.Store()), ast.Add(),
1121 ast.Name("y", ast.Store()))
1122 self.stmt(aug, "must have Load context")
1123
1124 def test_for(self):
1125 x = ast.Name("x", ast.Store())
1126 y = ast.Name("y", ast.Load())
1127 p = ast.Pass()
1128 self.stmt(ast.For(x, y, [], []), "empty body on For")
1129 self.stmt(ast.For(ast.Name("x", ast.Load()), y, [p], []),
1130 "must have Store context")
1131 self.stmt(ast.For(x, ast.Name("y", ast.Store()), [p], []),
1132 "must have Load context")
1133 e = ast.Expr(ast.Name("x", ast.Store()))
1134 self.stmt(ast.For(x, y, [e], []), "must have Load context")
1135 self.stmt(ast.For(x, y, [p], [e]), "must have Load context")
1136
1137 def test_while(self):
1138 self.stmt(ast.While(ast.Num(3), [], []), "empty body on While")
1139 self.stmt(ast.While(ast.Name("x", ast.Store()), [ast.Pass()], []),
1140 "must have Load context")
1141 self.stmt(ast.While(ast.Num(3), [ast.Pass()],
1142 [ast.Expr(ast.Name("x", ast.Store()))]),
1143 "must have Load context")
1144
1145 def test_if(self):
1146 self.stmt(ast.If(ast.Num(3), [], []), "empty body on If")
1147 i = ast.If(ast.Name("x", ast.Store()), [ast.Pass()], [])
1148 self.stmt(i, "must have Load context")
1149 i = ast.If(ast.Num(3), [ast.Expr(ast.Name("x", ast.Store()))], [])
1150 self.stmt(i, "must have Load context")
1151 i = ast.If(ast.Num(3), [ast.Pass()],
1152 [ast.Expr(ast.Name("x", ast.Store()))])
1153 self.stmt(i, "must have Load context")
1154
1155 def test_with(self):
1156 p = ast.Pass()
1157 self.stmt(ast.With([], [p]), "empty items on With")
1158 i = ast.withitem(ast.Num(3), None)
1159 self.stmt(ast.With([i], []), "empty body on With")
1160 i = ast.withitem(ast.Name("x", ast.Store()), None)
1161 self.stmt(ast.With([i], [p]), "must have Load context")
1162 i = ast.withitem(ast.Num(3), ast.Name("x", ast.Load()))
1163 self.stmt(ast.With([i], [p]), "must have Store context")
1164
1165 def test_raise(self):
1166 r = ast.Raise(None, ast.Num(3))
1167 self.stmt(r, "Raise with cause but no exception")
1168 r = ast.Raise(ast.Name("x", ast.Store()), None)
1169 self.stmt(r, "must have Load context")
1170 r = ast.Raise(ast.Num(4), ast.Name("x", ast.Store()))
1171 self.stmt(r, "must have Load context")
1172
1173 def test_try(self):
1174 p = ast.Pass()
1175 t = ast.Try([], [], [], [p])
1176 self.stmt(t, "empty body on Try")
1177 t = ast.Try([ast.Expr(ast.Name("x", ast.Store()))], [], [], [p])
1178 self.stmt(t, "must have Load context")
1179 t = ast.Try([p], [], [], [])
1180 self.stmt(t, "Try has neither except handlers nor finalbody")
1181 t = ast.Try([p], [], [p], [p])
1182 self.stmt(t, "Try has orelse but no except handlers")
1183 t = ast.Try([p], [ast.ExceptHandler(None, "x", [])], [], [])
1184 self.stmt(t, "empty body on ExceptHandler")
1185 e = [ast.ExceptHandler(ast.Name("x", ast.Store()), "y", [p])]
1186 self.stmt(ast.Try([p], e, [], []), "must have Load context")
1187 e = [ast.ExceptHandler(None, "x", [p])]
1188 t = ast.Try([p], e, [ast.Expr(ast.Name("x", ast.Store()))], [p])
1189 self.stmt(t, "must have Load context")
1190 t = ast.Try([p], e, [p], [ast.Expr(ast.Name("x", ast.Store()))])
1191 self.stmt(t, "must have Load context")
1192
1193 def test_assert(self):
1194 self.stmt(ast.Assert(ast.Name("x", ast.Store()), None),
1195 "must have Load context")
1196 assrt = ast.Assert(ast.Name("x", ast.Load()),
1197 ast.Name("y", ast.Store()))
1198 self.stmt(assrt, "must have Load context")
1199
1200 def test_import(self):
1201 self.stmt(ast.Import([]), "empty names on Import")
1202
1203 def test_importfrom(self):
1204 imp = ast.ImportFrom(None, [ast.alias("x", None)], -42)
Serhiy Storchaka7de28402016-06-27 23:40:43 +03001205 self.stmt(imp, "Negative ImportFrom level")
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001206 self.stmt(ast.ImportFrom(None, [], 0), "empty names on ImportFrom")
1207
1208 def test_global(self):
1209 self.stmt(ast.Global([]), "empty names on Global")
1210
1211 def test_nonlocal(self):
1212 self.stmt(ast.Nonlocal([]), "empty names on Nonlocal")
1213
1214 def test_expr(self):
1215 e = ast.Expr(ast.Name("x", ast.Store()))
1216 self.stmt(e, "must have Load context")
1217
1218 def test_boolop(self):
1219 b = ast.BoolOp(ast.And(), [])
1220 self.expr(b, "less than 2 values")
1221 b = ast.BoolOp(ast.And(), [ast.Num(3)])
1222 self.expr(b, "less than 2 values")
1223 b = ast.BoolOp(ast.And(), [ast.Num(4), None])
1224 self.expr(b, "None disallowed")
1225 b = ast.BoolOp(ast.And(), [ast.Num(4), ast.Name("x", ast.Store())])
1226 self.expr(b, "must have Load context")
1227
1228 def test_unaryop(self):
1229 u = ast.UnaryOp(ast.Not(), ast.Name("x", ast.Store()))
1230 self.expr(u, "must have Load context")
1231
1232 def test_lambda(self):
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01001233 a = ast.arguments([], [], None, [], [], None, [])
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001234 self.expr(ast.Lambda(a, ast.Name("x", ast.Store())),
1235 "must have Load context")
1236 def fac(args):
1237 return ast.Lambda(args, ast.Name("x", ast.Load()))
1238 self._check_arguments(fac, self.expr)
1239
1240 def test_ifexp(self):
1241 l = ast.Name("x", ast.Load())
1242 s = ast.Name("y", ast.Store())
1243 for args in (s, l, l), (l, s, l), (l, l, s):
Benjamin Peterson71ce8972011-08-09 16:17:12 -05001244 self.expr(ast.IfExp(*args), "must have Load context")
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001245
1246 def test_dict(self):
1247 d = ast.Dict([], [ast.Name("x", ast.Load())])
1248 self.expr(d, "same number of keys as values")
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001249 d = ast.Dict([ast.Name("x", ast.Load())], [None])
1250 self.expr(d, "None disallowed")
1251
1252 def test_set(self):
1253 self.expr(ast.Set([None]), "None disallowed")
1254 s = ast.Set([ast.Name("x", ast.Store())])
1255 self.expr(s, "must have Load context")
1256
1257 def _check_comprehension(self, fac):
1258 self.expr(fac([]), "comprehension with no generators")
1259 g = ast.comprehension(ast.Name("x", ast.Load()),
Yury Selivanov52c4e7c2016-09-09 10:36:01 -07001260 ast.Name("x", ast.Load()), [], 0)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001261 self.expr(fac([g]), "must have Store context")
1262 g = ast.comprehension(ast.Name("x", ast.Store()),
Yury Selivanov52c4e7c2016-09-09 10:36:01 -07001263 ast.Name("x", ast.Store()), [], 0)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001264 self.expr(fac([g]), "must have Load context")
1265 x = ast.Name("x", ast.Store())
1266 y = ast.Name("y", ast.Load())
Yury Selivanov52c4e7c2016-09-09 10:36:01 -07001267 g = ast.comprehension(x, y, [None], 0)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001268 self.expr(fac([g]), "None disallowed")
Yury Selivanov52c4e7c2016-09-09 10:36:01 -07001269 g = ast.comprehension(x, y, [ast.Name("x", ast.Store())], 0)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001270 self.expr(fac([g]), "must have Load context")
1271
1272 def _simple_comp(self, fac):
1273 g = ast.comprehension(ast.Name("x", ast.Store()),
Yury Selivanov52c4e7c2016-09-09 10:36:01 -07001274 ast.Name("x", ast.Load()), [], 0)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001275 self.expr(fac(ast.Name("x", ast.Store()), [g]),
1276 "must have Load context")
1277 def wrap(gens):
1278 return fac(ast.Name("x", ast.Store()), gens)
1279 self._check_comprehension(wrap)
1280
1281 def test_listcomp(self):
1282 self._simple_comp(ast.ListComp)
1283
1284 def test_setcomp(self):
1285 self._simple_comp(ast.SetComp)
1286
1287 def test_generatorexp(self):
1288 self._simple_comp(ast.GeneratorExp)
1289
1290 def test_dictcomp(self):
1291 g = ast.comprehension(ast.Name("y", ast.Store()),
Yury Selivanov52c4e7c2016-09-09 10:36:01 -07001292 ast.Name("p", ast.Load()), [], 0)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001293 c = ast.DictComp(ast.Name("x", ast.Store()),
1294 ast.Name("y", ast.Load()), [g])
1295 self.expr(c, "must have Load context")
1296 c = ast.DictComp(ast.Name("x", ast.Load()),
1297 ast.Name("y", ast.Store()), [g])
1298 self.expr(c, "must have Load context")
1299 def factory(comps):
1300 k = ast.Name("x", ast.Load())
1301 v = ast.Name("y", ast.Load())
1302 return ast.DictComp(k, v, comps)
1303 self._check_comprehension(factory)
1304
1305 def test_yield(self):
Benjamin Peterson527c6222012-01-14 08:58:23 -05001306 self.expr(ast.Yield(ast.Name("x", ast.Store())), "must have Load")
1307 self.expr(ast.YieldFrom(ast.Name("x", ast.Store())), "must have Load")
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001308
1309 def test_compare(self):
1310 left = ast.Name("x", ast.Load())
1311 comp = ast.Compare(left, [ast.In()], [])
1312 self.expr(comp, "no comparators")
1313 comp = ast.Compare(left, [ast.In()], [ast.Num(4), ast.Num(5)])
1314 self.expr(comp, "different number of comparators and operands")
1315 comp = ast.Compare(ast.Num("blah"), [ast.In()], [left])
Serhiy Storchaka3f228112018-09-27 17:42:37 +03001316 self.expr(comp)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001317 comp = ast.Compare(left, [ast.In()], [ast.Num("blah")])
Serhiy Storchaka3f228112018-09-27 17:42:37 +03001318 self.expr(comp)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001319
1320 def test_call(self):
1321 func = ast.Name("x", ast.Load())
1322 args = [ast.Name("y", ast.Load())]
1323 keywords = [ast.keyword("w", ast.Name("z", ast.Load()))]
Benjamin Peterson025e9eb2015-05-05 20:16:41 -04001324 call = ast.Call(ast.Name("x", ast.Store()), args, keywords)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001325 self.expr(call, "must have Load context")
Benjamin Peterson025e9eb2015-05-05 20:16:41 -04001326 call = ast.Call(func, [None], keywords)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001327 self.expr(call, "None disallowed")
1328 bad_keywords = [ast.keyword("w", ast.Name("z", ast.Store()))]
Benjamin Peterson025e9eb2015-05-05 20:16:41 -04001329 call = ast.Call(func, args, bad_keywords)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001330 self.expr(call, "must have Load context")
1331
1332 def test_num(self):
1333 class subint(int):
1334 pass
1335 class subfloat(float):
1336 pass
1337 class subcomplex(complex):
1338 pass
Serhiy Storchaka3f228112018-09-27 17:42:37 +03001339 for obj in "0", "hello":
1340 self.expr(ast.Num(obj))
1341 for obj in subint(), subfloat(), subcomplex():
1342 self.expr(ast.Num(obj), "invalid type", exc=TypeError)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001343
1344 def test_attribute(self):
1345 attr = ast.Attribute(ast.Name("x", ast.Store()), "y", ast.Load())
1346 self.expr(attr, "must have Load context")
1347
1348 def test_subscript(self):
Serhiy Storchaka13d52c22020-03-10 18:52:34 +02001349 sub = ast.Subscript(ast.Name("x", ast.Store()), ast.Num(3),
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001350 ast.Load())
1351 self.expr(sub, "must have Load context")
1352 x = ast.Name("x", ast.Load())
Serhiy Storchaka13d52c22020-03-10 18:52:34 +02001353 sub = ast.Subscript(x, ast.Name("y", ast.Store()),
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001354 ast.Load())
1355 self.expr(sub, "must have Load context")
1356 s = ast.Name("x", ast.Store())
1357 for args in (s, None, None), (None, s, None), (None, None, s):
1358 sl = ast.Slice(*args)
1359 self.expr(ast.Subscript(x, sl, ast.Load()),
1360 "must have Load context")
Serhiy Storchaka13d52c22020-03-10 18:52:34 +02001361 sl = ast.Tuple([], ast.Load())
1362 self.expr(ast.Subscript(x, sl, ast.Load()))
1363 sl = ast.Tuple([s], ast.Load())
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001364 self.expr(ast.Subscript(x, sl, ast.Load()), "must have Load context")
1365
1366 def test_starred(self):
1367 left = ast.List([ast.Starred(ast.Name("x", ast.Load()), ast.Store())],
1368 ast.Store())
1369 assign = ast.Assign([left], ast.Num(4))
1370 self.stmt(assign, "must have Store context")
1371
1372 def _sequence(self, fac):
1373 self.expr(fac([None], ast.Load()), "None disallowed")
1374 self.expr(fac([ast.Name("x", ast.Store())], ast.Load()),
1375 "must have Load context")
1376
1377 def test_list(self):
1378 self._sequence(ast.List)
1379
1380 def test_tuple(self):
1381 self._sequence(ast.Tuple)
1382
Benjamin Peterson442f2092012-12-06 17:41:04 -05001383 def test_nameconstant(self):
Serhiy Storchaka3f228112018-09-27 17:42:37 +03001384 self.expr(ast.NameConstant(4))
Benjamin Peterson442f2092012-12-06 17:41:04 -05001385
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001386 def test_stdlib_validates(self):
1387 stdlib = os.path.dirname(ast.__file__)
1388 tests = [fn for fn in os.listdir(stdlib) if fn.endswith(".py")]
1389 tests.extend(["test/test_grammar.py", "test/test_unpack_ex.py"])
1390 for module in tests:
Serhiy Storchaka3bcbedc2019-01-18 07:47:48 +02001391 with self.subTest(module):
1392 fn = os.path.join(stdlib, module)
1393 with open(fn, "r", encoding="utf-8") as fp:
1394 source = fp.read()
1395 mod = ast.parse(source, fn)
1396 compile(mod, fn, "exec")
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001397
1398
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001399class ConstantTests(unittest.TestCase):
1400 """Tests on the ast.Constant node type."""
1401
1402 def compile_constant(self, value):
1403 tree = ast.parse("x = 123")
1404
1405 node = tree.body[0].value
1406 new_node = ast.Constant(value=value)
1407 ast.copy_location(new_node, node)
1408 tree.body[0].value = new_node
1409
1410 code = compile(tree, "<string>", "exec")
1411
1412 ns = {}
1413 exec(code, ns)
1414 return ns['x']
1415
Victor Stinnerbe59d142016-01-27 00:39:12 +01001416 def test_validation(self):
1417 with self.assertRaises(TypeError) as cm:
1418 self.compile_constant([1, 2, 3])
1419 self.assertEqual(str(cm.exception),
1420 "got an invalid type in Constant: list")
1421
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001422 def test_singletons(self):
1423 for const in (None, False, True, Ellipsis, b'', frozenset()):
1424 with self.subTest(const=const):
1425 value = self.compile_constant(const)
1426 self.assertIs(value, const)
1427
1428 def test_values(self):
1429 nested_tuple = (1,)
1430 nested_frozenset = frozenset({1})
1431 for level in range(3):
1432 nested_tuple = (nested_tuple, 2)
1433 nested_frozenset = frozenset({nested_frozenset, 2})
1434 values = (123, 123.0, 123j,
1435 "unicode", b'bytes',
1436 tuple("tuple"), frozenset("frozenset"),
1437 nested_tuple, nested_frozenset)
1438 for value in values:
1439 with self.subTest(value=value):
1440 result = self.compile_constant(value)
1441 self.assertEqual(result, value)
1442
1443 def test_assign_to_constant(self):
1444 tree = ast.parse("x = 1")
1445
1446 target = tree.body[0].targets[0]
1447 new_target = ast.Constant(value=1)
1448 ast.copy_location(new_target, target)
1449 tree.body[0].targets[0] = new_target
1450
1451 with self.assertRaises(ValueError) as cm:
1452 compile(tree, "string", "exec")
1453 self.assertEqual(str(cm.exception),
1454 "expression which can't be assigned "
1455 "to in Store context")
1456
1457 def test_get_docstring(self):
1458 tree = ast.parse("'docstring'\nx = 1")
1459 self.assertEqual(ast.get_docstring(tree), 'docstring')
1460
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001461 def get_load_const(self, tree):
1462 # Compile to bytecode, disassemble and get parameter of LOAD_CONST
1463 # instructions
1464 co = compile(tree, '<string>', 'exec')
1465 consts = []
1466 for instr in dis.get_instructions(co):
1467 if instr.opname == 'LOAD_CONST':
1468 consts.append(instr.argval)
1469 return consts
1470
1471 @support.cpython_only
1472 def test_load_const(self):
1473 consts = [None,
1474 True, False,
1475 124,
1476 2.0,
1477 3j,
1478 "unicode",
1479 b'bytes',
1480 (1, 2, 3)]
1481
Victor Stinnera2724092016-02-08 18:17:58 +01001482 code = '\n'.join(['x={!r}'.format(const) for const in consts])
1483 code += '\nx = ...'
1484 consts.extend((Ellipsis, None))
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001485
1486 tree = ast.parse(code)
Victor Stinnera2724092016-02-08 18:17:58 +01001487 self.assertEqual(self.get_load_const(tree),
1488 consts)
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001489
1490 # Replace expression nodes with constants
Victor Stinnera2724092016-02-08 18:17:58 +01001491 for assign, const in zip(tree.body, consts):
1492 assert isinstance(assign, ast.Assign), ast.dump(assign)
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001493 new_node = ast.Constant(value=const)
Victor Stinnera2724092016-02-08 18:17:58 +01001494 ast.copy_location(new_node, assign.value)
1495 assign.value = new_node
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001496
Victor Stinnera2724092016-02-08 18:17:58 +01001497 self.assertEqual(self.get_load_const(tree),
1498 consts)
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001499
1500 def test_literal_eval(self):
1501 tree = ast.parse("1 + 2")
1502 binop = tree.body[0].value
1503
1504 new_left = ast.Constant(value=10)
1505 ast.copy_location(new_left, binop.left)
1506 binop.left = new_left
1507
Serhiy Storchakad8ac4d12018-01-04 11:15:39 +02001508 new_right = ast.Constant(value=20j)
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001509 ast.copy_location(new_right, binop.right)
1510 binop.right = new_right
1511
Serhiy Storchakad8ac4d12018-01-04 11:15:39 +02001512 self.assertEqual(ast.literal_eval(binop), 10+20j)
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001513
Guido van Rossum10f8ce62019-03-13 13:00:46 -07001514 def test_string_kind(self):
1515 c = ast.parse('"x"', mode='eval').body
1516 self.assertEqual(c.value, "x")
1517 self.assertEqual(c.kind, None)
1518
1519 c = ast.parse('u"x"', mode='eval').body
1520 self.assertEqual(c.value, "x")
1521 self.assertEqual(c.kind, "u")
1522
1523 c = ast.parse('r"x"', mode='eval').body
1524 self.assertEqual(c.value, "x")
1525 self.assertEqual(c.kind, None)
1526
1527 c = ast.parse('b"x"', mode='eval').body
1528 self.assertEqual(c.value, b"x")
1529 self.assertEqual(c.kind, None)
1530
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001531
Ivan Levkivskyi9932a222019-01-22 11:18:22 +00001532class EndPositionTests(unittest.TestCase):
1533 """Tests for end position of AST nodes.
1534
1535 Testing end positions of nodes requires a bit of extra care
1536 because of how LL parsers work.
1537 """
1538 def _check_end_pos(self, ast_node, end_lineno, end_col_offset):
1539 self.assertEqual(ast_node.end_lineno, end_lineno)
1540 self.assertEqual(ast_node.end_col_offset, end_col_offset)
1541
1542 def _check_content(self, source, ast_node, content):
1543 self.assertEqual(ast.get_source_segment(source, ast_node), content)
1544
1545 def _parse_value(self, s):
1546 # Use duck-typing to support both single expression
1547 # and a right hand side of an assignment statement.
1548 return ast.parse(s).body[0].value
1549
1550 def test_lambda(self):
1551 s = 'lambda x, *y: None'
1552 lam = self._parse_value(s)
1553 self._check_content(s, lam.body, 'None')
1554 self._check_content(s, lam.args.args[0], 'x')
1555 self._check_content(s, lam.args.vararg, 'y')
1556
1557 def test_func_def(self):
1558 s = dedent('''
1559 def func(x: int,
1560 *args: str,
1561 z: float = 0,
1562 **kwargs: Any) -> bool:
1563 return True
1564 ''').strip()
1565 fdef = ast.parse(s).body[0]
1566 self._check_end_pos(fdef, 5, 15)
1567 self._check_content(s, fdef.body[0], 'return True')
1568 self._check_content(s, fdef.args.args[0], 'x: int')
1569 self._check_content(s, fdef.args.args[0].annotation, 'int')
1570 self._check_content(s, fdef.args.kwarg, 'kwargs: Any')
1571 self._check_content(s, fdef.args.kwarg.annotation, 'Any')
1572
1573 def test_call(self):
1574 s = 'func(x, y=2, **kw)'
1575 call = self._parse_value(s)
1576 self._check_content(s, call.func, 'func')
1577 self._check_content(s, call.keywords[0].value, '2')
1578 self._check_content(s, call.keywords[1].value, 'kw')
1579
1580 def test_call_noargs(self):
1581 s = 'x[0]()'
1582 call = self._parse_value(s)
1583 self._check_content(s, call.func, 'x[0]')
1584 self._check_end_pos(call, 1, 6)
1585
1586 def test_class_def(self):
1587 s = dedent('''
1588 class C(A, B):
1589 x: int = 0
1590 ''').strip()
1591 cdef = ast.parse(s).body[0]
1592 self._check_end_pos(cdef, 2, 14)
1593 self._check_content(s, cdef.bases[1], 'B')
1594 self._check_content(s, cdef.body[0], 'x: int = 0')
1595
1596 def test_class_kw(self):
1597 s = 'class S(metaclass=abc.ABCMeta): pass'
1598 cdef = ast.parse(s).body[0]
1599 self._check_content(s, cdef.keywords[0].value, 'abc.ABCMeta')
1600
1601 def test_multi_line_str(self):
1602 s = dedent('''
1603 x = """Some multi-line text.
1604
1605 It goes on starting from same indent."""
1606 ''').strip()
1607 assign = ast.parse(s).body[0]
1608 self._check_end_pos(assign, 3, 40)
1609 self._check_end_pos(assign.value, 3, 40)
1610
1611 def test_continued_str(self):
1612 s = dedent('''
1613 x = "first part" \\
1614 "second part"
1615 ''').strip()
1616 assign = ast.parse(s).body[0]
1617 self._check_end_pos(assign, 2, 13)
1618 self._check_end_pos(assign.value, 2, 13)
1619
1620 def test_suites(self):
1621 # We intentionally put these into the same string to check
1622 # that empty lines are not part of the suite.
1623 s = dedent('''
1624 while True:
1625 pass
1626
1627 if one():
1628 x = None
1629 elif other():
1630 y = None
1631 else:
1632 z = None
1633
1634 for x, y in stuff:
1635 assert True
1636
1637 try:
1638 raise RuntimeError
1639 except TypeError as e:
1640 pass
1641
1642 pass
1643 ''').strip()
1644 mod = ast.parse(s)
1645 while_loop = mod.body[0]
1646 if_stmt = mod.body[1]
1647 for_loop = mod.body[2]
1648 try_stmt = mod.body[3]
1649 pass_stmt = mod.body[4]
1650
1651 self._check_end_pos(while_loop, 2, 8)
1652 self._check_end_pos(if_stmt, 9, 12)
1653 self._check_end_pos(for_loop, 12, 15)
1654 self._check_end_pos(try_stmt, 17, 8)
1655 self._check_end_pos(pass_stmt, 19, 4)
1656
1657 self._check_content(s, while_loop.test, 'True')
1658 self._check_content(s, if_stmt.body[0], 'x = None')
1659 self._check_content(s, if_stmt.orelse[0].test, 'other()')
1660 self._check_content(s, for_loop.target, 'x, y')
1661 self._check_content(s, try_stmt.body[0], 'raise RuntimeError')
1662 self._check_content(s, try_stmt.handlers[0].type, 'TypeError')
1663
1664 def test_fstring(self):
1665 s = 'x = f"abc {x + y} abc"'
1666 fstr = self._parse_value(s)
1667 binop = fstr.values[1].value
1668 self._check_content(s, binop, 'x + y')
1669
1670 def test_fstring_multi_line(self):
1671 s = dedent('''
1672 f"""Some multi-line text.
1673 {
1674 arg_one
1675 +
1676 arg_two
1677 }
1678 It goes on..."""
1679 ''').strip()
1680 fstr = self._parse_value(s)
1681 binop = fstr.values[1].value
1682 self._check_end_pos(binop, 5, 7)
1683 self._check_content(s, binop.left, 'arg_one')
1684 self._check_content(s, binop.right, 'arg_two')
1685
1686 def test_import_from_multi_line(self):
1687 s = dedent('''
1688 from x.y.z import (
1689 a, b, c as c
1690 )
1691 ''').strip()
1692 imp = ast.parse(s).body[0]
1693 self._check_end_pos(imp, 3, 1)
1694
1695 def test_slices(self):
1696 s1 = 'f()[1, 2] [0]'
1697 s2 = 'x[ a.b: c.d]'
1698 sm = dedent('''
1699 x[ a.b: f () ,
1700 g () : c.d
1701 ]
1702 ''').strip()
1703 i1, i2, im = map(self._parse_value, (s1, s2, sm))
1704 self._check_content(s1, i1.value, 'f()[1, 2]')
Serhiy Storchaka13d52c22020-03-10 18:52:34 +02001705 self._check_content(s1, i1.value.slice, '1, 2')
Ivan Levkivskyi9932a222019-01-22 11:18:22 +00001706 self._check_content(s2, i2.slice.lower, 'a.b')
1707 self._check_content(s2, i2.slice.upper, 'c.d')
Serhiy Storchaka13d52c22020-03-10 18:52:34 +02001708 self._check_content(sm, im.slice.elts[0].upper, 'f ()')
1709 self._check_content(sm, im.slice.elts[1].lower, 'g ()')
Ivan Levkivskyi9932a222019-01-22 11:18:22 +00001710 self._check_end_pos(im, 3, 3)
1711
1712 def test_binop(self):
1713 s = dedent('''
1714 (1 * 2 + (3 ) +
1715 4
1716 )
1717 ''').strip()
1718 binop = self._parse_value(s)
1719 self._check_end_pos(binop, 2, 6)
1720 self._check_content(s, binop.right, '4')
1721 self._check_content(s, binop.left, '1 * 2 + (3 )')
1722 self._check_content(s, binop.left.right, '3')
1723
1724 def test_boolop(self):
1725 s = dedent('''
1726 if (one_condition and
1727 (other_condition or yet_another_one)):
1728 pass
1729 ''').strip()
1730 bop = ast.parse(s).body[0].test
1731 self._check_end_pos(bop, 2, 44)
1732 self._check_content(s, bop.values[1],
1733 'other_condition or yet_another_one')
1734
1735 def test_tuples(self):
1736 s1 = 'x = () ;'
1737 s2 = 'x = 1 , ;'
1738 s3 = 'x = (1 , 2 ) ;'
1739 sm = dedent('''
1740 x = (
1741 a, b,
1742 )
1743 ''').strip()
1744 t1, t2, t3, tm = map(self._parse_value, (s1, s2, s3, sm))
1745 self._check_content(s1, t1, '()')
1746 self._check_content(s2, t2, '1 ,')
1747 self._check_content(s3, t3, '(1 , 2 )')
1748 self._check_end_pos(tm, 3, 1)
1749
1750 def test_attribute_spaces(self):
1751 s = 'func(x. y .z)'
1752 call = self._parse_value(s)
1753 self._check_content(s, call, s)
1754 self._check_content(s, call.args[0], 'x. y .z')
1755
Serhiy Storchaka6e619c42020-02-12 22:37:49 +02001756 def test_redundant_parenthesis(self):
1757 s = '( ( ( a + b ) ) )'
1758 v = ast.parse(s).body[0].value
1759 self.assertEqual(type(v).__name__, 'BinOp')
1760 self._check_content(s, v, 'a + b')
1761 s2 = 'await ' + s
1762 v = ast.parse(s2).body[0].value.value
1763 self.assertEqual(type(v).__name__, 'BinOp')
1764 self._check_content(s2, v, 'a + b')
1765
1766 def test_trailers_with_redundant_parenthesis(self):
1767 tests = (
1768 ('( ( ( a ) ) ) ( )', 'Call'),
1769 ('( ( ( a ) ) ) ( b )', 'Call'),
1770 ('( ( ( a ) ) ) [ b ]', 'Subscript'),
1771 ('( ( ( a ) ) ) . b', 'Attribute'),
1772 )
1773 for s, t in tests:
1774 with self.subTest(s):
1775 v = ast.parse(s).body[0].value
1776 self.assertEqual(type(v).__name__, t)
1777 self._check_content(s, v, s)
1778 s2 = 'await ' + s
1779 v = ast.parse(s2).body[0].value.value
1780 self.assertEqual(type(v).__name__, t)
1781 self._check_content(s2, v, s)
1782
Ivan Levkivskyi9932a222019-01-22 11:18:22 +00001783 def test_displays(self):
1784 s1 = '[{}, {1, }, {1, 2,} ]'
1785 s2 = '{a: b, f (): g () ,}'
1786 c1 = self._parse_value(s1)
1787 c2 = self._parse_value(s2)
1788 self._check_content(s1, c1.elts[0], '{}')
1789 self._check_content(s1, c1.elts[1], '{1, }')
1790 self._check_content(s1, c1.elts[2], '{1, 2,}')
1791 self._check_content(s2, c2.keys[1], 'f ()')
1792 self._check_content(s2, c2.values[1], 'g ()')
1793
1794 def test_comprehensions(self):
1795 s = dedent('''
1796 x = [{x for x, y in stuff
1797 if cond.x} for stuff in things]
1798 ''').strip()
1799 cmp = self._parse_value(s)
1800 self._check_end_pos(cmp, 2, 37)
1801 self._check_content(s, cmp.generators[0].iter, 'things')
1802 self._check_content(s, cmp.elt.generators[0].iter, 'stuff')
1803 self._check_content(s, cmp.elt.generators[0].ifs[0], 'cond.x')
1804 self._check_content(s, cmp.elt.generators[0].target, 'x, y')
1805
1806 def test_yield_await(self):
1807 s = dedent('''
1808 async def f():
1809 yield x
1810 await y
1811 ''').strip()
1812 fdef = ast.parse(s).body[0]
1813 self._check_content(s, fdef.body[0].value, 'yield x')
1814 self._check_content(s, fdef.body[1].value, 'await y')
1815
1816 def test_source_segment_multi(self):
1817 s_orig = dedent('''
1818 x = (
1819 a, b,
1820 ) + ()
1821 ''').strip()
1822 s_tuple = dedent('''
1823 (
1824 a, b,
1825 )
1826 ''').strip()
1827 binop = self._parse_value(s_orig)
1828 self.assertEqual(ast.get_source_segment(s_orig, binop.left), s_tuple)
1829
1830 def test_source_segment_padded(self):
1831 s_orig = dedent('''
1832 class C:
1833 def fun(self) -> None:
1834 "Đ–Đ–Đ–Đ–Đ–"
1835 ''').strip()
1836 s_method = ' def fun(self) -> None:\n' \
1837 ' "Đ–Đ–Đ–Đ–Đ–"'
1838 cdef = ast.parse(s_orig).body[0]
1839 self.assertEqual(ast.get_source_segment(s_orig, cdef.body[0], padded=True),
1840 s_method)
1841
1842 def test_source_segment_endings(self):
1843 s = 'v = 1\r\nw = 1\nx = 1\n\ry = 1\rz = 1\r\n'
1844 v, w, x, y, z = ast.parse(s).body
1845 self._check_content(s, v, 'v = 1')
1846 self._check_content(s, w, 'w = 1')
1847 self._check_content(s, x, 'x = 1')
1848 self._check_content(s, y, 'y = 1')
1849 self._check_content(s, z, 'z = 1')
1850
1851 def test_source_segment_tabs(self):
1852 s = dedent('''
1853 class C:
1854 \t\f def fun(self) -> None:
1855 \t\f pass
1856 ''').strip()
1857 s_method = ' \t\f def fun(self) -> None:\n' \
1858 ' \t\f pass'
1859
1860 cdef = ast.parse(s).body[0]
1861 self.assertEqual(ast.get_source_segment(s, cdef.body[0], padded=True), s_method)
1862
Irit Katriele6578a22020-05-18 19:14:12 +01001863 def test_source_segment_missing_info(self):
1864 s = 'v = 1\r\nw = 1\nx = 1\n\ry = 1\r\n'
1865 v, w, x, y = ast.parse(s).body
1866 del v.lineno
1867 del w.end_lineno
1868 del x.col_offset
1869 del y.end_col_offset
1870 self.assertIsNone(ast.get_source_segment(s, v))
1871 self.assertIsNone(ast.get_source_segment(s, w))
1872 self.assertIsNone(ast.get_source_segment(s, x))
1873 self.assertIsNone(ast.get_source_segment(s, y))
Ivan Levkivskyi9932a222019-01-22 11:18:22 +00001874
Serhiy Storchakac3ea41e2019-08-26 10:13:19 +03001875class NodeVisitorTests(unittest.TestCase):
1876 def test_old_constant_nodes(self):
1877 class Visitor(ast.NodeVisitor):
1878 def visit_Num(self, node):
1879 log.append((node.lineno, 'Num', node.n))
1880 def visit_Str(self, node):
1881 log.append((node.lineno, 'Str', node.s))
1882 def visit_Bytes(self, node):
1883 log.append((node.lineno, 'Bytes', node.s))
1884 def visit_NameConstant(self, node):
1885 log.append((node.lineno, 'NameConstant', node.value))
1886 def visit_Ellipsis(self, node):
1887 log.append((node.lineno, 'Ellipsis', ...))
1888 mod = ast.parse(dedent('''\
1889 i = 42
1890 f = 4.25
1891 c = 4.25j
1892 s = 'string'
1893 b = b'bytes'
1894 t = True
1895 n = None
1896 e = ...
1897 '''))
1898 visitor = Visitor()
1899 log = []
1900 with warnings.catch_warnings(record=True) as wlog:
1901 warnings.filterwarnings('always', '', DeprecationWarning)
1902 visitor.visit(mod)
1903 self.assertEqual(log, [
1904 (1, 'Num', 42),
1905 (2, 'Num', 4.25),
1906 (3, 'Num', 4.25j),
1907 (4, 'Str', 'string'),
1908 (5, 'Bytes', b'bytes'),
1909 (6, 'NameConstant', True),
1910 (7, 'NameConstant', None),
1911 (8, 'Ellipsis', ...),
1912 ])
1913 self.assertEqual([str(w.message) for w in wlog], [
1914 'visit_Num is deprecated; add visit_Constant',
1915 'visit_Num is deprecated; add visit_Constant',
1916 'visit_Num is deprecated; add visit_Constant',
1917 'visit_Str is deprecated; add visit_Constant',
1918 'visit_Bytes is deprecated; add visit_Constant',
1919 'visit_NameConstant is deprecated; add visit_Constant',
1920 'visit_NameConstant is deprecated; add visit_Constant',
1921 'visit_Ellipsis is deprecated; add visit_Constant',
1922 ])
1923
1924
Neal Norwitzee9b10a2008-03-31 05:29:39 +00001925def main():
1926 if __name__ != '__main__':
Martin v. Löwis49c5da12006-03-01 22:49:05 +00001927 return
Neal Norwitzee9b10a2008-03-31 05:29:39 +00001928 if sys.argv[1:] == ['-g']:
1929 for statements, kind in ((exec_tests, "exec"), (single_tests, "single"),
1930 (eval_tests, "eval")):
1931 print(kind+"_results = [")
Victor Stinnerf0891962016-02-08 17:15:21 +01001932 for statement in statements:
1933 tree = ast.parse(statement, "?", kind)
1934 print("%r," % (to_tuple(tree),))
Neal Norwitzee9b10a2008-03-31 05:29:39 +00001935 print("]")
1936 print("main()")
1937 raise SystemExit
Brett Cannon3e9a9ae2013-06-12 21:25:59 -04001938 unittest.main()
Tim Peters400cbc32006-02-28 18:44:41 +00001939
Guido van Rossumdcfcd142019-01-31 03:40:27 -08001940#### EVERYTHING BELOW IS GENERATED BY python Lib/test/test_ast.py -g #####
Tim Peters400cbc32006-02-28 18:44:41 +00001941exec_results = [
Serhiy Storchaka850a8852020-01-10 10:12:55 +02001942('Module', [('Expr', (1, 0, 1, 4), ('Constant', (1, 0, 1, 4), None, None))], []),
1943('Module', [('Expr', (1, 0, 1, 18), ('Constant', (1, 0, 1, 18), 'module docstring', None))], []),
1944('Module', [('FunctionDef', (1, 0, 1, 13), 'f', ('arguments', [], [], None, [], [], None, []), [('Pass', (1, 9, 1, 13))], [], None, None)], []),
1945('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)], []),
1946('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)], []),
1947('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)], []),
1948('Module', [('FunctionDef', (1, 0, 1, 18), 'f', ('arguments', [], [], ('arg', (1, 7, 1, 11), 'args', None, None), [], [], None, []), [('Pass', (1, 14, 1, 18))], [], None, None)], []),
1949('Module', [('FunctionDef', (1, 0, 1, 21), 'f', ('arguments', [], [], None, [], [], ('arg', (1, 8, 1, 14), 'kwargs', None, None), []), [('Pass', (1, 17, 1, 21))], [], None, None)], []),
1950('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)], []),
1951('Module', [('ClassDef', (1, 0, 1, 12), 'C', [], [], [('Pass', (1, 8, 1, 12))], [])], []),
1952('Module', [('ClassDef', (1, 0, 1, 32), 'C', [], [], [('Expr', (1, 9, 1, 32), ('Constant', (1, 9, 1, 32), 'docstring for class C', None))], [])], []),
1953('Module', [('ClassDef', (1, 0, 1, 21), 'C', [('Name', (1, 8, 1, 14), 'object', ('Load',))], [], [('Pass', (1, 17, 1, 21))], [])], []),
1954('Module', [('FunctionDef', (1, 0, 1, 16), 'f', ('arguments', [], [], None, [], [], None, []), [('Return', (1, 8, 1, 16), ('Constant', (1, 15, 1, 16), 1, None))], [], None, None)], []),
1955('Module', [('Delete', (1, 0, 1, 5), [('Name', (1, 4, 1, 5), 'v', ('Del',))])], []),
1956('Module', [('Assign', (1, 0, 1, 5), [('Name', (1, 0, 1, 1), 'v', ('Store',))], ('Constant', (1, 4, 1, 5), 1, None), None)], []),
1957('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)], []),
1958('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)], []),
1959('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)], []),
1960('Module', [('AugAssign', (1, 0, 1, 6), ('Name', (1, 0, 1, 1), 'v', ('Store',)), ('Add',), ('Constant', (1, 5, 1, 6), 1, None))], []),
1961('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)], []),
1962('Module', [('While', (1, 0, 1, 12), ('Name', (1, 6, 1, 7), 'v', ('Load',)), [('Pass', (1, 8, 1, 12))], [])], []),
1963('Module', [('If', (1, 0, 1, 9), ('Name', (1, 3, 1, 4), 'v', ('Load',)), [('Pass', (1, 5, 1, 9))], [])], []),
1964('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))], [])])], []),
1965('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))])])], []),
1966('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)], []),
1967('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)], []),
1968('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)], []),
1969('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))])], [], [])], []),
1970('Module', [('Try', (1, 0, 4, 6), [('Pass', (2, 2, 2, 6))], [], [], [('Pass', (4, 2, 4, 6))])], []),
1971('Module', [('Assert', (1, 0, 1, 8), ('Name', (1, 7, 1, 8), 'v', ('Load',)), None)], []),
1972('Module', [('Import', (1, 0, 1, 10), [('alias', 'sys', None)])], []),
1973('Module', [('ImportFrom', (1, 0, 1, 17), 'sys', [('alias', 'v', None)], 0)], []),
1974('Module', [('Global', (1, 0, 1, 8), ['v'])], []),
1975('Module', [('Expr', (1, 0, 1, 1), ('Constant', (1, 0, 1, 1), 1, None))], []),
1976('Module', [('Pass', (1, 0, 1, 4))], []),
1977('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)], []),
1978('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)], []),
1979('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)], []),
1980('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)], []),
1981('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)], []),
1982('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)]))], []),
1983('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)]))], []),
1984('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)]))], []),
1985('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)]))], []),
1986('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)]))], []),
1987('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)], []),
1988('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)], []),
1989('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)], []),
1990('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)]))], []),
1991('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)]))], []),
1992('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)], []),
1993('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)], []),
1994('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)], []),
1995('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)], [])])], []),
1996('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 +01001997('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 +02001998('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)))], []),
1999('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)], []),
2000('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)], []),
2001('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)], []),
2002('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)], []),
2003('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)], []),
2004('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)], []),
2005('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)], []),
2006('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)], []),
2007('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)], []),
2008('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 +00002009]
2010single_results = [
Serhiy Storchaka850a8852020-01-10 10:12:55 +02002011('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 +00002012]
2013eval_results = [
Serhiy Storchaka850a8852020-01-10 10:12:55 +02002014('Expression', ('Constant', (1, 0, 1, 4), None, None)),
2015('Expression', ('BoolOp', (1, 0, 1, 7), ('And',), [('Name', (1, 0, 1, 1), 'a', ('Load',)), ('Name', (1, 6, 1, 7), 'b', ('Load',))])),
2016('Expression', ('BinOp', (1, 0, 1, 5), ('Name', (1, 0, 1, 1), 'a', ('Load',)), ('Add',), ('Name', (1, 4, 1, 5), 'b', ('Load',)))),
2017('Expression', ('UnaryOp', (1, 0, 1, 5), ('Not',), ('Name', (1, 4, 1, 5), 'v', ('Load',)))),
2018('Expression', ('Lambda', (1, 0, 1, 11), ('arguments', [], [], None, [], [], None, []), ('Constant', (1, 7, 1, 11), None, None))),
2019('Expression', ('Dict', (1, 0, 1, 7), [('Constant', (1, 2, 1, 3), 1, None)], [('Constant', (1, 4, 1, 5), 2, None)])),
2020('Expression', ('Dict', (1, 0, 1, 2), [], [])),
2021('Expression', ('Set', (1, 0, 1, 7), [('Constant', (1, 1, 1, 5), None, None)])),
2022('Expression', ('Dict', (1, 0, 5, 6), [('Constant', (2, 6, 2, 7), 1, None)], [('Constant', (4, 10, 4, 11), 2, None)])),
2023('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)])),
2024('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)])),
2025('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)])),
2026('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)])),
2027('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)])),
2028('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)])),
2029('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)])),
2030('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)])),
2031('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)])),
2032('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)])),
2033('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)])),
2034('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 +01002035('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 +02002036('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',))], [])),
2037('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)])], [])),
2038('Expression', ('Constant', (1, 0, 1, 2), 10, None)),
2039('Expression', ('Constant', (1, 0, 1, 8), 'string', None)),
2040('Expression', ('Attribute', (1, 0, 1, 3), ('Name', (1, 0, 1, 1), 'a', ('Load',)), 'b', ('Load',))),
Serhiy Storchaka13d52c22020-03-10 18:52:34 +02002041('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 +02002042('Expression', ('Name', (1, 0, 1, 1), 'v', ('Load',))),
2043('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',))),
2044('Expression', ('List', (1, 0, 1, 2), [], ('Load',))),
2045('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',))),
2046('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',))),
2047('Expression', ('Tuple', (1, 0, 1, 2), [], ('Load',))),
Serhiy Storchaka13d52c22020-03-10 18:52:34 +02002048('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 +00002049]
Neal Norwitzee9b10a2008-03-31 05:29:39 +00002050main()