blob: 51a7c1af1ffe70299debe6b8d4e7269e317c2e81 [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))
Tim Peters400cbc32006-02-28 18:44:41 +000020 if t._fields is None:
21 return tuple(result)
22 for f in t._fields:
23 result.append(to_tuple(getattr(t, f)))
24 return tuple(result)
25
Neal Norwitzee9b10a2008-03-31 05:29:39 +000026
Tim Peters400cbc32006-02-28 18:44:41 +000027# These tests are compiled through "exec"
Ezio Melotti85a86292013-08-17 16:57:41 +030028# There should be at least one test per statement
Tim Peters400cbc32006-02-28 18:44:41 +000029exec_tests = [
Benjamin Peterson6ccfe852011-06-27 17:46:06 -050030 # None
31 "None",
INADA Naokicb41b272017-02-23 00:31:59 +090032 # Module docstring
33 "'module docstring'",
Tim Peters400cbc32006-02-28 18:44:41 +000034 # FunctionDef
35 "def f(): pass",
INADA Naokicb41b272017-02-23 00:31:59 +090036 # FunctionDef with docstring
37 "def f(): 'function docstring'",
Benjamin Peterson6ccfe852011-06-27 17:46:06 -050038 # FunctionDef with arg
39 "def f(a): pass",
40 # FunctionDef with arg and default value
41 "def f(a=0): pass",
42 # FunctionDef with varargs
43 "def f(*args): pass",
44 # FunctionDef with kwargs
45 "def f(**kwargs): pass",
INADA Naokicb41b272017-02-23 00:31:59 +090046 # FunctionDef with all kind of args and docstring
47 "def f(a, b=1, c=None, d=[], e={}, *args, f=42, **kwargs): 'doc for f()'",
Tim Peters400cbc32006-02-28 18:44:41 +000048 # ClassDef
49 "class C:pass",
INADA Naokicb41b272017-02-23 00:31:59 +090050 # ClassDef with docstring
51 "class C: 'docstring for class C'",
Benjamin Peterson6ccfe852011-06-27 17:46:06 -050052 # ClassDef, new style class
53 "class C(object): pass",
Tim Peters400cbc32006-02-28 18:44:41 +000054 # Return
55 "def f():return 1",
56 # Delete
57 "del v",
58 # Assign
59 "v = 1",
Serhiy Storchakab619b092018-11-27 09:40:29 +020060 "a,b = c",
61 "(a,b) = c",
62 "[a,b] = c",
Tim Peters400cbc32006-02-28 18:44:41 +000063 # AugAssign
64 "v += 1",
Tim Peters400cbc32006-02-28 18:44:41 +000065 # For
66 "for v in v:pass",
67 # While
68 "while v:pass",
69 # If
70 "if v:pass",
Lysandros Nikolaou025a6022019-12-12 22:40:21 +010071 # If-Elif
72 "if a:\n pass\nelif b:\n pass",
Lysandros Nikolaou5936a4c2019-12-14 11:24:57 +010073 # If-Elif-Else
74 "if a:\n pass\nelif b:\n pass\nelse:\n pass",
Benjamin Petersonaeabd5f2011-05-27 15:02:03 -050075 # With
76 "with x as y: pass",
77 "with x as y, z as q: pass",
Tim Peters400cbc32006-02-28 18:44:41 +000078 # Raise
Collin Winter828f04a2007-08-31 00:04:24 +000079 "raise Exception('string')",
Tim Peters400cbc32006-02-28 18:44:41 +000080 # TryExcept
81 "try:\n pass\nexcept Exception:\n pass",
82 # TryFinally
83 "try:\n pass\nfinally:\n pass",
84 # Assert
85 "assert v",
86 # Import
87 "import sys",
88 # ImportFrom
89 "from sys import v",
Tim Peters400cbc32006-02-28 18:44:41 +000090 # Global
91 "global v",
92 # Expr
93 "1",
94 # Pass,
95 "pass",
96 # Break
Yury Selivanovb3d53132015-09-01 16:10:49 -040097 "for v in v:break",
Tim Peters400cbc32006-02-28 18:44:41 +000098 # Continue
Yury Selivanovb3d53132015-09-01 16:10:49 -040099 "for v in v:continue",
Benjamin Peterson2e4b0e12009-09-11 22:36:20 +0000100 # for statements with naked tuples (see http://bugs.python.org/issue6704)
101 "for a,b in c: pass",
Serhiy Storchakab619b092018-11-27 09:40:29 +0200102 "for (a,b) in c: pass",
103 "for [a,b] in c: pass",
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500104 # Multiline generator expression (test for .lineno & .col_offset)
105 """(
106 (
107 Aa
108 ,
109 Bb
110 )
111 for
112 Aa
113 ,
114 Bb in Cc
115 )""",
116 # dictcomp
117 "{a : b for w in x for m in p if g}",
118 # dictcomp with naked tuple
119 "{a : b for v,w in x}",
120 # setcomp
121 "{r for l in x if g}",
122 # setcomp with naked tuple
123 "{r for l,m in x}",
Yury Selivanov75445082015-05-11 22:57:16 -0400124 # AsyncFunctionDef
INADA Naokicb41b272017-02-23 00:31:59 +0900125 "async def f():\n 'async function'\n await something()",
Yury Selivanov75445082015-05-11 22:57:16 -0400126 # AsyncFor
127 "async def f():\n async for e in i: 1\n else: 2",
128 # AsyncWith
129 "async def f():\n async with a as b: 1",
Yury Selivanovb3d53132015-09-01 16:10:49 -0400130 # PEP 448: Additional Unpacking Generalizations
131 "{**{1:2}, 2:3}",
132 "{*{1, 2}, 3}",
Yury Selivanov52c4e7c2016-09-09 10:36:01 -0700133 # Asynchronous comprehensions
134 "async def f():\n [i async for b in c]",
Serhiy Storchaka95b6acf2018-10-30 13:16:02 +0200135 # Decorated FunctionDef
Serhiy Storchaka26ae9f62019-10-26 16:46:05 +0300136 "@deco1\n@deco2()\n@deco3(1)\ndef f(): pass",
Serhiy Storchaka95b6acf2018-10-30 13:16:02 +0200137 # Decorated AsyncFunctionDef
Serhiy Storchaka26ae9f62019-10-26 16:46:05 +0300138 "@deco1\n@deco2()\n@deco3(1)\nasync def f(): pass",
Serhiy Storchaka95b6acf2018-10-30 13:16:02 +0200139 # Decorated ClassDef
Serhiy Storchaka26ae9f62019-10-26 16:46:05 +0300140 "@deco1\n@deco2()\n@deco3(1)\nclass C: pass",
Serhiy Storchakab619b092018-11-27 09:40:29 +0200141 # Decorator with generator argument
142 "@deco(a for a in b)\ndef f(): pass",
Pablo Galindo0c9258a2019-03-18 13:51:53 +0000143 # Simple assignment expression
144 "(a := 1)",
Pablo Galindo2f58a842019-05-31 14:09:49 +0100145 # Positional-only arguments
146 "def f(a, /,): pass",
147 "def f(a, /, c, d, e): pass",
148 "def f(a, /, c, *, d, e): pass",
149 "def f(a, /, c, *, d, e, **kwargs): pass",
150 # Positional-only arguments with defaults
151 "def f(a=1, /,): pass",
152 "def f(a=1, /, b=2, c=4): pass",
153 "def f(a=1, /, b=2, *, c=4): pass",
154 "def f(a=1, /, b=2, *, c): pass",
155 "def f(a=1, /, b=2, *, c=4, **kwargs): pass",
156 "def f(a=1, /, b=2, *, c, **kwargs): pass",
Pablo Galindo0c9258a2019-03-18 13:51:53 +0000157
Tim Peters400cbc32006-02-28 18:44:41 +0000158]
159
160# These are compiled through "single"
161# because of overlap with "eval", it just tests what
162# can't be tested with "eval"
163single_tests = [
164 "1+2"
165]
166
167# These are compiled through "eval"
168# It should test all expressions
169eval_tests = [
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500170 # None
171 "None",
Tim Peters400cbc32006-02-28 18:44:41 +0000172 # BoolOp
173 "a and b",
174 # BinOp
175 "a + b",
176 # UnaryOp
177 "not v",
178 # Lambda
179 "lambda:None",
180 # Dict
181 "{ 1:2 }",
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500182 # Empty dict
183 "{}",
184 # Set
185 "{None,}",
186 # Multiline dict (test for .lineno & .col_offset)
187 """{
188 1
189 :
190 2
191 }""",
Tim Peters400cbc32006-02-28 18:44:41 +0000192 # ListComp
193 "[a for b in c if d]",
194 # GeneratorExp
195 "(a for b in c if d)",
Serhiy Storchakab619b092018-11-27 09:40:29 +0200196 # Comprehensions with multiple for targets
197 "[(a,b) for a,b in c]",
198 "[(a,b) for (a,b) in c]",
199 "[(a,b) for [a,b] in c]",
200 "{(a,b) for a,b in c}",
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)",
Tim Peters400cbc32006-02-28 18:44:41 +0000206 # Yield - yield expressions can't work outside a function
207 #
208 # Compare
209 "1 < 2 < 3",
210 # Call
211 "f(1,2,c=3,*d,**e)",
Lysandros Nikolaou50d4f122019-12-18 01:20:55 +0100212 # Call with multi-character starred
213 "f(*[0, 1])",
Serhiy Storchakab619b092018-11-27 09:40:29 +0200214 # Call with a generator argument
215 "f(a for a in b)",
Tim Peters400cbc32006-02-28 18:44:41 +0000216 # Num
Guido van Rossume2a383d2007-01-15 16:59:06 +0000217 "10",
Tim Peters400cbc32006-02-28 18:44:41 +0000218 # Str
219 "'string'",
220 # Attribute
221 "a.b",
222 # Subscript
223 "a[b:c]",
224 # Name
225 "v",
226 # List
227 "[1,2,3]",
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500228 # Empty list
229 "[]",
Tim Peters400cbc32006-02-28 18:44:41 +0000230 # Tuple
Martin v. Löwis49c5da12006-03-01 22:49:05 +0000231 "1,2,3",
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500232 # Tuple
233 "(1,2,3)",
234 # Empty tuple
235 "()",
Martin v. Löwis49c5da12006-03-01 22:49:05 +0000236 # Combination
237 "a.b.c.d(a.b[1:2])",
238
Tim Peters400cbc32006-02-28 18:44:41 +0000239]
240
241# TODO: expr_context, slice, boolop, operator, unaryop, cmpop, comprehension
242# excepthandler, arguments, keywords, alias
243
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000244class AST_Tests(unittest.TestCase):
Tim Peters400cbc32006-02-28 18:44:41 +0000245
Benjamin Peterson7a66fc22015-02-02 10:51:20 -0500246 def _assertTrueorder(self, ast_node, parent_pos):
Georg Brandl0c77a822008-06-10 16:37:50 +0000247 if not isinstance(ast_node, ast.AST) or ast_node._fields is None:
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000248 return
Georg Brandl0c77a822008-06-10 16:37:50 +0000249 if isinstance(ast_node, (ast.expr, ast.stmt, ast.excepthandler)):
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000250 node_pos = (ast_node.lineno, ast_node.col_offset)
Serhiy Storchaka95b6acf2018-10-30 13:16:02 +0200251 self.assertGreaterEqual(node_pos, parent_pos)
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000252 parent_pos = (ast_node.lineno, ast_node.col_offset)
253 for name in ast_node._fields:
254 value = getattr(ast_node, name)
255 if isinstance(value, list):
Serhiy Storchaka95b6acf2018-10-30 13:16:02 +0200256 first_pos = parent_pos
257 if value and name == 'decorator_list':
258 first_pos = (value[0].lineno, value[0].col_offset)
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000259 for child in value:
Serhiy Storchaka95b6acf2018-10-30 13:16:02 +0200260 self._assertTrueorder(child, first_pos)
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000261 elif value is not None:
Benjamin Peterson7a66fc22015-02-02 10:51:20 -0500262 self._assertTrueorder(value, parent_pos)
Tim Peters5ddfe412006-03-01 23:02:57 +0000263
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500264 def test_AST_objects(self):
265 x = ast.AST()
266 self.assertEqual(x._fields, ())
Benjamin Peterson7e0dbfb2012-03-12 09:46:44 -0700267 x.foobar = 42
268 self.assertEqual(x.foobar, 42)
269 self.assertEqual(x.__dict__["foobar"], 42)
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500270
271 with self.assertRaises(AttributeError):
272 x.vararg
273
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500274 with self.assertRaises(TypeError):
275 # "_ast.AST constructor takes 0 positional arguments"
276 ast.AST(2)
277
Benjamin Peterson9ed37432012-07-08 11:13:36 -0700278 def test_AST_garbage_collection(self):
279 class X:
280 pass
281 a = ast.AST()
282 a.x = X()
283 a.x.a = a
284 ref = weakref.ref(a.x)
285 del a
286 support.gc_collect()
287 self.assertIsNone(ref())
288
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000289 def test_snippets(self):
290 for input, output, kind in ((exec_tests, exec_results, "exec"),
291 (single_tests, single_results, "single"),
292 (eval_tests, eval_results, "eval")):
293 for i, o in zip(input, output):
Yury Selivanovb3d53132015-09-01 16:10:49 -0400294 with self.subTest(action="parsing", input=i):
295 ast_tree = compile(i, "?", kind, ast.PyCF_ONLY_AST)
296 self.assertEqual(to_tuple(ast_tree), o)
297 self._assertTrueorder(ast_tree, (0, 0))
Victor Stinner15a30952016-02-08 22:45:06 +0100298 with self.subTest(action="compiling", input=i, kind=kind):
299 compile(ast_tree, "?", kind)
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000300
Pablo Galindo0c9258a2019-03-18 13:51:53 +0000301 def test_ast_validation(self):
302 # compile() is the only function that calls PyAST_Validate
303 snippets_to_validate = exec_tests + single_tests + eval_tests
304 for snippet in snippets_to_validate:
305 tree = ast.parse(snippet)
306 compile(tree, '<string>', 'exec')
307
Benjamin Peterson78565b22009-06-28 19:19:51 +0000308 def test_slice(self):
309 slc = ast.parse("x[::]").body[0].value.slice
310 self.assertIsNone(slc.upper)
311 self.assertIsNone(slc.lower)
312 self.assertIsNone(slc.step)
313
314 def test_from_import(self):
315 im = ast.parse("from . import y").body[0]
316 self.assertIsNone(im.module)
317
Benjamin Petersona4e4e352012-03-22 08:19:04 -0400318 def test_non_interned_future_from_ast(self):
319 mod = ast.parse("from __future__ import division")
320 self.assertIsInstance(mod.body[0], ast.ImportFrom)
321 mod.body[0].module = " __future__ ".strip()
322 compile(mod, "<test>", "exec")
323
Benjamin Petersona0dfa822009-11-13 02:25:08 +0000324 def test_base_classes(self):
325 self.assertTrue(issubclass(ast.For, ast.stmt))
326 self.assertTrue(issubclass(ast.Name, ast.expr))
327 self.assertTrue(issubclass(ast.stmt, ast.AST))
328 self.assertTrue(issubclass(ast.expr, ast.AST))
329 self.assertTrue(issubclass(ast.comprehension, ast.AST))
330 self.assertTrue(issubclass(ast.Gt, ast.AST))
331
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500332 def test_field_attr_existence(self):
333 for name, item in ast.__dict__.items():
334 if isinstance(item, type) and name != 'AST' and name[0].isupper():
335 x = item()
336 if isinstance(x, ast.AST):
337 self.assertEqual(type(x._fields), tuple)
338
339 def test_arguments(self):
340 x = ast.arguments()
Pablo Galindocd6e83b2019-07-15 01:32:18 +0200341 self.assertEqual(x._fields, ('posonlyargs', 'args', 'vararg', 'kwonlyargs',
342 'kw_defaults', 'kwarg', 'defaults'))
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500343
344 with self.assertRaises(AttributeError):
345 x.vararg
346
Pablo Galindo8c77b8c2019-04-29 13:36:57 +0100347 x = ast.arguments(*range(1, 8))
348 self.assertEqual(x.vararg, 3)
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500349
350 def test_field_attr_writable(self):
351 x = ast.Num()
352 # We can assign to _fields
353 x._fields = 666
354 self.assertEqual(x._fields, 666)
355
356 def test_classattrs(self):
357 x = ast.Num()
Guido van Rossum10f8ce62019-03-13 13:00:46 -0700358 self.assertEqual(x._fields, ('value', 'kind'))
Serhiy Storchaka3f228112018-09-27 17:42:37 +0300359
360 with self.assertRaises(AttributeError):
361 x.value
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500362
363 with self.assertRaises(AttributeError):
364 x.n
365
366 x = ast.Num(42)
Serhiy Storchaka3f228112018-09-27 17:42:37 +0300367 self.assertEqual(x.value, 42)
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500368 self.assertEqual(x.n, 42)
369
370 with self.assertRaises(AttributeError):
371 x.lineno
372
373 with self.assertRaises(AttributeError):
374 x.foobar
375
376 x = ast.Num(lineno=2)
377 self.assertEqual(x.lineno, 2)
378
379 x = ast.Num(42, lineno=0)
380 self.assertEqual(x.lineno, 0)
Guido van Rossum10f8ce62019-03-13 13:00:46 -0700381 self.assertEqual(x._fields, ('value', 'kind'))
Serhiy Storchaka3f228112018-09-27 17:42:37 +0300382 self.assertEqual(x.value, 42)
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500383 self.assertEqual(x.n, 42)
384
Guido van Rossum10f8ce62019-03-13 13:00:46 -0700385 self.assertRaises(TypeError, ast.Num, 1, None, 2)
386 self.assertRaises(TypeError, ast.Num, 1, None, 2, lineno=0)
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500387
Serhiy Storchaka3f228112018-09-27 17:42:37 +0300388 self.assertEqual(ast.Num(42).n, 42)
389 self.assertEqual(ast.Num(4.25).n, 4.25)
390 self.assertEqual(ast.Num(4.25j).n, 4.25j)
391 self.assertEqual(ast.Str('42').s, '42')
392 self.assertEqual(ast.Bytes(b'42').s, b'42')
393 self.assertIs(ast.NameConstant(True).value, True)
394 self.assertIs(ast.NameConstant(False).value, False)
395 self.assertIs(ast.NameConstant(None).value, None)
396
397 self.assertEqual(ast.Constant(42).value, 42)
398 self.assertEqual(ast.Constant(4.25).value, 4.25)
399 self.assertEqual(ast.Constant(4.25j).value, 4.25j)
400 self.assertEqual(ast.Constant('42').value, '42')
401 self.assertEqual(ast.Constant(b'42').value, b'42')
402 self.assertIs(ast.Constant(True).value, True)
403 self.assertIs(ast.Constant(False).value, False)
404 self.assertIs(ast.Constant(None).value, None)
405 self.assertIs(ast.Constant(...).value, ...)
406
407 def test_realtype(self):
408 self.assertEqual(type(ast.Num(42)), ast.Constant)
409 self.assertEqual(type(ast.Num(4.25)), ast.Constant)
410 self.assertEqual(type(ast.Num(4.25j)), ast.Constant)
411 self.assertEqual(type(ast.Str('42')), ast.Constant)
412 self.assertEqual(type(ast.Bytes(b'42')), ast.Constant)
413 self.assertEqual(type(ast.NameConstant(True)), ast.Constant)
414 self.assertEqual(type(ast.NameConstant(False)), ast.Constant)
415 self.assertEqual(type(ast.NameConstant(None)), ast.Constant)
416 self.assertEqual(type(ast.Ellipsis()), ast.Constant)
417
418 def test_isinstance(self):
419 self.assertTrue(isinstance(ast.Num(42), ast.Num))
420 self.assertTrue(isinstance(ast.Num(4.2), ast.Num))
421 self.assertTrue(isinstance(ast.Num(4.2j), ast.Num))
422 self.assertTrue(isinstance(ast.Str('42'), ast.Str))
423 self.assertTrue(isinstance(ast.Bytes(b'42'), ast.Bytes))
424 self.assertTrue(isinstance(ast.NameConstant(True), ast.NameConstant))
425 self.assertTrue(isinstance(ast.NameConstant(False), ast.NameConstant))
426 self.assertTrue(isinstance(ast.NameConstant(None), ast.NameConstant))
427 self.assertTrue(isinstance(ast.Ellipsis(), ast.Ellipsis))
428
429 self.assertTrue(isinstance(ast.Constant(42), ast.Num))
430 self.assertTrue(isinstance(ast.Constant(4.2), ast.Num))
431 self.assertTrue(isinstance(ast.Constant(4.2j), ast.Num))
432 self.assertTrue(isinstance(ast.Constant('42'), ast.Str))
433 self.assertTrue(isinstance(ast.Constant(b'42'), ast.Bytes))
434 self.assertTrue(isinstance(ast.Constant(True), ast.NameConstant))
435 self.assertTrue(isinstance(ast.Constant(False), ast.NameConstant))
436 self.assertTrue(isinstance(ast.Constant(None), ast.NameConstant))
437 self.assertTrue(isinstance(ast.Constant(...), ast.Ellipsis))
438
439 self.assertFalse(isinstance(ast.Str('42'), ast.Num))
440 self.assertFalse(isinstance(ast.Num(42), ast.Str))
441 self.assertFalse(isinstance(ast.Str('42'), ast.Bytes))
442 self.assertFalse(isinstance(ast.Num(42), ast.NameConstant))
443 self.assertFalse(isinstance(ast.Num(42), ast.Ellipsis))
Anthony Sottile74176222019-01-18 11:30:28 -0800444 self.assertFalse(isinstance(ast.NameConstant(True), ast.Num))
445 self.assertFalse(isinstance(ast.NameConstant(False), ast.Num))
Serhiy Storchaka3f228112018-09-27 17:42:37 +0300446
447 self.assertFalse(isinstance(ast.Constant('42'), ast.Num))
448 self.assertFalse(isinstance(ast.Constant(42), ast.Str))
449 self.assertFalse(isinstance(ast.Constant('42'), ast.Bytes))
450 self.assertFalse(isinstance(ast.Constant(42), ast.NameConstant))
451 self.assertFalse(isinstance(ast.Constant(42), ast.Ellipsis))
Anthony Sottile74176222019-01-18 11:30:28 -0800452 self.assertFalse(isinstance(ast.Constant(True), ast.Num))
453 self.assertFalse(isinstance(ast.Constant(False), ast.Num))
Serhiy Storchaka3f228112018-09-27 17:42:37 +0300454
455 self.assertFalse(isinstance(ast.Constant(), ast.Num))
456 self.assertFalse(isinstance(ast.Constant(), ast.Str))
457 self.assertFalse(isinstance(ast.Constant(), ast.Bytes))
458 self.assertFalse(isinstance(ast.Constant(), ast.NameConstant))
459 self.assertFalse(isinstance(ast.Constant(), ast.Ellipsis))
460
Serhiy Storchaka6015cc52018-10-28 13:43:03 +0200461 class S(str): pass
462 self.assertTrue(isinstance(ast.Constant(S('42')), ast.Str))
463 self.assertFalse(isinstance(ast.Constant(S('42')), ast.Num))
464
Serhiy Storchaka3f228112018-09-27 17:42:37 +0300465 def test_subclasses(self):
466 class N(ast.Num):
467 def __init__(self, *args, **kwargs):
468 super().__init__(*args, **kwargs)
469 self.z = 'spam'
470 class N2(ast.Num):
471 pass
472
473 n = N(42)
474 self.assertEqual(n.n, 42)
475 self.assertEqual(n.z, 'spam')
476 self.assertEqual(type(n), N)
477 self.assertTrue(isinstance(n, N))
478 self.assertTrue(isinstance(n, ast.Num))
479 self.assertFalse(isinstance(n, N2))
480 self.assertFalse(isinstance(ast.Num(42), N))
481 n = N(n=42)
482 self.assertEqual(n.n, 42)
483 self.assertEqual(type(n), N)
484
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500485 def test_module(self):
486 body = [ast.Num(42)]
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800487 x = ast.Module(body, [])
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500488 self.assertEqual(x.body, body)
489
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000490 def test_nodeclasses(self):
Florent Xicluna992d9e02011-11-11 19:35:42 +0100491 # Zero arguments constructor explicitly allowed
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500492 x = ast.BinOp()
493 self.assertEqual(x._fields, ('left', 'op', 'right'))
494
495 # Random attribute allowed too
496 x.foobarbaz = 5
497 self.assertEqual(x.foobarbaz, 5)
498
499 n1 = ast.Num(1)
500 n3 = ast.Num(3)
501 addop = ast.Add()
502 x = ast.BinOp(n1, addop, n3)
503 self.assertEqual(x.left, n1)
504 self.assertEqual(x.op, addop)
505 self.assertEqual(x.right, n3)
Benjamin Peterson68b543a2011-06-27 17:51:18 -0500506
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500507 x = ast.BinOp(1, 2, 3)
508 self.assertEqual(x.left, 1)
509 self.assertEqual(x.op, 2)
510 self.assertEqual(x.right, 3)
511
Georg Brandl0c77a822008-06-10 16:37:50 +0000512 x = ast.BinOp(1, 2, 3, lineno=0)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000513 self.assertEqual(x.left, 1)
514 self.assertEqual(x.op, 2)
515 self.assertEqual(x.right, 3)
516 self.assertEqual(x.lineno, 0)
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000517
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500518 # node raises exception when given too many arguments
519 self.assertRaises(TypeError, ast.BinOp, 1, 2, 3, 4)
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500520 # node raises exception when given too many arguments
521 self.assertRaises(TypeError, ast.BinOp, 1, 2, 3, 4, lineno=0)
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000522
523 # can set attributes through kwargs too
Georg Brandl0c77a822008-06-10 16:37:50 +0000524 x = ast.BinOp(left=1, op=2, right=3, lineno=0)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000525 self.assertEqual(x.left, 1)
526 self.assertEqual(x.op, 2)
527 self.assertEqual(x.right, 3)
528 self.assertEqual(x.lineno, 0)
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000529
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500530 # Random kwargs also allowed
531 x = ast.BinOp(1, 2, 3, foobarbaz=42)
532 self.assertEqual(x.foobarbaz, 42)
533
534 def test_no_fields(self):
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000535 # this used to fail because Sub._fields was None
Georg Brandl0c77a822008-06-10 16:37:50 +0000536 x = ast.Sub()
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500537 self.assertEqual(x._fields, ())
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000538
539 def test_pickling(self):
540 import pickle
541 mods = [pickle]
542 try:
543 import cPickle
544 mods.append(cPickle)
545 except ImportError:
546 pass
547 protocols = [0, 1, 2]
548 for mod in mods:
549 for protocol in protocols:
550 for ast in (compile(i, "?", "exec", 0x400) for i in exec_tests):
551 ast2 = mod.loads(mod.dumps(ast, protocol))
Ezio Melottib3aedd42010-11-20 19:04:17 +0000552 self.assertEqual(to_tuple(ast2), to_tuple(ast))
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000553
Benjamin Peterson5b066812010-11-20 01:38:49 +0000554 def test_invalid_sum(self):
555 pos = dict(lineno=2, col_offset=3)
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800556 m = ast.Module([ast.Expr(ast.expr(**pos), **pos)], [])
Benjamin Peterson5b066812010-11-20 01:38:49 +0000557 with self.assertRaises(TypeError) as cm:
558 compile(m, "<test>", "exec")
559 self.assertIn("but got <_ast.expr", str(cm.exception))
560
Min ho Kimc4cacc82019-07-31 08:16:13 +1000561 def test_invalid_identifier(self):
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800562 m = ast.Module([ast.Expr(ast.Name(42, ast.Load()))], [])
Benjamin Peterson2193d2b2011-07-22 10:50:23 -0500563 ast.fix_missing_locations(m)
564 with self.assertRaises(TypeError) as cm:
565 compile(m, "<test>", "exec")
566 self.assertIn("identifier must be of type str", str(cm.exception))
567
Mark Dickinsonded35ae2012-11-25 14:36:26 +0000568 def test_empty_yield_from(self):
569 # Issue 16546: yield from value is not optional.
570 empty_yield_from = ast.parse("def f():\n yield from g()")
571 empty_yield_from.body[0].body[0].value.value = None
572 with self.assertRaises(ValueError) as cm:
573 compile(empty_yield_from, "<test>", "exec")
574 self.assertIn("field value is required", str(cm.exception))
575
Oren Milman7dc46d82017-09-30 20:16:24 +0300576 @support.cpython_only
577 def test_issue31592(self):
578 # There shouldn't be an assertion failure in case of a bad
579 # unicodedata.normalize().
580 import unicodedata
581 def bad_normalize(*args):
582 return None
583 with support.swap_attr(unicodedata, 'normalize', bad_normalize):
584 self.assertRaises(TypeError, ast.parse, '\u03D5')
585
Carl Friedrich Bolz-Tereick110a47c2019-07-08 23:17:56 +0200586 def test_issue18374_binop_col_offset(self):
587 tree = ast.parse('4+5+6+7')
588 parent_binop = tree.body[0].value
589 child_binop = parent_binop.left
590 grandchild_binop = child_binop.left
591 self.assertEqual(parent_binop.col_offset, 0)
592 self.assertEqual(parent_binop.end_col_offset, 7)
593 self.assertEqual(child_binop.col_offset, 0)
594 self.assertEqual(child_binop.end_col_offset, 5)
595 self.assertEqual(grandchild_binop.col_offset, 0)
596 self.assertEqual(grandchild_binop.end_col_offset, 3)
597
598 tree = ast.parse('4+5-\\\n 6-7')
599 parent_binop = tree.body[0].value
600 child_binop = parent_binop.left
601 grandchild_binop = child_binop.left
602 self.assertEqual(parent_binop.col_offset, 0)
603 self.assertEqual(parent_binop.lineno, 1)
604 self.assertEqual(parent_binop.end_col_offset, 4)
605 self.assertEqual(parent_binop.end_lineno, 2)
606
607 self.assertEqual(child_binop.col_offset, 0)
Carl Friedrich Bolz-Tereick430a9f42019-07-09 14:20:01 +0200608 self.assertEqual(child_binop.lineno, 1)
Carl Friedrich Bolz-Tereick110a47c2019-07-08 23:17:56 +0200609 self.assertEqual(child_binop.end_col_offset, 2)
Carl Friedrich Bolz-Tereick430a9f42019-07-09 14:20:01 +0200610 self.assertEqual(child_binop.end_lineno, 2)
Carl Friedrich Bolz-Tereick110a47c2019-07-08 23:17:56 +0200611
612 self.assertEqual(grandchild_binop.col_offset, 0)
Carl Friedrich Bolz-Tereick430a9f42019-07-09 14:20:01 +0200613 self.assertEqual(grandchild_binop.lineno, 1)
Carl Friedrich Bolz-Tereick110a47c2019-07-08 23:17:56 +0200614 self.assertEqual(grandchild_binop.end_col_offset, 3)
Carl Friedrich Bolz-Tereick430a9f42019-07-09 14:20:01 +0200615 self.assertEqual(grandchild_binop.end_lineno, 1)
Georg Brandl0c77a822008-06-10 16:37:50 +0000616
617class ASTHelpers_Test(unittest.TestCase):
Guido van Rossum10f8ce62019-03-13 13:00:46 -0700618 maxDiff = None
Georg Brandl0c77a822008-06-10 16:37:50 +0000619
620 def test_parse(self):
621 a = ast.parse('foo(1 + 1)')
622 b = compile('foo(1 + 1)', '<unknown>', 'exec', ast.PyCF_ONLY_AST)
623 self.assertEqual(ast.dump(a), ast.dump(b))
624
Benjamin Peterson2e2c9032012-09-02 14:23:15 -0400625 def test_parse_in_error(self):
626 try:
627 1/0
628 except Exception:
Benjamin Petersonbd0df502012-09-02 15:04:51 -0400629 with self.assertRaises(SyntaxError) as e:
630 ast.literal_eval(r"'\U'")
631 self.assertIsNotNone(e.exception.__context__)
Benjamin Peterson2e2c9032012-09-02 14:23:15 -0400632
Georg Brandl0c77a822008-06-10 16:37:50 +0000633 def test_dump(self):
634 node = ast.parse('spam(eggs, "and cheese")')
635 self.assertEqual(ast.dump(node),
636 "Module(body=[Expr(value=Call(func=Name(id='spam', ctx=Load()), "
Guido van Rossum10f8ce62019-03-13 13:00:46 -0700637 "args=[Name(id='eggs', ctx=Load()), Constant(value='and cheese', kind=None)], "
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800638 "keywords=[]))], type_ignores=[])"
Georg Brandl0c77a822008-06-10 16:37:50 +0000639 )
640 self.assertEqual(ast.dump(node, annotate_fields=False),
641 "Module([Expr(Call(Name('spam', Load()), [Name('eggs', Load()), "
Guido van Rossum10f8ce62019-03-13 13:00:46 -0700642 "Constant('and cheese', None)], []))], [])"
Georg Brandl0c77a822008-06-10 16:37:50 +0000643 )
644 self.assertEqual(ast.dump(node, include_attributes=True),
645 "Module(body=[Expr(value=Call(func=Name(id='spam', ctx=Load(), "
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000646 "lineno=1, col_offset=0, end_lineno=1, end_col_offset=4), "
647 "args=[Name(id='eggs', ctx=Load(), lineno=1, col_offset=5, "
Guido van Rossum10f8ce62019-03-13 13:00:46 -0700648 "end_lineno=1, end_col_offset=9), Constant(value='and cheese', kind=None, "
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000649 "lineno=1, col_offset=11, end_lineno=1, end_col_offset=23)], keywords=[], "
650 "lineno=1, col_offset=0, end_lineno=1, end_col_offset=24), "
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800651 "lineno=1, col_offset=0, end_lineno=1, end_col_offset=24)], type_ignores=[])"
Georg Brandl0c77a822008-06-10 16:37:50 +0000652 )
653
Serhiy Storchaka850573b2019-09-09 19:33:13 +0300654 def test_dump_indent(self):
655 node = ast.parse('spam(eggs, "and cheese")')
656 self.assertEqual(ast.dump(node, indent=3), """\
657Module(
658 body=[
659 Expr(
660 value=Call(
661 func=Name(id='spam', ctx=Load()),
662 args=[
663 Name(id='eggs', ctx=Load()),
664 Constant(value='and cheese', kind=None)],
665 keywords=[]))],
666 type_ignores=[])""")
667 self.assertEqual(ast.dump(node, annotate_fields=False, indent='\t'), """\
668Module(
669\t[
670\t\tExpr(
671\t\t\tCall(
672\t\t\t\tName('spam', Load()),
673\t\t\t\t[
674\t\t\t\t\tName('eggs', Load()),
675\t\t\t\t\tConstant('and cheese', None)],
676\t\t\t\t[]))],
677\t[])""")
678 self.assertEqual(ast.dump(node, include_attributes=True, indent=3), """\
679Module(
680 body=[
681 Expr(
682 value=Call(
683 func=Name(
684 id='spam',
685 ctx=Load(),
686 lineno=1,
687 col_offset=0,
688 end_lineno=1,
689 end_col_offset=4),
690 args=[
691 Name(
692 id='eggs',
693 ctx=Load(),
694 lineno=1,
695 col_offset=5,
696 end_lineno=1,
697 end_col_offset=9),
698 Constant(
699 value='and cheese',
700 kind=None,
701 lineno=1,
702 col_offset=11,
703 end_lineno=1,
704 end_col_offset=23)],
705 keywords=[],
706 lineno=1,
707 col_offset=0,
708 end_lineno=1,
709 end_col_offset=24),
710 lineno=1,
711 col_offset=0,
712 end_lineno=1,
713 end_col_offset=24)],
714 type_ignores=[])""")
715
Serhiy Storchakae64f9482019-08-29 09:30:23 +0300716 def test_dump_incomplete(self):
717 node = ast.Raise(lineno=3, col_offset=4)
718 self.assertEqual(ast.dump(node),
719 "Raise()"
720 )
721 self.assertEqual(ast.dump(node, include_attributes=True),
722 "Raise(lineno=3, col_offset=4)"
723 )
724 node = ast.Raise(exc=ast.Name(id='e', ctx=ast.Load()), lineno=3, col_offset=4)
725 self.assertEqual(ast.dump(node),
726 "Raise(exc=Name(id='e', ctx=Load()))"
727 )
728 self.assertEqual(ast.dump(node, annotate_fields=False),
729 "Raise(Name('e', Load()))"
730 )
731 self.assertEqual(ast.dump(node, include_attributes=True),
732 "Raise(exc=Name(id='e', ctx=Load()), lineno=3, col_offset=4)"
733 )
734 self.assertEqual(ast.dump(node, annotate_fields=False, include_attributes=True),
735 "Raise(Name('e', Load()), lineno=3, col_offset=4)"
736 )
737 node = ast.Raise(cause=ast.Name(id='e', ctx=ast.Load()))
738 self.assertEqual(ast.dump(node),
739 "Raise(cause=Name(id='e', ctx=Load()))"
740 )
741 self.assertEqual(ast.dump(node, annotate_fields=False),
742 "Raise(cause=Name('e', Load()))"
743 )
744
Georg Brandl0c77a822008-06-10 16:37:50 +0000745 def test_copy_location(self):
746 src = ast.parse('1 + 1', mode='eval')
747 src.body.right = ast.copy_location(ast.Num(2), src.body.right)
748 self.assertEqual(ast.dump(src, include_attributes=True),
Guido van Rossum10f8ce62019-03-13 13:00:46 -0700749 'Expression(body=BinOp(left=Constant(value=1, kind=None, lineno=1, col_offset=0, '
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000750 'end_lineno=1, end_col_offset=1), op=Add(), right=Constant(value=2, '
751 'lineno=1, col_offset=4, end_lineno=1, end_col_offset=5), lineno=1, '
752 'col_offset=0, end_lineno=1, end_col_offset=5))'
Georg Brandl0c77a822008-06-10 16:37:50 +0000753 )
754
755 def test_fix_missing_locations(self):
756 src = ast.parse('write("spam")')
757 src.body.append(ast.Expr(ast.Call(ast.Name('spam', ast.Load()),
Benjamin Peterson025e9eb2015-05-05 20:16:41 -0400758 [ast.Str('eggs')], [])))
Georg Brandl0c77a822008-06-10 16:37:50 +0000759 self.assertEqual(src, ast.fix_missing_locations(src))
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000760 self.maxDiff = None
Georg Brandl0c77a822008-06-10 16:37:50 +0000761 self.assertEqual(ast.dump(src, include_attributes=True),
762 "Module(body=[Expr(value=Call(func=Name(id='write', ctx=Load(), "
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000763 "lineno=1, col_offset=0, end_lineno=1, end_col_offset=5), "
Guido van Rossum10f8ce62019-03-13 13:00:46 -0700764 "args=[Constant(value='spam', kind=None, lineno=1, col_offset=6, end_lineno=1, "
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000765 "end_col_offset=12)], keywords=[], lineno=1, col_offset=0, end_lineno=1, "
766 "end_col_offset=13), lineno=1, col_offset=0, end_lineno=1, "
767 "end_col_offset=13), Expr(value=Call(func=Name(id='spam', ctx=Load(), "
768 "lineno=1, col_offset=0, end_lineno=1, end_col_offset=0), "
769 "args=[Constant(value='eggs', lineno=1, col_offset=0, end_lineno=1, "
770 "end_col_offset=0)], keywords=[], lineno=1, col_offset=0, end_lineno=1, "
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800771 "end_col_offset=0), lineno=1, col_offset=0, end_lineno=1, end_col_offset=0)], "
772 "type_ignores=[])"
Georg Brandl0c77a822008-06-10 16:37:50 +0000773 )
774
775 def test_increment_lineno(self):
776 src = ast.parse('1 + 1', mode='eval')
777 self.assertEqual(ast.increment_lineno(src, n=3), src)
778 self.assertEqual(ast.dump(src, include_attributes=True),
Guido van Rossum10f8ce62019-03-13 13:00:46 -0700779 'Expression(body=BinOp(left=Constant(value=1, kind=None, lineno=4, col_offset=0, '
780 'end_lineno=4, end_col_offset=1), op=Add(), right=Constant(value=1, kind=None, '
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000781 'lineno=4, col_offset=4, end_lineno=4, end_col_offset=5), lineno=4, '
782 'col_offset=0, end_lineno=4, end_col_offset=5))'
Georg Brandl0c77a822008-06-10 16:37:50 +0000783 )
Georg Brandl619e7ba2011-01-09 07:38:51 +0000784 # issue10869: do not increment lineno of root twice
Georg Brandlefb69022011-01-09 07:50:48 +0000785 src = ast.parse('1 + 1', mode='eval')
Georg Brandl619e7ba2011-01-09 07:38:51 +0000786 self.assertEqual(ast.increment_lineno(src.body, n=3), src.body)
787 self.assertEqual(ast.dump(src, include_attributes=True),
Guido van Rossum10f8ce62019-03-13 13:00:46 -0700788 'Expression(body=BinOp(left=Constant(value=1, kind=None, lineno=4, col_offset=0, '
789 'end_lineno=4, end_col_offset=1), op=Add(), right=Constant(value=1, kind=None, '
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000790 'lineno=4, col_offset=4, end_lineno=4, end_col_offset=5), lineno=4, '
791 'col_offset=0, end_lineno=4, end_col_offset=5))'
Georg Brandl619e7ba2011-01-09 07:38:51 +0000792 )
Georg Brandl0c77a822008-06-10 16:37:50 +0000793
794 def test_iter_fields(self):
795 node = ast.parse('foo()', mode='eval')
796 d = dict(ast.iter_fields(node.body))
797 self.assertEqual(d.pop('func').id, 'foo')
Benjamin Peterson025e9eb2015-05-05 20:16:41 -0400798 self.assertEqual(d, {'keywords': [], 'args': []})
Georg Brandl0c77a822008-06-10 16:37:50 +0000799
800 def test_iter_child_nodes(self):
801 node = ast.parse("spam(23, 42, eggs='leek')", mode='eval')
802 self.assertEqual(len(list(ast.iter_child_nodes(node.body))), 4)
803 iterator = ast.iter_child_nodes(node.body)
804 self.assertEqual(next(iterator).id, 'spam')
Serhiy Storchaka3f228112018-09-27 17:42:37 +0300805 self.assertEqual(next(iterator).value, 23)
806 self.assertEqual(next(iterator).value, 42)
Georg Brandl0c77a822008-06-10 16:37:50 +0000807 self.assertEqual(ast.dump(next(iterator)),
Guido van Rossum10f8ce62019-03-13 13:00:46 -0700808 "keyword(arg='eggs', value=Constant(value='leek', kind=None))"
Georg Brandl0c77a822008-06-10 16:37:50 +0000809 )
810
811 def test_get_docstring(self):
Serhiy Storchaka08f127a2018-06-15 11:05:15 +0300812 node = ast.parse('"""line one\n line two"""')
813 self.assertEqual(ast.get_docstring(node),
814 'line one\nline two')
815
816 node = ast.parse('class foo:\n """line one\n line two"""')
817 self.assertEqual(ast.get_docstring(node.body[0]),
818 'line one\nline two')
819
Georg Brandl0c77a822008-06-10 16:37:50 +0000820 node = ast.parse('def foo():\n """line one\n line two"""')
821 self.assertEqual(ast.get_docstring(node.body[0]),
822 'line one\nline two')
823
Yury Selivanov2f07a662015-07-23 08:54:35 +0300824 node = ast.parse('async def foo():\n """spam\n ham"""')
825 self.assertEqual(ast.get_docstring(node.body[0]), 'spam\nham')
Serhiy Storchaka08f127a2018-06-15 11:05:15 +0300826
827 def test_get_docstring_none(self):
Matthias Bussonnier41cea702017-02-23 22:44:19 -0800828 self.assertIsNone(ast.get_docstring(ast.parse('')))
Serhiy Storchaka08f127a2018-06-15 11:05:15 +0300829 node = ast.parse('x = "not docstring"')
830 self.assertIsNone(ast.get_docstring(node))
831 node = ast.parse('def foo():\n pass')
832 self.assertIsNone(ast.get_docstring(node))
833
834 node = ast.parse('class foo:\n pass')
835 self.assertIsNone(ast.get_docstring(node.body[0]))
836 node = ast.parse('class foo:\n x = "not docstring"')
837 self.assertIsNone(ast.get_docstring(node.body[0]))
838 node = ast.parse('class foo:\n def bar(self): pass')
839 self.assertIsNone(ast.get_docstring(node.body[0]))
840
841 node = ast.parse('def foo():\n pass')
842 self.assertIsNone(ast.get_docstring(node.body[0]))
843 node = ast.parse('def foo():\n x = "not docstring"')
844 self.assertIsNone(ast.get_docstring(node.body[0]))
845
846 node = ast.parse('async def foo():\n pass')
847 self.assertIsNone(ast.get_docstring(node.body[0]))
848 node = ast.parse('async def foo():\n x = "not docstring"')
849 self.assertIsNone(ast.get_docstring(node.body[0]))
Yury Selivanov2f07a662015-07-23 08:54:35 +0300850
Anthony Sottile995d9b92019-01-12 20:05:13 -0800851 def test_multi_line_docstring_col_offset_and_lineno_issue16806(self):
852 node = ast.parse(
853 '"""line one\nline two"""\n\n'
854 'def foo():\n """line one\n line two"""\n\n'
855 ' def bar():\n """line one\n line two"""\n'
856 ' """line one\n line two"""\n'
857 '"""line one\nline two"""\n\n'
858 )
859 self.assertEqual(node.body[0].col_offset, 0)
860 self.assertEqual(node.body[0].lineno, 1)
861 self.assertEqual(node.body[1].body[0].col_offset, 2)
862 self.assertEqual(node.body[1].body[0].lineno, 5)
863 self.assertEqual(node.body[1].body[1].body[0].col_offset, 4)
864 self.assertEqual(node.body[1].body[1].body[0].lineno, 9)
865 self.assertEqual(node.body[1].body[2].col_offset, 2)
866 self.assertEqual(node.body[1].body[2].lineno, 11)
867 self.assertEqual(node.body[2].col_offset, 0)
868 self.assertEqual(node.body[2].lineno, 13)
869
Lysandros Nikolaou025a6022019-12-12 22:40:21 +0100870 def test_elif_stmt_start_position(self):
871 node = ast.parse('if a:\n pass\nelif b:\n pass\n')
872 elif_stmt = node.body[0].orelse[0]
873 self.assertEqual(elif_stmt.lineno, 3)
874 self.assertEqual(elif_stmt.col_offset, 0)
875
Lysandros Nikolaou5936a4c2019-12-14 11:24:57 +0100876 def test_elif_stmt_start_position_with_else(self):
877 node = ast.parse('if a:\n pass\nelif b:\n pass\nelse:\n pass\n')
878 elif_stmt = node.body[0].orelse[0]
879 self.assertEqual(elif_stmt.lineno, 3)
880 self.assertEqual(elif_stmt.col_offset, 0)
881
Lysandros Nikolaou50d4f122019-12-18 01:20:55 +0100882 def test_starred_expr_end_position_within_call(self):
883 node = ast.parse('f(*[0, 1])')
884 starred_expr = node.body[0].value.args[0]
885 self.assertEqual(starred_expr.end_lineno, 1)
886 self.assertEqual(starred_expr.end_col_offset, 9)
887
Georg Brandl0c77a822008-06-10 16:37:50 +0000888 def test_literal_eval(self):
889 self.assertEqual(ast.literal_eval('[1, 2, 3]'), [1, 2, 3])
890 self.assertEqual(ast.literal_eval('{"foo": 42}'), {"foo": 42})
891 self.assertEqual(ast.literal_eval('(True, False, None)'), (True, False, None))
Benjamin Peterson3e742892010-07-11 12:59:24 +0000892 self.assertEqual(ast.literal_eval('{1, 2, 3}'), {1, 2, 3})
Benjamin Peterson5ef96e52010-07-11 23:06:06 +0000893 self.assertEqual(ast.literal_eval('b"hi"'), b"hi")
Georg Brandl0c77a822008-06-10 16:37:50 +0000894 self.assertRaises(ValueError, ast.literal_eval, 'foo()')
Serhiy Storchakad8ac4d12018-01-04 11:15:39 +0200895 self.assertEqual(ast.literal_eval('6'), 6)
896 self.assertEqual(ast.literal_eval('+6'), 6)
Raymond Hettingerbc959732010-10-08 00:47:45 +0000897 self.assertEqual(ast.literal_eval('-6'), -6)
Raymond Hettingerbc959732010-10-08 00:47:45 +0000898 self.assertEqual(ast.literal_eval('3.25'), 3.25)
Serhiy Storchakad8ac4d12018-01-04 11:15:39 +0200899 self.assertEqual(ast.literal_eval('+3.25'), 3.25)
900 self.assertEqual(ast.literal_eval('-3.25'), -3.25)
901 self.assertEqual(repr(ast.literal_eval('-0.0')), '-0.0')
902 self.assertRaises(ValueError, ast.literal_eval, '++6')
903 self.assertRaises(ValueError, ast.literal_eval, '+True')
904 self.assertRaises(ValueError, ast.literal_eval, '2+3')
Georg Brandl0c77a822008-06-10 16:37:50 +0000905
Serhiy Storchakad8ac4d12018-01-04 11:15:39 +0200906 def test_literal_eval_complex(self):
907 # Issue #4907
908 self.assertEqual(ast.literal_eval('6j'), 6j)
909 self.assertEqual(ast.literal_eval('-6j'), -6j)
910 self.assertEqual(ast.literal_eval('6.75j'), 6.75j)
911 self.assertEqual(ast.literal_eval('-6.75j'), -6.75j)
912 self.assertEqual(ast.literal_eval('3+6j'), 3+6j)
913 self.assertEqual(ast.literal_eval('-3+6j'), -3+6j)
914 self.assertEqual(ast.literal_eval('3-6j'), 3-6j)
915 self.assertEqual(ast.literal_eval('-3-6j'), -3-6j)
916 self.assertEqual(ast.literal_eval('3.25+6.75j'), 3.25+6.75j)
917 self.assertEqual(ast.literal_eval('-3.25+6.75j'), -3.25+6.75j)
918 self.assertEqual(ast.literal_eval('3.25-6.75j'), 3.25-6.75j)
919 self.assertEqual(ast.literal_eval('-3.25-6.75j'), -3.25-6.75j)
920 self.assertEqual(ast.literal_eval('(3+6j)'), 3+6j)
921 self.assertRaises(ValueError, ast.literal_eval, '-6j+3')
922 self.assertRaises(ValueError, ast.literal_eval, '-6j+3j')
923 self.assertRaises(ValueError, ast.literal_eval, '3+-6j')
924 self.assertRaises(ValueError, ast.literal_eval, '3+(0+6j)')
925 self.assertRaises(ValueError, ast.literal_eval, '-(3+6j)')
Benjamin Peterson058e31e2009-01-16 03:54:08 +0000926
Amaury Forgeot d'Arc58e87612011-11-22 21:51:55 +0100927 def test_bad_integer(self):
928 # issue13436: Bad error message with invalid numeric values
929 body = [ast.ImportFrom(module='time',
930 names=[ast.alias(name='sleep')],
931 level=None,
932 lineno=None, col_offset=None)]
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800933 mod = ast.Module(body, [])
Amaury Forgeot d'Arc58e87612011-11-22 21:51:55 +0100934 with self.assertRaises(ValueError) as cm:
935 compile(mod, 'test', 'exec')
936 self.assertIn("invalid integer value: None", str(cm.exception))
937
Berker Peksag0a5bd512016-04-29 19:50:02 +0300938 def test_level_as_none(self):
939 body = [ast.ImportFrom(module='time',
940 names=[ast.alias(name='sleep')],
941 level=None,
942 lineno=0, col_offset=0)]
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800943 mod = ast.Module(body, [])
Berker Peksag0a5bd512016-04-29 19:50:02 +0300944 code = compile(mod, 'test', 'exec')
945 ns = {}
946 exec(code, ns)
947 self.assertIn('sleep', ns)
948
Georg Brandl0c77a822008-06-10 16:37:50 +0000949
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500950class ASTValidatorTests(unittest.TestCase):
951
952 def mod(self, mod, msg=None, mode="exec", *, exc=ValueError):
953 mod.lineno = mod.col_offset = 0
954 ast.fix_missing_locations(mod)
Serhiy Storchaka3f228112018-09-27 17:42:37 +0300955 if msg is None:
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500956 compile(mod, "<test>", mode)
Serhiy Storchaka3f228112018-09-27 17:42:37 +0300957 else:
958 with self.assertRaises(exc) as cm:
959 compile(mod, "<test>", mode)
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500960 self.assertIn(msg, str(cm.exception))
961
962 def expr(self, node, msg=None, *, exc=ValueError):
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800963 mod = ast.Module([ast.Expr(node)], [])
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500964 self.mod(mod, msg, exc=exc)
965
966 def stmt(self, stmt, msg=None):
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800967 mod = ast.Module([stmt], [])
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500968 self.mod(mod, msg)
969
970 def test_module(self):
971 m = ast.Interactive([ast.Expr(ast.Name("x", ast.Store()))])
972 self.mod(m, "must have Load context", "single")
973 m = ast.Expression(ast.Name("x", ast.Store()))
974 self.mod(m, "must have Load context", "eval")
975
976 def _check_arguments(self, fac, check):
Pablo Galindo8c77b8c2019-04-29 13:36:57 +0100977 def arguments(args=None, posonlyargs=None, vararg=None,
Benjamin Petersoncda75be2013-03-18 10:48:58 -0700978 kwonlyargs=None, kwarg=None,
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500979 defaults=None, kw_defaults=None):
980 if args is None:
981 args = []
Pablo Galindo8c77b8c2019-04-29 13:36:57 +0100982 if posonlyargs is None:
983 posonlyargs = []
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500984 if kwonlyargs is None:
985 kwonlyargs = []
986 if defaults is None:
987 defaults = []
988 if kw_defaults is None:
989 kw_defaults = []
Pablo Galindo8c77b8c2019-04-29 13:36:57 +0100990 args = ast.arguments(args, posonlyargs, vararg, kwonlyargs,
991 kw_defaults, kwarg, defaults)
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500992 return fac(args)
993 args = [ast.arg("x", ast.Name("x", ast.Store()))]
994 check(arguments(args=args), "must have Load context")
Pablo Galindo8c77b8c2019-04-29 13:36:57 +0100995 check(arguments(posonlyargs=args), "must have Load context")
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500996 check(arguments(kwonlyargs=args), "must have Load context")
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500997 check(arguments(defaults=[ast.Num(3)]),
998 "more positional defaults than args")
999 check(arguments(kw_defaults=[ast.Num(4)]),
1000 "length of kwonlyargs is not the same as kw_defaults")
1001 args = [ast.arg("x", ast.Name("x", ast.Load()))]
1002 check(arguments(args=args, defaults=[ast.Name("x", ast.Store())]),
1003 "must have Load context")
1004 args = [ast.arg("a", ast.Name("x", ast.Load())),
1005 ast.arg("b", ast.Name("y", ast.Load()))]
1006 check(arguments(kwonlyargs=args,
1007 kw_defaults=[None, ast.Name("x", ast.Store())]),
1008 "must have Load context")
1009
1010 def test_funcdef(self):
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01001011 a = ast.arguments([], [], None, [], [], None, [])
Serhiy Storchaka73cbe7a2018-05-29 12:04:55 +03001012 f = ast.FunctionDef("x", a, [], [], None)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001013 self.stmt(f, "empty body on FunctionDef")
1014 f = ast.FunctionDef("x", a, [ast.Pass()], [ast.Name("x", ast.Store())],
Serhiy Storchaka73cbe7a2018-05-29 12:04:55 +03001015 None)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001016 self.stmt(f, "must have Load context")
1017 f = ast.FunctionDef("x", a, [ast.Pass()], [],
Serhiy Storchaka73cbe7a2018-05-29 12:04:55 +03001018 ast.Name("x", ast.Store()))
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001019 self.stmt(f, "must have Load context")
1020 def fac(args):
Serhiy Storchaka73cbe7a2018-05-29 12:04:55 +03001021 return ast.FunctionDef("x", args, [ast.Pass()], [], None)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001022 self._check_arguments(fac, self.stmt)
1023
1024 def test_classdef(self):
Benjamin Peterson025e9eb2015-05-05 20:16:41 -04001025 def cls(bases=None, keywords=None, body=None, decorator_list=None):
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001026 if bases is None:
1027 bases = []
1028 if keywords is None:
1029 keywords = []
1030 if body is None:
1031 body = [ast.Pass()]
1032 if decorator_list is None:
1033 decorator_list = []
Benjamin Peterson025e9eb2015-05-05 20:16:41 -04001034 return ast.ClassDef("myclass", bases, keywords,
Serhiy Storchaka73cbe7a2018-05-29 12:04:55 +03001035 body, decorator_list)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001036 self.stmt(cls(bases=[ast.Name("x", ast.Store())]),
1037 "must have Load context")
1038 self.stmt(cls(keywords=[ast.keyword("x", ast.Name("x", ast.Store()))]),
1039 "must have Load context")
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001040 self.stmt(cls(body=[]), "empty body on ClassDef")
1041 self.stmt(cls(body=[None]), "None disallowed")
1042 self.stmt(cls(decorator_list=[ast.Name("x", ast.Store())]),
1043 "must have Load context")
1044
1045 def test_delete(self):
1046 self.stmt(ast.Delete([]), "empty targets on Delete")
1047 self.stmt(ast.Delete([None]), "None disallowed")
1048 self.stmt(ast.Delete([ast.Name("x", ast.Load())]),
1049 "must have Del context")
1050
1051 def test_assign(self):
1052 self.stmt(ast.Assign([], ast.Num(3)), "empty targets on Assign")
1053 self.stmt(ast.Assign([None], ast.Num(3)), "None disallowed")
1054 self.stmt(ast.Assign([ast.Name("x", ast.Load())], ast.Num(3)),
1055 "must have Store context")
1056 self.stmt(ast.Assign([ast.Name("x", ast.Store())],
1057 ast.Name("y", ast.Store())),
1058 "must have Load context")
1059
1060 def test_augassign(self):
1061 aug = ast.AugAssign(ast.Name("x", ast.Load()), ast.Add(),
1062 ast.Name("y", ast.Load()))
1063 self.stmt(aug, "must have Store context")
1064 aug = ast.AugAssign(ast.Name("x", ast.Store()), ast.Add(),
1065 ast.Name("y", ast.Store()))
1066 self.stmt(aug, "must have Load context")
1067
1068 def test_for(self):
1069 x = ast.Name("x", ast.Store())
1070 y = ast.Name("y", ast.Load())
1071 p = ast.Pass()
1072 self.stmt(ast.For(x, y, [], []), "empty body on For")
1073 self.stmt(ast.For(ast.Name("x", ast.Load()), y, [p], []),
1074 "must have Store context")
1075 self.stmt(ast.For(x, ast.Name("y", ast.Store()), [p], []),
1076 "must have Load context")
1077 e = ast.Expr(ast.Name("x", ast.Store()))
1078 self.stmt(ast.For(x, y, [e], []), "must have Load context")
1079 self.stmt(ast.For(x, y, [p], [e]), "must have Load context")
1080
1081 def test_while(self):
1082 self.stmt(ast.While(ast.Num(3), [], []), "empty body on While")
1083 self.stmt(ast.While(ast.Name("x", ast.Store()), [ast.Pass()], []),
1084 "must have Load context")
1085 self.stmt(ast.While(ast.Num(3), [ast.Pass()],
1086 [ast.Expr(ast.Name("x", ast.Store()))]),
1087 "must have Load context")
1088
1089 def test_if(self):
1090 self.stmt(ast.If(ast.Num(3), [], []), "empty body on If")
1091 i = ast.If(ast.Name("x", ast.Store()), [ast.Pass()], [])
1092 self.stmt(i, "must have Load context")
1093 i = ast.If(ast.Num(3), [ast.Expr(ast.Name("x", ast.Store()))], [])
1094 self.stmt(i, "must have Load context")
1095 i = ast.If(ast.Num(3), [ast.Pass()],
1096 [ast.Expr(ast.Name("x", ast.Store()))])
1097 self.stmt(i, "must have Load context")
1098
1099 def test_with(self):
1100 p = ast.Pass()
1101 self.stmt(ast.With([], [p]), "empty items on With")
1102 i = ast.withitem(ast.Num(3), None)
1103 self.stmt(ast.With([i], []), "empty body on With")
1104 i = ast.withitem(ast.Name("x", ast.Store()), None)
1105 self.stmt(ast.With([i], [p]), "must have Load context")
1106 i = ast.withitem(ast.Num(3), ast.Name("x", ast.Load()))
1107 self.stmt(ast.With([i], [p]), "must have Store context")
1108
1109 def test_raise(self):
1110 r = ast.Raise(None, ast.Num(3))
1111 self.stmt(r, "Raise with cause but no exception")
1112 r = ast.Raise(ast.Name("x", ast.Store()), None)
1113 self.stmt(r, "must have Load context")
1114 r = ast.Raise(ast.Num(4), ast.Name("x", ast.Store()))
1115 self.stmt(r, "must have Load context")
1116
1117 def test_try(self):
1118 p = ast.Pass()
1119 t = ast.Try([], [], [], [p])
1120 self.stmt(t, "empty body on Try")
1121 t = ast.Try([ast.Expr(ast.Name("x", ast.Store()))], [], [], [p])
1122 self.stmt(t, "must have Load context")
1123 t = ast.Try([p], [], [], [])
1124 self.stmt(t, "Try has neither except handlers nor finalbody")
1125 t = ast.Try([p], [], [p], [p])
1126 self.stmt(t, "Try has orelse but no except handlers")
1127 t = ast.Try([p], [ast.ExceptHandler(None, "x", [])], [], [])
1128 self.stmt(t, "empty body on ExceptHandler")
1129 e = [ast.ExceptHandler(ast.Name("x", ast.Store()), "y", [p])]
1130 self.stmt(ast.Try([p], e, [], []), "must have Load context")
1131 e = [ast.ExceptHandler(None, "x", [p])]
1132 t = ast.Try([p], e, [ast.Expr(ast.Name("x", ast.Store()))], [p])
1133 self.stmt(t, "must have Load context")
1134 t = ast.Try([p], e, [p], [ast.Expr(ast.Name("x", ast.Store()))])
1135 self.stmt(t, "must have Load context")
1136
1137 def test_assert(self):
1138 self.stmt(ast.Assert(ast.Name("x", ast.Store()), None),
1139 "must have Load context")
1140 assrt = ast.Assert(ast.Name("x", ast.Load()),
1141 ast.Name("y", ast.Store()))
1142 self.stmt(assrt, "must have Load context")
1143
1144 def test_import(self):
1145 self.stmt(ast.Import([]), "empty names on Import")
1146
1147 def test_importfrom(self):
1148 imp = ast.ImportFrom(None, [ast.alias("x", None)], -42)
Serhiy Storchaka7de28402016-06-27 23:40:43 +03001149 self.stmt(imp, "Negative ImportFrom level")
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001150 self.stmt(ast.ImportFrom(None, [], 0), "empty names on ImportFrom")
1151
1152 def test_global(self):
1153 self.stmt(ast.Global([]), "empty names on Global")
1154
1155 def test_nonlocal(self):
1156 self.stmt(ast.Nonlocal([]), "empty names on Nonlocal")
1157
1158 def test_expr(self):
1159 e = ast.Expr(ast.Name("x", ast.Store()))
1160 self.stmt(e, "must have Load context")
1161
1162 def test_boolop(self):
1163 b = ast.BoolOp(ast.And(), [])
1164 self.expr(b, "less than 2 values")
1165 b = ast.BoolOp(ast.And(), [ast.Num(3)])
1166 self.expr(b, "less than 2 values")
1167 b = ast.BoolOp(ast.And(), [ast.Num(4), None])
1168 self.expr(b, "None disallowed")
1169 b = ast.BoolOp(ast.And(), [ast.Num(4), ast.Name("x", ast.Store())])
1170 self.expr(b, "must have Load context")
1171
1172 def test_unaryop(self):
1173 u = ast.UnaryOp(ast.Not(), ast.Name("x", ast.Store()))
1174 self.expr(u, "must have Load context")
1175
1176 def test_lambda(self):
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01001177 a = ast.arguments([], [], None, [], [], None, [])
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001178 self.expr(ast.Lambda(a, ast.Name("x", ast.Store())),
1179 "must have Load context")
1180 def fac(args):
1181 return ast.Lambda(args, ast.Name("x", ast.Load()))
1182 self._check_arguments(fac, self.expr)
1183
1184 def test_ifexp(self):
1185 l = ast.Name("x", ast.Load())
1186 s = ast.Name("y", ast.Store())
1187 for args in (s, l, l), (l, s, l), (l, l, s):
Benjamin Peterson71ce8972011-08-09 16:17:12 -05001188 self.expr(ast.IfExp(*args), "must have Load context")
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001189
1190 def test_dict(self):
1191 d = ast.Dict([], [ast.Name("x", ast.Load())])
1192 self.expr(d, "same number of keys as values")
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001193 d = ast.Dict([ast.Name("x", ast.Load())], [None])
1194 self.expr(d, "None disallowed")
1195
1196 def test_set(self):
1197 self.expr(ast.Set([None]), "None disallowed")
1198 s = ast.Set([ast.Name("x", ast.Store())])
1199 self.expr(s, "must have Load context")
1200
1201 def _check_comprehension(self, fac):
1202 self.expr(fac([]), "comprehension with no generators")
1203 g = ast.comprehension(ast.Name("x", ast.Load()),
Yury Selivanov52c4e7c2016-09-09 10:36:01 -07001204 ast.Name("x", ast.Load()), [], 0)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001205 self.expr(fac([g]), "must have Store context")
1206 g = ast.comprehension(ast.Name("x", ast.Store()),
Yury Selivanov52c4e7c2016-09-09 10:36:01 -07001207 ast.Name("x", ast.Store()), [], 0)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001208 self.expr(fac([g]), "must have Load context")
1209 x = ast.Name("x", ast.Store())
1210 y = ast.Name("y", ast.Load())
Yury Selivanov52c4e7c2016-09-09 10:36:01 -07001211 g = ast.comprehension(x, y, [None], 0)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001212 self.expr(fac([g]), "None disallowed")
Yury Selivanov52c4e7c2016-09-09 10:36:01 -07001213 g = ast.comprehension(x, y, [ast.Name("x", ast.Store())], 0)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001214 self.expr(fac([g]), "must have Load context")
1215
1216 def _simple_comp(self, fac):
1217 g = ast.comprehension(ast.Name("x", ast.Store()),
Yury Selivanov52c4e7c2016-09-09 10:36:01 -07001218 ast.Name("x", ast.Load()), [], 0)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001219 self.expr(fac(ast.Name("x", ast.Store()), [g]),
1220 "must have Load context")
1221 def wrap(gens):
1222 return fac(ast.Name("x", ast.Store()), gens)
1223 self._check_comprehension(wrap)
1224
1225 def test_listcomp(self):
1226 self._simple_comp(ast.ListComp)
1227
1228 def test_setcomp(self):
1229 self._simple_comp(ast.SetComp)
1230
1231 def test_generatorexp(self):
1232 self._simple_comp(ast.GeneratorExp)
1233
1234 def test_dictcomp(self):
1235 g = ast.comprehension(ast.Name("y", ast.Store()),
Yury Selivanov52c4e7c2016-09-09 10:36:01 -07001236 ast.Name("p", ast.Load()), [], 0)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001237 c = ast.DictComp(ast.Name("x", ast.Store()),
1238 ast.Name("y", ast.Load()), [g])
1239 self.expr(c, "must have Load context")
1240 c = ast.DictComp(ast.Name("x", ast.Load()),
1241 ast.Name("y", ast.Store()), [g])
1242 self.expr(c, "must have Load context")
1243 def factory(comps):
1244 k = ast.Name("x", ast.Load())
1245 v = ast.Name("y", ast.Load())
1246 return ast.DictComp(k, v, comps)
1247 self._check_comprehension(factory)
1248
1249 def test_yield(self):
Benjamin Peterson527c6222012-01-14 08:58:23 -05001250 self.expr(ast.Yield(ast.Name("x", ast.Store())), "must have Load")
1251 self.expr(ast.YieldFrom(ast.Name("x", ast.Store())), "must have Load")
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001252
1253 def test_compare(self):
1254 left = ast.Name("x", ast.Load())
1255 comp = ast.Compare(left, [ast.In()], [])
1256 self.expr(comp, "no comparators")
1257 comp = ast.Compare(left, [ast.In()], [ast.Num(4), ast.Num(5)])
1258 self.expr(comp, "different number of comparators and operands")
1259 comp = ast.Compare(ast.Num("blah"), [ast.In()], [left])
Serhiy Storchaka3f228112018-09-27 17:42:37 +03001260 self.expr(comp)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001261 comp = ast.Compare(left, [ast.In()], [ast.Num("blah")])
Serhiy Storchaka3f228112018-09-27 17:42:37 +03001262 self.expr(comp)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001263
1264 def test_call(self):
1265 func = ast.Name("x", ast.Load())
1266 args = [ast.Name("y", ast.Load())]
1267 keywords = [ast.keyword("w", ast.Name("z", ast.Load()))]
Benjamin Peterson025e9eb2015-05-05 20:16:41 -04001268 call = ast.Call(ast.Name("x", ast.Store()), args, keywords)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001269 self.expr(call, "must have Load context")
Benjamin Peterson025e9eb2015-05-05 20:16:41 -04001270 call = ast.Call(func, [None], keywords)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001271 self.expr(call, "None disallowed")
1272 bad_keywords = [ast.keyword("w", ast.Name("z", ast.Store()))]
Benjamin Peterson025e9eb2015-05-05 20:16:41 -04001273 call = ast.Call(func, args, bad_keywords)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001274 self.expr(call, "must have Load context")
1275
1276 def test_num(self):
1277 class subint(int):
1278 pass
1279 class subfloat(float):
1280 pass
1281 class subcomplex(complex):
1282 pass
Serhiy Storchaka3f228112018-09-27 17:42:37 +03001283 for obj in "0", "hello":
1284 self.expr(ast.Num(obj))
1285 for obj in subint(), subfloat(), subcomplex():
1286 self.expr(ast.Num(obj), "invalid type", exc=TypeError)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001287
1288 def test_attribute(self):
1289 attr = ast.Attribute(ast.Name("x", ast.Store()), "y", ast.Load())
1290 self.expr(attr, "must have Load context")
1291
1292 def test_subscript(self):
1293 sub = ast.Subscript(ast.Name("x", ast.Store()), ast.Index(ast.Num(3)),
1294 ast.Load())
1295 self.expr(sub, "must have Load context")
1296 x = ast.Name("x", ast.Load())
1297 sub = ast.Subscript(x, ast.Index(ast.Name("y", ast.Store())),
1298 ast.Load())
1299 self.expr(sub, "must have Load context")
1300 s = ast.Name("x", ast.Store())
1301 for args in (s, None, None), (None, s, None), (None, None, s):
1302 sl = ast.Slice(*args)
1303 self.expr(ast.Subscript(x, sl, ast.Load()),
1304 "must have Load context")
1305 sl = ast.ExtSlice([])
1306 self.expr(ast.Subscript(x, sl, ast.Load()), "empty dims on ExtSlice")
1307 sl = ast.ExtSlice([ast.Index(s)])
1308 self.expr(ast.Subscript(x, sl, ast.Load()), "must have Load context")
1309
1310 def test_starred(self):
1311 left = ast.List([ast.Starred(ast.Name("x", ast.Load()), ast.Store())],
1312 ast.Store())
1313 assign = ast.Assign([left], ast.Num(4))
1314 self.stmt(assign, "must have Store context")
1315
1316 def _sequence(self, fac):
1317 self.expr(fac([None], ast.Load()), "None disallowed")
1318 self.expr(fac([ast.Name("x", ast.Store())], ast.Load()),
1319 "must have Load context")
1320
1321 def test_list(self):
1322 self._sequence(ast.List)
1323
1324 def test_tuple(self):
1325 self._sequence(ast.Tuple)
1326
Benjamin Peterson442f2092012-12-06 17:41:04 -05001327 def test_nameconstant(self):
Serhiy Storchaka3f228112018-09-27 17:42:37 +03001328 self.expr(ast.NameConstant(4))
Benjamin Peterson442f2092012-12-06 17:41:04 -05001329
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001330 def test_stdlib_validates(self):
1331 stdlib = os.path.dirname(ast.__file__)
1332 tests = [fn for fn in os.listdir(stdlib) if fn.endswith(".py")]
1333 tests.extend(["test/test_grammar.py", "test/test_unpack_ex.py"])
1334 for module in tests:
Serhiy Storchaka3bcbedc2019-01-18 07:47:48 +02001335 with self.subTest(module):
1336 fn = os.path.join(stdlib, module)
1337 with open(fn, "r", encoding="utf-8") as fp:
1338 source = fp.read()
1339 mod = ast.parse(source, fn)
1340 compile(mod, fn, "exec")
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001341
1342
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001343class ConstantTests(unittest.TestCase):
1344 """Tests on the ast.Constant node type."""
1345
1346 def compile_constant(self, value):
1347 tree = ast.parse("x = 123")
1348
1349 node = tree.body[0].value
1350 new_node = ast.Constant(value=value)
1351 ast.copy_location(new_node, node)
1352 tree.body[0].value = new_node
1353
1354 code = compile(tree, "<string>", "exec")
1355
1356 ns = {}
1357 exec(code, ns)
1358 return ns['x']
1359
Victor Stinnerbe59d142016-01-27 00:39:12 +01001360 def test_validation(self):
1361 with self.assertRaises(TypeError) as cm:
1362 self.compile_constant([1, 2, 3])
1363 self.assertEqual(str(cm.exception),
1364 "got an invalid type in Constant: list")
1365
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001366 def test_singletons(self):
1367 for const in (None, False, True, Ellipsis, b'', frozenset()):
1368 with self.subTest(const=const):
1369 value = self.compile_constant(const)
1370 self.assertIs(value, const)
1371
1372 def test_values(self):
1373 nested_tuple = (1,)
1374 nested_frozenset = frozenset({1})
1375 for level in range(3):
1376 nested_tuple = (nested_tuple, 2)
1377 nested_frozenset = frozenset({nested_frozenset, 2})
1378 values = (123, 123.0, 123j,
1379 "unicode", b'bytes',
1380 tuple("tuple"), frozenset("frozenset"),
1381 nested_tuple, nested_frozenset)
1382 for value in values:
1383 with self.subTest(value=value):
1384 result = self.compile_constant(value)
1385 self.assertEqual(result, value)
1386
1387 def test_assign_to_constant(self):
1388 tree = ast.parse("x = 1")
1389
1390 target = tree.body[0].targets[0]
1391 new_target = ast.Constant(value=1)
1392 ast.copy_location(new_target, target)
1393 tree.body[0].targets[0] = new_target
1394
1395 with self.assertRaises(ValueError) as cm:
1396 compile(tree, "string", "exec")
1397 self.assertEqual(str(cm.exception),
1398 "expression which can't be assigned "
1399 "to in Store context")
1400
1401 def test_get_docstring(self):
1402 tree = ast.parse("'docstring'\nx = 1")
1403 self.assertEqual(ast.get_docstring(tree), 'docstring')
1404
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001405 def get_load_const(self, tree):
1406 # Compile to bytecode, disassemble and get parameter of LOAD_CONST
1407 # instructions
1408 co = compile(tree, '<string>', 'exec')
1409 consts = []
1410 for instr in dis.get_instructions(co):
1411 if instr.opname == 'LOAD_CONST':
1412 consts.append(instr.argval)
1413 return consts
1414
1415 @support.cpython_only
1416 def test_load_const(self):
1417 consts = [None,
1418 True, False,
1419 124,
1420 2.0,
1421 3j,
1422 "unicode",
1423 b'bytes',
1424 (1, 2, 3)]
1425
Victor Stinnera2724092016-02-08 18:17:58 +01001426 code = '\n'.join(['x={!r}'.format(const) for const in consts])
1427 code += '\nx = ...'
1428 consts.extend((Ellipsis, None))
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001429
1430 tree = ast.parse(code)
Victor Stinnera2724092016-02-08 18:17:58 +01001431 self.assertEqual(self.get_load_const(tree),
1432 consts)
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001433
1434 # Replace expression nodes with constants
Victor Stinnera2724092016-02-08 18:17:58 +01001435 for assign, const in zip(tree.body, consts):
1436 assert isinstance(assign, ast.Assign), ast.dump(assign)
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001437 new_node = ast.Constant(value=const)
Victor Stinnera2724092016-02-08 18:17:58 +01001438 ast.copy_location(new_node, assign.value)
1439 assign.value = new_node
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001440
Victor Stinnera2724092016-02-08 18:17:58 +01001441 self.assertEqual(self.get_load_const(tree),
1442 consts)
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001443
1444 def test_literal_eval(self):
1445 tree = ast.parse("1 + 2")
1446 binop = tree.body[0].value
1447
1448 new_left = ast.Constant(value=10)
1449 ast.copy_location(new_left, binop.left)
1450 binop.left = new_left
1451
Serhiy Storchakad8ac4d12018-01-04 11:15:39 +02001452 new_right = ast.Constant(value=20j)
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001453 ast.copy_location(new_right, binop.right)
1454 binop.right = new_right
1455
Serhiy Storchakad8ac4d12018-01-04 11:15:39 +02001456 self.assertEqual(ast.literal_eval(binop), 10+20j)
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001457
Guido van Rossum10f8ce62019-03-13 13:00:46 -07001458 def test_string_kind(self):
1459 c = ast.parse('"x"', mode='eval').body
1460 self.assertEqual(c.value, "x")
1461 self.assertEqual(c.kind, None)
1462
1463 c = ast.parse('u"x"', mode='eval').body
1464 self.assertEqual(c.value, "x")
1465 self.assertEqual(c.kind, "u")
1466
1467 c = ast.parse('r"x"', mode='eval').body
1468 self.assertEqual(c.value, "x")
1469 self.assertEqual(c.kind, None)
1470
1471 c = ast.parse('b"x"', mode='eval').body
1472 self.assertEqual(c.value, b"x")
1473 self.assertEqual(c.kind, None)
1474
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001475
Ivan Levkivskyi9932a222019-01-22 11:18:22 +00001476class EndPositionTests(unittest.TestCase):
1477 """Tests for end position of AST nodes.
1478
1479 Testing end positions of nodes requires a bit of extra care
1480 because of how LL parsers work.
1481 """
1482 def _check_end_pos(self, ast_node, end_lineno, end_col_offset):
1483 self.assertEqual(ast_node.end_lineno, end_lineno)
1484 self.assertEqual(ast_node.end_col_offset, end_col_offset)
1485
1486 def _check_content(self, source, ast_node, content):
1487 self.assertEqual(ast.get_source_segment(source, ast_node), content)
1488
1489 def _parse_value(self, s):
1490 # Use duck-typing to support both single expression
1491 # and a right hand side of an assignment statement.
1492 return ast.parse(s).body[0].value
1493
1494 def test_lambda(self):
1495 s = 'lambda x, *y: None'
1496 lam = self._parse_value(s)
1497 self._check_content(s, lam.body, 'None')
1498 self._check_content(s, lam.args.args[0], 'x')
1499 self._check_content(s, lam.args.vararg, 'y')
1500
1501 def test_func_def(self):
1502 s = dedent('''
1503 def func(x: int,
1504 *args: str,
1505 z: float = 0,
1506 **kwargs: Any) -> bool:
1507 return True
1508 ''').strip()
1509 fdef = ast.parse(s).body[0]
1510 self._check_end_pos(fdef, 5, 15)
1511 self._check_content(s, fdef.body[0], 'return True')
1512 self._check_content(s, fdef.args.args[0], 'x: int')
1513 self._check_content(s, fdef.args.args[0].annotation, 'int')
1514 self._check_content(s, fdef.args.kwarg, 'kwargs: Any')
1515 self._check_content(s, fdef.args.kwarg.annotation, 'Any')
1516
1517 def test_call(self):
1518 s = 'func(x, y=2, **kw)'
1519 call = self._parse_value(s)
1520 self._check_content(s, call.func, 'func')
1521 self._check_content(s, call.keywords[0].value, '2')
1522 self._check_content(s, call.keywords[1].value, 'kw')
1523
1524 def test_call_noargs(self):
1525 s = 'x[0]()'
1526 call = self._parse_value(s)
1527 self._check_content(s, call.func, 'x[0]')
1528 self._check_end_pos(call, 1, 6)
1529
1530 def test_class_def(self):
1531 s = dedent('''
1532 class C(A, B):
1533 x: int = 0
1534 ''').strip()
1535 cdef = ast.parse(s).body[0]
1536 self._check_end_pos(cdef, 2, 14)
1537 self._check_content(s, cdef.bases[1], 'B')
1538 self._check_content(s, cdef.body[0], 'x: int = 0')
1539
1540 def test_class_kw(self):
1541 s = 'class S(metaclass=abc.ABCMeta): pass'
1542 cdef = ast.parse(s).body[0]
1543 self._check_content(s, cdef.keywords[0].value, 'abc.ABCMeta')
1544
1545 def test_multi_line_str(self):
1546 s = dedent('''
1547 x = """Some multi-line text.
1548
1549 It goes on starting from same indent."""
1550 ''').strip()
1551 assign = ast.parse(s).body[0]
1552 self._check_end_pos(assign, 3, 40)
1553 self._check_end_pos(assign.value, 3, 40)
1554
1555 def test_continued_str(self):
1556 s = dedent('''
1557 x = "first part" \\
1558 "second part"
1559 ''').strip()
1560 assign = ast.parse(s).body[0]
1561 self._check_end_pos(assign, 2, 13)
1562 self._check_end_pos(assign.value, 2, 13)
1563
1564 def test_suites(self):
1565 # We intentionally put these into the same string to check
1566 # that empty lines are not part of the suite.
1567 s = dedent('''
1568 while True:
1569 pass
1570
1571 if one():
1572 x = None
1573 elif other():
1574 y = None
1575 else:
1576 z = None
1577
1578 for x, y in stuff:
1579 assert True
1580
1581 try:
1582 raise RuntimeError
1583 except TypeError as e:
1584 pass
1585
1586 pass
1587 ''').strip()
1588 mod = ast.parse(s)
1589 while_loop = mod.body[0]
1590 if_stmt = mod.body[1]
1591 for_loop = mod.body[2]
1592 try_stmt = mod.body[3]
1593 pass_stmt = mod.body[4]
1594
1595 self._check_end_pos(while_loop, 2, 8)
1596 self._check_end_pos(if_stmt, 9, 12)
1597 self._check_end_pos(for_loop, 12, 15)
1598 self._check_end_pos(try_stmt, 17, 8)
1599 self._check_end_pos(pass_stmt, 19, 4)
1600
1601 self._check_content(s, while_loop.test, 'True')
1602 self._check_content(s, if_stmt.body[0], 'x = None')
1603 self._check_content(s, if_stmt.orelse[0].test, 'other()')
1604 self._check_content(s, for_loop.target, 'x, y')
1605 self._check_content(s, try_stmt.body[0], 'raise RuntimeError')
1606 self._check_content(s, try_stmt.handlers[0].type, 'TypeError')
1607
1608 def test_fstring(self):
1609 s = 'x = f"abc {x + y} abc"'
1610 fstr = self._parse_value(s)
1611 binop = fstr.values[1].value
1612 self._check_content(s, binop, 'x + y')
1613
1614 def test_fstring_multi_line(self):
1615 s = dedent('''
1616 f"""Some multi-line text.
1617 {
1618 arg_one
1619 +
1620 arg_two
1621 }
1622 It goes on..."""
1623 ''').strip()
1624 fstr = self._parse_value(s)
1625 binop = fstr.values[1].value
1626 self._check_end_pos(binop, 5, 7)
1627 self._check_content(s, binop.left, 'arg_one')
1628 self._check_content(s, binop.right, 'arg_two')
1629
1630 def test_import_from_multi_line(self):
1631 s = dedent('''
1632 from x.y.z import (
1633 a, b, c as c
1634 )
1635 ''').strip()
1636 imp = ast.parse(s).body[0]
1637 self._check_end_pos(imp, 3, 1)
1638
1639 def test_slices(self):
1640 s1 = 'f()[1, 2] [0]'
1641 s2 = 'x[ a.b: c.d]'
1642 sm = dedent('''
1643 x[ a.b: f () ,
1644 g () : c.d
1645 ]
1646 ''').strip()
1647 i1, i2, im = map(self._parse_value, (s1, s2, sm))
1648 self._check_content(s1, i1.value, 'f()[1, 2]')
1649 self._check_content(s1, i1.value.slice.value, '1, 2')
1650 self._check_content(s2, i2.slice.lower, 'a.b')
1651 self._check_content(s2, i2.slice.upper, 'c.d')
1652 self._check_content(sm, im.slice.dims[0].upper, 'f ()')
1653 self._check_content(sm, im.slice.dims[1].lower, 'g ()')
1654 self._check_end_pos(im, 3, 3)
1655
1656 def test_binop(self):
1657 s = dedent('''
1658 (1 * 2 + (3 ) +
1659 4
1660 )
1661 ''').strip()
1662 binop = self._parse_value(s)
1663 self._check_end_pos(binop, 2, 6)
1664 self._check_content(s, binop.right, '4')
1665 self._check_content(s, binop.left, '1 * 2 + (3 )')
1666 self._check_content(s, binop.left.right, '3')
1667
1668 def test_boolop(self):
1669 s = dedent('''
1670 if (one_condition and
1671 (other_condition or yet_another_one)):
1672 pass
1673 ''').strip()
1674 bop = ast.parse(s).body[0].test
1675 self._check_end_pos(bop, 2, 44)
1676 self._check_content(s, bop.values[1],
1677 'other_condition or yet_another_one')
1678
1679 def test_tuples(self):
1680 s1 = 'x = () ;'
1681 s2 = 'x = 1 , ;'
1682 s3 = 'x = (1 , 2 ) ;'
1683 sm = dedent('''
1684 x = (
1685 a, b,
1686 )
1687 ''').strip()
1688 t1, t2, t3, tm = map(self._parse_value, (s1, s2, s3, sm))
1689 self._check_content(s1, t1, '()')
1690 self._check_content(s2, t2, '1 ,')
1691 self._check_content(s3, t3, '(1 , 2 )')
1692 self._check_end_pos(tm, 3, 1)
1693
1694 def test_attribute_spaces(self):
1695 s = 'func(x. y .z)'
1696 call = self._parse_value(s)
1697 self._check_content(s, call, s)
1698 self._check_content(s, call.args[0], 'x. y .z')
1699
1700 def test_displays(self):
1701 s1 = '[{}, {1, }, {1, 2,} ]'
1702 s2 = '{a: b, f (): g () ,}'
1703 c1 = self._parse_value(s1)
1704 c2 = self._parse_value(s2)
1705 self._check_content(s1, c1.elts[0], '{}')
1706 self._check_content(s1, c1.elts[1], '{1, }')
1707 self._check_content(s1, c1.elts[2], '{1, 2,}')
1708 self._check_content(s2, c2.keys[1], 'f ()')
1709 self._check_content(s2, c2.values[1], 'g ()')
1710
1711 def test_comprehensions(self):
1712 s = dedent('''
1713 x = [{x for x, y in stuff
1714 if cond.x} for stuff in things]
1715 ''').strip()
1716 cmp = self._parse_value(s)
1717 self._check_end_pos(cmp, 2, 37)
1718 self._check_content(s, cmp.generators[0].iter, 'things')
1719 self._check_content(s, cmp.elt.generators[0].iter, 'stuff')
1720 self._check_content(s, cmp.elt.generators[0].ifs[0], 'cond.x')
1721 self._check_content(s, cmp.elt.generators[0].target, 'x, y')
1722
1723 def test_yield_await(self):
1724 s = dedent('''
1725 async def f():
1726 yield x
1727 await y
1728 ''').strip()
1729 fdef = ast.parse(s).body[0]
1730 self._check_content(s, fdef.body[0].value, 'yield x')
1731 self._check_content(s, fdef.body[1].value, 'await y')
1732
1733 def test_source_segment_multi(self):
1734 s_orig = dedent('''
1735 x = (
1736 a, b,
1737 ) + ()
1738 ''').strip()
1739 s_tuple = dedent('''
1740 (
1741 a, b,
1742 )
1743 ''').strip()
1744 binop = self._parse_value(s_orig)
1745 self.assertEqual(ast.get_source_segment(s_orig, binop.left), s_tuple)
1746
1747 def test_source_segment_padded(self):
1748 s_orig = dedent('''
1749 class C:
1750 def fun(self) -> None:
1751 "ЖЖЖЖЖ"
1752 ''').strip()
1753 s_method = ' def fun(self) -> None:\n' \
1754 ' "ЖЖЖЖЖ"'
1755 cdef = ast.parse(s_orig).body[0]
1756 self.assertEqual(ast.get_source_segment(s_orig, cdef.body[0], padded=True),
1757 s_method)
1758
1759 def test_source_segment_endings(self):
1760 s = 'v = 1\r\nw = 1\nx = 1\n\ry = 1\rz = 1\r\n'
1761 v, w, x, y, z = ast.parse(s).body
1762 self._check_content(s, v, 'v = 1')
1763 self._check_content(s, w, 'w = 1')
1764 self._check_content(s, x, 'x = 1')
1765 self._check_content(s, y, 'y = 1')
1766 self._check_content(s, z, 'z = 1')
1767
1768 def test_source_segment_tabs(self):
1769 s = dedent('''
1770 class C:
1771 \t\f def fun(self) -> None:
1772 \t\f pass
1773 ''').strip()
1774 s_method = ' \t\f def fun(self) -> None:\n' \
1775 ' \t\f pass'
1776
1777 cdef = ast.parse(s).body[0]
1778 self.assertEqual(ast.get_source_segment(s, cdef.body[0], padded=True), s_method)
1779
1780
Serhiy Storchakac3ea41e2019-08-26 10:13:19 +03001781class NodeVisitorTests(unittest.TestCase):
1782 def test_old_constant_nodes(self):
1783 class Visitor(ast.NodeVisitor):
1784 def visit_Num(self, node):
1785 log.append((node.lineno, 'Num', node.n))
1786 def visit_Str(self, node):
1787 log.append((node.lineno, 'Str', node.s))
1788 def visit_Bytes(self, node):
1789 log.append((node.lineno, 'Bytes', node.s))
1790 def visit_NameConstant(self, node):
1791 log.append((node.lineno, 'NameConstant', node.value))
1792 def visit_Ellipsis(self, node):
1793 log.append((node.lineno, 'Ellipsis', ...))
1794 mod = ast.parse(dedent('''\
1795 i = 42
1796 f = 4.25
1797 c = 4.25j
1798 s = 'string'
1799 b = b'bytes'
1800 t = True
1801 n = None
1802 e = ...
1803 '''))
1804 visitor = Visitor()
1805 log = []
1806 with warnings.catch_warnings(record=True) as wlog:
1807 warnings.filterwarnings('always', '', DeprecationWarning)
1808 visitor.visit(mod)
1809 self.assertEqual(log, [
1810 (1, 'Num', 42),
1811 (2, 'Num', 4.25),
1812 (3, 'Num', 4.25j),
1813 (4, 'Str', 'string'),
1814 (5, 'Bytes', b'bytes'),
1815 (6, 'NameConstant', True),
1816 (7, 'NameConstant', None),
1817 (8, 'Ellipsis', ...),
1818 ])
1819 self.assertEqual([str(w.message) for w in wlog], [
1820 'visit_Num is deprecated; add visit_Constant',
1821 'visit_Num is deprecated; add visit_Constant',
1822 'visit_Num is deprecated; add visit_Constant',
1823 'visit_Str is deprecated; add visit_Constant',
1824 'visit_Bytes is deprecated; add visit_Constant',
1825 'visit_NameConstant is deprecated; add visit_Constant',
1826 'visit_NameConstant is deprecated; add visit_Constant',
1827 'visit_Ellipsis is deprecated; add visit_Constant',
1828 ])
1829
1830
Neal Norwitzee9b10a2008-03-31 05:29:39 +00001831def main():
1832 if __name__ != '__main__':
Martin v. Löwis49c5da12006-03-01 22:49:05 +00001833 return
Neal Norwitzee9b10a2008-03-31 05:29:39 +00001834 if sys.argv[1:] == ['-g']:
1835 for statements, kind in ((exec_tests, "exec"), (single_tests, "single"),
1836 (eval_tests, "eval")):
1837 print(kind+"_results = [")
Victor Stinnerf0891962016-02-08 17:15:21 +01001838 for statement in statements:
1839 tree = ast.parse(statement, "?", kind)
1840 print("%r," % (to_tuple(tree),))
Neal Norwitzee9b10a2008-03-31 05:29:39 +00001841 print("]")
1842 print("main()")
1843 raise SystemExit
Brett Cannon3e9a9ae2013-06-12 21:25:59 -04001844 unittest.main()
Tim Peters400cbc32006-02-28 18:44:41 +00001845
Guido van Rossumdcfcd142019-01-31 03:40:27 -08001846#### EVERYTHING BELOW IS GENERATED BY python Lib/test/test_ast.py -g #####
Tim Peters400cbc32006-02-28 18:44:41 +00001847exec_results = [
Guido van Rossum10f8ce62019-03-13 13:00:46 -07001848('Module', [('Expr', (1, 0), ('Constant', (1, 0), None, None))], []),
1849('Module', [('Expr', (1, 0), ('Constant', (1, 0), 'module docstring', None))], []),
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01001850('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [], [], None, [], [], None, []), [('Pass', (1, 9))], [], None, None)], []),
1851('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [], [], None, [], [], None, []), [('Expr', (1, 9), ('Constant', (1, 9), 'function docstring', None))], [], None, None)], []),
Pablo Galindocd6e83b2019-07-15 01:32:18 +02001852('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [], [('arg', (1, 6), 'a', None, None)], None, [], [], None, []), [('Pass', (1, 10))], [], None, None)], []),
1853('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [], [('arg', (1, 6), 'a', None, None)], None, [], [], None, [('Constant', (1, 8), 0, None)]), [('Pass', (1, 12))], [], None, None)], []),
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01001854('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [], [], ('arg', (1, 7), 'args', None, None), [], [], None, []), [('Pass', (1, 14))], [], None, None)], []),
1855('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [], [], None, [], [], ('arg', (1, 8), 'kwargs', None, None), []), [('Pass', (1, 17))], [], None, None)], []),
Pablo Galindocd6e83b2019-07-15 01:32:18 +02001856('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [], [('arg', (1, 6), 'a', None, None), ('arg', (1, 9), 'b', None, None), ('arg', (1, 14), 'c', None, None), ('arg', (1, 22), 'd', None, None), ('arg', (1, 28), 'e', None, None)], ('arg', (1, 35), 'args', None, None), [('arg', (1, 41), 'f', None, None)], [('Constant', (1, 43), 42, None)], ('arg', (1, 49), 'kwargs', None, None), [('Constant', (1, 11), 1, None), ('Constant', (1, 16), None, None), ('List', (1, 24), [], ('Load',)), ('Dict', (1, 30), [], [])]), [('Expr', (1, 58), ('Constant', (1, 58), 'doc for f()', None))], [], None, None)], []),
Guido van Rossumdcfcd142019-01-31 03:40:27 -08001857('Module', [('ClassDef', (1, 0), 'C', [], [], [('Pass', (1, 8))], [])], []),
Guido van Rossum10f8ce62019-03-13 13:00:46 -07001858('Module', [('ClassDef', (1, 0), 'C', [], [], [('Expr', (1, 9), ('Constant', (1, 9), 'docstring for class C', None))], [])], []),
Guido van Rossumdcfcd142019-01-31 03:40:27 -08001859('Module', [('ClassDef', (1, 0), 'C', [('Name', (1, 8), 'object', ('Load',))], [], [('Pass', (1, 17))], [])], []),
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01001860('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [], [], None, [], [], None, []), [('Return', (1, 8), ('Constant', (1, 15), 1, None))], [], None, None)], []),
Guido van Rossumdcfcd142019-01-31 03:40:27 -08001861('Module', [('Delete', (1, 0), [('Name', (1, 4), 'v', ('Del',))])], []),
Guido van Rossum10f8ce62019-03-13 13:00:46 -07001862('Module', [('Assign', (1, 0), [('Name', (1, 0), 'v', ('Store',))], ('Constant', (1, 4), 1, None), None)], []),
Guido van Rossumdcfcd142019-01-31 03:40:27 -08001863('Module', [('Assign', (1, 0), [('Tuple', (1, 0), [('Name', (1, 0), 'a', ('Store',)), ('Name', (1, 2), 'b', ('Store',))], ('Store',))], ('Name', (1, 6), 'c', ('Load',)), None)], []),
1864('Module', [('Assign', (1, 0), [('Tuple', (1, 0), [('Name', (1, 1), 'a', ('Store',)), ('Name', (1, 3), 'b', ('Store',))], ('Store',))], ('Name', (1, 8), 'c', ('Load',)), None)], []),
1865('Module', [('Assign', (1, 0), [('List', (1, 0), [('Name', (1, 1), 'a', ('Store',)), ('Name', (1, 3), 'b', ('Store',))], ('Store',))], ('Name', (1, 8), 'c', ('Load',)), None)], []),
Guido van Rossum10f8ce62019-03-13 13:00:46 -07001866('Module', [('AugAssign', (1, 0), ('Name', (1, 0), 'v', ('Store',)), ('Add',), ('Constant', (1, 5), 1, None))], []),
Guido van Rossumdcfcd142019-01-31 03:40:27 -08001867('Module', [('For', (1, 0), ('Name', (1, 4), 'v', ('Store',)), ('Name', (1, 9), 'v', ('Load',)), [('Pass', (1, 11))], [], None)], []),
1868('Module', [('While', (1, 0), ('Name', (1, 6), 'v', ('Load',)), [('Pass', (1, 8))], [])], []),
1869('Module', [('If', (1, 0), ('Name', (1, 3), 'v', ('Load',)), [('Pass', (1, 5))], [])], []),
Lysandros Nikolaou025a6022019-12-12 22:40:21 +01001870('Module', [('If', (1, 0), ('Name', (1, 3), 'a', ('Load',)), [('Pass', (2, 2))], [('If', (3, 0), ('Name', (3, 5), 'b', ('Load',)), [('Pass', (4, 2))], [])])], []),
Lysandros Nikolaou5936a4c2019-12-14 11:24:57 +01001871('Module', [('If', (1, 0), ('Name', (1, 3), 'a', ('Load',)), [('Pass', (2, 2))], [('If', (3, 0), ('Name', (3, 5), 'b', ('Load',)), [('Pass', (4, 2))], [('Pass', (6, 2))])])], []),
Guido van Rossumdcfcd142019-01-31 03:40:27 -08001872('Module', [('With', (1, 0), [('withitem', ('Name', (1, 5), 'x', ('Load',)), ('Name', (1, 10), 'y', ('Store',)))], [('Pass', (1, 13))], None)], []),
1873('Module', [('With', (1, 0), [('withitem', ('Name', (1, 5), 'x', ('Load',)), ('Name', (1, 10), 'y', ('Store',))), ('withitem', ('Name', (1, 13), 'z', ('Load',)), ('Name', (1, 18), 'q', ('Store',)))], [('Pass', (1, 21))], None)], []),
Guido van Rossum10f8ce62019-03-13 13:00:46 -07001874('Module', [('Raise', (1, 0), ('Call', (1, 6), ('Name', (1, 6), 'Exception', ('Load',)), [('Constant', (1, 16), 'string', None)], []), None)], []),
Guido van Rossumdcfcd142019-01-31 03:40:27 -08001875('Module', [('Try', (1, 0), [('Pass', (2, 2))], [('ExceptHandler', (3, 0), ('Name', (3, 7), 'Exception', ('Load',)), None, [('Pass', (4, 2))])], [], [])], []),
1876('Module', [('Try', (1, 0), [('Pass', (2, 2))], [], [], [('Pass', (4, 2))])], []),
1877('Module', [('Assert', (1, 0), ('Name', (1, 7), 'v', ('Load',)), None)], []),
1878('Module', [('Import', (1, 0), [('alias', 'sys', None)])], []),
1879('Module', [('ImportFrom', (1, 0), 'sys', [('alias', 'v', None)], 0)], []),
1880('Module', [('Global', (1, 0), ['v'])], []),
Guido van Rossum10f8ce62019-03-13 13:00:46 -07001881('Module', [('Expr', (1, 0), ('Constant', (1, 0), 1, None))], []),
Guido van Rossumdcfcd142019-01-31 03:40:27 -08001882('Module', [('Pass', (1, 0))], []),
1883('Module', [('For', (1, 0), ('Name', (1, 4), 'v', ('Store',)), ('Name', (1, 9), 'v', ('Load',)), [('Break', (1, 11))], [], None)], []),
1884('Module', [('For', (1, 0), ('Name', (1, 4), 'v', ('Store',)), ('Name', (1, 9), 'v', ('Load',)), [('Continue', (1, 11))], [], None)], []),
1885('Module', [('For', (1, 0), ('Tuple', (1, 4), [('Name', (1, 4), 'a', ('Store',)), ('Name', (1, 6), 'b', ('Store',))], ('Store',)), ('Name', (1, 11), 'c', ('Load',)), [('Pass', (1, 14))], [], None)], []),
1886('Module', [('For', (1, 0), ('Tuple', (1, 4), [('Name', (1, 5), 'a', ('Store',)), ('Name', (1, 7), 'b', ('Store',))], ('Store',)), ('Name', (1, 13), 'c', ('Load',)), [('Pass', (1, 16))], [], None)], []),
1887('Module', [('For', (1, 0), ('List', (1, 4), [('Name', (1, 5), 'a', ('Store',)), ('Name', (1, 7), 'b', ('Store',))], ('Store',)), ('Name', (1, 13), 'c', ('Load',)), [('Pass', (1, 16))], [], None)], []),
1888('Module', [('Expr', (1, 0), ('GeneratorExp', (1, 0), ('Tuple', (2, 4), [('Name', (3, 4), 'Aa', ('Load',)), ('Name', (5, 7), 'Bb', ('Load',))], ('Load',)), [('comprehension', ('Tuple', (8, 4), [('Name', (8, 4), 'Aa', ('Store',)), ('Name', (10, 4), 'Bb', ('Store',))], ('Store',)), ('Name', (10, 10), 'Cc', ('Load',)), [], 0)]))], []),
1889('Module', [('Expr', (1, 0), ('DictComp', (1, 0), ('Name', (1, 1), 'a', ('Load',)), ('Name', (1, 5), 'b', ('Load',)), [('comprehension', ('Name', (1, 11), 'w', ('Store',)), ('Name', (1, 16), 'x', ('Load',)), [], 0), ('comprehension', ('Name', (1, 22), 'm', ('Store',)), ('Name', (1, 27), 'p', ('Load',)), [('Name', (1, 32), 'g', ('Load',))], 0)]))], []),
1890('Module', [('Expr', (1, 0), ('DictComp', (1, 0), ('Name', (1, 1), 'a', ('Load',)), ('Name', (1, 5), 'b', ('Load',)), [('comprehension', ('Tuple', (1, 11), [('Name', (1, 11), 'v', ('Store',)), ('Name', (1, 13), 'w', ('Store',))], ('Store',)), ('Name', (1, 18), 'x', ('Load',)), [], 0)]))], []),
1891('Module', [('Expr', (1, 0), ('SetComp', (1, 0), ('Name', (1, 1), 'r', ('Load',)), [('comprehension', ('Name', (1, 7), 'l', ('Store',)), ('Name', (1, 12), 'x', ('Load',)), [('Name', (1, 17), 'g', ('Load',))], 0)]))], []),
1892('Module', [('Expr', (1, 0), ('SetComp', (1, 0), ('Name', (1, 1), 'r', ('Load',)), [('comprehension', ('Tuple', (1, 7), [('Name', (1, 7), 'l', ('Store',)), ('Name', (1, 9), 'm', ('Store',))], ('Store',)), ('Name', (1, 14), 'x', ('Load',)), [], 0)]))], []),
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01001893('Module', [('AsyncFunctionDef', (1, 0), 'f', ('arguments', [], [], None, [], [], None, []), [('Expr', (2, 1), ('Constant', (2, 1), 'async function', None)), ('Expr', (3, 1), ('Await', (3, 1), ('Call', (3, 7), ('Name', (3, 7), 'something', ('Load',)), [], [])))], [], None, None)], []),
1894('Module', [('AsyncFunctionDef', (1, 0), 'f', ('arguments', [], [], None, [], [], None, []), [('AsyncFor', (2, 1), ('Name', (2, 11), 'e', ('Store',)), ('Name', (2, 16), 'i', ('Load',)), [('Expr', (2, 19), ('Constant', (2, 19), 1, None))], [('Expr', (3, 7), ('Constant', (3, 7), 2, None))], None)], [], None, None)], []),
1895('Module', [('AsyncFunctionDef', (1, 0), 'f', ('arguments', [], [], None, [], [], None, []), [('AsyncWith', (2, 1), [('withitem', ('Name', (2, 12), 'a', ('Load',)), ('Name', (2, 17), 'b', ('Store',)))], [('Expr', (2, 20), ('Constant', (2, 20), 1, None))], None)], [], None, None)], []),
Guido van Rossum10f8ce62019-03-13 13:00:46 -07001896('Module', [('Expr', (1, 0), ('Dict', (1, 0), [None, ('Constant', (1, 10), 2, None)], [('Dict', (1, 3), [('Constant', (1, 4), 1, None)], [('Constant', (1, 6), 2, None)]), ('Constant', (1, 12), 3, None)]))], []),
1897('Module', [('Expr', (1, 0), ('Set', (1, 0), [('Starred', (1, 1), ('Set', (1, 2), [('Constant', (1, 3), 1, None), ('Constant', (1, 6), 2, None)]), ('Load',)), ('Constant', (1, 10), 3, None)]))], []),
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01001898('Module', [('AsyncFunctionDef', (1, 0), 'f', ('arguments', [], [], None, [], [], None, []), [('Expr', (2, 1), ('ListComp', (2, 1), ('Name', (2, 2), 'i', ('Load',)), [('comprehension', ('Name', (2, 14), 'b', ('Store',)), ('Name', (2, 19), 'c', ('Load',)), [], 1)]))], [], None, None)], []),
Serhiy Storchaka26ae9f62019-10-26 16:46:05 +03001899('Module', [('FunctionDef', (4, 0), 'f', ('arguments', [], [], None, [], [], None, []), [('Pass', (4, 9))], [('Name', (1, 1), 'deco1', ('Load',)), ('Call', (2, 1), ('Name', (2, 1), 'deco2', ('Load',)), [], []), ('Call', (3, 1), ('Name', (3, 1), 'deco3', ('Load',)), [('Constant', (3, 7), 1, None)], [])], None, None)], []),
1900('Module', [('AsyncFunctionDef', (4, 0), 'f', ('arguments', [], [], None, [], [], None, []), [('Pass', (4, 15))], [('Name', (1, 1), 'deco1', ('Load',)), ('Call', (2, 1), ('Name', (2, 1), 'deco2', ('Load',)), [], []), ('Call', (3, 1), ('Name', (3, 1), 'deco3', ('Load',)), [('Constant', (3, 7), 1, None)], [])], None, None)], []),
1901('Module', [('ClassDef', (4, 0), 'C', [], [], [('Pass', (4, 9))], [('Name', (1, 1), 'deco1', ('Load',)), ('Call', (2, 1), ('Name', (2, 1), 'deco2', ('Load',)), [], []), ('Call', (3, 1), ('Name', (3, 1), 'deco3', ('Load',)), [('Constant', (3, 7), 1, None)], [])])], []),
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01001902('Module', [('FunctionDef', (2, 0), 'f', ('arguments', [], [], None, [], [], None, []), [('Pass', (2, 9))], [('Call', (1, 1), ('Name', (1, 1), 'deco', ('Load',)), [('GeneratorExp', (1, 5), ('Name', (1, 6), 'a', ('Load',)), [('comprehension', ('Name', (1, 12), 'a', ('Store',)), ('Name', (1, 17), 'b', ('Load',)), [], 0)])], [])], None, None)], []),
Pablo Galindo0c9258a2019-03-18 13:51:53 +00001903('Module', [('Expr', (1, 0), ('NamedExpr', (1, 1), ('Name', (1, 1), 'a', ('Store',)), ('Constant', (1, 6), 1, None)))], []),
Pablo Galindocd6e83b2019-07-15 01:32:18 +02001904('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [('arg', (1, 6), 'a', None, None)], [], None, [], [], None, []), [('Pass', (1, 14))], [], None, None)], []),
1905('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [('arg', (1, 6), 'a', None, None)], [('arg', (1, 12), 'c', None, None), ('arg', (1, 15), 'd', None, None), ('arg', (1, 18), 'e', None, None)], None, [], [], None, []), [('Pass', (1, 22))], [], None, None)], []),
1906('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [('arg', (1, 6), 'a', None, None)], [('arg', (1, 12), 'c', None, None)], None, [('arg', (1, 18), 'd', None, None), ('arg', (1, 21), 'e', None, None)], [None, None], None, []), [('Pass', (1, 25))], [], None, None)], []),
1907('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [('arg', (1, 6), 'a', None, None)], [('arg', (1, 12), 'c', None, None)], None, [('arg', (1, 18), 'd', None, None), ('arg', (1, 21), 'e', None, None)], [None, None], ('arg', (1, 26), 'kwargs', None, None), []), [('Pass', (1, 35))], [], None, None)], []),
1908('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [('arg', (1, 6), 'a', None, None)], [], None, [], [], None, [('Constant', (1, 8), 1, None)]), [('Pass', (1, 16))], [], None, None)], []),
1909('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [('arg', (1, 6), 'a', None, None)], [('arg', (1, 14), 'b', None, None), ('arg', (1, 19), 'c', None, None)], None, [], [], None, [('Constant', (1, 8), 1, None), ('Constant', (1, 16), 2, None), ('Constant', (1, 21), 4, None)]), [('Pass', (1, 25))], [], None, None)], []),
1910('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [('arg', (1, 6), 'a', None, None)], [('arg', (1, 14), 'b', None, None)], None, [('arg', (1, 22), 'c', None, None)], [('Constant', (1, 24), 4, None)], None, [('Constant', (1, 8), 1, None), ('Constant', (1, 16), 2, None)]), [('Pass', (1, 28))], [], None, None)], []),
1911('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [('arg', (1, 6), 'a', None, None)], [('arg', (1, 14), 'b', None, None)], None, [('arg', (1, 22), 'c', None, None)], [None], None, [('Constant', (1, 8), 1, None), ('Constant', (1, 16), 2, None)]), [('Pass', (1, 26))], [], None, None)], []),
1912('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [('arg', (1, 6), 'a', None, None)], [('arg', (1, 14), 'b', None, None)], None, [('arg', (1, 22), 'c', None, None)], [('Constant', (1, 24), 4, None)], ('arg', (1, 29), 'kwargs', None, None), [('Constant', (1, 8), 1, None), ('Constant', (1, 16), 2, None)]), [('Pass', (1, 38))], [], None, None)], []),
1913('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [('arg', (1, 6), 'a', None, None)], [('arg', (1, 14), 'b', None, None)], None, [('arg', (1, 22), 'c', None, None)], [None], ('arg', (1, 27), 'kwargs', None, None), [('Constant', (1, 8), 1, None), ('Constant', (1, 16), 2, None)]), [('Pass', (1, 36))], [], None, None)], []),
Tim Peters400cbc32006-02-28 18:44:41 +00001914]
1915single_results = [
Guido van Rossum10f8ce62019-03-13 13:00:46 -07001916('Interactive', [('Expr', (1, 0), ('BinOp', (1, 0), ('Constant', (1, 0), 1, None), ('Add',), ('Constant', (1, 2), 2, None)))]),
Tim Peters400cbc32006-02-28 18:44:41 +00001917]
1918eval_results = [
Guido van Rossum10f8ce62019-03-13 13:00:46 -07001919('Expression', ('Constant', (1, 0), None, None)),
Martin v. Löwis49c5da12006-03-01 22:49:05 +00001920('Expression', ('BoolOp', (1, 0), ('And',), [('Name', (1, 0), 'a', ('Load',)), ('Name', (1, 6), 'b', ('Load',))])),
1921('Expression', ('BinOp', (1, 0), ('Name', (1, 0), 'a', ('Load',)), ('Add',), ('Name', (1, 4), 'b', ('Load',)))),
1922('Expression', ('UnaryOp', (1, 0), ('Not',), ('Name', (1, 4), 'v', ('Load',)))),
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01001923('Expression', ('Lambda', (1, 0), ('arguments', [], [], None, [], [], None, []), ('Constant', (1, 7), None, None))),
Guido van Rossum10f8ce62019-03-13 13:00:46 -07001924('Expression', ('Dict', (1, 0), [('Constant', (1, 2), 1, None)], [('Constant', (1, 4), 2, None)])),
Benjamin Peterson6ccfe852011-06-27 17:46:06 -05001925('Expression', ('Dict', (1, 0), [], [])),
Guido van Rossum10f8ce62019-03-13 13:00:46 -07001926('Expression', ('Set', (1, 0), [('Constant', (1, 1), None, None)])),
1927('Expression', ('Dict', (1, 0), [('Constant', (2, 6), 1, None)], [('Constant', (4, 10), 2, None)])),
Serhiy Storchakab619b092018-11-27 09:40:29 +02001928('Expression', ('ListComp', (1, 0), ('Name', (1, 1), 'a', ('Load',)), [('comprehension', ('Name', (1, 7), 'b', ('Store',)), ('Name', (1, 12), 'c', ('Load',)), [('Name', (1, 17), 'd', ('Load',))], 0)])),
1929('Expression', ('GeneratorExp', (1, 0), ('Name', (1, 1), 'a', ('Load',)), [('comprehension', ('Name', (1, 7), 'b', ('Store',)), ('Name', (1, 12), 'c', ('Load',)), [('Name', (1, 17), 'd', ('Load',))], 0)])),
1930('Expression', ('ListComp', (1, 0), ('Tuple', (1, 1), [('Name', (1, 2), 'a', ('Load',)), ('Name', (1, 4), 'b', ('Load',))], ('Load',)), [('comprehension', ('Tuple', (1, 11), [('Name', (1, 11), 'a', ('Store',)), ('Name', (1, 13), 'b', ('Store',))], ('Store',)), ('Name', (1, 18), 'c', ('Load',)), [], 0)])),
1931('Expression', ('ListComp', (1, 0), ('Tuple', (1, 1), [('Name', (1, 2), 'a', ('Load',)), ('Name', (1, 4), 'b', ('Load',))], ('Load',)), [('comprehension', ('Tuple', (1, 11), [('Name', (1, 12), 'a', ('Store',)), ('Name', (1, 14), 'b', ('Store',))], ('Store',)), ('Name', (1, 20), 'c', ('Load',)), [], 0)])),
1932('Expression', ('ListComp', (1, 0), ('Tuple', (1, 1), [('Name', (1, 2), 'a', ('Load',)), ('Name', (1, 4), 'b', ('Load',))], ('Load',)), [('comprehension', ('List', (1, 11), [('Name', (1, 12), 'a', ('Store',)), ('Name', (1, 14), 'b', ('Store',))], ('Store',)), ('Name', (1, 20), 'c', ('Load',)), [], 0)])),
1933('Expression', ('SetComp', (1, 0), ('Tuple', (1, 1), [('Name', (1, 2), 'a', ('Load',)), ('Name', (1, 4), 'b', ('Load',))], ('Load',)), [('comprehension', ('Tuple', (1, 11), [('Name', (1, 11), 'a', ('Store',)), ('Name', (1, 13), 'b', ('Store',))], ('Store',)), ('Name', (1, 18), 'c', ('Load',)), [], 0)])),
1934('Expression', ('SetComp', (1, 0), ('Tuple', (1, 1), [('Name', (1, 2), 'a', ('Load',)), ('Name', (1, 4), 'b', ('Load',))], ('Load',)), [('comprehension', ('Tuple', (1, 11), [('Name', (1, 12), 'a', ('Store',)), ('Name', (1, 14), 'b', ('Store',))], ('Store',)), ('Name', (1, 20), 'c', ('Load',)), [], 0)])),
1935('Expression', ('SetComp', (1, 0), ('Tuple', (1, 1), [('Name', (1, 2), 'a', ('Load',)), ('Name', (1, 4), 'b', ('Load',))], ('Load',)), [('comprehension', ('List', (1, 11), [('Name', (1, 12), 'a', ('Store',)), ('Name', (1, 14), 'b', ('Store',))], ('Store',)), ('Name', (1, 20), 'c', ('Load',)), [], 0)])),
1936('Expression', ('GeneratorExp', (1, 0), ('Tuple', (1, 1), [('Name', (1, 2), 'a', ('Load',)), ('Name', (1, 4), 'b', ('Load',))], ('Load',)), [('comprehension', ('Tuple', (1, 11), [('Name', (1, 11), 'a', ('Store',)), ('Name', (1, 13), 'b', ('Store',))], ('Store',)), ('Name', (1, 18), 'c', ('Load',)), [], 0)])),
1937('Expression', ('GeneratorExp', (1, 0), ('Tuple', (1, 1), [('Name', (1, 2), 'a', ('Load',)), ('Name', (1, 4), 'b', ('Load',))], ('Load',)), [('comprehension', ('Tuple', (1, 11), [('Name', (1, 12), 'a', ('Store',)), ('Name', (1, 14), 'b', ('Store',))], ('Store',)), ('Name', (1, 20), 'c', ('Load',)), [], 0)])),
1938('Expression', ('GeneratorExp', (1, 0), ('Tuple', (1, 1), [('Name', (1, 2), 'a', ('Load',)), ('Name', (1, 4), 'b', ('Load',))], ('Load',)), [('comprehension', ('List', (1, 11), [('Name', (1, 12), 'a', ('Store',)), ('Name', (1, 14), 'b', ('Store',))], ('Store',)), ('Name', (1, 20), 'c', ('Load',)), [], 0)])),
Guido van Rossum10f8ce62019-03-13 13:00:46 -07001939('Expression', ('Compare', (1, 0), ('Constant', (1, 0), 1, None), [('Lt',), ('Lt',)], [('Constant', (1, 4), 2, None), ('Constant', (1, 8), 3, None)])),
1940('Expression', ('Call', (1, 0), ('Name', (1, 0), 'f', ('Load',)), [('Constant', (1, 2), 1, None), ('Constant', (1, 4), 2, None), ('Starred', (1, 10), ('Name', (1, 11), 'd', ('Load',)), ('Load',))], [('keyword', 'c', ('Constant', (1, 8), 3, None)), ('keyword', None, ('Name', (1, 15), 'e', ('Load',)))])),
Lysandros Nikolaou50d4f122019-12-18 01:20:55 +01001941('Expression', ('Call', (1, 0), ('Name', (1, 0), 'f', ('Load',)), [('Starred', (1, 2), ('List', (1, 3), [('Constant', (1, 4), 0, None), ('Constant', (1, 7), 1, None)], ('Load',)), ('Load',))], [])),
Serhiy Storchakab619b092018-11-27 09:40:29 +02001942('Expression', ('Call', (1, 0), ('Name', (1, 0), 'f', ('Load',)), [('GeneratorExp', (1, 1), ('Name', (1, 2), 'a', ('Load',)), [('comprehension', ('Name', (1, 8), 'a', ('Store',)), ('Name', (1, 13), 'b', ('Load',)), [], 0)])], [])),
Guido van Rossum10f8ce62019-03-13 13:00:46 -07001943('Expression', ('Constant', (1, 0), 10, None)),
1944('Expression', ('Constant', (1, 0), 'string', None)),
Benjamin Peterson7a66fc22015-02-02 10:51:20 -05001945('Expression', ('Attribute', (1, 0), ('Name', (1, 0), 'a', ('Load',)), 'b', ('Load',))),
1946('Expression', ('Subscript', (1, 0), ('Name', (1, 0), 'a', ('Load',)), ('Slice', ('Name', (1, 2), 'b', ('Load',)), ('Name', (1, 4), 'c', ('Load',)), None), ('Load',))),
Martin v. Löwis49c5da12006-03-01 22:49:05 +00001947('Expression', ('Name', (1, 0), 'v', ('Load',))),
Guido van Rossum10f8ce62019-03-13 13:00:46 -07001948('Expression', ('List', (1, 0), [('Constant', (1, 1), 1, None), ('Constant', (1, 3), 2, None), ('Constant', (1, 5), 3, None)], ('Load',))),
Benjamin Peterson6ccfe852011-06-27 17:46:06 -05001949('Expression', ('List', (1, 0), [], ('Load',))),
Guido van Rossum10f8ce62019-03-13 13:00:46 -07001950('Expression', ('Tuple', (1, 0), [('Constant', (1, 0), 1, None), ('Constant', (1, 2), 2, None), ('Constant', (1, 4), 3, None)], ('Load',))),
1951('Expression', ('Tuple', (1, 0), [('Constant', (1, 1), 1, None), ('Constant', (1, 3), 2, None), ('Constant', (1, 5), 3, None)], ('Load',))),
Benjamin Peterson6ccfe852011-06-27 17:46:06 -05001952('Expression', ('Tuple', (1, 0), [], ('Load',))),
Guido van Rossum10f8ce62019-03-13 13:00:46 -07001953('Expression', ('Call', (1, 0), ('Attribute', (1, 0), ('Attribute', (1, 0), ('Attribute', (1, 0), ('Name', (1, 0), 'a', ('Load',)), 'b', ('Load',)), 'c', ('Load',)), 'd', ('Load',)), [('Subscript', (1, 8), ('Attribute', (1, 8), ('Name', (1, 8), 'a', ('Load',)), 'b', ('Load',)), ('Slice', ('Constant', (1, 12), 1, None), ('Constant', (1, 14), 2, None), None), ('Load',))], [])),
Tim Peters400cbc32006-02-28 18:44:41 +00001954]
Neal Norwitzee9b10a2008-03-31 05:29:39 +00001955main()