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