blob: 3e8a39dc41047e61321a94f1d5ac5bc1d4af6dea [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
Miss Islington (bot)522a3942019-08-26 00:43:33 -07006import 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",
Miss Islington (bot)3b18b172019-12-13 08:21:54 -080071 # If-Elif
72 "if a:\n pass\nelif b:\n pass",
Miss Islington (bot)ce333cd2019-12-14 02:43:42 -080073 # 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
Miss Skeleton (bot)ba3a5662019-10-26 07:06:40 -0700136 "@deco1\n@deco2()\n@deco3(1)\ndef f(): pass",
Serhiy Storchaka95b6acf2018-10-30 13:16:02 +0200137 # Decorated AsyncFunctionDef
Miss Skeleton (bot)ba3a5662019-10-26 07:06:40 -0700138 "@deco1\n@deco2()\n@deco3(1)\nasync def f(): pass",
Serhiy Storchaka95b6acf2018-10-30 13:16:02 +0200139 # Decorated ClassDef
Miss Skeleton (bot)ba3a5662019-10-26 07:06:40 -0700140 "@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",
Lysandros Nikolaou8b9cebc2020-02-08 01:21:38 +0100143 # Decorator with attribute
144 "@a.b.c\ndef f(): pass",
Pablo Galindo0c9258a2019-03-18 13:51:53 +0000145 # Simple assignment expression
146 "(a := 1)",
Pablo Galindo2f58a842019-05-31 14:09:49 +0100147 # Positional-only arguments
148 "def f(a, /,): pass",
149 "def f(a, /, c, d, e): pass",
150 "def f(a, /, c, *, d, e): pass",
151 "def f(a, /, c, *, d, e, **kwargs): pass",
152 # Positional-only arguments with defaults
153 "def f(a=1, /,): pass",
154 "def f(a=1, /, b=2, c=4): pass",
155 "def f(a=1, /, b=2, *, c=4): pass",
156 "def f(a=1, /, b=2, *, c): pass",
157 "def f(a=1, /, b=2, *, c=4, **kwargs): pass",
158 "def f(a=1, /, b=2, *, c, **kwargs): pass",
Pablo Galindo0c9258a2019-03-18 13:51:53 +0000159
Tim Peters400cbc32006-02-28 18:44:41 +0000160]
161
162# These are compiled through "single"
163# because of overlap with "eval", it just tests what
164# can't be tested with "eval"
165single_tests = [
166 "1+2"
167]
168
169# These are compiled through "eval"
170# It should test all expressions
171eval_tests = [
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500172 # None
173 "None",
Tim Peters400cbc32006-02-28 18:44:41 +0000174 # BoolOp
175 "a and b",
176 # BinOp
177 "a + b",
178 # UnaryOp
179 "not v",
180 # Lambda
181 "lambda:None",
182 # Dict
183 "{ 1:2 }",
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500184 # Empty dict
185 "{}",
186 # Set
187 "{None,}",
188 # Multiline dict (test for .lineno & .col_offset)
189 """{
190 1
191 :
192 2
193 }""",
Tim Peters400cbc32006-02-28 18:44:41 +0000194 # ListComp
195 "[a for b in c if d]",
196 # GeneratorExp
197 "(a for b in c if d)",
Serhiy Storchakab619b092018-11-27 09:40:29 +0200198 # Comprehensions with multiple for targets
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)",
206 "((a,b) for (a,b) in c)",
207 "((a,b) for [a,b] in c)",
Tim Peters400cbc32006-02-28 18:44:41 +0000208 # Yield - yield expressions can't work outside a function
209 #
210 # Compare
211 "1 < 2 < 3",
212 # Call
213 "f(1,2,c=3,*d,**e)",
Pablo Galindob1f20442019-12-18 01:41:58 +0000214 # Call with multi-character starred
215 "f(*[0, 1])",
Serhiy Storchakab619b092018-11-27 09:40:29 +0200216 # Call with a generator argument
217 "f(a for a in b)",
Tim Peters400cbc32006-02-28 18:44:41 +0000218 # Num
Guido van Rossume2a383d2007-01-15 16:59:06 +0000219 "10",
Tim Peters400cbc32006-02-28 18:44:41 +0000220 # Str
221 "'string'",
222 # Attribute
223 "a.b",
224 # Subscript
225 "a[b:c]",
226 # Name
227 "v",
228 # List
229 "[1,2,3]",
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500230 # Empty list
231 "[]",
Tim Peters400cbc32006-02-28 18:44:41 +0000232 # Tuple
Martin v. Löwis49c5da12006-03-01 22:49:05 +0000233 "1,2,3",
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500234 # Tuple
235 "(1,2,3)",
236 # Empty tuple
237 "()",
Martin v. Löwis49c5da12006-03-01 22:49:05 +0000238 # Combination
239 "a.b.c.d(a.b[1:2])",
240
Tim Peters400cbc32006-02-28 18:44:41 +0000241]
242
243# TODO: expr_context, slice, boolop, operator, unaryop, cmpop, comprehension
244# excepthandler, arguments, keywords, alias
245
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000246class AST_Tests(unittest.TestCase):
Tim Peters400cbc32006-02-28 18:44:41 +0000247
Benjamin Peterson7a66fc22015-02-02 10:51:20 -0500248 def _assertTrueorder(self, ast_node, parent_pos):
Georg Brandl0c77a822008-06-10 16:37:50 +0000249 if not isinstance(ast_node, ast.AST) or ast_node._fields is None:
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000250 return
Georg Brandl0c77a822008-06-10 16:37:50 +0000251 if isinstance(ast_node, (ast.expr, ast.stmt, ast.excepthandler)):
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000252 node_pos = (ast_node.lineno, ast_node.col_offset)
Serhiy Storchaka95b6acf2018-10-30 13:16:02 +0200253 self.assertGreaterEqual(node_pos, parent_pos)
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000254 parent_pos = (ast_node.lineno, ast_node.col_offset)
255 for name in ast_node._fields:
256 value = getattr(ast_node, name)
257 if isinstance(value, list):
Serhiy Storchaka95b6acf2018-10-30 13:16:02 +0200258 first_pos = parent_pos
259 if value and name == 'decorator_list':
260 first_pos = (value[0].lineno, value[0].col_offset)
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000261 for child in value:
Serhiy Storchaka95b6acf2018-10-30 13:16:02 +0200262 self._assertTrueorder(child, first_pos)
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000263 elif value is not None:
Benjamin Peterson7a66fc22015-02-02 10:51:20 -0500264 self._assertTrueorder(value, parent_pos)
Tim Peters5ddfe412006-03-01 23:02:57 +0000265
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500266 def test_AST_objects(self):
267 x = ast.AST()
268 self.assertEqual(x._fields, ())
Benjamin Peterson7e0dbfb2012-03-12 09:46:44 -0700269 x.foobar = 42
270 self.assertEqual(x.foobar, 42)
271 self.assertEqual(x.__dict__["foobar"], 42)
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500272
273 with self.assertRaises(AttributeError):
274 x.vararg
275
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500276 with self.assertRaises(TypeError):
277 # "_ast.AST constructor takes 0 positional arguments"
278 ast.AST(2)
279
Benjamin Peterson9ed37432012-07-08 11:13:36 -0700280 def test_AST_garbage_collection(self):
281 class X:
282 pass
283 a = ast.AST()
284 a.x = X()
285 a.x.a = a
286 ref = weakref.ref(a.x)
287 del a
288 support.gc_collect()
289 self.assertIsNone(ref())
290
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000291 def test_snippets(self):
292 for input, output, kind in ((exec_tests, exec_results, "exec"),
293 (single_tests, single_results, "single"),
294 (eval_tests, eval_results, "eval")):
295 for i, o in zip(input, output):
Yury Selivanovb3d53132015-09-01 16:10:49 -0400296 with self.subTest(action="parsing", input=i):
297 ast_tree = compile(i, "?", kind, ast.PyCF_ONLY_AST)
298 self.assertEqual(to_tuple(ast_tree), o)
299 self._assertTrueorder(ast_tree, (0, 0))
Victor Stinner15a30952016-02-08 22:45:06 +0100300 with self.subTest(action="compiling", input=i, kind=kind):
301 compile(ast_tree, "?", kind)
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000302
Pablo Galindo0c9258a2019-03-18 13:51:53 +0000303 def test_ast_validation(self):
304 # compile() is the only function that calls PyAST_Validate
305 snippets_to_validate = exec_tests + single_tests + eval_tests
306 for snippet in snippets_to_validate:
307 tree = ast.parse(snippet)
308 compile(tree, '<string>', 'exec')
309
Benjamin Peterson78565b22009-06-28 19:19:51 +0000310 def test_slice(self):
311 slc = ast.parse("x[::]").body[0].value.slice
312 self.assertIsNone(slc.upper)
313 self.assertIsNone(slc.lower)
314 self.assertIsNone(slc.step)
315
316 def test_from_import(self):
317 im = ast.parse("from . import y").body[0]
318 self.assertIsNone(im.module)
319
Benjamin Petersona4e4e352012-03-22 08:19:04 -0400320 def test_non_interned_future_from_ast(self):
321 mod = ast.parse("from __future__ import division")
322 self.assertIsInstance(mod.body[0], ast.ImportFrom)
323 mod.body[0].module = " __future__ ".strip()
324 compile(mod, "<test>", "exec")
325
Benjamin Petersona0dfa822009-11-13 02:25:08 +0000326 def test_base_classes(self):
327 self.assertTrue(issubclass(ast.For, ast.stmt))
328 self.assertTrue(issubclass(ast.Name, ast.expr))
329 self.assertTrue(issubclass(ast.stmt, ast.AST))
330 self.assertTrue(issubclass(ast.expr, ast.AST))
331 self.assertTrue(issubclass(ast.comprehension, ast.AST))
332 self.assertTrue(issubclass(ast.Gt, ast.AST))
333
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500334 def test_field_attr_existence(self):
335 for name, item in ast.__dict__.items():
336 if isinstance(item, type) and name != 'AST' and name[0].isupper():
337 x = item()
338 if isinstance(x, ast.AST):
339 self.assertEqual(type(x._fields), tuple)
340
341 def test_arguments(self):
342 x = ast.arguments()
Miss Islington (bot)cf9a63c2019-07-14 16:49:52 -0700343 self.assertEqual(x._fields, ('posonlyargs', 'args', 'vararg', 'kwonlyargs',
344 'kw_defaults', 'kwarg', 'defaults'))
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500345
346 with self.assertRaises(AttributeError):
347 x.vararg
348
Pablo Galindo8c77b8c2019-04-29 13:36:57 +0100349 x = ast.arguments(*range(1, 8))
350 self.assertEqual(x.vararg, 3)
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500351
352 def test_field_attr_writable(self):
353 x = ast.Num()
354 # We can assign to _fields
355 x._fields = 666
356 self.assertEqual(x._fields, 666)
357
358 def test_classattrs(self):
359 x = ast.Num()
Guido van Rossum10f8ce62019-03-13 13:00:46 -0700360 self.assertEqual(x._fields, ('value', 'kind'))
Serhiy Storchaka3f228112018-09-27 17:42:37 +0300361
362 with self.assertRaises(AttributeError):
363 x.value
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500364
365 with self.assertRaises(AttributeError):
366 x.n
367
368 x = ast.Num(42)
Serhiy Storchaka3f228112018-09-27 17:42:37 +0300369 self.assertEqual(x.value, 42)
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500370 self.assertEqual(x.n, 42)
371
372 with self.assertRaises(AttributeError):
373 x.lineno
374
375 with self.assertRaises(AttributeError):
376 x.foobar
377
378 x = ast.Num(lineno=2)
379 self.assertEqual(x.lineno, 2)
380
381 x = ast.Num(42, lineno=0)
382 self.assertEqual(x.lineno, 0)
Guido van Rossum10f8ce62019-03-13 13:00:46 -0700383 self.assertEqual(x._fields, ('value', 'kind'))
Serhiy Storchaka3f228112018-09-27 17:42:37 +0300384 self.assertEqual(x.value, 42)
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500385 self.assertEqual(x.n, 42)
386
Guido van Rossum10f8ce62019-03-13 13:00:46 -0700387 self.assertRaises(TypeError, ast.Num, 1, None, 2)
388 self.assertRaises(TypeError, ast.Num, 1, None, 2, lineno=0)
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500389
Serhiy Storchaka3f228112018-09-27 17:42:37 +0300390 self.assertEqual(ast.Num(42).n, 42)
391 self.assertEqual(ast.Num(4.25).n, 4.25)
392 self.assertEqual(ast.Num(4.25j).n, 4.25j)
393 self.assertEqual(ast.Str('42').s, '42')
394 self.assertEqual(ast.Bytes(b'42').s, b'42')
395 self.assertIs(ast.NameConstant(True).value, True)
396 self.assertIs(ast.NameConstant(False).value, False)
397 self.assertIs(ast.NameConstant(None).value, None)
398
399 self.assertEqual(ast.Constant(42).value, 42)
400 self.assertEqual(ast.Constant(4.25).value, 4.25)
401 self.assertEqual(ast.Constant(4.25j).value, 4.25j)
402 self.assertEqual(ast.Constant('42').value, '42')
403 self.assertEqual(ast.Constant(b'42').value, b'42')
404 self.assertIs(ast.Constant(True).value, True)
405 self.assertIs(ast.Constant(False).value, False)
406 self.assertIs(ast.Constant(None).value, None)
407 self.assertIs(ast.Constant(...).value, ...)
408
409 def test_realtype(self):
410 self.assertEqual(type(ast.Num(42)), ast.Constant)
411 self.assertEqual(type(ast.Num(4.25)), ast.Constant)
412 self.assertEqual(type(ast.Num(4.25j)), ast.Constant)
413 self.assertEqual(type(ast.Str('42')), ast.Constant)
414 self.assertEqual(type(ast.Bytes(b'42')), ast.Constant)
415 self.assertEqual(type(ast.NameConstant(True)), ast.Constant)
416 self.assertEqual(type(ast.NameConstant(False)), ast.Constant)
417 self.assertEqual(type(ast.NameConstant(None)), ast.Constant)
418 self.assertEqual(type(ast.Ellipsis()), ast.Constant)
419
420 def test_isinstance(self):
421 self.assertTrue(isinstance(ast.Num(42), ast.Num))
422 self.assertTrue(isinstance(ast.Num(4.2), ast.Num))
423 self.assertTrue(isinstance(ast.Num(4.2j), ast.Num))
424 self.assertTrue(isinstance(ast.Str('42'), ast.Str))
425 self.assertTrue(isinstance(ast.Bytes(b'42'), ast.Bytes))
426 self.assertTrue(isinstance(ast.NameConstant(True), ast.NameConstant))
427 self.assertTrue(isinstance(ast.NameConstant(False), ast.NameConstant))
428 self.assertTrue(isinstance(ast.NameConstant(None), ast.NameConstant))
429 self.assertTrue(isinstance(ast.Ellipsis(), ast.Ellipsis))
430
431 self.assertTrue(isinstance(ast.Constant(42), ast.Num))
432 self.assertTrue(isinstance(ast.Constant(4.2), ast.Num))
433 self.assertTrue(isinstance(ast.Constant(4.2j), ast.Num))
434 self.assertTrue(isinstance(ast.Constant('42'), ast.Str))
435 self.assertTrue(isinstance(ast.Constant(b'42'), ast.Bytes))
436 self.assertTrue(isinstance(ast.Constant(True), ast.NameConstant))
437 self.assertTrue(isinstance(ast.Constant(False), ast.NameConstant))
438 self.assertTrue(isinstance(ast.Constant(None), ast.NameConstant))
439 self.assertTrue(isinstance(ast.Constant(...), ast.Ellipsis))
440
441 self.assertFalse(isinstance(ast.Str('42'), ast.Num))
442 self.assertFalse(isinstance(ast.Num(42), ast.Str))
443 self.assertFalse(isinstance(ast.Str('42'), ast.Bytes))
444 self.assertFalse(isinstance(ast.Num(42), ast.NameConstant))
445 self.assertFalse(isinstance(ast.Num(42), ast.Ellipsis))
Anthony Sottile74176222019-01-18 11:30:28 -0800446 self.assertFalse(isinstance(ast.NameConstant(True), ast.Num))
447 self.assertFalse(isinstance(ast.NameConstant(False), ast.Num))
Serhiy Storchaka3f228112018-09-27 17:42:37 +0300448
449 self.assertFalse(isinstance(ast.Constant('42'), ast.Num))
450 self.assertFalse(isinstance(ast.Constant(42), ast.Str))
451 self.assertFalse(isinstance(ast.Constant('42'), ast.Bytes))
452 self.assertFalse(isinstance(ast.Constant(42), ast.NameConstant))
453 self.assertFalse(isinstance(ast.Constant(42), ast.Ellipsis))
Anthony Sottile74176222019-01-18 11:30:28 -0800454 self.assertFalse(isinstance(ast.Constant(True), ast.Num))
455 self.assertFalse(isinstance(ast.Constant(False), ast.Num))
Serhiy Storchaka3f228112018-09-27 17:42:37 +0300456
457 self.assertFalse(isinstance(ast.Constant(), ast.Num))
458 self.assertFalse(isinstance(ast.Constant(), ast.Str))
459 self.assertFalse(isinstance(ast.Constant(), ast.Bytes))
460 self.assertFalse(isinstance(ast.Constant(), ast.NameConstant))
461 self.assertFalse(isinstance(ast.Constant(), ast.Ellipsis))
462
Serhiy Storchaka6015cc52018-10-28 13:43:03 +0200463 class S(str): pass
464 self.assertTrue(isinstance(ast.Constant(S('42')), ast.Str))
465 self.assertFalse(isinstance(ast.Constant(S('42')), ast.Num))
466
Serhiy Storchaka3f228112018-09-27 17:42:37 +0300467 def test_subclasses(self):
468 class N(ast.Num):
469 def __init__(self, *args, **kwargs):
470 super().__init__(*args, **kwargs)
471 self.z = 'spam'
472 class N2(ast.Num):
473 pass
474
475 n = N(42)
476 self.assertEqual(n.n, 42)
477 self.assertEqual(n.z, 'spam')
478 self.assertEqual(type(n), N)
479 self.assertTrue(isinstance(n, N))
480 self.assertTrue(isinstance(n, ast.Num))
481 self.assertFalse(isinstance(n, N2))
482 self.assertFalse(isinstance(ast.Num(42), N))
483 n = N(n=42)
484 self.assertEqual(n.n, 42)
485 self.assertEqual(type(n), N)
486
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500487 def test_module(self):
488 body = [ast.Num(42)]
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800489 x = ast.Module(body, [])
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500490 self.assertEqual(x.body, body)
491
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000492 def test_nodeclasses(self):
Florent Xicluna992d9e02011-11-11 19:35:42 +0100493 # Zero arguments constructor explicitly allowed
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500494 x = ast.BinOp()
495 self.assertEqual(x._fields, ('left', 'op', 'right'))
496
497 # Random attribute allowed too
498 x.foobarbaz = 5
499 self.assertEqual(x.foobarbaz, 5)
500
501 n1 = ast.Num(1)
502 n3 = ast.Num(3)
503 addop = ast.Add()
504 x = ast.BinOp(n1, addop, n3)
505 self.assertEqual(x.left, n1)
506 self.assertEqual(x.op, addop)
507 self.assertEqual(x.right, n3)
Benjamin Peterson68b543a2011-06-27 17:51:18 -0500508
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500509 x = ast.BinOp(1, 2, 3)
510 self.assertEqual(x.left, 1)
511 self.assertEqual(x.op, 2)
512 self.assertEqual(x.right, 3)
513
Georg Brandl0c77a822008-06-10 16:37:50 +0000514 x = ast.BinOp(1, 2, 3, lineno=0)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000515 self.assertEqual(x.left, 1)
516 self.assertEqual(x.op, 2)
517 self.assertEqual(x.right, 3)
518 self.assertEqual(x.lineno, 0)
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000519
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)
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500522 # node raises exception when given too many arguments
523 self.assertRaises(TypeError, ast.BinOp, 1, 2, 3, 4, lineno=0)
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000524
525 # can set attributes through kwargs too
Georg Brandl0c77a822008-06-10 16:37:50 +0000526 x = ast.BinOp(left=1, op=2, right=3, lineno=0)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000527 self.assertEqual(x.left, 1)
528 self.assertEqual(x.op, 2)
529 self.assertEqual(x.right, 3)
530 self.assertEqual(x.lineno, 0)
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000531
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500532 # Random kwargs also allowed
533 x = ast.BinOp(1, 2, 3, foobarbaz=42)
534 self.assertEqual(x.foobarbaz, 42)
535
536 def test_no_fields(self):
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000537 # this used to fail because Sub._fields was None
Georg Brandl0c77a822008-06-10 16:37:50 +0000538 x = ast.Sub()
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500539 self.assertEqual(x._fields, ())
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000540
541 def test_pickling(self):
542 import pickle
543 mods = [pickle]
544 try:
545 import cPickle
546 mods.append(cPickle)
547 except ImportError:
548 pass
549 protocols = [0, 1, 2]
550 for mod in mods:
551 for protocol in protocols:
552 for ast in (compile(i, "?", "exec", 0x400) for i in exec_tests):
553 ast2 = mod.loads(mod.dumps(ast, protocol))
Ezio Melottib3aedd42010-11-20 19:04:17 +0000554 self.assertEqual(to_tuple(ast2), to_tuple(ast))
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000555
Benjamin Peterson5b066812010-11-20 01:38:49 +0000556 def test_invalid_sum(self):
557 pos = dict(lineno=2, col_offset=3)
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800558 m = ast.Module([ast.Expr(ast.expr(**pos), **pos)], [])
Benjamin Peterson5b066812010-11-20 01:38:49 +0000559 with self.assertRaises(TypeError) as cm:
560 compile(m, "<test>", "exec")
561 self.assertIn("but got <_ast.expr", str(cm.exception))
562
Benjamin Peterson2193d2b2011-07-22 10:50:23 -0500563 def test_invalid_identitifer(self):
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800564 m = ast.Module([ast.Expr(ast.Name(42, ast.Load()))], [])
Benjamin Peterson2193d2b2011-07-22 10:50:23 -0500565 ast.fix_missing_locations(m)
566 with self.assertRaises(TypeError) as cm:
567 compile(m, "<test>", "exec")
568 self.assertIn("identifier must be of type str", str(cm.exception))
569
Mark Dickinsonded35ae2012-11-25 14:36:26 +0000570 def test_empty_yield_from(self):
571 # Issue 16546: yield from value is not optional.
572 empty_yield_from = ast.parse("def f():\n yield from g()")
573 empty_yield_from.body[0].body[0].value.value = None
574 with self.assertRaises(ValueError) as cm:
575 compile(empty_yield_from, "<test>", "exec")
576 self.assertIn("field value is required", str(cm.exception))
577
Oren Milman7dc46d82017-09-30 20:16:24 +0300578 @support.cpython_only
579 def test_issue31592(self):
580 # There shouldn't be an assertion failure in case of a bad
581 # unicodedata.normalize().
582 import unicodedata
583 def bad_normalize(*args):
584 return None
585 with support.swap_attr(unicodedata, 'normalize', bad_normalize):
586 self.assertRaises(TypeError, ast.parse, '\u03D5')
587
Miss Islington (bot)c7be35c2019-07-08 14:41:34 -0700588 def test_issue18374_binop_col_offset(self):
589 tree = ast.parse('4+5+6+7')
590 parent_binop = tree.body[0].value
591 child_binop = parent_binop.left
592 grandchild_binop = child_binop.left
593 self.assertEqual(parent_binop.col_offset, 0)
594 self.assertEqual(parent_binop.end_col_offset, 7)
595 self.assertEqual(child_binop.col_offset, 0)
596 self.assertEqual(child_binop.end_col_offset, 5)
597 self.assertEqual(grandchild_binop.col_offset, 0)
598 self.assertEqual(grandchild_binop.end_col_offset, 3)
599
600 tree = ast.parse('4+5-\\\n 6-7')
601 parent_binop = tree.body[0].value
602 child_binop = parent_binop.left
603 grandchild_binop = child_binop.left
604 self.assertEqual(parent_binop.col_offset, 0)
605 self.assertEqual(parent_binop.lineno, 1)
606 self.assertEqual(parent_binop.end_col_offset, 4)
607 self.assertEqual(parent_binop.end_lineno, 2)
608
609 self.assertEqual(child_binop.col_offset, 0)
Miss Islington (bot)68bd9c52019-07-09 06:28:57 -0700610 self.assertEqual(child_binop.lineno, 1)
Miss Islington (bot)c7be35c2019-07-08 14:41:34 -0700611 self.assertEqual(child_binop.end_col_offset, 2)
Miss Islington (bot)68bd9c52019-07-09 06:28:57 -0700612 self.assertEqual(child_binop.end_lineno, 2)
Miss Islington (bot)c7be35c2019-07-08 14:41:34 -0700613
614 self.assertEqual(grandchild_binop.col_offset, 0)
Miss Islington (bot)68bd9c52019-07-09 06:28:57 -0700615 self.assertEqual(grandchild_binop.lineno, 1)
Miss Islington (bot)c7be35c2019-07-08 14:41:34 -0700616 self.assertEqual(grandchild_binop.end_col_offset, 3)
Miss Islington (bot)68bd9c52019-07-09 06:28:57 -0700617 self.assertEqual(grandchild_binop.end_lineno, 1)
Georg Brandl0c77a822008-06-10 16:37:50 +0000618
Lysandros Nikolaou8b9cebc2020-02-08 01:21:38 +0100619 def test_issue39579_dotted_name_end_col_offset(self):
620 tree = ast.parse('@a.b.c\ndef f(): pass')
621 attr_b = tree.body[0].decorator_list[0].value
622 self.assertEqual(attr_b.end_col_offset, 4)
623
Georg Brandl0c77a822008-06-10 16:37:50 +0000624class ASTHelpers_Test(unittest.TestCase):
Guido van Rossum10f8ce62019-03-13 13:00:46 -0700625 maxDiff = None
Georg Brandl0c77a822008-06-10 16:37:50 +0000626
627 def test_parse(self):
628 a = ast.parse('foo(1 + 1)')
629 b = compile('foo(1 + 1)', '<unknown>', 'exec', ast.PyCF_ONLY_AST)
630 self.assertEqual(ast.dump(a), ast.dump(b))
631
Benjamin Peterson2e2c9032012-09-02 14:23:15 -0400632 def test_parse_in_error(self):
633 try:
634 1/0
635 except Exception:
Benjamin Petersonbd0df502012-09-02 15:04:51 -0400636 with self.assertRaises(SyntaxError) as e:
637 ast.literal_eval(r"'\U'")
638 self.assertIsNotNone(e.exception.__context__)
Benjamin Peterson2e2c9032012-09-02 14:23:15 -0400639
Georg Brandl0c77a822008-06-10 16:37:50 +0000640 def test_dump(self):
641 node = ast.parse('spam(eggs, "and cheese")')
642 self.assertEqual(ast.dump(node),
643 "Module(body=[Expr(value=Call(func=Name(id='spam', ctx=Load()), "
Guido van Rossum10f8ce62019-03-13 13:00:46 -0700644 "args=[Name(id='eggs', ctx=Load()), Constant(value='and cheese', kind=None)], "
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800645 "keywords=[]))], type_ignores=[])"
Georg Brandl0c77a822008-06-10 16:37:50 +0000646 )
647 self.assertEqual(ast.dump(node, annotate_fields=False),
648 "Module([Expr(Call(Name('spam', Load()), [Name('eggs', Load()), "
Guido van Rossum10f8ce62019-03-13 13:00:46 -0700649 "Constant('and cheese', None)], []))], [])"
Georg Brandl0c77a822008-06-10 16:37:50 +0000650 )
651 self.assertEqual(ast.dump(node, include_attributes=True),
652 "Module(body=[Expr(value=Call(func=Name(id='spam', ctx=Load(), "
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000653 "lineno=1, col_offset=0, end_lineno=1, end_col_offset=4), "
654 "args=[Name(id='eggs', ctx=Load(), lineno=1, col_offset=5, "
Guido van Rossum10f8ce62019-03-13 13:00:46 -0700655 "end_lineno=1, end_col_offset=9), Constant(value='and cheese', kind=None, "
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000656 "lineno=1, col_offset=11, end_lineno=1, end_col_offset=23)], keywords=[], "
657 "lineno=1, col_offset=0, end_lineno=1, end_col_offset=24), "
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800658 "lineno=1, col_offset=0, end_lineno=1, end_col_offset=24)], type_ignores=[])"
Georg Brandl0c77a822008-06-10 16:37:50 +0000659 )
660
Serhiy Storchaka097eae52019-08-29 10:50:28 +0300661 def test_dump_incomplete(self):
662 node = ast.Raise(lineno=3, col_offset=4)
663 self.assertEqual(ast.dump(node),
664 "Raise()"
665 )
666 self.assertEqual(ast.dump(node, include_attributes=True),
667 "Raise(lineno=3, col_offset=4)"
668 )
669 node = ast.Raise(exc=ast.Name(id='e', ctx=ast.Load()), lineno=3, col_offset=4)
670 self.assertEqual(ast.dump(node),
671 "Raise(exc=Name(id='e', ctx=Load()))"
672 )
673 self.assertEqual(ast.dump(node, annotate_fields=False),
674 "Raise(Name('e', Load()))"
675 )
676 self.assertEqual(ast.dump(node, include_attributes=True),
677 "Raise(exc=Name(id='e', ctx=Load()), lineno=3, col_offset=4)"
678 )
679 self.assertEqual(ast.dump(node, annotate_fields=False, include_attributes=True),
680 "Raise(Name('e', Load()), lineno=3, col_offset=4)"
681 )
682 node = ast.Raise(cause=ast.Name(id='e', ctx=ast.Load()))
683 self.assertEqual(ast.dump(node),
684 "Raise(cause=Name(id='e', ctx=Load()))"
685 )
686 self.assertEqual(ast.dump(node, annotate_fields=False),
687 "Raise(cause=Name('e', Load()))"
688 )
689
Georg Brandl0c77a822008-06-10 16:37:50 +0000690 def test_copy_location(self):
691 src = ast.parse('1 + 1', mode='eval')
692 src.body.right = ast.copy_location(ast.Num(2), src.body.right)
693 self.assertEqual(ast.dump(src, include_attributes=True),
Guido van Rossum10f8ce62019-03-13 13:00:46 -0700694 'Expression(body=BinOp(left=Constant(value=1, kind=None, lineno=1, col_offset=0, '
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000695 'end_lineno=1, end_col_offset=1), op=Add(), right=Constant(value=2, '
696 'lineno=1, col_offset=4, end_lineno=1, end_col_offset=5), lineno=1, '
697 'col_offset=0, end_lineno=1, end_col_offset=5))'
Georg Brandl0c77a822008-06-10 16:37:50 +0000698 )
699
700 def test_fix_missing_locations(self):
701 src = ast.parse('write("spam")')
702 src.body.append(ast.Expr(ast.Call(ast.Name('spam', ast.Load()),
Benjamin Peterson025e9eb2015-05-05 20:16:41 -0400703 [ast.Str('eggs')], [])))
Georg Brandl0c77a822008-06-10 16:37:50 +0000704 self.assertEqual(src, ast.fix_missing_locations(src))
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000705 self.maxDiff = None
Georg Brandl0c77a822008-06-10 16:37:50 +0000706 self.assertEqual(ast.dump(src, include_attributes=True),
707 "Module(body=[Expr(value=Call(func=Name(id='write', ctx=Load(), "
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000708 "lineno=1, col_offset=0, end_lineno=1, end_col_offset=5), "
Guido van Rossum10f8ce62019-03-13 13:00:46 -0700709 "args=[Constant(value='spam', kind=None, lineno=1, col_offset=6, end_lineno=1, "
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000710 "end_col_offset=12)], keywords=[], lineno=1, col_offset=0, end_lineno=1, "
711 "end_col_offset=13), lineno=1, col_offset=0, end_lineno=1, "
712 "end_col_offset=13), Expr(value=Call(func=Name(id='spam', ctx=Load(), "
713 "lineno=1, col_offset=0, end_lineno=1, end_col_offset=0), "
714 "args=[Constant(value='eggs', lineno=1, col_offset=0, end_lineno=1, "
715 "end_col_offset=0)], keywords=[], lineno=1, col_offset=0, end_lineno=1, "
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800716 "end_col_offset=0), lineno=1, col_offset=0, end_lineno=1, end_col_offset=0)], "
717 "type_ignores=[])"
Georg Brandl0c77a822008-06-10 16:37:50 +0000718 )
719
720 def test_increment_lineno(self):
721 src = ast.parse('1 + 1', mode='eval')
722 self.assertEqual(ast.increment_lineno(src, n=3), src)
723 self.assertEqual(ast.dump(src, include_attributes=True),
Guido van Rossum10f8ce62019-03-13 13:00:46 -0700724 'Expression(body=BinOp(left=Constant(value=1, kind=None, lineno=4, col_offset=0, '
725 'end_lineno=4, end_col_offset=1), op=Add(), right=Constant(value=1, kind=None, '
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000726 'lineno=4, col_offset=4, end_lineno=4, end_col_offset=5), lineno=4, '
727 'col_offset=0, end_lineno=4, end_col_offset=5))'
Georg Brandl0c77a822008-06-10 16:37:50 +0000728 )
Georg Brandl619e7ba2011-01-09 07:38:51 +0000729 # issue10869: do not increment lineno of root twice
Georg Brandlefb69022011-01-09 07:50:48 +0000730 src = ast.parse('1 + 1', mode='eval')
Georg Brandl619e7ba2011-01-09 07:38:51 +0000731 self.assertEqual(ast.increment_lineno(src.body, n=3), src.body)
732 self.assertEqual(ast.dump(src, include_attributes=True),
Guido van Rossum10f8ce62019-03-13 13:00:46 -0700733 'Expression(body=BinOp(left=Constant(value=1, kind=None, lineno=4, col_offset=0, '
734 'end_lineno=4, end_col_offset=1), op=Add(), right=Constant(value=1, kind=None, '
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000735 'lineno=4, col_offset=4, end_lineno=4, end_col_offset=5), lineno=4, '
736 'col_offset=0, end_lineno=4, end_col_offset=5))'
Georg Brandl619e7ba2011-01-09 07:38:51 +0000737 )
Georg Brandl0c77a822008-06-10 16:37:50 +0000738
739 def test_iter_fields(self):
740 node = ast.parse('foo()', mode='eval')
741 d = dict(ast.iter_fields(node.body))
742 self.assertEqual(d.pop('func').id, 'foo')
Benjamin Peterson025e9eb2015-05-05 20:16:41 -0400743 self.assertEqual(d, {'keywords': [], 'args': []})
Georg Brandl0c77a822008-06-10 16:37:50 +0000744
745 def test_iter_child_nodes(self):
746 node = ast.parse("spam(23, 42, eggs='leek')", mode='eval')
747 self.assertEqual(len(list(ast.iter_child_nodes(node.body))), 4)
748 iterator = ast.iter_child_nodes(node.body)
749 self.assertEqual(next(iterator).id, 'spam')
Serhiy Storchaka3f228112018-09-27 17:42:37 +0300750 self.assertEqual(next(iterator).value, 23)
751 self.assertEqual(next(iterator).value, 42)
Georg Brandl0c77a822008-06-10 16:37:50 +0000752 self.assertEqual(ast.dump(next(iterator)),
Guido van Rossum10f8ce62019-03-13 13:00:46 -0700753 "keyword(arg='eggs', value=Constant(value='leek', kind=None))"
Georg Brandl0c77a822008-06-10 16:37:50 +0000754 )
755
756 def test_get_docstring(self):
Serhiy Storchaka08f127a2018-06-15 11:05:15 +0300757 node = ast.parse('"""line one\n line two"""')
758 self.assertEqual(ast.get_docstring(node),
759 'line one\nline two')
760
761 node = ast.parse('class foo:\n """line one\n line two"""')
762 self.assertEqual(ast.get_docstring(node.body[0]),
763 'line one\nline two')
764
Georg Brandl0c77a822008-06-10 16:37:50 +0000765 node = ast.parse('def foo():\n """line one\n line two"""')
766 self.assertEqual(ast.get_docstring(node.body[0]),
767 'line one\nline two')
768
Yury Selivanov2f07a662015-07-23 08:54:35 +0300769 node = ast.parse('async def foo():\n """spam\n ham"""')
770 self.assertEqual(ast.get_docstring(node.body[0]), 'spam\nham')
Serhiy Storchaka08f127a2018-06-15 11:05:15 +0300771
772 def test_get_docstring_none(self):
Matthias Bussonnier41cea702017-02-23 22:44:19 -0800773 self.assertIsNone(ast.get_docstring(ast.parse('')))
Serhiy Storchaka08f127a2018-06-15 11:05:15 +0300774 node = ast.parse('x = "not docstring"')
775 self.assertIsNone(ast.get_docstring(node))
776 node = ast.parse('def foo():\n pass')
777 self.assertIsNone(ast.get_docstring(node))
778
779 node = ast.parse('class foo:\n pass')
780 self.assertIsNone(ast.get_docstring(node.body[0]))
781 node = ast.parse('class foo:\n x = "not docstring"')
782 self.assertIsNone(ast.get_docstring(node.body[0]))
783 node = ast.parse('class foo:\n def bar(self): pass')
784 self.assertIsNone(ast.get_docstring(node.body[0]))
785
786 node = ast.parse('def foo():\n pass')
787 self.assertIsNone(ast.get_docstring(node.body[0]))
788 node = ast.parse('def foo():\n x = "not docstring"')
789 self.assertIsNone(ast.get_docstring(node.body[0]))
790
791 node = ast.parse('async def foo():\n pass')
792 self.assertIsNone(ast.get_docstring(node.body[0]))
793 node = ast.parse('async def foo():\n x = "not docstring"')
794 self.assertIsNone(ast.get_docstring(node.body[0]))
Yury Selivanov2f07a662015-07-23 08:54:35 +0300795
Anthony Sottile995d9b92019-01-12 20:05:13 -0800796 def test_multi_line_docstring_col_offset_and_lineno_issue16806(self):
797 node = ast.parse(
798 '"""line one\nline two"""\n\n'
799 'def foo():\n """line one\n line two"""\n\n'
800 ' def bar():\n """line one\n line two"""\n'
801 ' """line one\n line two"""\n'
802 '"""line one\nline two"""\n\n'
803 )
804 self.assertEqual(node.body[0].col_offset, 0)
805 self.assertEqual(node.body[0].lineno, 1)
806 self.assertEqual(node.body[1].body[0].col_offset, 2)
807 self.assertEqual(node.body[1].body[0].lineno, 5)
808 self.assertEqual(node.body[1].body[1].body[0].col_offset, 4)
809 self.assertEqual(node.body[1].body[1].body[0].lineno, 9)
810 self.assertEqual(node.body[1].body[2].col_offset, 2)
811 self.assertEqual(node.body[1].body[2].lineno, 11)
812 self.assertEqual(node.body[2].col_offset, 0)
813 self.assertEqual(node.body[2].lineno, 13)
814
Miss Islington (bot)3b18b172019-12-13 08:21:54 -0800815 def test_elif_stmt_start_position(self):
816 node = ast.parse('if a:\n pass\nelif b:\n pass\n')
817 elif_stmt = node.body[0].orelse[0]
818 self.assertEqual(elif_stmt.lineno, 3)
819 self.assertEqual(elif_stmt.col_offset, 0)
820
Miss Islington (bot)ce333cd2019-12-14 02:43:42 -0800821 def test_elif_stmt_start_position_with_else(self):
822 node = ast.parse('if a:\n pass\nelif b:\n pass\nelse:\n pass\n')
823 elif_stmt = node.body[0].orelse[0]
824 self.assertEqual(elif_stmt.lineno, 3)
825 self.assertEqual(elif_stmt.col_offset, 0)
826
Pablo Galindob1f20442019-12-18 01:41:58 +0000827 def test_starred_expr_end_position_within_call(self):
828 node = ast.parse('f(*[0, 1])')
829 starred_expr = node.body[0].value.args[0]
830 self.assertEqual(starred_expr.end_lineno, 1)
831 self.assertEqual(starred_expr.end_col_offset, 9)
832
Georg Brandl0c77a822008-06-10 16:37:50 +0000833 def test_literal_eval(self):
834 self.assertEqual(ast.literal_eval('[1, 2, 3]'), [1, 2, 3])
835 self.assertEqual(ast.literal_eval('{"foo": 42}'), {"foo": 42})
836 self.assertEqual(ast.literal_eval('(True, False, None)'), (True, False, None))
Benjamin Peterson3e742892010-07-11 12:59:24 +0000837 self.assertEqual(ast.literal_eval('{1, 2, 3}'), {1, 2, 3})
Benjamin Peterson5ef96e52010-07-11 23:06:06 +0000838 self.assertEqual(ast.literal_eval('b"hi"'), b"hi")
Georg Brandl0c77a822008-06-10 16:37:50 +0000839 self.assertRaises(ValueError, ast.literal_eval, 'foo()')
Serhiy Storchakad8ac4d12018-01-04 11:15:39 +0200840 self.assertEqual(ast.literal_eval('6'), 6)
841 self.assertEqual(ast.literal_eval('+6'), 6)
Raymond Hettingerbc959732010-10-08 00:47:45 +0000842 self.assertEqual(ast.literal_eval('-6'), -6)
Raymond Hettingerbc959732010-10-08 00:47:45 +0000843 self.assertEqual(ast.literal_eval('3.25'), 3.25)
Serhiy Storchakad8ac4d12018-01-04 11:15:39 +0200844 self.assertEqual(ast.literal_eval('+3.25'), 3.25)
845 self.assertEqual(ast.literal_eval('-3.25'), -3.25)
846 self.assertEqual(repr(ast.literal_eval('-0.0')), '-0.0')
847 self.assertRaises(ValueError, ast.literal_eval, '++6')
848 self.assertRaises(ValueError, ast.literal_eval, '+True')
849 self.assertRaises(ValueError, ast.literal_eval, '2+3')
Georg Brandl0c77a822008-06-10 16:37:50 +0000850
Serhiy Storchakad8ac4d12018-01-04 11:15:39 +0200851 def test_literal_eval_complex(self):
852 # Issue #4907
853 self.assertEqual(ast.literal_eval('6j'), 6j)
854 self.assertEqual(ast.literal_eval('-6j'), -6j)
855 self.assertEqual(ast.literal_eval('6.75j'), 6.75j)
856 self.assertEqual(ast.literal_eval('-6.75j'), -6.75j)
857 self.assertEqual(ast.literal_eval('3+6j'), 3+6j)
858 self.assertEqual(ast.literal_eval('-3+6j'), -3+6j)
859 self.assertEqual(ast.literal_eval('3-6j'), 3-6j)
860 self.assertEqual(ast.literal_eval('-3-6j'), -3-6j)
861 self.assertEqual(ast.literal_eval('3.25+6.75j'), 3.25+6.75j)
862 self.assertEqual(ast.literal_eval('-3.25+6.75j'), -3.25+6.75j)
863 self.assertEqual(ast.literal_eval('3.25-6.75j'), 3.25-6.75j)
864 self.assertEqual(ast.literal_eval('-3.25-6.75j'), -3.25-6.75j)
865 self.assertEqual(ast.literal_eval('(3+6j)'), 3+6j)
866 self.assertRaises(ValueError, ast.literal_eval, '-6j+3')
867 self.assertRaises(ValueError, ast.literal_eval, '-6j+3j')
868 self.assertRaises(ValueError, ast.literal_eval, '3+-6j')
869 self.assertRaises(ValueError, ast.literal_eval, '3+(0+6j)')
870 self.assertRaises(ValueError, ast.literal_eval, '-(3+6j)')
Benjamin Peterson058e31e2009-01-16 03:54:08 +0000871
Amaury Forgeot d'Arc58e87612011-11-22 21:51:55 +0100872 def test_bad_integer(self):
873 # issue13436: Bad error message with invalid numeric values
874 body = [ast.ImportFrom(module='time',
875 names=[ast.alias(name='sleep')],
876 level=None,
877 lineno=None, col_offset=None)]
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800878 mod = ast.Module(body, [])
Amaury Forgeot d'Arc58e87612011-11-22 21:51:55 +0100879 with self.assertRaises(ValueError) as cm:
880 compile(mod, 'test', 'exec')
881 self.assertIn("invalid integer value: None", str(cm.exception))
882
Berker Peksag0a5bd512016-04-29 19:50:02 +0300883 def test_level_as_none(self):
884 body = [ast.ImportFrom(module='time',
885 names=[ast.alias(name='sleep')],
886 level=None,
887 lineno=0, col_offset=0)]
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800888 mod = ast.Module(body, [])
Berker Peksag0a5bd512016-04-29 19:50:02 +0300889 code = compile(mod, 'test', 'exec')
890 ns = {}
891 exec(code, ns)
892 self.assertIn('sleep', ns)
893
Georg Brandl0c77a822008-06-10 16:37:50 +0000894
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500895class ASTValidatorTests(unittest.TestCase):
896
897 def mod(self, mod, msg=None, mode="exec", *, exc=ValueError):
898 mod.lineno = mod.col_offset = 0
899 ast.fix_missing_locations(mod)
Serhiy Storchaka3f228112018-09-27 17:42:37 +0300900 if msg is None:
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500901 compile(mod, "<test>", mode)
Serhiy Storchaka3f228112018-09-27 17:42:37 +0300902 else:
903 with self.assertRaises(exc) as cm:
904 compile(mod, "<test>", mode)
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500905 self.assertIn(msg, str(cm.exception))
906
907 def expr(self, node, msg=None, *, exc=ValueError):
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800908 mod = ast.Module([ast.Expr(node)], [])
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500909 self.mod(mod, msg, exc=exc)
910
911 def stmt(self, stmt, msg=None):
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800912 mod = ast.Module([stmt], [])
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500913 self.mod(mod, msg)
914
915 def test_module(self):
916 m = ast.Interactive([ast.Expr(ast.Name("x", ast.Store()))])
917 self.mod(m, "must have Load context", "single")
918 m = ast.Expression(ast.Name("x", ast.Store()))
919 self.mod(m, "must have Load context", "eval")
920
921 def _check_arguments(self, fac, check):
Pablo Galindo8c77b8c2019-04-29 13:36:57 +0100922 def arguments(args=None, posonlyargs=None, vararg=None,
Benjamin Petersoncda75be2013-03-18 10:48:58 -0700923 kwonlyargs=None, kwarg=None,
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500924 defaults=None, kw_defaults=None):
925 if args is None:
926 args = []
Pablo Galindo8c77b8c2019-04-29 13:36:57 +0100927 if posonlyargs is None:
928 posonlyargs = []
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500929 if kwonlyargs is None:
930 kwonlyargs = []
931 if defaults is None:
932 defaults = []
933 if kw_defaults is None:
934 kw_defaults = []
Pablo Galindo8c77b8c2019-04-29 13:36:57 +0100935 args = ast.arguments(args, posonlyargs, vararg, kwonlyargs,
936 kw_defaults, kwarg, defaults)
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500937 return fac(args)
938 args = [ast.arg("x", ast.Name("x", ast.Store()))]
939 check(arguments(args=args), "must have Load context")
Pablo Galindo8c77b8c2019-04-29 13:36:57 +0100940 check(arguments(posonlyargs=args), "must have Load context")
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500941 check(arguments(kwonlyargs=args), "must have Load context")
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500942 check(arguments(defaults=[ast.Num(3)]),
943 "more positional defaults than args")
944 check(arguments(kw_defaults=[ast.Num(4)]),
945 "length of kwonlyargs is not the same as kw_defaults")
946 args = [ast.arg("x", ast.Name("x", ast.Load()))]
947 check(arguments(args=args, defaults=[ast.Name("x", ast.Store())]),
948 "must have Load context")
949 args = [ast.arg("a", ast.Name("x", ast.Load())),
950 ast.arg("b", ast.Name("y", ast.Load()))]
951 check(arguments(kwonlyargs=args,
952 kw_defaults=[None, ast.Name("x", ast.Store())]),
953 "must have Load context")
954
955 def test_funcdef(self):
Pablo Galindo8c77b8c2019-04-29 13:36:57 +0100956 a = ast.arguments([], [], None, [], [], None, [])
Serhiy Storchaka73cbe7a2018-05-29 12:04:55 +0300957 f = ast.FunctionDef("x", a, [], [], None)
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500958 self.stmt(f, "empty body on FunctionDef")
959 f = ast.FunctionDef("x", a, [ast.Pass()], [ast.Name("x", ast.Store())],
Serhiy Storchaka73cbe7a2018-05-29 12:04:55 +0300960 None)
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500961 self.stmt(f, "must have Load context")
962 f = ast.FunctionDef("x", a, [ast.Pass()], [],
Serhiy Storchaka73cbe7a2018-05-29 12:04:55 +0300963 ast.Name("x", ast.Store()))
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500964 self.stmt(f, "must have Load context")
965 def fac(args):
Serhiy Storchaka73cbe7a2018-05-29 12:04:55 +0300966 return ast.FunctionDef("x", args, [ast.Pass()], [], None)
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500967 self._check_arguments(fac, self.stmt)
968
969 def test_classdef(self):
Benjamin Peterson025e9eb2015-05-05 20:16:41 -0400970 def cls(bases=None, keywords=None, body=None, decorator_list=None):
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500971 if bases is None:
972 bases = []
973 if keywords is None:
974 keywords = []
975 if body is None:
976 body = [ast.Pass()]
977 if decorator_list is None:
978 decorator_list = []
Benjamin Peterson025e9eb2015-05-05 20:16:41 -0400979 return ast.ClassDef("myclass", bases, keywords,
Serhiy Storchaka73cbe7a2018-05-29 12:04:55 +0300980 body, decorator_list)
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500981 self.stmt(cls(bases=[ast.Name("x", ast.Store())]),
982 "must have Load context")
983 self.stmt(cls(keywords=[ast.keyword("x", ast.Name("x", ast.Store()))]),
984 "must have Load context")
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500985 self.stmt(cls(body=[]), "empty body on ClassDef")
986 self.stmt(cls(body=[None]), "None disallowed")
987 self.stmt(cls(decorator_list=[ast.Name("x", ast.Store())]),
988 "must have Load context")
989
990 def test_delete(self):
991 self.stmt(ast.Delete([]), "empty targets on Delete")
992 self.stmt(ast.Delete([None]), "None disallowed")
993 self.stmt(ast.Delete([ast.Name("x", ast.Load())]),
994 "must have Del context")
995
996 def test_assign(self):
997 self.stmt(ast.Assign([], ast.Num(3)), "empty targets on Assign")
998 self.stmt(ast.Assign([None], ast.Num(3)), "None disallowed")
999 self.stmt(ast.Assign([ast.Name("x", ast.Load())], ast.Num(3)),
1000 "must have Store context")
1001 self.stmt(ast.Assign([ast.Name("x", ast.Store())],
1002 ast.Name("y", ast.Store())),
1003 "must have Load context")
1004
1005 def test_augassign(self):
1006 aug = ast.AugAssign(ast.Name("x", ast.Load()), ast.Add(),
1007 ast.Name("y", ast.Load()))
1008 self.stmt(aug, "must have Store context")
1009 aug = ast.AugAssign(ast.Name("x", ast.Store()), ast.Add(),
1010 ast.Name("y", ast.Store()))
1011 self.stmt(aug, "must have Load context")
1012
1013 def test_for(self):
1014 x = ast.Name("x", ast.Store())
1015 y = ast.Name("y", ast.Load())
1016 p = ast.Pass()
1017 self.stmt(ast.For(x, y, [], []), "empty body on For")
1018 self.stmt(ast.For(ast.Name("x", ast.Load()), y, [p], []),
1019 "must have Store context")
1020 self.stmt(ast.For(x, ast.Name("y", ast.Store()), [p], []),
1021 "must have Load context")
1022 e = ast.Expr(ast.Name("x", ast.Store()))
1023 self.stmt(ast.For(x, y, [e], []), "must have Load context")
1024 self.stmt(ast.For(x, y, [p], [e]), "must have Load context")
1025
1026 def test_while(self):
1027 self.stmt(ast.While(ast.Num(3), [], []), "empty body on While")
1028 self.stmt(ast.While(ast.Name("x", ast.Store()), [ast.Pass()], []),
1029 "must have Load context")
1030 self.stmt(ast.While(ast.Num(3), [ast.Pass()],
1031 [ast.Expr(ast.Name("x", ast.Store()))]),
1032 "must have Load context")
1033
1034 def test_if(self):
1035 self.stmt(ast.If(ast.Num(3), [], []), "empty body on If")
1036 i = ast.If(ast.Name("x", ast.Store()), [ast.Pass()], [])
1037 self.stmt(i, "must have Load context")
1038 i = ast.If(ast.Num(3), [ast.Expr(ast.Name("x", ast.Store()))], [])
1039 self.stmt(i, "must have Load context")
1040 i = ast.If(ast.Num(3), [ast.Pass()],
1041 [ast.Expr(ast.Name("x", ast.Store()))])
1042 self.stmt(i, "must have Load context")
1043
1044 def test_with(self):
1045 p = ast.Pass()
1046 self.stmt(ast.With([], [p]), "empty items on With")
1047 i = ast.withitem(ast.Num(3), None)
1048 self.stmt(ast.With([i], []), "empty body on With")
1049 i = ast.withitem(ast.Name("x", ast.Store()), None)
1050 self.stmt(ast.With([i], [p]), "must have Load context")
1051 i = ast.withitem(ast.Num(3), ast.Name("x", ast.Load()))
1052 self.stmt(ast.With([i], [p]), "must have Store context")
1053
1054 def test_raise(self):
1055 r = ast.Raise(None, ast.Num(3))
1056 self.stmt(r, "Raise with cause but no exception")
1057 r = ast.Raise(ast.Name("x", ast.Store()), None)
1058 self.stmt(r, "must have Load context")
1059 r = ast.Raise(ast.Num(4), ast.Name("x", ast.Store()))
1060 self.stmt(r, "must have Load context")
1061
1062 def test_try(self):
1063 p = ast.Pass()
1064 t = ast.Try([], [], [], [p])
1065 self.stmt(t, "empty body on Try")
1066 t = ast.Try([ast.Expr(ast.Name("x", ast.Store()))], [], [], [p])
1067 self.stmt(t, "must have Load context")
1068 t = ast.Try([p], [], [], [])
1069 self.stmt(t, "Try has neither except handlers nor finalbody")
1070 t = ast.Try([p], [], [p], [p])
1071 self.stmt(t, "Try has orelse but no except handlers")
1072 t = ast.Try([p], [ast.ExceptHandler(None, "x", [])], [], [])
1073 self.stmt(t, "empty body on ExceptHandler")
1074 e = [ast.ExceptHandler(ast.Name("x", ast.Store()), "y", [p])]
1075 self.stmt(ast.Try([p], e, [], []), "must have Load context")
1076 e = [ast.ExceptHandler(None, "x", [p])]
1077 t = ast.Try([p], e, [ast.Expr(ast.Name("x", ast.Store()))], [p])
1078 self.stmt(t, "must have Load context")
1079 t = ast.Try([p], e, [p], [ast.Expr(ast.Name("x", ast.Store()))])
1080 self.stmt(t, "must have Load context")
1081
1082 def test_assert(self):
1083 self.stmt(ast.Assert(ast.Name("x", ast.Store()), None),
1084 "must have Load context")
1085 assrt = ast.Assert(ast.Name("x", ast.Load()),
1086 ast.Name("y", ast.Store()))
1087 self.stmt(assrt, "must have Load context")
1088
1089 def test_import(self):
1090 self.stmt(ast.Import([]), "empty names on Import")
1091
1092 def test_importfrom(self):
1093 imp = ast.ImportFrom(None, [ast.alias("x", None)], -42)
Serhiy Storchaka7de28402016-06-27 23:40:43 +03001094 self.stmt(imp, "Negative ImportFrom level")
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001095 self.stmt(ast.ImportFrom(None, [], 0), "empty names on ImportFrom")
1096
1097 def test_global(self):
1098 self.stmt(ast.Global([]), "empty names on Global")
1099
1100 def test_nonlocal(self):
1101 self.stmt(ast.Nonlocal([]), "empty names on Nonlocal")
1102
1103 def test_expr(self):
1104 e = ast.Expr(ast.Name("x", ast.Store()))
1105 self.stmt(e, "must have Load context")
1106
1107 def test_boolop(self):
1108 b = ast.BoolOp(ast.And(), [])
1109 self.expr(b, "less than 2 values")
1110 b = ast.BoolOp(ast.And(), [ast.Num(3)])
1111 self.expr(b, "less than 2 values")
1112 b = ast.BoolOp(ast.And(), [ast.Num(4), None])
1113 self.expr(b, "None disallowed")
1114 b = ast.BoolOp(ast.And(), [ast.Num(4), ast.Name("x", ast.Store())])
1115 self.expr(b, "must have Load context")
1116
1117 def test_unaryop(self):
1118 u = ast.UnaryOp(ast.Not(), ast.Name("x", ast.Store()))
1119 self.expr(u, "must have Load context")
1120
1121 def test_lambda(self):
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01001122 a = ast.arguments([], [], None, [], [], None, [])
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001123 self.expr(ast.Lambda(a, ast.Name("x", ast.Store())),
1124 "must have Load context")
1125 def fac(args):
1126 return ast.Lambda(args, ast.Name("x", ast.Load()))
1127 self._check_arguments(fac, self.expr)
1128
1129 def test_ifexp(self):
1130 l = ast.Name("x", ast.Load())
1131 s = ast.Name("y", ast.Store())
1132 for args in (s, l, l), (l, s, l), (l, l, s):
Benjamin Peterson71ce8972011-08-09 16:17:12 -05001133 self.expr(ast.IfExp(*args), "must have Load context")
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001134
1135 def test_dict(self):
1136 d = ast.Dict([], [ast.Name("x", ast.Load())])
1137 self.expr(d, "same number of keys as values")
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001138 d = ast.Dict([ast.Name("x", ast.Load())], [None])
1139 self.expr(d, "None disallowed")
1140
1141 def test_set(self):
1142 self.expr(ast.Set([None]), "None disallowed")
1143 s = ast.Set([ast.Name("x", ast.Store())])
1144 self.expr(s, "must have Load context")
1145
1146 def _check_comprehension(self, fac):
1147 self.expr(fac([]), "comprehension with no generators")
1148 g = ast.comprehension(ast.Name("x", ast.Load()),
Yury Selivanov52c4e7c2016-09-09 10:36:01 -07001149 ast.Name("x", ast.Load()), [], 0)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001150 self.expr(fac([g]), "must have Store context")
1151 g = ast.comprehension(ast.Name("x", ast.Store()),
Yury Selivanov52c4e7c2016-09-09 10:36:01 -07001152 ast.Name("x", ast.Store()), [], 0)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001153 self.expr(fac([g]), "must have Load context")
1154 x = ast.Name("x", ast.Store())
1155 y = ast.Name("y", ast.Load())
Yury Selivanov52c4e7c2016-09-09 10:36:01 -07001156 g = ast.comprehension(x, y, [None], 0)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001157 self.expr(fac([g]), "None disallowed")
Yury Selivanov52c4e7c2016-09-09 10:36:01 -07001158 g = ast.comprehension(x, y, [ast.Name("x", ast.Store())], 0)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001159 self.expr(fac([g]), "must have Load context")
1160
1161 def _simple_comp(self, fac):
1162 g = ast.comprehension(ast.Name("x", ast.Store()),
Yury Selivanov52c4e7c2016-09-09 10:36:01 -07001163 ast.Name("x", ast.Load()), [], 0)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001164 self.expr(fac(ast.Name("x", ast.Store()), [g]),
1165 "must have Load context")
1166 def wrap(gens):
1167 return fac(ast.Name("x", ast.Store()), gens)
1168 self._check_comprehension(wrap)
1169
1170 def test_listcomp(self):
1171 self._simple_comp(ast.ListComp)
1172
1173 def test_setcomp(self):
1174 self._simple_comp(ast.SetComp)
1175
1176 def test_generatorexp(self):
1177 self._simple_comp(ast.GeneratorExp)
1178
1179 def test_dictcomp(self):
1180 g = ast.comprehension(ast.Name("y", ast.Store()),
Yury Selivanov52c4e7c2016-09-09 10:36:01 -07001181 ast.Name("p", ast.Load()), [], 0)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001182 c = ast.DictComp(ast.Name("x", ast.Store()),
1183 ast.Name("y", ast.Load()), [g])
1184 self.expr(c, "must have Load context")
1185 c = ast.DictComp(ast.Name("x", ast.Load()),
1186 ast.Name("y", ast.Store()), [g])
1187 self.expr(c, "must have Load context")
1188 def factory(comps):
1189 k = ast.Name("x", ast.Load())
1190 v = ast.Name("y", ast.Load())
1191 return ast.DictComp(k, v, comps)
1192 self._check_comprehension(factory)
1193
1194 def test_yield(self):
Benjamin Peterson527c6222012-01-14 08:58:23 -05001195 self.expr(ast.Yield(ast.Name("x", ast.Store())), "must have Load")
1196 self.expr(ast.YieldFrom(ast.Name("x", ast.Store())), "must have Load")
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001197
1198 def test_compare(self):
1199 left = ast.Name("x", ast.Load())
1200 comp = ast.Compare(left, [ast.In()], [])
1201 self.expr(comp, "no comparators")
1202 comp = ast.Compare(left, [ast.In()], [ast.Num(4), ast.Num(5)])
1203 self.expr(comp, "different number of comparators and operands")
1204 comp = ast.Compare(ast.Num("blah"), [ast.In()], [left])
Serhiy Storchaka3f228112018-09-27 17:42:37 +03001205 self.expr(comp)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001206 comp = ast.Compare(left, [ast.In()], [ast.Num("blah")])
Serhiy Storchaka3f228112018-09-27 17:42:37 +03001207 self.expr(comp)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001208
1209 def test_call(self):
1210 func = ast.Name("x", ast.Load())
1211 args = [ast.Name("y", ast.Load())]
1212 keywords = [ast.keyword("w", ast.Name("z", ast.Load()))]
Benjamin Peterson025e9eb2015-05-05 20:16:41 -04001213 call = ast.Call(ast.Name("x", ast.Store()), args, keywords)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001214 self.expr(call, "must have Load context")
Benjamin Peterson025e9eb2015-05-05 20:16:41 -04001215 call = ast.Call(func, [None], keywords)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001216 self.expr(call, "None disallowed")
1217 bad_keywords = [ast.keyword("w", ast.Name("z", ast.Store()))]
Benjamin Peterson025e9eb2015-05-05 20:16:41 -04001218 call = ast.Call(func, args, bad_keywords)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001219 self.expr(call, "must have Load context")
1220
1221 def test_num(self):
1222 class subint(int):
1223 pass
1224 class subfloat(float):
1225 pass
1226 class subcomplex(complex):
1227 pass
Serhiy Storchaka3f228112018-09-27 17:42:37 +03001228 for obj in "0", "hello":
1229 self.expr(ast.Num(obj))
1230 for obj in subint(), subfloat(), subcomplex():
1231 self.expr(ast.Num(obj), "invalid type", exc=TypeError)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001232
1233 def test_attribute(self):
1234 attr = ast.Attribute(ast.Name("x", ast.Store()), "y", ast.Load())
1235 self.expr(attr, "must have Load context")
1236
1237 def test_subscript(self):
1238 sub = ast.Subscript(ast.Name("x", ast.Store()), ast.Index(ast.Num(3)),
1239 ast.Load())
1240 self.expr(sub, "must have Load context")
1241 x = ast.Name("x", ast.Load())
1242 sub = ast.Subscript(x, ast.Index(ast.Name("y", ast.Store())),
1243 ast.Load())
1244 self.expr(sub, "must have Load context")
1245 s = ast.Name("x", ast.Store())
1246 for args in (s, None, None), (None, s, None), (None, None, s):
1247 sl = ast.Slice(*args)
1248 self.expr(ast.Subscript(x, sl, ast.Load()),
1249 "must have Load context")
1250 sl = ast.ExtSlice([])
1251 self.expr(ast.Subscript(x, sl, ast.Load()), "empty dims on ExtSlice")
1252 sl = ast.ExtSlice([ast.Index(s)])
1253 self.expr(ast.Subscript(x, sl, ast.Load()), "must have Load context")
1254
1255 def test_starred(self):
1256 left = ast.List([ast.Starred(ast.Name("x", ast.Load()), ast.Store())],
1257 ast.Store())
1258 assign = ast.Assign([left], ast.Num(4))
1259 self.stmt(assign, "must have Store context")
1260
1261 def _sequence(self, fac):
1262 self.expr(fac([None], ast.Load()), "None disallowed")
1263 self.expr(fac([ast.Name("x", ast.Store())], ast.Load()),
1264 "must have Load context")
1265
1266 def test_list(self):
1267 self._sequence(ast.List)
1268
1269 def test_tuple(self):
1270 self._sequence(ast.Tuple)
1271
Benjamin Peterson442f2092012-12-06 17:41:04 -05001272 def test_nameconstant(self):
Serhiy Storchaka3f228112018-09-27 17:42:37 +03001273 self.expr(ast.NameConstant(4))
Benjamin Peterson442f2092012-12-06 17:41:04 -05001274
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001275 def test_stdlib_validates(self):
1276 stdlib = os.path.dirname(ast.__file__)
1277 tests = [fn for fn in os.listdir(stdlib) if fn.endswith(".py")]
1278 tests.extend(["test/test_grammar.py", "test/test_unpack_ex.py"])
1279 for module in tests:
Serhiy Storchaka3bcbedc2019-01-18 07:47:48 +02001280 with self.subTest(module):
1281 fn = os.path.join(stdlib, module)
1282 with open(fn, "r", encoding="utf-8") as fp:
1283 source = fp.read()
1284 mod = ast.parse(source, fn)
1285 compile(mod, fn, "exec")
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001286
1287
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001288class ConstantTests(unittest.TestCase):
1289 """Tests on the ast.Constant node type."""
1290
1291 def compile_constant(self, value):
1292 tree = ast.parse("x = 123")
1293
1294 node = tree.body[0].value
1295 new_node = ast.Constant(value=value)
1296 ast.copy_location(new_node, node)
1297 tree.body[0].value = new_node
1298
1299 code = compile(tree, "<string>", "exec")
1300
1301 ns = {}
1302 exec(code, ns)
1303 return ns['x']
1304
Victor Stinnerbe59d142016-01-27 00:39:12 +01001305 def test_validation(self):
1306 with self.assertRaises(TypeError) as cm:
1307 self.compile_constant([1, 2, 3])
1308 self.assertEqual(str(cm.exception),
1309 "got an invalid type in Constant: list")
1310
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001311 def test_singletons(self):
1312 for const in (None, False, True, Ellipsis, b'', frozenset()):
1313 with self.subTest(const=const):
1314 value = self.compile_constant(const)
1315 self.assertIs(value, const)
1316
1317 def test_values(self):
1318 nested_tuple = (1,)
1319 nested_frozenset = frozenset({1})
1320 for level in range(3):
1321 nested_tuple = (nested_tuple, 2)
1322 nested_frozenset = frozenset({nested_frozenset, 2})
1323 values = (123, 123.0, 123j,
1324 "unicode", b'bytes',
1325 tuple("tuple"), frozenset("frozenset"),
1326 nested_tuple, nested_frozenset)
1327 for value in values:
1328 with self.subTest(value=value):
1329 result = self.compile_constant(value)
1330 self.assertEqual(result, value)
1331
1332 def test_assign_to_constant(self):
1333 tree = ast.parse("x = 1")
1334
1335 target = tree.body[0].targets[0]
1336 new_target = ast.Constant(value=1)
1337 ast.copy_location(new_target, target)
1338 tree.body[0].targets[0] = new_target
1339
1340 with self.assertRaises(ValueError) as cm:
1341 compile(tree, "string", "exec")
1342 self.assertEqual(str(cm.exception),
1343 "expression which can't be assigned "
1344 "to in Store context")
1345
1346 def test_get_docstring(self):
1347 tree = ast.parse("'docstring'\nx = 1")
1348 self.assertEqual(ast.get_docstring(tree), 'docstring')
1349
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001350 def get_load_const(self, tree):
1351 # Compile to bytecode, disassemble and get parameter of LOAD_CONST
1352 # instructions
1353 co = compile(tree, '<string>', 'exec')
1354 consts = []
1355 for instr in dis.get_instructions(co):
1356 if instr.opname == 'LOAD_CONST':
1357 consts.append(instr.argval)
1358 return consts
1359
1360 @support.cpython_only
1361 def test_load_const(self):
1362 consts = [None,
1363 True, False,
1364 124,
1365 2.0,
1366 3j,
1367 "unicode",
1368 b'bytes',
1369 (1, 2, 3)]
1370
Victor Stinnera2724092016-02-08 18:17:58 +01001371 code = '\n'.join(['x={!r}'.format(const) for const in consts])
1372 code += '\nx = ...'
1373 consts.extend((Ellipsis, None))
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001374
1375 tree = ast.parse(code)
Victor Stinnera2724092016-02-08 18:17:58 +01001376 self.assertEqual(self.get_load_const(tree),
1377 consts)
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001378
1379 # Replace expression nodes with constants
Victor Stinnera2724092016-02-08 18:17:58 +01001380 for assign, const in zip(tree.body, consts):
1381 assert isinstance(assign, ast.Assign), ast.dump(assign)
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001382 new_node = ast.Constant(value=const)
Victor Stinnera2724092016-02-08 18:17:58 +01001383 ast.copy_location(new_node, assign.value)
1384 assign.value = new_node
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001385
Victor Stinnera2724092016-02-08 18:17:58 +01001386 self.assertEqual(self.get_load_const(tree),
1387 consts)
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001388
1389 def test_literal_eval(self):
1390 tree = ast.parse("1 + 2")
1391 binop = tree.body[0].value
1392
1393 new_left = ast.Constant(value=10)
1394 ast.copy_location(new_left, binop.left)
1395 binop.left = new_left
1396
Serhiy Storchakad8ac4d12018-01-04 11:15:39 +02001397 new_right = ast.Constant(value=20j)
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001398 ast.copy_location(new_right, binop.right)
1399 binop.right = new_right
1400
Serhiy Storchakad8ac4d12018-01-04 11:15:39 +02001401 self.assertEqual(ast.literal_eval(binop), 10+20j)
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001402
Guido van Rossum10f8ce62019-03-13 13:00:46 -07001403 def test_string_kind(self):
1404 c = ast.parse('"x"', mode='eval').body
1405 self.assertEqual(c.value, "x")
1406 self.assertEqual(c.kind, None)
1407
1408 c = ast.parse('u"x"', mode='eval').body
1409 self.assertEqual(c.value, "x")
1410 self.assertEqual(c.kind, "u")
1411
1412 c = ast.parse('r"x"', mode='eval').body
1413 self.assertEqual(c.value, "x")
1414 self.assertEqual(c.kind, None)
1415
1416 c = ast.parse('b"x"', mode='eval').body
1417 self.assertEqual(c.value, b"x")
1418 self.assertEqual(c.kind, None)
1419
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001420
Ivan Levkivskyi9932a222019-01-22 11:18:22 +00001421class EndPositionTests(unittest.TestCase):
1422 """Tests for end position of AST nodes.
1423
1424 Testing end positions of nodes requires a bit of extra care
1425 because of how LL parsers work.
1426 """
1427 def _check_end_pos(self, ast_node, end_lineno, end_col_offset):
1428 self.assertEqual(ast_node.end_lineno, end_lineno)
1429 self.assertEqual(ast_node.end_col_offset, end_col_offset)
1430
1431 def _check_content(self, source, ast_node, content):
1432 self.assertEqual(ast.get_source_segment(source, ast_node), content)
1433
1434 def _parse_value(self, s):
1435 # Use duck-typing to support both single expression
1436 # and a right hand side of an assignment statement.
1437 return ast.parse(s).body[0].value
1438
1439 def test_lambda(self):
1440 s = 'lambda x, *y: None'
1441 lam = self._parse_value(s)
1442 self._check_content(s, lam.body, 'None')
1443 self._check_content(s, lam.args.args[0], 'x')
1444 self._check_content(s, lam.args.vararg, 'y')
1445
1446 def test_func_def(self):
1447 s = dedent('''
1448 def func(x: int,
1449 *args: str,
1450 z: float = 0,
1451 **kwargs: Any) -> bool:
1452 return True
1453 ''').strip()
1454 fdef = ast.parse(s).body[0]
1455 self._check_end_pos(fdef, 5, 15)
1456 self._check_content(s, fdef.body[0], 'return True')
1457 self._check_content(s, fdef.args.args[0], 'x: int')
1458 self._check_content(s, fdef.args.args[0].annotation, 'int')
1459 self._check_content(s, fdef.args.kwarg, 'kwargs: Any')
1460 self._check_content(s, fdef.args.kwarg.annotation, 'Any')
1461
1462 def test_call(self):
1463 s = 'func(x, y=2, **kw)'
1464 call = self._parse_value(s)
1465 self._check_content(s, call.func, 'func')
1466 self._check_content(s, call.keywords[0].value, '2')
1467 self._check_content(s, call.keywords[1].value, 'kw')
1468
1469 def test_call_noargs(self):
1470 s = 'x[0]()'
1471 call = self._parse_value(s)
1472 self._check_content(s, call.func, 'x[0]')
1473 self._check_end_pos(call, 1, 6)
1474
1475 def test_class_def(self):
1476 s = dedent('''
1477 class C(A, B):
1478 x: int = 0
1479 ''').strip()
1480 cdef = ast.parse(s).body[0]
1481 self._check_end_pos(cdef, 2, 14)
1482 self._check_content(s, cdef.bases[1], 'B')
1483 self._check_content(s, cdef.body[0], 'x: int = 0')
1484
1485 def test_class_kw(self):
1486 s = 'class S(metaclass=abc.ABCMeta): pass'
1487 cdef = ast.parse(s).body[0]
1488 self._check_content(s, cdef.keywords[0].value, 'abc.ABCMeta')
1489
1490 def test_multi_line_str(self):
1491 s = dedent('''
1492 x = """Some multi-line text.
1493
1494 It goes on starting from same indent."""
1495 ''').strip()
1496 assign = ast.parse(s).body[0]
1497 self._check_end_pos(assign, 3, 40)
1498 self._check_end_pos(assign.value, 3, 40)
1499
1500 def test_continued_str(self):
1501 s = dedent('''
1502 x = "first part" \\
1503 "second part"
1504 ''').strip()
1505 assign = ast.parse(s).body[0]
1506 self._check_end_pos(assign, 2, 13)
1507 self._check_end_pos(assign.value, 2, 13)
1508
1509 def test_suites(self):
1510 # We intentionally put these into the same string to check
1511 # that empty lines are not part of the suite.
1512 s = dedent('''
1513 while True:
1514 pass
1515
1516 if one():
1517 x = None
1518 elif other():
1519 y = None
1520 else:
1521 z = None
1522
1523 for x, y in stuff:
1524 assert True
1525
1526 try:
1527 raise RuntimeError
1528 except TypeError as e:
1529 pass
1530
1531 pass
1532 ''').strip()
1533 mod = ast.parse(s)
1534 while_loop = mod.body[0]
1535 if_stmt = mod.body[1]
1536 for_loop = mod.body[2]
1537 try_stmt = mod.body[3]
1538 pass_stmt = mod.body[4]
1539
1540 self._check_end_pos(while_loop, 2, 8)
1541 self._check_end_pos(if_stmt, 9, 12)
1542 self._check_end_pos(for_loop, 12, 15)
1543 self._check_end_pos(try_stmt, 17, 8)
1544 self._check_end_pos(pass_stmt, 19, 4)
1545
1546 self._check_content(s, while_loop.test, 'True')
1547 self._check_content(s, if_stmt.body[0], 'x = None')
1548 self._check_content(s, if_stmt.orelse[0].test, 'other()')
1549 self._check_content(s, for_loop.target, 'x, y')
1550 self._check_content(s, try_stmt.body[0], 'raise RuntimeError')
1551 self._check_content(s, try_stmt.handlers[0].type, 'TypeError')
1552
1553 def test_fstring(self):
1554 s = 'x = f"abc {x + y} abc"'
1555 fstr = self._parse_value(s)
1556 binop = fstr.values[1].value
1557 self._check_content(s, binop, 'x + y')
1558
1559 def test_fstring_multi_line(self):
1560 s = dedent('''
1561 f"""Some multi-line text.
1562 {
1563 arg_one
1564 +
1565 arg_two
1566 }
1567 It goes on..."""
1568 ''').strip()
1569 fstr = self._parse_value(s)
1570 binop = fstr.values[1].value
1571 self._check_end_pos(binop, 5, 7)
1572 self._check_content(s, binop.left, 'arg_one')
1573 self._check_content(s, binop.right, 'arg_two')
1574
1575 def test_import_from_multi_line(self):
1576 s = dedent('''
1577 from x.y.z import (
1578 a, b, c as c
1579 )
1580 ''').strip()
1581 imp = ast.parse(s).body[0]
1582 self._check_end_pos(imp, 3, 1)
1583
1584 def test_slices(self):
1585 s1 = 'f()[1, 2] [0]'
1586 s2 = 'x[ a.b: c.d]'
1587 sm = dedent('''
1588 x[ a.b: f () ,
1589 g () : c.d
1590 ]
1591 ''').strip()
1592 i1, i2, im = map(self._parse_value, (s1, s2, sm))
1593 self._check_content(s1, i1.value, 'f()[1, 2]')
1594 self._check_content(s1, i1.value.slice.value, '1, 2')
1595 self._check_content(s2, i2.slice.lower, 'a.b')
1596 self._check_content(s2, i2.slice.upper, 'c.d')
1597 self._check_content(sm, im.slice.dims[0].upper, 'f ()')
1598 self._check_content(sm, im.slice.dims[1].lower, 'g ()')
1599 self._check_end_pos(im, 3, 3)
1600
1601 def test_binop(self):
1602 s = dedent('''
1603 (1 * 2 + (3 ) +
1604 4
1605 )
1606 ''').strip()
1607 binop = self._parse_value(s)
1608 self._check_end_pos(binop, 2, 6)
1609 self._check_content(s, binop.right, '4')
1610 self._check_content(s, binop.left, '1 * 2 + (3 )')
1611 self._check_content(s, binop.left.right, '3')
1612
1613 def test_boolop(self):
1614 s = dedent('''
1615 if (one_condition and
1616 (other_condition or yet_another_one)):
1617 pass
1618 ''').strip()
1619 bop = ast.parse(s).body[0].test
1620 self._check_end_pos(bop, 2, 44)
1621 self._check_content(s, bop.values[1],
1622 'other_condition or yet_another_one')
1623
1624 def test_tuples(self):
1625 s1 = 'x = () ;'
1626 s2 = 'x = 1 , ;'
1627 s3 = 'x = (1 , 2 ) ;'
1628 sm = dedent('''
1629 x = (
1630 a, b,
1631 )
1632 ''').strip()
1633 t1, t2, t3, tm = map(self._parse_value, (s1, s2, s3, sm))
1634 self._check_content(s1, t1, '()')
1635 self._check_content(s2, t2, '1 ,')
1636 self._check_content(s3, t3, '(1 , 2 )')
1637 self._check_end_pos(tm, 3, 1)
1638
1639 def test_attribute_spaces(self):
1640 s = 'func(x. y .z)'
1641 call = self._parse_value(s)
1642 self._check_content(s, call, s)
1643 self._check_content(s, call.args[0], 'x. y .z')
1644
Miss Islington (bot)2076d4f2020-02-12 12:56:44 -08001645 def test_redundant_parenthesis(self):
1646 s = '( ( ( a + b ) ) )'
1647 v = ast.parse(s).body[0].value
1648 self.assertEqual(type(v).__name__, 'BinOp')
1649 self._check_content(s, v, 'a + b')
1650 s2 = 'await ' + s
1651 v = ast.parse(s2).body[0].value.value
1652 self.assertEqual(type(v).__name__, 'BinOp')
1653 self._check_content(s2, v, 'a + b')
1654
1655 def test_trailers_with_redundant_parenthesis(self):
1656 tests = (
1657 ('( ( ( a ) ) ) ( )', 'Call'),
1658 ('( ( ( a ) ) ) ( b )', 'Call'),
1659 ('( ( ( a ) ) ) [ b ]', 'Subscript'),
1660 ('( ( ( a ) ) ) . b', 'Attribute'),
1661 )
1662 for s, t in tests:
1663 with self.subTest(s):
1664 v = ast.parse(s).body[0].value
1665 self.assertEqual(type(v).__name__, t)
1666 self._check_content(s, v, s)
1667 s2 = 'await ' + s
1668 v = ast.parse(s2).body[0].value.value
1669 self.assertEqual(type(v).__name__, t)
1670 self._check_content(s2, v, s)
1671
Ivan Levkivskyi9932a222019-01-22 11:18:22 +00001672 def test_displays(self):
1673 s1 = '[{}, {1, }, {1, 2,} ]'
1674 s2 = '{a: b, f (): g () ,}'
1675 c1 = self._parse_value(s1)
1676 c2 = self._parse_value(s2)
1677 self._check_content(s1, c1.elts[0], '{}')
1678 self._check_content(s1, c1.elts[1], '{1, }')
1679 self._check_content(s1, c1.elts[2], '{1, 2,}')
1680 self._check_content(s2, c2.keys[1], 'f ()')
1681 self._check_content(s2, c2.values[1], 'g ()')
1682
1683 def test_comprehensions(self):
1684 s = dedent('''
1685 x = [{x for x, y in stuff
1686 if cond.x} for stuff in things]
1687 ''').strip()
1688 cmp = self._parse_value(s)
1689 self._check_end_pos(cmp, 2, 37)
1690 self._check_content(s, cmp.generators[0].iter, 'things')
1691 self._check_content(s, cmp.elt.generators[0].iter, 'stuff')
1692 self._check_content(s, cmp.elt.generators[0].ifs[0], 'cond.x')
1693 self._check_content(s, cmp.elt.generators[0].target, 'x, y')
1694
1695 def test_yield_await(self):
1696 s = dedent('''
1697 async def f():
1698 yield x
1699 await y
1700 ''').strip()
1701 fdef = ast.parse(s).body[0]
1702 self._check_content(s, fdef.body[0].value, 'yield x')
1703 self._check_content(s, fdef.body[1].value, 'await y')
1704
1705 def test_source_segment_multi(self):
1706 s_orig = dedent('''
1707 x = (
1708 a, b,
1709 ) + ()
1710 ''').strip()
1711 s_tuple = dedent('''
1712 (
1713 a, b,
1714 )
1715 ''').strip()
1716 binop = self._parse_value(s_orig)
1717 self.assertEqual(ast.get_source_segment(s_orig, binop.left), s_tuple)
1718
1719 def test_source_segment_padded(self):
1720 s_orig = dedent('''
1721 class C:
1722 def fun(self) -> None:
1723 "ЖЖЖЖЖ"
1724 ''').strip()
1725 s_method = ' def fun(self) -> None:\n' \
1726 ' "ЖЖЖЖЖ"'
1727 cdef = ast.parse(s_orig).body[0]
1728 self.assertEqual(ast.get_source_segment(s_orig, cdef.body[0], padded=True),
1729 s_method)
1730
1731 def test_source_segment_endings(self):
1732 s = 'v = 1\r\nw = 1\nx = 1\n\ry = 1\rz = 1\r\n'
1733 v, w, x, y, z = ast.parse(s).body
1734 self._check_content(s, v, 'v = 1')
1735 self._check_content(s, w, 'w = 1')
1736 self._check_content(s, x, 'x = 1')
1737 self._check_content(s, y, 'y = 1')
1738 self._check_content(s, z, 'z = 1')
1739
1740 def test_source_segment_tabs(self):
1741 s = dedent('''
1742 class C:
1743 \t\f def fun(self) -> None:
1744 \t\f pass
1745 ''').strip()
1746 s_method = ' \t\f def fun(self) -> None:\n' \
1747 ' \t\f pass'
1748
1749 cdef = ast.parse(s).body[0]
1750 self.assertEqual(ast.get_source_segment(s, cdef.body[0], padded=True), s_method)
1751
1752
Miss Islington (bot)522a3942019-08-26 00:43:33 -07001753class NodeVisitorTests(unittest.TestCase):
1754 def test_old_constant_nodes(self):
1755 class Visitor(ast.NodeVisitor):
1756 def visit_Num(self, node):
1757 log.append((node.lineno, 'Num', node.n))
1758 def visit_Str(self, node):
1759 log.append((node.lineno, 'Str', node.s))
1760 def visit_Bytes(self, node):
1761 log.append((node.lineno, 'Bytes', node.s))
1762 def visit_NameConstant(self, node):
1763 log.append((node.lineno, 'NameConstant', node.value))
1764 def visit_Ellipsis(self, node):
1765 log.append((node.lineno, 'Ellipsis', ...))
1766 mod = ast.parse(dedent('''\
1767 i = 42
1768 f = 4.25
1769 c = 4.25j
1770 s = 'string'
1771 b = b'bytes'
1772 t = True
1773 n = None
1774 e = ...
1775 '''))
1776 visitor = Visitor()
1777 log = []
1778 with warnings.catch_warnings(record=True) as wlog:
1779 warnings.filterwarnings('always', '', PendingDeprecationWarning)
1780 visitor.visit(mod)
1781 self.assertEqual(log, [
1782 (1, 'Num', 42),
1783 (2, 'Num', 4.25),
1784 (3, 'Num', 4.25j),
1785 (4, 'Str', 'string'),
1786 (5, 'Bytes', b'bytes'),
1787 (6, 'NameConstant', True),
1788 (7, 'NameConstant', None),
1789 (8, 'Ellipsis', ...),
1790 ])
1791 self.assertEqual([str(w.message) for w in wlog], [
1792 'visit_Num is deprecated; add visit_Constant',
1793 'visit_Num is deprecated; add visit_Constant',
1794 'visit_Num is deprecated; add visit_Constant',
1795 'visit_Str is deprecated; add visit_Constant',
1796 'visit_Bytes is deprecated; add visit_Constant',
1797 'visit_NameConstant is deprecated; add visit_Constant',
1798 'visit_NameConstant is deprecated; add visit_Constant',
1799 'visit_Ellipsis is deprecated; add visit_Constant',
1800 ])
1801
1802
Neal Norwitzee9b10a2008-03-31 05:29:39 +00001803def main():
1804 if __name__ != '__main__':
Martin v. Löwis49c5da12006-03-01 22:49:05 +00001805 return
Neal Norwitzee9b10a2008-03-31 05:29:39 +00001806 if sys.argv[1:] == ['-g']:
1807 for statements, kind in ((exec_tests, "exec"), (single_tests, "single"),
1808 (eval_tests, "eval")):
1809 print(kind+"_results = [")
Victor Stinnerf0891962016-02-08 17:15:21 +01001810 for statement in statements:
1811 tree = ast.parse(statement, "?", kind)
1812 print("%r," % (to_tuple(tree),))
Neal Norwitzee9b10a2008-03-31 05:29:39 +00001813 print("]")
1814 print("main()")
1815 raise SystemExit
Brett Cannon3e9a9ae2013-06-12 21:25:59 -04001816 unittest.main()
Tim Peters400cbc32006-02-28 18:44:41 +00001817
Guido van Rossumdcfcd142019-01-31 03:40:27 -08001818#### EVERYTHING BELOW IS GENERATED BY python Lib/test/test_ast.py -g #####
Tim Peters400cbc32006-02-28 18:44:41 +00001819exec_results = [
Guido van Rossum10f8ce62019-03-13 13:00:46 -07001820('Module', [('Expr', (1, 0), ('Constant', (1, 0), None, None))], []),
1821('Module', [('Expr', (1, 0), ('Constant', (1, 0), 'module docstring', None))], []),
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01001822('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [], [], None, [], [], None, []), [('Pass', (1, 9))], [], None, None)], []),
1823('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [], [], None, [], [], None, []), [('Expr', (1, 9), ('Constant', (1, 9), 'function docstring', None))], [], None, None)], []),
Miss Islington (bot)cf9a63c2019-07-14 16:49:52 -07001824('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [], [('arg', (1, 6), 'a', None, None)], None, [], [], None, []), [('Pass', (1, 10))], [], None, None)], []),
1825('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 +01001826('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [], [], ('arg', (1, 7), 'args', None, None), [], [], None, []), [('Pass', (1, 14))], [], None, None)], []),
1827('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [], [], None, [], [], ('arg', (1, 8), 'kwargs', None, None), []), [('Pass', (1, 17))], [], None, None)], []),
Miss Islington (bot)cf9a63c2019-07-14 16:49:52 -07001828('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 -08001829('Module', [('ClassDef', (1, 0), 'C', [], [], [('Pass', (1, 8))], [])], []),
Guido van Rossum10f8ce62019-03-13 13:00:46 -07001830('Module', [('ClassDef', (1, 0), 'C', [], [], [('Expr', (1, 9), ('Constant', (1, 9), 'docstring for class C', None))], [])], []),
Guido van Rossumdcfcd142019-01-31 03:40:27 -08001831('Module', [('ClassDef', (1, 0), 'C', [('Name', (1, 8), 'object', ('Load',))], [], [('Pass', (1, 17))], [])], []),
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01001832('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 -08001833('Module', [('Delete', (1, 0), [('Name', (1, 4), 'v', ('Del',))])], []),
Guido van Rossum10f8ce62019-03-13 13:00:46 -07001834('Module', [('Assign', (1, 0), [('Name', (1, 0), 'v', ('Store',))], ('Constant', (1, 4), 1, None), None)], []),
Guido van Rossumdcfcd142019-01-31 03:40:27 -08001835('Module', [('Assign', (1, 0), [('Tuple', (1, 0), [('Name', (1, 0), 'a', ('Store',)), ('Name', (1, 2), 'b', ('Store',))], ('Store',))], ('Name', (1, 6), 'c', ('Load',)), None)], []),
1836('Module', [('Assign', (1, 0), [('Tuple', (1, 0), [('Name', (1, 1), 'a', ('Store',)), ('Name', (1, 3), 'b', ('Store',))], ('Store',))], ('Name', (1, 8), 'c', ('Load',)), None)], []),
1837('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 -07001838('Module', [('AugAssign', (1, 0), ('Name', (1, 0), 'v', ('Store',)), ('Add',), ('Constant', (1, 5), 1, None))], []),
Guido van Rossumdcfcd142019-01-31 03:40:27 -08001839('Module', [('For', (1, 0), ('Name', (1, 4), 'v', ('Store',)), ('Name', (1, 9), 'v', ('Load',)), [('Pass', (1, 11))], [], None)], []),
1840('Module', [('While', (1, 0), ('Name', (1, 6), 'v', ('Load',)), [('Pass', (1, 8))], [])], []),
1841('Module', [('If', (1, 0), ('Name', (1, 3), 'v', ('Load',)), [('Pass', (1, 5))], [])], []),
Miss Islington (bot)3b18b172019-12-13 08:21:54 -08001842('Module', [('If', (1, 0), ('Name', (1, 3), 'a', ('Load',)), [('Pass', (2, 2))], [('If', (3, 0), ('Name', (3, 5), 'b', ('Load',)), [('Pass', (4, 2))], [])])], []),
Miss Islington (bot)ce333cd2019-12-14 02:43:42 -08001843('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 -08001844('Module', [('With', (1, 0), [('withitem', ('Name', (1, 5), 'x', ('Load',)), ('Name', (1, 10), 'y', ('Store',)))], [('Pass', (1, 13))], None)], []),
1845('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 -07001846('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 -08001847('Module', [('Try', (1, 0), [('Pass', (2, 2))], [('ExceptHandler', (3, 0), ('Name', (3, 7), 'Exception', ('Load',)), None, [('Pass', (4, 2))])], [], [])], []),
1848('Module', [('Try', (1, 0), [('Pass', (2, 2))], [], [], [('Pass', (4, 2))])], []),
1849('Module', [('Assert', (1, 0), ('Name', (1, 7), 'v', ('Load',)), None)], []),
1850('Module', [('Import', (1, 0), [('alias', 'sys', None)])], []),
1851('Module', [('ImportFrom', (1, 0), 'sys', [('alias', 'v', None)], 0)], []),
1852('Module', [('Global', (1, 0), ['v'])], []),
Guido van Rossum10f8ce62019-03-13 13:00:46 -07001853('Module', [('Expr', (1, 0), ('Constant', (1, 0), 1, None))], []),
Guido van Rossumdcfcd142019-01-31 03:40:27 -08001854('Module', [('Pass', (1, 0))], []),
1855('Module', [('For', (1, 0), ('Name', (1, 4), 'v', ('Store',)), ('Name', (1, 9), 'v', ('Load',)), [('Break', (1, 11))], [], None)], []),
1856('Module', [('For', (1, 0), ('Name', (1, 4), 'v', ('Store',)), ('Name', (1, 9), 'v', ('Load',)), [('Continue', (1, 11))], [], None)], []),
1857('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)], []),
1858('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)], []),
1859('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)], []),
1860('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)]))], []),
1861('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)]))], []),
1862('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)]))], []),
1863('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)]))], []),
1864('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 +01001865('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)], []),
1866('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)], []),
1867('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 -07001868('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)]))], []),
1869('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 +01001870('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)], []),
Miss Skeleton (bot)ba3a5662019-10-26 07:06:40 -07001871('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)], []),
1872('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)], []),
1873('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 +01001874('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)], []),
Lysandros Nikolaou8b9cebc2020-02-08 01:21:38 +01001875('Module', [('FunctionDef', (2, 0), 'f', ('arguments', [], [], None, [], [], None, []), [('Pass', (2, 9))], [('Attribute', (1, 1), ('Attribute', (1, 1), ('Name', (1, 1), 'a', ('Load',)), 'b', ('Load',)), 'c', ('Load',))], None, None)], []),
Pablo Galindo0c9258a2019-03-18 13:51:53 +00001876('Module', [('Expr', (1, 0), ('NamedExpr', (1, 1), ('Name', (1, 1), 'a', ('Store',)), ('Constant', (1, 6), 1, None)))], []),
Miss Islington (bot)cf9a63c2019-07-14 16:49:52 -07001877('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [('arg', (1, 6), 'a', None, None)], [], None, [], [], None, []), [('Pass', (1, 14))], [], None, None)], []),
1878('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)], []),
1879('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)], []),
1880('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)], []),
1881('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [('arg', (1, 6), 'a', None, None)], [], None, [], [], None, [('Constant', (1, 8), 1, None)]), [('Pass', (1, 16))], [], None, None)], []),
1882('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)], []),
1883('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)], []),
1884('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)], []),
1885('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)], []),
1886('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 +00001887]
1888single_results = [
Guido van Rossum10f8ce62019-03-13 13:00:46 -07001889('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 +00001890]
1891eval_results = [
Guido van Rossum10f8ce62019-03-13 13:00:46 -07001892('Expression', ('Constant', (1, 0), None, None)),
Martin v. Löwis49c5da12006-03-01 22:49:05 +00001893('Expression', ('BoolOp', (1, 0), ('And',), [('Name', (1, 0), 'a', ('Load',)), ('Name', (1, 6), 'b', ('Load',))])),
1894('Expression', ('BinOp', (1, 0), ('Name', (1, 0), 'a', ('Load',)), ('Add',), ('Name', (1, 4), 'b', ('Load',)))),
1895('Expression', ('UnaryOp', (1, 0), ('Not',), ('Name', (1, 4), 'v', ('Load',)))),
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01001896('Expression', ('Lambda', (1, 0), ('arguments', [], [], None, [], [], None, []), ('Constant', (1, 7), None, None))),
Guido van Rossum10f8ce62019-03-13 13:00:46 -07001897('Expression', ('Dict', (1, 0), [('Constant', (1, 2), 1, None)], [('Constant', (1, 4), 2, None)])),
Benjamin Peterson6ccfe852011-06-27 17:46:06 -05001898('Expression', ('Dict', (1, 0), [], [])),
Guido van Rossum10f8ce62019-03-13 13:00:46 -07001899('Expression', ('Set', (1, 0), [('Constant', (1, 1), None, None)])),
1900('Expression', ('Dict', (1, 0), [('Constant', (2, 6), 1, None)], [('Constant', (4, 10), 2, None)])),
Serhiy Storchakab619b092018-11-27 09:40:29 +02001901('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)])),
1902('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)])),
1903('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)])),
1904('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)])),
1905('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)])),
1906('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)])),
1907('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)])),
1908('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)])),
1909('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)])),
1910('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)])),
1911('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 -07001912('Expression', ('Compare', (1, 0), ('Constant', (1, 0), 1, None), [('Lt',), ('Lt',)], [('Constant', (1, 4), 2, None), ('Constant', (1, 8), 3, None)])),
1913('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',)))])),
Pablo Galindob1f20442019-12-18 01:41:58 +00001914('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 +02001915('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 -07001916('Expression', ('Constant', (1, 0), 10, None)),
1917('Expression', ('Constant', (1, 0), 'string', None)),
Benjamin Peterson7a66fc22015-02-02 10:51:20 -05001918('Expression', ('Attribute', (1, 0), ('Name', (1, 0), 'a', ('Load',)), 'b', ('Load',))),
1919('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 +00001920('Expression', ('Name', (1, 0), 'v', ('Load',))),
Guido van Rossum10f8ce62019-03-13 13:00:46 -07001921('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 -05001922('Expression', ('List', (1, 0), [], ('Load',))),
Guido van Rossum10f8ce62019-03-13 13:00:46 -07001923('Expression', ('Tuple', (1, 0), [('Constant', (1, 0), 1, None), ('Constant', (1, 2), 2, None), ('Constant', (1, 4), 3, None)], ('Load',))),
1924('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 -05001925('Expression', ('Tuple', (1, 0), [], ('Load',))),
Guido van Rossum10f8ce62019-03-13 13:00:46 -07001926('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 +00001927]
Neal Norwitzee9b10a2008-03-31 05:29:39 +00001928main()