blob: 486f2aa707e83fbf1ca413f8ea6cc59129fbfbee [file] [log] [blame]
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001import ast
2import dis
Benjamin Peterson832bfe22011-08-09 16:15:04 -05003import os
4import sys
5import unittest
Miss Islington (bot)522a3942019-08-26 00:43:33 -07006import warnings
Benjamin Peterson9ed37432012-07-08 11:13:36 -07007import weakref
Ivan Levkivskyi9932a222019-01-22 11:18:22 +00008from textwrap import dedent
Benjamin Peterson9ed37432012-07-08 11:13:36 -07009
10from test import support
Tim Peters400cbc32006-02-28 18:44:41 +000011
12def to_tuple(t):
Guido van Rossum3172c5d2007-10-16 18:12:55 +000013 if t is None or isinstance(t, (str, int, complex)):
Tim Peters400cbc32006-02-28 18:44:41 +000014 return t
15 elif isinstance(t, list):
16 return [to_tuple(e) for e in t]
17 result = [t.__class__.__name__]
Martin v. Löwis49c5da12006-03-01 22:49:05 +000018 if hasattr(t, 'lineno') and hasattr(t, 'col_offset'):
19 result.append((t.lineno, t.col_offset))
Tim Peters400cbc32006-02-28 18:44:41 +000020 if t._fields is None:
21 return tuple(result)
22 for f in t._fields:
23 result.append(to_tuple(getattr(t, f)))
24 return tuple(result)
25
Neal Norwitzee9b10a2008-03-31 05:29:39 +000026
Tim Peters400cbc32006-02-28 18:44:41 +000027# These tests are compiled through "exec"
Ezio Melotti85a86292013-08-17 16:57:41 +030028# There should be at least one test per statement
Tim Peters400cbc32006-02-28 18:44:41 +000029exec_tests = [
Benjamin Peterson6ccfe852011-06-27 17:46:06 -050030 # None
31 "None",
INADA Naokicb41b272017-02-23 00:31:59 +090032 # Module docstring
33 "'module docstring'",
Tim Peters400cbc32006-02-28 18:44:41 +000034 # FunctionDef
35 "def f(): pass",
INADA Naokicb41b272017-02-23 00:31:59 +090036 # FunctionDef with docstring
37 "def f(): 'function docstring'",
Benjamin Peterson6ccfe852011-06-27 17:46:06 -050038 # FunctionDef with arg
39 "def f(a): pass",
40 # FunctionDef with arg and default value
41 "def f(a=0): pass",
42 # FunctionDef with varargs
43 "def f(*args): pass",
44 # FunctionDef with kwargs
45 "def f(**kwargs): pass",
INADA Naokicb41b272017-02-23 00:31:59 +090046 # FunctionDef with all kind of args and docstring
47 "def f(a, b=1, c=None, d=[], e={}, *args, f=42, **kwargs): 'doc for f()'",
Tim Peters400cbc32006-02-28 18:44:41 +000048 # ClassDef
49 "class C:pass",
INADA Naokicb41b272017-02-23 00:31:59 +090050 # ClassDef with docstring
51 "class C: 'docstring for class C'",
Benjamin Peterson6ccfe852011-06-27 17:46:06 -050052 # ClassDef, new style class
53 "class C(object): pass",
Tim Peters400cbc32006-02-28 18:44:41 +000054 # Return
55 "def f():return 1",
56 # Delete
57 "del v",
58 # Assign
59 "v = 1",
Serhiy Storchakab619b092018-11-27 09:40:29 +020060 "a,b = c",
61 "(a,b) = c",
62 "[a,b] = c",
Tim Peters400cbc32006-02-28 18:44:41 +000063 # AugAssign
64 "v += 1",
Tim Peters400cbc32006-02-28 18:44:41 +000065 # For
66 "for v in v:pass",
67 # While
68 "while v:pass",
69 # If
70 "if v:pass",
Miss Islington (bot)3b18b172019-12-13 08:21:54 -080071 # If-Elif
72 "if a:\n pass\nelif b:\n pass",
Miss Islington (bot)ce333cd2019-12-14 02:43:42 -080073 # If-Elif-Else
74 "if a:\n pass\nelif b:\n pass\nelse:\n pass",
Benjamin Petersonaeabd5f2011-05-27 15:02:03 -050075 # With
76 "with x as y: pass",
77 "with x as y, z as q: pass",
Tim Peters400cbc32006-02-28 18:44:41 +000078 # Raise
Collin Winter828f04a2007-08-31 00:04:24 +000079 "raise Exception('string')",
Tim Peters400cbc32006-02-28 18:44:41 +000080 # TryExcept
81 "try:\n pass\nexcept Exception:\n pass",
82 # TryFinally
83 "try:\n pass\nfinally:\n pass",
84 # Assert
85 "assert v",
86 # Import
87 "import sys",
88 # ImportFrom
89 "from sys import v",
Tim Peters400cbc32006-02-28 18:44:41 +000090 # Global
91 "global v",
92 # Expr
93 "1",
94 # Pass,
95 "pass",
96 # Break
Yury Selivanovb3d53132015-09-01 16:10:49 -040097 "for v in v:break",
Tim Peters400cbc32006-02-28 18:44:41 +000098 # Continue
Yury Selivanovb3d53132015-09-01 16:10:49 -040099 "for v in v:continue",
Benjamin Peterson2e4b0e12009-09-11 22:36:20 +0000100 # for statements with naked tuples (see http://bugs.python.org/issue6704)
101 "for a,b in c: pass",
Serhiy Storchakab619b092018-11-27 09:40:29 +0200102 "for (a,b) in c: pass",
103 "for [a,b] in c: pass",
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500104 # Multiline generator expression (test for .lineno & .col_offset)
105 """(
106 (
107 Aa
108 ,
109 Bb
110 )
111 for
112 Aa
113 ,
114 Bb in Cc
115 )""",
116 # dictcomp
117 "{a : b for w in x for m in p if g}",
118 # dictcomp with naked tuple
119 "{a : b for v,w in x}",
120 # setcomp
121 "{r for l in x if g}",
122 # setcomp with naked tuple
123 "{r for l,m in x}",
Yury Selivanov75445082015-05-11 22:57:16 -0400124 # AsyncFunctionDef
INADA Naokicb41b272017-02-23 00:31:59 +0900125 "async def f():\n 'async function'\n await something()",
Yury Selivanov75445082015-05-11 22:57:16 -0400126 # AsyncFor
127 "async def f():\n async for e in i: 1\n else: 2",
128 # AsyncWith
129 "async def f():\n async with a as b: 1",
Yury Selivanovb3d53132015-09-01 16:10:49 -0400130 # PEP 448: Additional Unpacking Generalizations
131 "{**{1:2}, 2:3}",
132 "{*{1, 2}, 3}",
Yury Selivanov52c4e7c2016-09-09 10:36:01 -0700133 # Asynchronous comprehensions
134 "async def f():\n [i async for b in c]",
Serhiy Storchaka95b6acf2018-10-30 13:16:02 +0200135 # Decorated FunctionDef
Miss Skeleton (bot)ba3a5662019-10-26 07:06:40 -0700136 "@deco1\n@deco2()\n@deco3(1)\ndef f(): pass",
Serhiy Storchaka95b6acf2018-10-30 13:16:02 +0200137 # Decorated AsyncFunctionDef
Miss Skeleton (bot)ba3a5662019-10-26 07:06:40 -0700138 "@deco1\n@deco2()\n@deco3(1)\nasync def f(): pass",
Serhiy Storchaka95b6acf2018-10-30 13:16:02 +0200139 # Decorated ClassDef
Miss Skeleton (bot)ba3a5662019-10-26 07:06:40 -0700140 "@deco1\n@deco2()\n@deco3(1)\nclass C: pass",
Serhiy Storchakab619b092018-11-27 09:40:29 +0200141 # Decorator with generator argument
142 "@deco(a for a in b)\ndef f(): pass",
Lysandros Nikolaou8b9cebc2020-02-08 01:21:38 +0100143 # Decorator with attribute
144 "@a.b.c\ndef f(): pass",
Pablo Galindo0c9258a2019-03-18 13:51:53 +0000145 # Simple assignment expression
146 "(a := 1)",
Pablo Galindo2f58a842019-05-31 14:09:49 +0100147 # Positional-only arguments
148 "def f(a, /,): pass",
149 "def f(a, /, c, d, e): pass",
150 "def f(a, /, c, *, d, e): pass",
151 "def f(a, /, c, *, d, e, **kwargs): pass",
152 # Positional-only arguments with defaults
153 "def f(a=1, /,): pass",
154 "def f(a=1, /, b=2, c=4): pass",
155 "def f(a=1, /, b=2, *, c=4): pass",
156 "def f(a=1, /, b=2, *, c): pass",
157 "def f(a=1, /, b=2, *, c=4, **kwargs): pass",
158 "def f(a=1, /, b=2, *, c, **kwargs): pass",
Pablo Galindo0c9258a2019-03-18 13:51:53 +0000159
Tim Peters400cbc32006-02-28 18:44:41 +0000160]
161
162# These are compiled through "single"
163# because of overlap with "eval", it just tests what
164# can't be tested with "eval"
165single_tests = [
166 "1+2"
167]
168
169# These are compiled through "eval"
170# It should test all expressions
171eval_tests = [
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500172 # None
173 "None",
Tim Peters400cbc32006-02-28 18:44:41 +0000174 # BoolOp
175 "a and b",
176 # BinOp
177 "a + b",
178 # UnaryOp
179 "not v",
180 # Lambda
181 "lambda:None",
182 # Dict
183 "{ 1:2 }",
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500184 # Empty dict
185 "{}",
186 # Set
187 "{None,}",
188 # Multiline dict (test for .lineno & .col_offset)
189 """{
190 1
191 :
192 2
193 }""",
Tim Peters400cbc32006-02-28 18:44:41 +0000194 # ListComp
195 "[a for b in c if d]",
196 # GeneratorExp
197 "(a for b in c if d)",
Serhiy Storchakab619b092018-11-27 09:40:29 +0200198 # Comprehensions with multiple for targets
199 "[(a,b) for a,b in c]",
200 "[(a,b) for (a,b) in c]",
201 "[(a,b) for [a,b] in c]",
202 "{(a,b) for a,b in c}",
203 "{(a,b) for (a,b) in c}",
204 "{(a,b) for [a,b] in c}",
205 "((a,b) for a,b in c)",
206 "((a,b) for (a,b) in c)",
207 "((a,b) for [a,b] in c)",
Tim Peters400cbc32006-02-28 18:44:41 +0000208 # Yield - yield expressions can't work outside a function
209 #
210 # Compare
211 "1 < 2 < 3",
212 # Call
213 "f(1,2,c=3,*d,**e)",
Pablo Galindob1f20442019-12-18 01:41:58 +0000214 # Call with multi-character starred
215 "f(*[0, 1])",
Serhiy Storchakab619b092018-11-27 09:40:29 +0200216 # Call with a generator argument
217 "f(a for a in b)",
Tim Peters400cbc32006-02-28 18:44:41 +0000218 # Num
Guido van Rossume2a383d2007-01-15 16:59:06 +0000219 "10",
Tim Peters400cbc32006-02-28 18:44:41 +0000220 # Str
221 "'string'",
222 # Attribute
223 "a.b",
224 # Subscript
225 "a[b:c]",
226 # Name
227 "v",
228 # List
229 "[1,2,3]",
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500230 # Empty list
231 "[]",
Tim Peters400cbc32006-02-28 18:44:41 +0000232 # Tuple
Martin v. Löwis49c5da12006-03-01 22:49:05 +0000233 "1,2,3",
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500234 # Tuple
235 "(1,2,3)",
236 # Empty tuple
237 "()",
Martin v. Löwis49c5da12006-03-01 22:49:05 +0000238 # Combination
239 "a.b.c.d(a.b[1:2])",
240
Tim Peters400cbc32006-02-28 18:44:41 +0000241]
242
243# TODO: expr_context, slice, boolop, operator, unaryop, cmpop, comprehension
244# excepthandler, arguments, keywords, alias
245
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000246class AST_Tests(unittest.TestCase):
Tim Peters400cbc32006-02-28 18:44:41 +0000247
Benjamin Peterson7a66fc22015-02-02 10:51:20 -0500248 def _assertTrueorder(self, ast_node, parent_pos):
Georg Brandl0c77a822008-06-10 16:37:50 +0000249 if not isinstance(ast_node, ast.AST) or ast_node._fields is None:
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000250 return
Georg Brandl0c77a822008-06-10 16:37:50 +0000251 if isinstance(ast_node, (ast.expr, ast.stmt, ast.excepthandler)):
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000252 node_pos = (ast_node.lineno, ast_node.col_offset)
Serhiy Storchaka95b6acf2018-10-30 13:16:02 +0200253 self.assertGreaterEqual(node_pos, parent_pos)
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000254 parent_pos = (ast_node.lineno, ast_node.col_offset)
255 for name in ast_node._fields:
256 value = getattr(ast_node, name)
257 if isinstance(value, list):
Serhiy Storchaka95b6acf2018-10-30 13:16:02 +0200258 first_pos = parent_pos
259 if value and name == 'decorator_list':
260 first_pos = (value[0].lineno, value[0].col_offset)
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000261 for child in value:
Serhiy Storchaka95b6acf2018-10-30 13:16:02 +0200262 self._assertTrueorder(child, first_pos)
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000263 elif value is not None:
Benjamin Peterson7a66fc22015-02-02 10:51:20 -0500264 self._assertTrueorder(value, parent_pos)
Tim Peters5ddfe412006-03-01 23:02:57 +0000265
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500266 def test_AST_objects(self):
267 x = ast.AST()
268 self.assertEqual(x._fields, ())
Benjamin Peterson7e0dbfb2012-03-12 09:46:44 -0700269 x.foobar = 42
270 self.assertEqual(x.foobar, 42)
271 self.assertEqual(x.__dict__["foobar"], 42)
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500272
273 with self.assertRaises(AttributeError):
274 x.vararg
275
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500276 with self.assertRaises(TypeError):
277 # "_ast.AST constructor takes 0 positional arguments"
278 ast.AST(2)
279
Benjamin Peterson9ed37432012-07-08 11:13:36 -0700280 def test_AST_garbage_collection(self):
281 class X:
282 pass
283 a = ast.AST()
284 a.x = X()
285 a.x.a = a
286 ref = weakref.ref(a.x)
287 del a
288 support.gc_collect()
289 self.assertIsNone(ref())
290
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000291 def test_snippets(self):
292 for input, output, kind in ((exec_tests, exec_results, "exec"),
293 (single_tests, single_results, "single"),
294 (eval_tests, eval_results, "eval")):
295 for i, o in zip(input, output):
Yury Selivanovb3d53132015-09-01 16:10:49 -0400296 with self.subTest(action="parsing", input=i):
297 ast_tree = compile(i, "?", kind, ast.PyCF_ONLY_AST)
298 self.assertEqual(to_tuple(ast_tree), o)
299 self._assertTrueorder(ast_tree, (0, 0))
Victor Stinner15a30952016-02-08 22:45:06 +0100300 with self.subTest(action="compiling", input=i, kind=kind):
301 compile(ast_tree, "?", kind)
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000302
Pablo Galindo0c9258a2019-03-18 13:51:53 +0000303 def test_ast_validation(self):
304 # compile() is the only function that calls PyAST_Validate
305 snippets_to_validate = exec_tests + single_tests + eval_tests
306 for snippet in snippets_to_validate:
307 tree = ast.parse(snippet)
308 compile(tree, '<string>', 'exec')
309
Benjamin Peterson78565b22009-06-28 19:19:51 +0000310 def test_slice(self):
311 slc = ast.parse("x[::]").body[0].value.slice
312 self.assertIsNone(slc.upper)
313 self.assertIsNone(slc.lower)
314 self.assertIsNone(slc.step)
315
316 def test_from_import(self):
317 im = ast.parse("from . import y").body[0]
318 self.assertIsNone(im.module)
319
Benjamin Petersona4e4e352012-03-22 08:19:04 -0400320 def test_non_interned_future_from_ast(self):
321 mod = ast.parse("from __future__ import division")
322 self.assertIsInstance(mod.body[0], ast.ImportFrom)
323 mod.body[0].module = " __future__ ".strip()
324 compile(mod, "<test>", "exec")
325
Benjamin Petersona0dfa822009-11-13 02:25:08 +0000326 def test_base_classes(self):
327 self.assertTrue(issubclass(ast.For, ast.stmt))
328 self.assertTrue(issubclass(ast.Name, ast.expr))
329 self.assertTrue(issubclass(ast.stmt, ast.AST))
330 self.assertTrue(issubclass(ast.expr, ast.AST))
331 self.assertTrue(issubclass(ast.comprehension, ast.AST))
332 self.assertTrue(issubclass(ast.Gt, ast.AST))
333
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500334 def test_field_attr_existence(self):
335 for name, item in ast.__dict__.items():
336 if isinstance(item, type) and name != 'AST' and name[0].isupper():
337 x = item()
338 if isinstance(x, ast.AST):
339 self.assertEqual(type(x._fields), tuple)
340
341 def test_arguments(self):
342 x = ast.arguments()
Miss Islington (bot)cf9a63c2019-07-14 16:49:52 -0700343 self.assertEqual(x._fields, ('posonlyargs', 'args', 'vararg', 'kwonlyargs',
344 'kw_defaults', 'kwarg', 'defaults'))
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500345
346 with self.assertRaises(AttributeError):
347 x.vararg
348
Pablo Galindo8c77b8c2019-04-29 13:36:57 +0100349 x = ast.arguments(*range(1, 8))
350 self.assertEqual(x.vararg, 3)
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500351
352 def test_field_attr_writable(self):
353 x = ast.Num()
354 # We can assign to _fields
355 x._fields = 666
356 self.assertEqual(x._fields, 666)
357
358 def test_classattrs(self):
359 x = ast.Num()
Guido van Rossum10f8ce62019-03-13 13:00:46 -0700360 self.assertEqual(x._fields, ('value', 'kind'))
Serhiy Storchaka3f228112018-09-27 17:42:37 +0300361
362 with self.assertRaises(AttributeError):
363 x.value
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500364
365 with self.assertRaises(AttributeError):
366 x.n
367
368 x = ast.Num(42)
Serhiy Storchaka3f228112018-09-27 17:42:37 +0300369 self.assertEqual(x.value, 42)
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500370 self.assertEqual(x.n, 42)
371
372 with self.assertRaises(AttributeError):
373 x.lineno
374
375 with self.assertRaises(AttributeError):
376 x.foobar
377
378 x = ast.Num(lineno=2)
379 self.assertEqual(x.lineno, 2)
380
381 x = ast.Num(42, lineno=0)
382 self.assertEqual(x.lineno, 0)
Guido van Rossum10f8ce62019-03-13 13:00:46 -0700383 self.assertEqual(x._fields, ('value', 'kind'))
Serhiy Storchaka3f228112018-09-27 17:42:37 +0300384 self.assertEqual(x.value, 42)
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500385 self.assertEqual(x.n, 42)
386
Guido van Rossum10f8ce62019-03-13 13:00:46 -0700387 self.assertRaises(TypeError, ast.Num, 1, None, 2)
388 self.assertRaises(TypeError, ast.Num, 1, None, 2, lineno=0)
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500389
Miss Islington (bot)907ee1f2020-05-24 14:31:47 -0700390 # Arbitrary keyword arguments are supported
391 self.assertEqual(ast.Constant(1, foo='bar').foo, 'bar')
392 self.assertEqual(ast.Num(1, foo='bar').foo, 'bar')
393
394 with self.assertRaisesRegex(TypeError, "Num got multiple values for argument 'n'"):
395 ast.Num(1, n=2)
396 with self.assertRaisesRegex(TypeError, "Constant got multiple values for argument 'value'"):
397 ast.Constant(1, value=2)
398
Serhiy Storchaka3f228112018-09-27 17:42:37 +0300399 self.assertEqual(ast.Num(42).n, 42)
400 self.assertEqual(ast.Num(4.25).n, 4.25)
401 self.assertEqual(ast.Num(4.25j).n, 4.25j)
402 self.assertEqual(ast.Str('42').s, '42')
403 self.assertEqual(ast.Bytes(b'42').s, b'42')
404 self.assertIs(ast.NameConstant(True).value, True)
405 self.assertIs(ast.NameConstant(False).value, False)
406 self.assertIs(ast.NameConstant(None).value, None)
407
408 self.assertEqual(ast.Constant(42).value, 42)
409 self.assertEqual(ast.Constant(4.25).value, 4.25)
410 self.assertEqual(ast.Constant(4.25j).value, 4.25j)
411 self.assertEqual(ast.Constant('42').value, '42')
412 self.assertEqual(ast.Constant(b'42').value, b'42')
413 self.assertIs(ast.Constant(True).value, True)
414 self.assertIs(ast.Constant(False).value, False)
415 self.assertIs(ast.Constant(None).value, None)
416 self.assertIs(ast.Constant(...).value, ...)
417
418 def test_realtype(self):
419 self.assertEqual(type(ast.Num(42)), ast.Constant)
420 self.assertEqual(type(ast.Num(4.25)), ast.Constant)
421 self.assertEqual(type(ast.Num(4.25j)), ast.Constant)
422 self.assertEqual(type(ast.Str('42')), ast.Constant)
423 self.assertEqual(type(ast.Bytes(b'42')), ast.Constant)
424 self.assertEqual(type(ast.NameConstant(True)), ast.Constant)
425 self.assertEqual(type(ast.NameConstant(False)), ast.Constant)
426 self.assertEqual(type(ast.NameConstant(None)), ast.Constant)
427 self.assertEqual(type(ast.Ellipsis()), ast.Constant)
428
429 def test_isinstance(self):
430 self.assertTrue(isinstance(ast.Num(42), ast.Num))
431 self.assertTrue(isinstance(ast.Num(4.2), ast.Num))
432 self.assertTrue(isinstance(ast.Num(4.2j), ast.Num))
433 self.assertTrue(isinstance(ast.Str('42'), ast.Str))
434 self.assertTrue(isinstance(ast.Bytes(b'42'), ast.Bytes))
435 self.assertTrue(isinstance(ast.NameConstant(True), ast.NameConstant))
436 self.assertTrue(isinstance(ast.NameConstant(False), ast.NameConstant))
437 self.assertTrue(isinstance(ast.NameConstant(None), ast.NameConstant))
438 self.assertTrue(isinstance(ast.Ellipsis(), ast.Ellipsis))
439
440 self.assertTrue(isinstance(ast.Constant(42), ast.Num))
441 self.assertTrue(isinstance(ast.Constant(4.2), ast.Num))
442 self.assertTrue(isinstance(ast.Constant(4.2j), ast.Num))
443 self.assertTrue(isinstance(ast.Constant('42'), ast.Str))
444 self.assertTrue(isinstance(ast.Constant(b'42'), ast.Bytes))
445 self.assertTrue(isinstance(ast.Constant(True), ast.NameConstant))
446 self.assertTrue(isinstance(ast.Constant(False), ast.NameConstant))
447 self.assertTrue(isinstance(ast.Constant(None), ast.NameConstant))
448 self.assertTrue(isinstance(ast.Constant(...), ast.Ellipsis))
449
450 self.assertFalse(isinstance(ast.Str('42'), ast.Num))
451 self.assertFalse(isinstance(ast.Num(42), ast.Str))
452 self.assertFalse(isinstance(ast.Str('42'), ast.Bytes))
453 self.assertFalse(isinstance(ast.Num(42), ast.NameConstant))
454 self.assertFalse(isinstance(ast.Num(42), ast.Ellipsis))
Anthony Sottile74176222019-01-18 11:30:28 -0800455 self.assertFalse(isinstance(ast.NameConstant(True), ast.Num))
456 self.assertFalse(isinstance(ast.NameConstant(False), ast.Num))
Serhiy Storchaka3f228112018-09-27 17:42:37 +0300457
458 self.assertFalse(isinstance(ast.Constant('42'), ast.Num))
459 self.assertFalse(isinstance(ast.Constant(42), ast.Str))
460 self.assertFalse(isinstance(ast.Constant('42'), ast.Bytes))
461 self.assertFalse(isinstance(ast.Constant(42), ast.NameConstant))
462 self.assertFalse(isinstance(ast.Constant(42), ast.Ellipsis))
Anthony Sottile74176222019-01-18 11:30:28 -0800463 self.assertFalse(isinstance(ast.Constant(True), ast.Num))
464 self.assertFalse(isinstance(ast.Constant(False), ast.Num))
Serhiy Storchaka3f228112018-09-27 17:42:37 +0300465
466 self.assertFalse(isinstance(ast.Constant(), ast.Num))
467 self.assertFalse(isinstance(ast.Constant(), ast.Str))
468 self.assertFalse(isinstance(ast.Constant(), ast.Bytes))
469 self.assertFalse(isinstance(ast.Constant(), ast.NameConstant))
470 self.assertFalse(isinstance(ast.Constant(), ast.Ellipsis))
471
Serhiy Storchaka6015cc52018-10-28 13:43:03 +0200472 class S(str): pass
473 self.assertTrue(isinstance(ast.Constant(S('42')), ast.Str))
474 self.assertFalse(isinstance(ast.Constant(S('42')), ast.Num))
475
Serhiy Storchaka3f228112018-09-27 17:42:37 +0300476 def test_subclasses(self):
477 class N(ast.Num):
478 def __init__(self, *args, **kwargs):
479 super().__init__(*args, **kwargs)
480 self.z = 'spam'
481 class N2(ast.Num):
482 pass
483
484 n = N(42)
485 self.assertEqual(n.n, 42)
486 self.assertEqual(n.z, 'spam')
487 self.assertEqual(type(n), N)
488 self.assertTrue(isinstance(n, N))
489 self.assertTrue(isinstance(n, ast.Num))
490 self.assertFalse(isinstance(n, N2))
491 self.assertFalse(isinstance(ast.Num(42), N))
492 n = N(n=42)
493 self.assertEqual(n.n, 42)
494 self.assertEqual(type(n), N)
495
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500496 def test_module(self):
497 body = [ast.Num(42)]
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800498 x = ast.Module(body, [])
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500499 self.assertEqual(x.body, body)
500
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000501 def test_nodeclasses(self):
Florent Xicluna992d9e02011-11-11 19:35:42 +0100502 # Zero arguments constructor explicitly allowed
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500503 x = ast.BinOp()
504 self.assertEqual(x._fields, ('left', 'op', 'right'))
505
506 # Random attribute allowed too
507 x.foobarbaz = 5
508 self.assertEqual(x.foobarbaz, 5)
509
510 n1 = ast.Num(1)
511 n3 = ast.Num(3)
512 addop = ast.Add()
513 x = ast.BinOp(n1, addop, n3)
514 self.assertEqual(x.left, n1)
515 self.assertEqual(x.op, addop)
516 self.assertEqual(x.right, n3)
Benjamin Peterson68b543a2011-06-27 17:51:18 -0500517
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500518 x = ast.BinOp(1, 2, 3)
519 self.assertEqual(x.left, 1)
520 self.assertEqual(x.op, 2)
521 self.assertEqual(x.right, 3)
522
Georg Brandl0c77a822008-06-10 16:37:50 +0000523 x = ast.BinOp(1, 2, 3, lineno=0)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000524 self.assertEqual(x.left, 1)
525 self.assertEqual(x.op, 2)
526 self.assertEqual(x.right, 3)
527 self.assertEqual(x.lineno, 0)
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000528
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500529 # node raises exception when given too many arguments
530 self.assertRaises(TypeError, ast.BinOp, 1, 2, 3, 4)
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500531 # node raises exception when given too many arguments
532 self.assertRaises(TypeError, ast.BinOp, 1, 2, 3, 4, lineno=0)
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000533
534 # can set attributes through kwargs too
Georg Brandl0c77a822008-06-10 16:37:50 +0000535 x = ast.BinOp(left=1, op=2, right=3, lineno=0)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000536 self.assertEqual(x.left, 1)
537 self.assertEqual(x.op, 2)
538 self.assertEqual(x.right, 3)
539 self.assertEqual(x.lineno, 0)
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000540
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500541 # Random kwargs also allowed
542 x = ast.BinOp(1, 2, 3, foobarbaz=42)
543 self.assertEqual(x.foobarbaz, 42)
544
545 def test_no_fields(self):
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000546 # this used to fail because Sub._fields was None
Georg Brandl0c77a822008-06-10 16:37:50 +0000547 x = ast.Sub()
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500548 self.assertEqual(x._fields, ())
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000549
550 def test_pickling(self):
551 import pickle
552 mods = [pickle]
553 try:
554 import cPickle
555 mods.append(cPickle)
556 except ImportError:
557 pass
558 protocols = [0, 1, 2]
559 for mod in mods:
560 for protocol in protocols:
561 for ast in (compile(i, "?", "exec", 0x400) for i in exec_tests):
562 ast2 = mod.loads(mod.dumps(ast, protocol))
Ezio Melottib3aedd42010-11-20 19:04:17 +0000563 self.assertEqual(to_tuple(ast2), to_tuple(ast))
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000564
Benjamin Peterson5b066812010-11-20 01:38:49 +0000565 def test_invalid_sum(self):
566 pos = dict(lineno=2, col_offset=3)
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800567 m = ast.Module([ast.Expr(ast.expr(**pos), **pos)], [])
Benjamin Peterson5b066812010-11-20 01:38:49 +0000568 with self.assertRaises(TypeError) as cm:
569 compile(m, "<test>", "exec")
570 self.assertIn("but got <_ast.expr", str(cm.exception))
571
Benjamin Peterson2193d2b2011-07-22 10:50:23 -0500572 def test_invalid_identitifer(self):
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800573 m = ast.Module([ast.Expr(ast.Name(42, ast.Load()))], [])
Benjamin Peterson2193d2b2011-07-22 10:50:23 -0500574 ast.fix_missing_locations(m)
575 with self.assertRaises(TypeError) as cm:
576 compile(m, "<test>", "exec")
577 self.assertIn("identifier must be of type str", str(cm.exception))
578
Mark Dickinsonded35ae2012-11-25 14:36:26 +0000579 def test_empty_yield_from(self):
580 # Issue 16546: yield from value is not optional.
581 empty_yield_from = ast.parse("def f():\n yield from g()")
582 empty_yield_from.body[0].body[0].value.value = None
583 with self.assertRaises(ValueError) as cm:
584 compile(empty_yield_from, "<test>", "exec")
585 self.assertIn("field value is required", str(cm.exception))
586
Oren Milman7dc46d82017-09-30 20:16:24 +0300587 @support.cpython_only
588 def test_issue31592(self):
589 # There shouldn't be an assertion failure in case of a bad
590 # unicodedata.normalize().
591 import unicodedata
592 def bad_normalize(*args):
593 return None
594 with support.swap_attr(unicodedata, 'normalize', bad_normalize):
595 self.assertRaises(TypeError, ast.parse, '\u03D5')
596
Miss Islington (bot)c7be35c2019-07-08 14:41:34 -0700597 def test_issue18374_binop_col_offset(self):
598 tree = ast.parse('4+5+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.end_col_offset, 7)
604 self.assertEqual(child_binop.col_offset, 0)
605 self.assertEqual(child_binop.end_col_offset, 5)
606 self.assertEqual(grandchild_binop.col_offset, 0)
607 self.assertEqual(grandchild_binop.end_col_offset, 3)
608
609 tree = ast.parse('4+5-\\\n 6-7')
610 parent_binop = tree.body[0].value
611 child_binop = parent_binop.left
612 grandchild_binop = child_binop.left
613 self.assertEqual(parent_binop.col_offset, 0)
614 self.assertEqual(parent_binop.lineno, 1)
615 self.assertEqual(parent_binop.end_col_offset, 4)
616 self.assertEqual(parent_binop.end_lineno, 2)
617
618 self.assertEqual(child_binop.col_offset, 0)
Miss Islington (bot)68bd9c52019-07-09 06:28:57 -0700619 self.assertEqual(child_binop.lineno, 1)
Miss Islington (bot)c7be35c2019-07-08 14:41:34 -0700620 self.assertEqual(child_binop.end_col_offset, 2)
Miss Islington (bot)68bd9c52019-07-09 06:28:57 -0700621 self.assertEqual(child_binop.end_lineno, 2)
Miss Islington (bot)c7be35c2019-07-08 14:41:34 -0700622
623 self.assertEqual(grandchild_binop.col_offset, 0)
Miss Islington (bot)68bd9c52019-07-09 06:28:57 -0700624 self.assertEqual(grandchild_binop.lineno, 1)
Miss Islington (bot)c7be35c2019-07-08 14:41:34 -0700625 self.assertEqual(grandchild_binop.end_col_offset, 3)
Miss Islington (bot)68bd9c52019-07-09 06:28:57 -0700626 self.assertEqual(grandchild_binop.end_lineno, 1)
Georg Brandl0c77a822008-06-10 16:37:50 +0000627
Lysandros Nikolaou8b9cebc2020-02-08 01:21:38 +0100628 def test_issue39579_dotted_name_end_col_offset(self):
629 tree = ast.parse('@a.b.c\ndef f(): pass')
630 attr_b = tree.body[0].decorator_list[0].value
631 self.assertEqual(attr_b.end_col_offset, 4)
632
Georg Brandl0c77a822008-06-10 16:37:50 +0000633class ASTHelpers_Test(unittest.TestCase):
Guido van Rossum10f8ce62019-03-13 13:00:46 -0700634 maxDiff = None
Georg Brandl0c77a822008-06-10 16:37:50 +0000635
636 def test_parse(self):
637 a = ast.parse('foo(1 + 1)')
638 b = compile('foo(1 + 1)', '<unknown>', 'exec', ast.PyCF_ONLY_AST)
639 self.assertEqual(ast.dump(a), ast.dump(b))
640
Benjamin Peterson2e2c9032012-09-02 14:23:15 -0400641 def test_parse_in_error(self):
642 try:
643 1/0
644 except Exception:
Benjamin Petersonbd0df502012-09-02 15:04:51 -0400645 with self.assertRaises(SyntaxError) as e:
646 ast.literal_eval(r"'\U'")
647 self.assertIsNotNone(e.exception.__context__)
Benjamin Peterson2e2c9032012-09-02 14:23:15 -0400648
Georg Brandl0c77a822008-06-10 16:37:50 +0000649 def test_dump(self):
650 node = ast.parse('spam(eggs, "and cheese")')
651 self.assertEqual(ast.dump(node),
652 "Module(body=[Expr(value=Call(func=Name(id='spam', ctx=Load()), "
Guido van Rossum10f8ce62019-03-13 13:00:46 -0700653 "args=[Name(id='eggs', ctx=Load()), Constant(value='and cheese', kind=None)], "
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800654 "keywords=[]))], type_ignores=[])"
Georg Brandl0c77a822008-06-10 16:37:50 +0000655 )
656 self.assertEqual(ast.dump(node, annotate_fields=False),
657 "Module([Expr(Call(Name('spam', Load()), [Name('eggs', Load()), "
Guido van Rossum10f8ce62019-03-13 13:00:46 -0700658 "Constant('and cheese', None)], []))], [])"
Georg Brandl0c77a822008-06-10 16:37:50 +0000659 )
660 self.assertEqual(ast.dump(node, include_attributes=True),
661 "Module(body=[Expr(value=Call(func=Name(id='spam', ctx=Load(), "
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000662 "lineno=1, col_offset=0, end_lineno=1, end_col_offset=4), "
663 "args=[Name(id='eggs', ctx=Load(), lineno=1, col_offset=5, "
Guido van Rossum10f8ce62019-03-13 13:00:46 -0700664 "end_lineno=1, end_col_offset=9), Constant(value='and cheese', kind=None, "
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000665 "lineno=1, col_offset=11, end_lineno=1, end_col_offset=23)], keywords=[], "
666 "lineno=1, col_offset=0, end_lineno=1, end_col_offset=24), "
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800667 "lineno=1, col_offset=0, end_lineno=1, end_col_offset=24)], type_ignores=[])"
Georg Brandl0c77a822008-06-10 16:37:50 +0000668 )
669
Serhiy Storchaka097eae52019-08-29 10:50:28 +0300670 def test_dump_incomplete(self):
671 node = ast.Raise(lineno=3, col_offset=4)
672 self.assertEqual(ast.dump(node),
673 "Raise()"
674 )
675 self.assertEqual(ast.dump(node, include_attributes=True),
676 "Raise(lineno=3, col_offset=4)"
677 )
678 node = ast.Raise(exc=ast.Name(id='e', ctx=ast.Load()), lineno=3, col_offset=4)
679 self.assertEqual(ast.dump(node),
680 "Raise(exc=Name(id='e', ctx=Load()))"
681 )
682 self.assertEqual(ast.dump(node, annotate_fields=False),
683 "Raise(Name('e', Load()))"
684 )
685 self.assertEqual(ast.dump(node, include_attributes=True),
686 "Raise(exc=Name(id='e', ctx=Load()), lineno=3, col_offset=4)"
687 )
688 self.assertEqual(ast.dump(node, annotate_fields=False, include_attributes=True),
689 "Raise(Name('e', Load()), lineno=3, col_offset=4)"
690 )
691 node = ast.Raise(cause=ast.Name(id='e', ctx=ast.Load()))
692 self.assertEqual(ast.dump(node),
693 "Raise(cause=Name(id='e', ctx=Load()))"
694 )
695 self.assertEqual(ast.dump(node, annotate_fields=False),
696 "Raise(cause=Name('e', Load()))"
697 )
698
Georg Brandl0c77a822008-06-10 16:37:50 +0000699 def test_copy_location(self):
700 src = ast.parse('1 + 1', mode='eval')
701 src.body.right = ast.copy_location(ast.Num(2), src.body.right)
702 self.assertEqual(ast.dump(src, include_attributes=True),
Guido van Rossum10f8ce62019-03-13 13:00:46 -0700703 'Expression(body=BinOp(left=Constant(value=1, kind=None, lineno=1, col_offset=0, '
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000704 'end_lineno=1, end_col_offset=1), op=Add(), right=Constant(value=2, '
705 'lineno=1, col_offset=4, end_lineno=1, end_col_offset=5), lineno=1, '
706 'col_offset=0, end_lineno=1, end_col_offset=5))'
Georg Brandl0c77a822008-06-10 16:37:50 +0000707 )
708
709 def test_fix_missing_locations(self):
710 src = ast.parse('write("spam")')
711 src.body.append(ast.Expr(ast.Call(ast.Name('spam', ast.Load()),
Benjamin Peterson025e9eb2015-05-05 20:16:41 -0400712 [ast.Str('eggs')], [])))
Georg Brandl0c77a822008-06-10 16:37:50 +0000713 self.assertEqual(src, ast.fix_missing_locations(src))
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000714 self.maxDiff = None
Georg Brandl0c77a822008-06-10 16:37:50 +0000715 self.assertEqual(ast.dump(src, include_attributes=True),
716 "Module(body=[Expr(value=Call(func=Name(id='write', ctx=Load(), "
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000717 "lineno=1, col_offset=0, end_lineno=1, end_col_offset=5), "
Guido van Rossum10f8ce62019-03-13 13:00:46 -0700718 "args=[Constant(value='spam', kind=None, lineno=1, col_offset=6, end_lineno=1, "
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000719 "end_col_offset=12)], keywords=[], lineno=1, col_offset=0, end_lineno=1, "
720 "end_col_offset=13), lineno=1, col_offset=0, end_lineno=1, "
721 "end_col_offset=13), Expr(value=Call(func=Name(id='spam', ctx=Load(), "
722 "lineno=1, col_offset=0, end_lineno=1, end_col_offset=0), "
723 "args=[Constant(value='eggs', lineno=1, col_offset=0, end_lineno=1, "
724 "end_col_offset=0)], keywords=[], lineno=1, col_offset=0, end_lineno=1, "
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800725 "end_col_offset=0), lineno=1, col_offset=0, end_lineno=1, end_col_offset=0)], "
726 "type_ignores=[])"
Georg Brandl0c77a822008-06-10 16:37:50 +0000727 )
728
729 def test_increment_lineno(self):
730 src = ast.parse('1 + 1', mode='eval')
731 self.assertEqual(ast.increment_lineno(src, n=3), src)
732 self.assertEqual(ast.dump(src, include_attributes=True),
Guido van Rossum10f8ce62019-03-13 13:00:46 -0700733 'Expression(body=BinOp(left=Constant(value=1, kind=None, lineno=4, col_offset=0, '
734 'end_lineno=4, end_col_offset=1), op=Add(), right=Constant(value=1, kind=None, '
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000735 'lineno=4, col_offset=4, end_lineno=4, end_col_offset=5), lineno=4, '
736 'col_offset=0, end_lineno=4, end_col_offset=5))'
Georg Brandl0c77a822008-06-10 16:37:50 +0000737 )
Georg Brandl619e7ba2011-01-09 07:38:51 +0000738 # issue10869: do not increment lineno of root twice
Georg Brandlefb69022011-01-09 07:50:48 +0000739 src = ast.parse('1 + 1', mode='eval')
Georg Brandl619e7ba2011-01-09 07:38:51 +0000740 self.assertEqual(ast.increment_lineno(src.body, n=3), src.body)
741 self.assertEqual(ast.dump(src, include_attributes=True),
Guido van Rossum10f8ce62019-03-13 13:00:46 -0700742 'Expression(body=BinOp(left=Constant(value=1, kind=None, lineno=4, col_offset=0, '
743 'end_lineno=4, end_col_offset=1), op=Add(), right=Constant(value=1, kind=None, '
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000744 'lineno=4, col_offset=4, end_lineno=4, end_col_offset=5), lineno=4, '
745 'col_offset=0, end_lineno=4, end_col_offset=5))'
Georg Brandl619e7ba2011-01-09 07:38:51 +0000746 )
Georg Brandl0c77a822008-06-10 16:37:50 +0000747
748 def test_iter_fields(self):
749 node = ast.parse('foo()', mode='eval')
750 d = dict(ast.iter_fields(node.body))
751 self.assertEqual(d.pop('func').id, 'foo')
Benjamin Peterson025e9eb2015-05-05 20:16:41 -0400752 self.assertEqual(d, {'keywords': [], 'args': []})
Georg Brandl0c77a822008-06-10 16:37:50 +0000753
754 def test_iter_child_nodes(self):
755 node = ast.parse("spam(23, 42, eggs='leek')", mode='eval')
756 self.assertEqual(len(list(ast.iter_child_nodes(node.body))), 4)
757 iterator = ast.iter_child_nodes(node.body)
758 self.assertEqual(next(iterator).id, 'spam')
Serhiy Storchaka3f228112018-09-27 17:42:37 +0300759 self.assertEqual(next(iterator).value, 23)
760 self.assertEqual(next(iterator).value, 42)
Georg Brandl0c77a822008-06-10 16:37:50 +0000761 self.assertEqual(ast.dump(next(iterator)),
Guido van Rossum10f8ce62019-03-13 13:00:46 -0700762 "keyword(arg='eggs', value=Constant(value='leek', kind=None))"
Georg Brandl0c77a822008-06-10 16:37:50 +0000763 )
764
765 def test_get_docstring(self):
Serhiy Storchaka08f127a2018-06-15 11:05:15 +0300766 node = ast.parse('"""line one\n line two"""')
767 self.assertEqual(ast.get_docstring(node),
768 'line one\nline two')
769
770 node = ast.parse('class foo:\n """line one\n line two"""')
771 self.assertEqual(ast.get_docstring(node.body[0]),
772 'line one\nline two')
773
Georg Brandl0c77a822008-06-10 16:37:50 +0000774 node = ast.parse('def foo():\n """line one\n line two"""')
775 self.assertEqual(ast.get_docstring(node.body[0]),
776 'line one\nline two')
777
Yury Selivanov2f07a662015-07-23 08:54:35 +0300778 node = ast.parse('async def foo():\n """spam\n ham"""')
779 self.assertEqual(ast.get_docstring(node.body[0]), 'spam\nham')
Serhiy Storchaka08f127a2018-06-15 11:05:15 +0300780
781 def test_get_docstring_none(self):
Matthias Bussonnier41cea702017-02-23 22:44:19 -0800782 self.assertIsNone(ast.get_docstring(ast.parse('')))
Serhiy Storchaka08f127a2018-06-15 11:05:15 +0300783 node = ast.parse('x = "not docstring"')
784 self.assertIsNone(ast.get_docstring(node))
785 node = ast.parse('def foo():\n pass')
786 self.assertIsNone(ast.get_docstring(node))
787
788 node = ast.parse('class foo:\n pass')
789 self.assertIsNone(ast.get_docstring(node.body[0]))
790 node = ast.parse('class foo:\n x = "not docstring"')
791 self.assertIsNone(ast.get_docstring(node.body[0]))
792 node = ast.parse('class foo:\n def bar(self): pass')
793 self.assertIsNone(ast.get_docstring(node.body[0]))
794
795 node = ast.parse('def foo():\n pass')
796 self.assertIsNone(ast.get_docstring(node.body[0]))
797 node = ast.parse('def foo():\n x = "not docstring"')
798 self.assertIsNone(ast.get_docstring(node.body[0]))
799
800 node = ast.parse('async def foo():\n pass')
801 self.assertIsNone(ast.get_docstring(node.body[0]))
802 node = ast.parse('async def foo():\n x = "not docstring"')
803 self.assertIsNone(ast.get_docstring(node.body[0]))
Yury Selivanov2f07a662015-07-23 08:54:35 +0300804
Anthony Sottile995d9b92019-01-12 20:05:13 -0800805 def test_multi_line_docstring_col_offset_and_lineno_issue16806(self):
806 node = ast.parse(
807 '"""line one\nline two"""\n\n'
808 'def foo():\n """line one\n line two"""\n\n'
809 ' def bar():\n """line one\n line two"""\n'
810 ' """line one\n line two"""\n'
811 '"""line one\nline two"""\n\n'
812 )
813 self.assertEqual(node.body[0].col_offset, 0)
814 self.assertEqual(node.body[0].lineno, 1)
815 self.assertEqual(node.body[1].body[0].col_offset, 2)
816 self.assertEqual(node.body[1].body[0].lineno, 5)
817 self.assertEqual(node.body[1].body[1].body[0].col_offset, 4)
818 self.assertEqual(node.body[1].body[1].body[0].lineno, 9)
819 self.assertEqual(node.body[1].body[2].col_offset, 2)
820 self.assertEqual(node.body[1].body[2].lineno, 11)
821 self.assertEqual(node.body[2].col_offset, 0)
822 self.assertEqual(node.body[2].lineno, 13)
823
Miss Islington (bot)3b18b172019-12-13 08:21:54 -0800824 def test_elif_stmt_start_position(self):
825 node = ast.parse('if a:\n pass\nelif b:\n pass\n')
826 elif_stmt = node.body[0].orelse[0]
827 self.assertEqual(elif_stmt.lineno, 3)
828 self.assertEqual(elif_stmt.col_offset, 0)
829
Miss Islington (bot)ce333cd2019-12-14 02:43:42 -0800830 def test_elif_stmt_start_position_with_else(self):
831 node = ast.parse('if a:\n pass\nelif b:\n pass\nelse:\n pass\n')
832 elif_stmt = node.body[0].orelse[0]
833 self.assertEqual(elif_stmt.lineno, 3)
834 self.assertEqual(elif_stmt.col_offset, 0)
835
Pablo Galindob1f20442019-12-18 01:41:58 +0000836 def test_starred_expr_end_position_within_call(self):
837 node = ast.parse('f(*[0, 1])')
838 starred_expr = node.body[0].value.args[0]
839 self.assertEqual(starred_expr.end_lineno, 1)
840 self.assertEqual(starred_expr.end_col_offset, 9)
841
Georg Brandl0c77a822008-06-10 16:37:50 +0000842 def test_literal_eval(self):
843 self.assertEqual(ast.literal_eval('[1, 2, 3]'), [1, 2, 3])
844 self.assertEqual(ast.literal_eval('{"foo": 42}'), {"foo": 42})
845 self.assertEqual(ast.literal_eval('(True, False, None)'), (True, False, None))
Benjamin Peterson3e742892010-07-11 12:59:24 +0000846 self.assertEqual(ast.literal_eval('{1, 2, 3}'), {1, 2, 3})
Benjamin Peterson5ef96e52010-07-11 23:06:06 +0000847 self.assertEqual(ast.literal_eval('b"hi"'), b"hi")
Georg Brandl0c77a822008-06-10 16:37:50 +0000848 self.assertRaises(ValueError, ast.literal_eval, 'foo()')
Serhiy Storchakad8ac4d12018-01-04 11:15:39 +0200849 self.assertEqual(ast.literal_eval('6'), 6)
850 self.assertEqual(ast.literal_eval('+6'), 6)
Raymond Hettingerbc959732010-10-08 00:47:45 +0000851 self.assertEqual(ast.literal_eval('-6'), -6)
Raymond Hettingerbc959732010-10-08 00:47:45 +0000852 self.assertEqual(ast.literal_eval('3.25'), 3.25)
Serhiy Storchakad8ac4d12018-01-04 11:15:39 +0200853 self.assertEqual(ast.literal_eval('+3.25'), 3.25)
854 self.assertEqual(ast.literal_eval('-3.25'), -3.25)
855 self.assertEqual(repr(ast.literal_eval('-0.0')), '-0.0')
856 self.assertRaises(ValueError, ast.literal_eval, '++6')
857 self.assertRaises(ValueError, ast.literal_eval, '+True')
858 self.assertRaises(ValueError, ast.literal_eval, '2+3')
Georg Brandl0c77a822008-06-10 16:37:50 +0000859
Serhiy Storchakad8ac4d12018-01-04 11:15:39 +0200860 def test_literal_eval_complex(self):
861 # Issue #4907
862 self.assertEqual(ast.literal_eval('6j'), 6j)
863 self.assertEqual(ast.literal_eval('-6j'), -6j)
864 self.assertEqual(ast.literal_eval('6.75j'), 6.75j)
865 self.assertEqual(ast.literal_eval('-6.75j'), -6.75j)
866 self.assertEqual(ast.literal_eval('3+6j'), 3+6j)
867 self.assertEqual(ast.literal_eval('-3+6j'), -3+6j)
868 self.assertEqual(ast.literal_eval('3-6j'), 3-6j)
869 self.assertEqual(ast.literal_eval('-3-6j'), -3-6j)
870 self.assertEqual(ast.literal_eval('3.25+6.75j'), 3.25+6.75j)
871 self.assertEqual(ast.literal_eval('-3.25+6.75j'), -3.25+6.75j)
872 self.assertEqual(ast.literal_eval('3.25-6.75j'), 3.25-6.75j)
873 self.assertEqual(ast.literal_eval('-3.25-6.75j'), -3.25-6.75j)
874 self.assertEqual(ast.literal_eval('(3+6j)'), 3+6j)
875 self.assertRaises(ValueError, ast.literal_eval, '-6j+3')
876 self.assertRaises(ValueError, ast.literal_eval, '-6j+3j')
877 self.assertRaises(ValueError, ast.literal_eval, '3+-6j')
878 self.assertRaises(ValueError, ast.literal_eval, '3+(0+6j)')
879 self.assertRaises(ValueError, ast.literal_eval, '-(3+6j)')
Benjamin Peterson058e31e2009-01-16 03:54:08 +0000880
Miss Islington (bot)2a3b8762020-05-05 13:00:57 -0700881 def test_literal_eval_malformed_dict_nodes(self):
882 malformed = ast.Dict(keys=[ast.Constant(1), ast.Constant(2)], values=[ast.Constant(3)])
883 self.assertRaises(ValueError, ast.literal_eval, malformed)
884 malformed = ast.Dict(keys=[ast.Constant(1)], values=[ast.Constant(2), ast.Constant(3)])
885 self.assertRaises(ValueError, ast.literal_eval, malformed)
886
Amaury Forgeot d'Arc58e87612011-11-22 21:51:55 +0100887 def test_bad_integer(self):
888 # issue13436: Bad error message with invalid numeric values
889 body = [ast.ImportFrom(module='time',
890 names=[ast.alias(name='sleep')],
891 level=None,
892 lineno=None, col_offset=None)]
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800893 mod = ast.Module(body, [])
Amaury Forgeot d'Arc58e87612011-11-22 21:51:55 +0100894 with self.assertRaises(ValueError) as cm:
895 compile(mod, 'test', 'exec')
896 self.assertIn("invalid integer value: None", str(cm.exception))
897
Berker Peksag0a5bd512016-04-29 19:50:02 +0300898 def test_level_as_none(self):
899 body = [ast.ImportFrom(module='time',
900 names=[ast.alias(name='sleep')],
901 level=None,
902 lineno=0, col_offset=0)]
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800903 mod = ast.Module(body, [])
Berker Peksag0a5bd512016-04-29 19:50:02 +0300904 code = compile(mod, 'test', 'exec')
905 ns = {}
906 exec(code, ns)
907 self.assertIn('sleep', ns)
908
Georg Brandl0c77a822008-06-10 16:37:50 +0000909
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500910class ASTValidatorTests(unittest.TestCase):
911
912 def mod(self, mod, msg=None, mode="exec", *, exc=ValueError):
913 mod.lineno = mod.col_offset = 0
914 ast.fix_missing_locations(mod)
Serhiy Storchaka3f228112018-09-27 17:42:37 +0300915 if msg is None:
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500916 compile(mod, "<test>", mode)
Serhiy Storchaka3f228112018-09-27 17:42:37 +0300917 else:
918 with self.assertRaises(exc) as cm:
919 compile(mod, "<test>", mode)
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500920 self.assertIn(msg, str(cm.exception))
921
922 def expr(self, node, msg=None, *, exc=ValueError):
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800923 mod = ast.Module([ast.Expr(node)], [])
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500924 self.mod(mod, msg, exc=exc)
925
926 def stmt(self, stmt, msg=None):
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800927 mod = ast.Module([stmt], [])
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500928 self.mod(mod, msg)
929
930 def test_module(self):
931 m = ast.Interactive([ast.Expr(ast.Name("x", ast.Store()))])
932 self.mod(m, "must have Load context", "single")
933 m = ast.Expression(ast.Name("x", ast.Store()))
934 self.mod(m, "must have Load context", "eval")
935
936 def _check_arguments(self, fac, check):
Pablo Galindo8c77b8c2019-04-29 13:36:57 +0100937 def arguments(args=None, posonlyargs=None, vararg=None,
Benjamin Petersoncda75be2013-03-18 10:48:58 -0700938 kwonlyargs=None, kwarg=None,
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500939 defaults=None, kw_defaults=None):
940 if args is None:
941 args = []
Pablo Galindo8c77b8c2019-04-29 13:36:57 +0100942 if posonlyargs is None:
943 posonlyargs = []
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500944 if kwonlyargs is None:
945 kwonlyargs = []
946 if defaults is None:
947 defaults = []
948 if kw_defaults is None:
949 kw_defaults = []
Pablo Galindo8c77b8c2019-04-29 13:36:57 +0100950 args = ast.arguments(args, posonlyargs, vararg, kwonlyargs,
951 kw_defaults, kwarg, defaults)
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500952 return fac(args)
953 args = [ast.arg("x", ast.Name("x", ast.Store()))]
954 check(arguments(args=args), "must have Load context")
Pablo Galindo8c77b8c2019-04-29 13:36:57 +0100955 check(arguments(posonlyargs=args), "must have Load context")
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500956 check(arguments(kwonlyargs=args), "must have Load context")
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500957 check(arguments(defaults=[ast.Num(3)]),
958 "more positional defaults than args")
959 check(arguments(kw_defaults=[ast.Num(4)]),
960 "length of kwonlyargs is not the same as kw_defaults")
961 args = [ast.arg("x", ast.Name("x", ast.Load()))]
962 check(arguments(args=args, defaults=[ast.Name("x", ast.Store())]),
963 "must have Load context")
964 args = [ast.arg("a", ast.Name("x", ast.Load())),
965 ast.arg("b", ast.Name("y", ast.Load()))]
966 check(arguments(kwonlyargs=args,
967 kw_defaults=[None, ast.Name("x", ast.Store())]),
968 "must have Load context")
969
970 def test_funcdef(self):
Pablo Galindo8c77b8c2019-04-29 13:36:57 +0100971 a = ast.arguments([], [], None, [], [], None, [])
Serhiy Storchaka73cbe7a2018-05-29 12:04:55 +0300972 f = ast.FunctionDef("x", a, [], [], None)
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500973 self.stmt(f, "empty body on FunctionDef")
974 f = ast.FunctionDef("x", a, [ast.Pass()], [ast.Name("x", ast.Store())],
Serhiy Storchaka73cbe7a2018-05-29 12:04:55 +0300975 None)
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500976 self.stmt(f, "must have Load context")
977 f = ast.FunctionDef("x", a, [ast.Pass()], [],
Serhiy Storchaka73cbe7a2018-05-29 12:04:55 +0300978 ast.Name("x", ast.Store()))
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500979 self.stmt(f, "must have Load context")
980 def fac(args):
Serhiy Storchaka73cbe7a2018-05-29 12:04:55 +0300981 return ast.FunctionDef("x", args, [ast.Pass()], [], None)
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500982 self._check_arguments(fac, self.stmt)
983
984 def test_classdef(self):
Benjamin Peterson025e9eb2015-05-05 20:16:41 -0400985 def cls(bases=None, keywords=None, body=None, decorator_list=None):
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500986 if bases is None:
987 bases = []
988 if keywords is None:
989 keywords = []
990 if body is None:
991 body = [ast.Pass()]
992 if decorator_list is None:
993 decorator_list = []
Benjamin Peterson025e9eb2015-05-05 20:16:41 -0400994 return ast.ClassDef("myclass", bases, keywords,
Serhiy Storchaka73cbe7a2018-05-29 12:04:55 +0300995 body, decorator_list)
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500996 self.stmt(cls(bases=[ast.Name("x", ast.Store())]),
997 "must have Load context")
998 self.stmt(cls(keywords=[ast.keyword("x", ast.Name("x", ast.Store()))]),
999 "must have Load context")
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001000 self.stmt(cls(body=[]), "empty body on ClassDef")
1001 self.stmt(cls(body=[None]), "None disallowed")
1002 self.stmt(cls(decorator_list=[ast.Name("x", ast.Store())]),
1003 "must have Load context")
1004
1005 def test_delete(self):
1006 self.stmt(ast.Delete([]), "empty targets on Delete")
1007 self.stmt(ast.Delete([None]), "None disallowed")
1008 self.stmt(ast.Delete([ast.Name("x", ast.Load())]),
1009 "must have Del context")
1010
1011 def test_assign(self):
1012 self.stmt(ast.Assign([], ast.Num(3)), "empty targets on Assign")
1013 self.stmt(ast.Assign([None], ast.Num(3)), "None disallowed")
1014 self.stmt(ast.Assign([ast.Name("x", ast.Load())], ast.Num(3)),
1015 "must have Store context")
1016 self.stmt(ast.Assign([ast.Name("x", ast.Store())],
1017 ast.Name("y", ast.Store())),
1018 "must have Load context")
1019
1020 def test_augassign(self):
1021 aug = ast.AugAssign(ast.Name("x", ast.Load()), ast.Add(),
1022 ast.Name("y", ast.Load()))
1023 self.stmt(aug, "must have Store context")
1024 aug = ast.AugAssign(ast.Name("x", ast.Store()), ast.Add(),
1025 ast.Name("y", ast.Store()))
1026 self.stmt(aug, "must have Load context")
1027
1028 def test_for(self):
1029 x = ast.Name("x", ast.Store())
1030 y = ast.Name("y", ast.Load())
1031 p = ast.Pass()
1032 self.stmt(ast.For(x, y, [], []), "empty body on For")
1033 self.stmt(ast.For(ast.Name("x", ast.Load()), y, [p], []),
1034 "must have Store context")
1035 self.stmt(ast.For(x, ast.Name("y", ast.Store()), [p], []),
1036 "must have Load context")
1037 e = ast.Expr(ast.Name("x", ast.Store()))
1038 self.stmt(ast.For(x, y, [e], []), "must have Load context")
1039 self.stmt(ast.For(x, y, [p], [e]), "must have Load context")
1040
1041 def test_while(self):
1042 self.stmt(ast.While(ast.Num(3), [], []), "empty body on While")
1043 self.stmt(ast.While(ast.Name("x", ast.Store()), [ast.Pass()], []),
1044 "must have Load context")
1045 self.stmt(ast.While(ast.Num(3), [ast.Pass()],
1046 [ast.Expr(ast.Name("x", ast.Store()))]),
1047 "must have Load context")
1048
1049 def test_if(self):
1050 self.stmt(ast.If(ast.Num(3), [], []), "empty body on If")
1051 i = ast.If(ast.Name("x", ast.Store()), [ast.Pass()], [])
1052 self.stmt(i, "must have Load context")
1053 i = ast.If(ast.Num(3), [ast.Expr(ast.Name("x", ast.Store()))], [])
1054 self.stmt(i, "must have Load context")
1055 i = ast.If(ast.Num(3), [ast.Pass()],
1056 [ast.Expr(ast.Name("x", ast.Store()))])
1057 self.stmt(i, "must have Load context")
1058
1059 def test_with(self):
1060 p = ast.Pass()
1061 self.stmt(ast.With([], [p]), "empty items on With")
1062 i = ast.withitem(ast.Num(3), None)
1063 self.stmt(ast.With([i], []), "empty body on With")
1064 i = ast.withitem(ast.Name("x", ast.Store()), None)
1065 self.stmt(ast.With([i], [p]), "must have Load context")
1066 i = ast.withitem(ast.Num(3), ast.Name("x", ast.Load()))
1067 self.stmt(ast.With([i], [p]), "must have Store context")
1068
1069 def test_raise(self):
1070 r = ast.Raise(None, ast.Num(3))
1071 self.stmt(r, "Raise with cause but no exception")
1072 r = ast.Raise(ast.Name("x", ast.Store()), None)
1073 self.stmt(r, "must have Load context")
1074 r = ast.Raise(ast.Num(4), ast.Name("x", ast.Store()))
1075 self.stmt(r, "must have Load context")
1076
1077 def test_try(self):
1078 p = ast.Pass()
1079 t = ast.Try([], [], [], [p])
1080 self.stmt(t, "empty body on Try")
1081 t = ast.Try([ast.Expr(ast.Name("x", ast.Store()))], [], [], [p])
1082 self.stmt(t, "must have Load context")
1083 t = ast.Try([p], [], [], [])
1084 self.stmt(t, "Try has neither except handlers nor finalbody")
1085 t = ast.Try([p], [], [p], [p])
1086 self.stmt(t, "Try has orelse but no except handlers")
1087 t = ast.Try([p], [ast.ExceptHandler(None, "x", [])], [], [])
1088 self.stmt(t, "empty body on ExceptHandler")
1089 e = [ast.ExceptHandler(ast.Name("x", ast.Store()), "y", [p])]
1090 self.stmt(ast.Try([p], e, [], []), "must have Load context")
1091 e = [ast.ExceptHandler(None, "x", [p])]
1092 t = ast.Try([p], e, [ast.Expr(ast.Name("x", ast.Store()))], [p])
1093 self.stmt(t, "must have Load context")
1094 t = ast.Try([p], e, [p], [ast.Expr(ast.Name("x", ast.Store()))])
1095 self.stmt(t, "must have Load context")
1096
1097 def test_assert(self):
1098 self.stmt(ast.Assert(ast.Name("x", ast.Store()), None),
1099 "must have Load context")
1100 assrt = ast.Assert(ast.Name("x", ast.Load()),
1101 ast.Name("y", ast.Store()))
1102 self.stmt(assrt, "must have Load context")
1103
1104 def test_import(self):
1105 self.stmt(ast.Import([]), "empty names on Import")
1106
1107 def test_importfrom(self):
1108 imp = ast.ImportFrom(None, [ast.alias("x", None)], -42)
Serhiy Storchaka7de28402016-06-27 23:40:43 +03001109 self.stmt(imp, "Negative ImportFrom level")
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001110 self.stmt(ast.ImportFrom(None, [], 0), "empty names on ImportFrom")
1111
1112 def test_global(self):
1113 self.stmt(ast.Global([]), "empty names on Global")
1114
1115 def test_nonlocal(self):
1116 self.stmt(ast.Nonlocal([]), "empty names on Nonlocal")
1117
1118 def test_expr(self):
1119 e = ast.Expr(ast.Name("x", ast.Store()))
1120 self.stmt(e, "must have Load context")
1121
1122 def test_boolop(self):
1123 b = ast.BoolOp(ast.And(), [])
1124 self.expr(b, "less than 2 values")
1125 b = ast.BoolOp(ast.And(), [ast.Num(3)])
1126 self.expr(b, "less than 2 values")
1127 b = ast.BoolOp(ast.And(), [ast.Num(4), None])
1128 self.expr(b, "None disallowed")
1129 b = ast.BoolOp(ast.And(), [ast.Num(4), ast.Name("x", ast.Store())])
1130 self.expr(b, "must have Load context")
1131
1132 def test_unaryop(self):
1133 u = ast.UnaryOp(ast.Not(), ast.Name("x", ast.Store()))
1134 self.expr(u, "must have Load context")
1135
1136 def test_lambda(self):
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01001137 a = ast.arguments([], [], None, [], [], None, [])
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001138 self.expr(ast.Lambda(a, ast.Name("x", ast.Store())),
1139 "must have Load context")
1140 def fac(args):
1141 return ast.Lambda(args, ast.Name("x", ast.Load()))
1142 self._check_arguments(fac, self.expr)
1143
1144 def test_ifexp(self):
1145 l = ast.Name("x", ast.Load())
1146 s = ast.Name("y", ast.Store())
1147 for args in (s, l, l), (l, s, l), (l, l, s):
Benjamin Peterson71ce8972011-08-09 16:17:12 -05001148 self.expr(ast.IfExp(*args), "must have Load context")
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001149
1150 def test_dict(self):
1151 d = ast.Dict([], [ast.Name("x", ast.Load())])
1152 self.expr(d, "same number of keys as values")
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001153 d = ast.Dict([ast.Name("x", ast.Load())], [None])
1154 self.expr(d, "None disallowed")
1155
1156 def test_set(self):
1157 self.expr(ast.Set([None]), "None disallowed")
1158 s = ast.Set([ast.Name("x", ast.Store())])
1159 self.expr(s, "must have Load context")
1160
1161 def _check_comprehension(self, fac):
1162 self.expr(fac([]), "comprehension with no generators")
1163 g = ast.comprehension(ast.Name("x", ast.Load()),
Yury Selivanov52c4e7c2016-09-09 10:36:01 -07001164 ast.Name("x", ast.Load()), [], 0)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001165 self.expr(fac([g]), "must have Store context")
1166 g = ast.comprehension(ast.Name("x", ast.Store()),
Yury Selivanov52c4e7c2016-09-09 10:36:01 -07001167 ast.Name("x", ast.Store()), [], 0)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001168 self.expr(fac([g]), "must have Load context")
1169 x = ast.Name("x", ast.Store())
1170 y = ast.Name("y", ast.Load())
Yury Selivanov52c4e7c2016-09-09 10:36:01 -07001171 g = ast.comprehension(x, y, [None], 0)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001172 self.expr(fac([g]), "None disallowed")
Yury Selivanov52c4e7c2016-09-09 10:36:01 -07001173 g = ast.comprehension(x, y, [ast.Name("x", ast.Store())], 0)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001174 self.expr(fac([g]), "must have Load context")
1175
1176 def _simple_comp(self, fac):
1177 g = ast.comprehension(ast.Name("x", ast.Store()),
Yury Selivanov52c4e7c2016-09-09 10:36:01 -07001178 ast.Name("x", ast.Load()), [], 0)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001179 self.expr(fac(ast.Name("x", ast.Store()), [g]),
1180 "must have Load context")
1181 def wrap(gens):
1182 return fac(ast.Name("x", ast.Store()), gens)
1183 self._check_comprehension(wrap)
1184
1185 def test_listcomp(self):
1186 self._simple_comp(ast.ListComp)
1187
1188 def test_setcomp(self):
1189 self._simple_comp(ast.SetComp)
1190
1191 def test_generatorexp(self):
1192 self._simple_comp(ast.GeneratorExp)
1193
1194 def test_dictcomp(self):
1195 g = ast.comprehension(ast.Name("y", ast.Store()),
Yury Selivanov52c4e7c2016-09-09 10:36:01 -07001196 ast.Name("p", ast.Load()), [], 0)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001197 c = ast.DictComp(ast.Name("x", ast.Store()),
1198 ast.Name("y", ast.Load()), [g])
1199 self.expr(c, "must have Load context")
1200 c = ast.DictComp(ast.Name("x", ast.Load()),
1201 ast.Name("y", ast.Store()), [g])
1202 self.expr(c, "must have Load context")
1203 def factory(comps):
1204 k = ast.Name("x", ast.Load())
1205 v = ast.Name("y", ast.Load())
1206 return ast.DictComp(k, v, comps)
1207 self._check_comprehension(factory)
1208
1209 def test_yield(self):
Benjamin Peterson527c6222012-01-14 08:58:23 -05001210 self.expr(ast.Yield(ast.Name("x", ast.Store())), "must have Load")
1211 self.expr(ast.YieldFrom(ast.Name("x", ast.Store())), "must have Load")
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001212
1213 def test_compare(self):
1214 left = ast.Name("x", ast.Load())
1215 comp = ast.Compare(left, [ast.In()], [])
1216 self.expr(comp, "no comparators")
1217 comp = ast.Compare(left, [ast.In()], [ast.Num(4), ast.Num(5)])
1218 self.expr(comp, "different number of comparators and operands")
1219 comp = ast.Compare(ast.Num("blah"), [ast.In()], [left])
Serhiy Storchaka3f228112018-09-27 17:42:37 +03001220 self.expr(comp)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001221 comp = ast.Compare(left, [ast.In()], [ast.Num("blah")])
Serhiy Storchaka3f228112018-09-27 17:42:37 +03001222 self.expr(comp)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001223
1224 def test_call(self):
1225 func = ast.Name("x", ast.Load())
1226 args = [ast.Name("y", ast.Load())]
1227 keywords = [ast.keyword("w", ast.Name("z", ast.Load()))]
Benjamin Peterson025e9eb2015-05-05 20:16:41 -04001228 call = ast.Call(ast.Name("x", ast.Store()), args, keywords)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001229 self.expr(call, "must have Load context")
Benjamin Peterson025e9eb2015-05-05 20:16:41 -04001230 call = ast.Call(func, [None], keywords)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001231 self.expr(call, "None disallowed")
1232 bad_keywords = [ast.keyword("w", ast.Name("z", ast.Store()))]
Benjamin Peterson025e9eb2015-05-05 20:16:41 -04001233 call = ast.Call(func, args, bad_keywords)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001234 self.expr(call, "must have Load context")
1235
1236 def test_num(self):
1237 class subint(int):
1238 pass
1239 class subfloat(float):
1240 pass
1241 class subcomplex(complex):
1242 pass
Serhiy Storchaka3f228112018-09-27 17:42:37 +03001243 for obj in "0", "hello":
1244 self.expr(ast.Num(obj))
1245 for obj in subint(), subfloat(), subcomplex():
1246 self.expr(ast.Num(obj), "invalid type", exc=TypeError)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001247
1248 def test_attribute(self):
1249 attr = ast.Attribute(ast.Name("x", ast.Store()), "y", ast.Load())
1250 self.expr(attr, "must have Load context")
1251
1252 def test_subscript(self):
1253 sub = ast.Subscript(ast.Name("x", ast.Store()), ast.Index(ast.Num(3)),
1254 ast.Load())
1255 self.expr(sub, "must have Load context")
1256 x = ast.Name("x", ast.Load())
1257 sub = ast.Subscript(x, ast.Index(ast.Name("y", ast.Store())),
1258 ast.Load())
1259 self.expr(sub, "must have Load context")
1260 s = ast.Name("x", ast.Store())
1261 for args in (s, None, None), (None, s, None), (None, None, s):
1262 sl = ast.Slice(*args)
1263 self.expr(ast.Subscript(x, sl, ast.Load()),
1264 "must have Load context")
1265 sl = ast.ExtSlice([])
1266 self.expr(ast.Subscript(x, sl, ast.Load()), "empty dims on ExtSlice")
1267 sl = ast.ExtSlice([ast.Index(s)])
1268 self.expr(ast.Subscript(x, sl, ast.Load()), "must have Load context")
1269
1270 def test_starred(self):
1271 left = ast.List([ast.Starred(ast.Name("x", ast.Load()), ast.Store())],
1272 ast.Store())
1273 assign = ast.Assign([left], ast.Num(4))
1274 self.stmt(assign, "must have Store context")
1275
1276 def _sequence(self, fac):
1277 self.expr(fac([None], ast.Load()), "None disallowed")
1278 self.expr(fac([ast.Name("x", ast.Store())], ast.Load()),
1279 "must have Load context")
1280
1281 def test_list(self):
1282 self._sequence(ast.List)
1283
1284 def test_tuple(self):
1285 self._sequence(ast.Tuple)
1286
Benjamin Peterson442f2092012-12-06 17:41:04 -05001287 def test_nameconstant(self):
Serhiy Storchaka3f228112018-09-27 17:42:37 +03001288 self.expr(ast.NameConstant(4))
Benjamin Peterson442f2092012-12-06 17:41:04 -05001289
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001290 def test_stdlib_validates(self):
1291 stdlib = os.path.dirname(ast.__file__)
1292 tests = [fn for fn in os.listdir(stdlib) if fn.endswith(".py")]
1293 tests.extend(["test/test_grammar.py", "test/test_unpack_ex.py"])
1294 for module in tests:
Serhiy Storchaka3bcbedc2019-01-18 07:47:48 +02001295 with self.subTest(module):
1296 fn = os.path.join(stdlib, module)
1297 with open(fn, "r", encoding="utf-8") as fp:
1298 source = fp.read()
1299 mod = ast.parse(source, fn)
1300 compile(mod, fn, "exec")
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001301
1302
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001303class ConstantTests(unittest.TestCase):
1304 """Tests on the ast.Constant node type."""
1305
1306 def compile_constant(self, value):
1307 tree = ast.parse("x = 123")
1308
1309 node = tree.body[0].value
1310 new_node = ast.Constant(value=value)
1311 ast.copy_location(new_node, node)
1312 tree.body[0].value = new_node
1313
1314 code = compile(tree, "<string>", "exec")
1315
1316 ns = {}
1317 exec(code, ns)
1318 return ns['x']
1319
Victor Stinnerbe59d142016-01-27 00:39:12 +01001320 def test_validation(self):
1321 with self.assertRaises(TypeError) as cm:
1322 self.compile_constant([1, 2, 3])
1323 self.assertEqual(str(cm.exception),
1324 "got an invalid type in Constant: list")
1325
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001326 def test_singletons(self):
1327 for const in (None, False, True, Ellipsis, b'', frozenset()):
1328 with self.subTest(const=const):
1329 value = self.compile_constant(const)
1330 self.assertIs(value, const)
1331
1332 def test_values(self):
1333 nested_tuple = (1,)
1334 nested_frozenset = frozenset({1})
1335 for level in range(3):
1336 nested_tuple = (nested_tuple, 2)
1337 nested_frozenset = frozenset({nested_frozenset, 2})
1338 values = (123, 123.0, 123j,
1339 "unicode", b'bytes',
1340 tuple("tuple"), frozenset("frozenset"),
1341 nested_tuple, nested_frozenset)
1342 for value in values:
1343 with self.subTest(value=value):
1344 result = self.compile_constant(value)
1345 self.assertEqual(result, value)
1346
1347 def test_assign_to_constant(self):
1348 tree = ast.parse("x = 1")
1349
1350 target = tree.body[0].targets[0]
1351 new_target = ast.Constant(value=1)
1352 ast.copy_location(new_target, target)
1353 tree.body[0].targets[0] = new_target
1354
1355 with self.assertRaises(ValueError) as cm:
1356 compile(tree, "string", "exec")
1357 self.assertEqual(str(cm.exception),
1358 "expression which can't be assigned "
1359 "to in Store context")
1360
1361 def test_get_docstring(self):
1362 tree = ast.parse("'docstring'\nx = 1")
1363 self.assertEqual(ast.get_docstring(tree), 'docstring')
1364
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001365 def get_load_const(self, tree):
1366 # Compile to bytecode, disassemble and get parameter of LOAD_CONST
1367 # instructions
1368 co = compile(tree, '<string>', 'exec')
1369 consts = []
1370 for instr in dis.get_instructions(co):
1371 if instr.opname == 'LOAD_CONST':
1372 consts.append(instr.argval)
1373 return consts
1374
1375 @support.cpython_only
1376 def test_load_const(self):
1377 consts = [None,
1378 True, False,
1379 124,
1380 2.0,
1381 3j,
1382 "unicode",
1383 b'bytes',
1384 (1, 2, 3)]
1385
Victor Stinnera2724092016-02-08 18:17:58 +01001386 code = '\n'.join(['x={!r}'.format(const) for const in consts])
1387 code += '\nx = ...'
1388 consts.extend((Ellipsis, None))
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001389
1390 tree = ast.parse(code)
Victor Stinnera2724092016-02-08 18:17:58 +01001391 self.assertEqual(self.get_load_const(tree),
1392 consts)
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001393
1394 # Replace expression nodes with constants
Victor Stinnera2724092016-02-08 18:17:58 +01001395 for assign, const in zip(tree.body, consts):
1396 assert isinstance(assign, ast.Assign), ast.dump(assign)
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001397 new_node = ast.Constant(value=const)
Victor Stinnera2724092016-02-08 18:17:58 +01001398 ast.copy_location(new_node, assign.value)
1399 assign.value = new_node
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001400
Victor Stinnera2724092016-02-08 18:17:58 +01001401 self.assertEqual(self.get_load_const(tree),
1402 consts)
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001403
1404 def test_literal_eval(self):
1405 tree = ast.parse("1 + 2")
1406 binop = tree.body[0].value
1407
1408 new_left = ast.Constant(value=10)
1409 ast.copy_location(new_left, binop.left)
1410 binop.left = new_left
1411
Serhiy Storchakad8ac4d12018-01-04 11:15:39 +02001412 new_right = ast.Constant(value=20j)
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001413 ast.copy_location(new_right, binop.right)
1414 binop.right = new_right
1415
Serhiy Storchakad8ac4d12018-01-04 11:15:39 +02001416 self.assertEqual(ast.literal_eval(binop), 10+20j)
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001417
Guido van Rossum10f8ce62019-03-13 13:00:46 -07001418 def test_string_kind(self):
1419 c = ast.parse('"x"', mode='eval').body
1420 self.assertEqual(c.value, "x")
1421 self.assertEqual(c.kind, None)
1422
1423 c = ast.parse('u"x"', mode='eval').body
1424 self.assertEqual(c.value, "x")
1425 self.assertEqual(c.kind, "u")
1426
1427 c = ast.parse('r"x"', mode='eval').body
1428 self.assertEqual(c.value, "x")
1429 self.assertEqual(c.kind, None)
1430
1431 c = ast.parse('b"x"', mode='eval').body
1432 self.assertEqual(c.value, b"x")
1433 self.assertEqual(c.kind, None)
1434
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001435
Ivan Levkivskyi9932a222019-01-22 11:18:22 +00001436class EndPositionTests(unittest.TestCase):
1437 """Tests for end position of AST nodes.
1438
1439 Testing end positions of nodes requires a bit of extra care
1440 because of how LL parsers work.
1441 """
1442 def _check_end_pos(self, ast_node, end_lineno, end_col_offset):
1443 self.assertEqual(ast_node.end_lineno, end_lineno)
1444 self.assertEqual(ast_node.end_col_offset, end_col_offset)
1445
1446 def _check_content(self, source, ast_node, content):
1447 self.assertEqual(ast.get_source_segment(source, ast_node), content)
1448
1449 def _parse_value(self, s):
1450 # Use duck-typing to support both single expression
1451 # and a right hand side of an assignment statement.
1452 return ast.parse(s).body[0].value
1453
1454 def test_lambda(self):
1455 s = 'lambda x, *y: None'
1456 lam = self._parse_value(s)
1457 self._check_content(s, lam.body, 'None')
1458 self._check_content(s, lam.args.args[0], 'x')
1459 self._check_content(s, lam.args.vararg, 'y')
1460
1461 def test_func_def(self):
1462 s = dedent('''
1463 def func(x: int,
1464 *args: str,
1465 z: float = 0,
1466 **kwargs: Any) -> bool:
1467 return True
1468 ''').strip()
1469 fdef = ast.parse(s).body[0]
1470 self._check_end_pos(fdef, 5, 15)
1471 self._check_content(s, fdef.body[0], 'return True')
1472 self._check_content(s, fdef.args.args[0], 'x: int')
1473 self._check_content(s, fdef.args.args[0].annotation, 'int')
1474 self._check_content(s, fdef.args.kwarg, 'kwargs: Any')
1475 self._check_content(s, fdef.args.kwarg.annotation, 'Any')
1476
1477 def test_call(self):
1478 s = 'func(x, y=2, **kw)'
1479 call = self._parse_value(s)
1480 self._check_content(s, call.func, 'func')
1481 self._check_content(s, call.keywords[0].value, '2')
1482 self._check_content(s, call.keywords[1].value, 'kw')
1483
1484 def test_call_noargs(self):
1485 s = 'x[0]()'
1486 call = self._parse_value(s)
1487 self._check_content(s, call.func, 'x[0]')
1488 self._check_end_pos(call, 1, 6)
1489
1490 def test_class_def(self):
1491 s = dedent('''
1492 class C(A, B):
1493 x: int = 0
1494 ''').strip()
1495 cdef = ast.parse(s).body[0]
1496 self._check_end_pos(cdef, 2, 14)
1497 self._check_content(s, cdef.bases[1], 'B')
1498 self._check_content(s, cdef.body[0], 'x: int = 0')
1499
1500 def test_class_kw(self):
1501 s = 'class S(metaclass=abc.ABCMeta): pass'
1502 cdef = ast.parse(s).body[0]
1503 self._check_content(s, cdef.keywords[0].value, 'abc.ABCMeta')
1504
1505 def test_multi_line_str(self):
1506 s = dedent('''
1507 x = """Some multi-line text.
1508
1509 It goes on starting from same indent."""
1510 ''').strip()
1511 assign = ast.parse(s).body[0]
1512 self._check_end_pos(assign, 3, 40)
1513 self._check_end_pos(assign.value, 3, 40)
1514
1515 def test_continued_str(self):
1516 s = dedent('''
1517 x = "first part" \\
1518 "second part"
1519 ''').strip()
1520 assign = ast.parse(s).body[0]
1521 self._check_end_pos(assign, 2, 13)
1522 self._check_end_pos(assign.value, 2, 13)
1523
1524 def test_suites(self):
1525 # We intentionally put these into the same string to check
1526 # that empty lines are not part of the suite.
1527 s = dedent('''
1528 while True:
1529 pass
1530
1531 if one():
1532 x = None
1533 elif other():
1534 y = None
1535 else:
1536 z = None
1537
1538 for x, y in stuff:
1539 assert True
1540
1541 try:
1542 raise RuntimeError
1543 except TypeError as e:
1544 pass
1545
1546 pass
1547 ''').strip()
1548 mod = ast.parse(s)
1549 while_loop = mod.body[0]
1550 if_stmt = mod.body[1]
1551 for_loop = mod.body[2]
1552 try_stmt = mod.body[3]
1553 pass_stmt = mod.body[4]
1554
1555 self._check_end_pos(while_loop, 2, 8)
1556 self._check_end_pos(if_stmt, 9, 12)
1557 self._check_end_pos(for_loop, 12, 15)
1558 self._check_end_pos(try_stmt, 17, 8)
1559 self._check_end_pos(pass_stmt, 19, 4)
1560
1561 self._check_content(s, while_loop.test, 'True')
1562 self._check_content(s, if_stmt.body[0], 'x = None')
1563 self._check_content(s, if_stmt.orelse[0].test, 'other()')
1564 self._check_content(s, for_loop.target, 'x, y')
1565 self._check_content(s, try_stmt.body[0], 'raise RuntimeError')
1566 self._check_content(s, try_stmt.handlers[0].type, 'TypeError')
1567
1568 def test_fstring(self):
1569 s = 'x = f"abc {x + y} abc"'
1570 fstr = self._parse_value(s)
1571 binop = fstr.values[1].value
1572 self._check_content(s, binop, 'x + y')
1573
1574 def test_fstring_multi_line(self):
1575 s = dedent('''
1576 f"""Some multi-line text.
1577 {
1578 arg_one
1579 +
1580 arg_two
1581 }
1582 It goes on..."""
1583 ''').strip()
1584 fstr = self._parse_value(s)
1585 binop = fstr.values[1].value
1586 self._check_end_pos(binop, 5, 7)
1587 self._check_content(s, binop.left, 'arg_one')
1588 self._check_content(s, binop.right, 'arg_two')
1589
1590 def test_import_from_multi_line(self):
1591 s = dedent('''
1592 from x.y.z import (
1593 a, b, c as c
1594 )
1595 ''').strip()
1596 imp = ast.parse(s).body[0]
1597 self._check_end_pos(imp, 3, 1)
1598
1599 def test_slices(self):
1600 s1 = 'f()[1, 2] [0]'
1601 s2 = 'x[ a.b: c.d]'
1602 sm = dedent('''
1603 x[ a.b: f () ,
1604 g () : c.d
1605 ]
1606 ''').strip()
1607 i1, i2, im = map(self._parse_value, (s1, s2, sm))
1608 self._check_content(s1, i1.value, 'f()[1, 2]')
1609 self._check_content(s1, i1.value.slice.value, '1, 2')
1610 self._check_content(s2, i2.slice.lower, 'a.b')
1611 self._check_content(s2, i2.slice.upper, 'c.d')
1612 self._check_content(sm, im.slice.dims[0].upper, 'f ()')
1613 self._check_content(sm, im.slice.dims[1].lower, 'g ()')
1614 self._check_end_pos(im, 3, 3)
1615
1616 def test_binop(self):
1617 s = dedent('''
1618 (1 * 2 + (3 ) +
1619 4
1620 )
1621 ''').strip()
1622 binop = self._parse_value(s)
1623 self._check_end_pos(binop, 2, 6)
1624 self._check_content(s, binop.right, '4')
1625 self._check_content(s, binop.left, '1 * 2 + (3 )')
1626 self._check_content(s, binop.left.right, '3')
1627
1628 def test_boolop(self):
1629 s = dedent('''
1630 if (one_condition and
1631 (other_condition or yet_another_one)):
1632 pass
1633 ''').strip()
1634 bop = ast.parse(s).body[0].test
1635 self._check_end_pos(bop, 2, 44)
1636 self._check_content(s, bop.values[1],
1637 'other_condition or yet_another_one')
1638
1639 def test_tuples(self):
1640 s1 = 'x = () ;'
1641 s2 = 'x = 1 , ;'
1642 s3 = 'x = (1 , 2 ) ;'
1643 sm = dedent('''
1644 x = (
1645 a, b,
1646 )
1647 ''').strip()
1648 t1, t2, t3, tm = map(self._parse_value, (s1, s2, s3, sm))
1649 self._check_content(s1, t1, '()')
1650 self._check_content(s2, t2, '1 ,')
1651 self._check_content(s3, t3, '(1 , 2 )')
1652 self._check_end_pos(tm, 3, 1)
1653
1654 def test_attribute_spaces(self):
1655 s = 'func(x. y .z)'
1656 call = self._parse_value(s)
1657 self._check_content(s, call, s)
1658 self._check_content(s, call.args[0], 'x. y .z')
1659
Miss Islington (bot)2076d4f2020-02-12 12:56:44 -08001660 def test_redundant_parenthesis(self):
1661 s = '( ( ( a + b ) ) )'
1662 v = ast.parse(s).body[0].value
1663 self.assertEqual(type(v).__name__, 'BinOp')
1664 self._check_content(s, v, 'a + b')
1665 s2 = 'await ' + s
1666 v = ast.parse(s2).body[0].value.value
1667 self.assertEqual(type(v).__name__, 'BinOp')
1668 self._check_content(s2, v, 'a + b')
1669
1670 def test_trailers_with_redundant_parenthesis(self):
1671 tests = (
1672 ('( ( ( a ) ) ) ( )', 'Call'),
1673 ('( ( ( a ) ) ) ( b )', 'Call'),
1674 ('( ( ( a ) ) ) [ b ]', 'Subscript'),
1675 ('( ( ( a ) ) ) . b', 'Attribute'),
1676 )
1677 for s, t in tests:
1678 with self.subTest(s):
1679 v = ast.parse(s).body[0].value
1680 self.assertEqual(type(v).__name__, t)
1681 self._check_content(s, v, s)
1682 s2 = 'await ' + s
1683 v = ast.parse(s2).body[0].value.value
1684 self.assertEqual(type(v).__name__, t)
1685 self._check_content(s2, v, s)
1686
Ivan Levkivskyi9932a222019-01-22 11:18:22 +00001687 def test_displays(self):
1688 s1 = '[{}, {1, }, {1, 2,} ]'
1689 s2 = '{a: b, f (): g () ,}'
1690 c1 = self._parse_value(s1)
1691 c2 = self._parse_value(s2)
1692 self._check_content(s1, c1.elts[0], '{}')
1693 self._check_content(s1, c1.elts[1], '{1, }')
1694 self._check_content(s1, c1.elts[2], '{1, 2,}')
1695 self._check_content(s2, c2.keys[1], 'f ()')
1696 self._check_content(s2, c2.values[1], 'g ()')
1697
1698 def test_comprehensions(self):
1699 s = dedent('''
1700 x = [{x for x, y in stuff
1701 if cond.x} for stuff in things]
1702 ''').strip()
1703 cmp = self._parse_value(s)
1704 self._check_end_pos(cmp, 2, 37)
1705 self._check_content(s, cmp.generators[0].iter, 'things')
1706 self._check_content(s, cmp.elt.generators[0].iter, 'stuff')
1707 self._check_content(s, cmp.elt.generators[0].ifs[0], 'cond.x')
1708 self._check_content(s, cmp.elt.generators[0].target, 'x, y')
1709
1710 def test_yield_await(self):
1711 s = dedent('''
1712 async def f():
1713 yield x
1714 await y
1715 ''').strip()
1716 fdef = ast.parse(s).body[0]
1717 self._check_content(s, fdef.body[0].value, 'yield x')
1718 self._check_content(s, fdef.body[1].value, 'await y')
1719
1720 def test_source_segment_multi(self):
1721 s_orig = dedent('''
1722 x = (
1723 a, b,
1724 ) + ()
1725 ''').strip()
1726 s_tuple = dedent('''
1727 (
1728 a, b,
1729 )
1730 ''').strip()
1731 binop = self._parse_value(s_orig)
1732 self.assertEqual(ast.get_source_segment(s_orig, binop.left), s_tuple)
1733
1734 def test_source_segment_padded(self):
1735 s_orig = dedent('''
1736 class C:
1737 def fun(self) -> None:
1738 "ЖЖЖЖЖ"
1739 ''').strip()
1740 s_method = ' def fun(self) -> None:\n' \
1741 ' "ЖЖЖЖЖ"'
1742 cdef = ast.parse(s_orig).body[0]
1743 self.assertEqual(ast.get_source_segment(s_orig, cdef.body[0], padded=True),
1744 s_method)
1745
1746 def test_source_segment_endings(self):
1747 s = 'v = 1\r\nw = 1\nx = 1\n\ry = 1\rz = 1\r\n'
1748 v, w, x, y, z = ast.parse(s).body
1749 self._check_content(s, v, 'v = 1')
1750 self._check_content(s, w, 'w = 1')
1751 self._check_content(s, x, 'x = 1')
1752 self._check_content(s, y, 'y = 1')
1753 self._check_content(s, z, 'z = 1')
1754
1755 def test_source_segment_tabs(self):
1756 s = dedent('''
1757 class C:
1758 \t\f def fun(self) -> None:
1759 \t\f pass
1760 ''').strip()
1761 s_method = ' \t\f def fun(self) -> None:\n' \
1762 ' \t\f pass'
1763
1764 cdef = ast.parse(s).body[0]
1765 self.assertEqual(ast.get_source_segment(s, cdef.body[0], padded=True), s_method)
1766
1767
Miss Islington (bot)522a3942019-08-26 00:43:33 -07001768class NodeVisitorTests(unittest.TestCase):
1769 def test_old_constant_nodes(self):
1770 class Visitor(ast.NodeVisitor):
1771 def visit_Num(self, node):
1772 log.append((node.lineno, 'Num', node.n))
1773 def visit_Str(self, node):
1774 log.append((node.lineno, 'Str', node.s))
1775 def visit_Bytes(self, node):
1776 log.append((node.lineno, 'Bytes', node.s))
1777 def visit_NameConstant(self, node):
1778 log.append((node.lineno, 'NameConstant', node.value))
1779 def visit_Ellipsis(self, node):
1780 log.append((node.lineno, 'Ellipsis', ...))
1781 mod = ast.parse(dedent('''\
1782 i = 42
1783 f = 4.25
1784 c = 4.25j
1785 s = 'string'
1786 b = b'bytes'
1787 t = True
1788 n = None
1789 e = ...
1790 '''))
1791 visitor = Visitor()
1792 log = []
1793 with warnings.catch_warnings(record=True) as wlog:
1794 warnings.filterwarnings('always', '', PendingDeprecationWarning)
1795 visitor.visit(mod)
1796 self.assertEqual(log, [
1797 (1, 'Num', 42),
1798 (2, 'Num', 4.25),
1799 (3, 'Num', 4.25j),
1800 (4, 'Str', 'string'),
1801 (5, 'Bytes', b'bytes'),
1802 (6, 'NameConstant', True),
1803 (7, 'NameConstant', None),
1804 (8, 'Ellipsis', ...),
1805 ])
1806 self.assertEqual([str(w.message) for w in wlog], [
1807 'visit_Num is deprecated; add visit_Constant',
1808 'visit_Num is deprecated; add visit_Constant',
1809 'visit_Num is deprecated; add visit_Constant',
1810 'visit_Str is deprecated; add visit_Constant',
1811 'visit_Bytes is deprecated; add visit_Constant',
1812 'visit_NameConstant is deprecated; add visit_Constant',
1813 'visit_NameConstant is deprecated; add visit_Constant',
1814 'visit_Ellipsis is deprecated; add visit_Constant',
1815 ])
1816
1817
Neal Norwitzee9b10a2008-03-31 05:29:39 +00001818def main():
1819 if __name__ != '__main__':
Martin v. Löwis49c5da12006-03-01 22:49:05 +00001820 return
Neal Norwitzee9b10a2008-03-31 05:29:39 +00001821 if sys.argv[1:] == ['-g']:
1822 for statements, kind in ((exec_tests, "exec"), (single_tests, "single"),
1823 (eval_tests, "eval")):
1824 print(kind+"_results = [")
Victor Stinnerf0891962016-02-08 17:15:21 +01001825 for statement in statements:
1826 tree = ast.parse(statement, "?", kind)
1827 print("%r," % (to_tuple(tree),))
Neal Norwitzee9b10a2008-03-31 05:29:39 +00001828 print("]")
1829 print("main()")
1830 raise SystemExit
Brett Cannon3e9a9ae2013-06-12 21:25:59 -04001831 unittest.main()
Tim Peters400cbc32006-02-28 18:44:41 +00001832
Guido van Rossumdcfcd142019-01-31 03:40:27 -08001833#### EVERYTHING BELOW IS GENERATED BY python Lib/test/test_ast.py -g #####
Tim Peters400cbc32006-02-28 18:44:41 +00001834exec_results = [
Guido van Rossum10f8ce62019-03-13 13:00:46 -07001835('Module', [('Expr', (1, 0), ('Constant', (1, 0), None, None))], []),
1836('Module', [('Expr', (1, 0), ('Constant', (1, 0), 'module docstring', None))], []),
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01001837('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [], [], None, [], [], None, []), [('Pass', (1, 9))], [], None, None)], []),
1838('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [], [], None, [], [], None, []), [('Expr', (1, 9), ('Constant', (1, 9), 'function docstring', None))], [], None, None)], []),
Miss Islington (bot)cf9a63c2019-07-14 16:49:52 -07001839('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [], [('arg', (1, 6), 'a', None, None)], None, [], [], None, []), [('Pass', (1, 10))], [], None, None)], []),
1840('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 +01001841('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [], [], ('arg', (1, 7), 'args', None, None), [], [], None, []), [('Pass', (1, 14))], [], None, None)], []),
1842('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [], [], None, [], [], ('arg', (1, 8), 'kwargs', None, None), []), [('Pass', (1, 17))], [], None, None)], []),
Miss Islington (bot)cf9a63c2019-07-14 16:49:52 -07001843('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 -08001844('Module', [('ClassDef', (1, 0), 'C', [], [], [('Pass', (1, 8))], [])], []),
Guido van Rossum10f8ce62019-03-13 13:00:46 -07001845('Module', [('ClassDef', (1, 0), 'C', [], [], [('Expr', (1, 9), ('Constant', (1, 9), 'docstring for class C', None))], [])], []),
Guido van Rossumdcfcd142019-01-31 03:40:27 -08001846('Module', [('ClassDef', (1, 0), 'C', [('Name', (1, 8), 'object', ('Load',))], [], [('Pass', (1, 17))], [])], []),
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01001847('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 -08001848('Module', [('Delete', (1, 0), [('Name', (1, 4), 'v', ('Del',))])], []),
Guido van Rossum10f8ce62019-03-13 13:00:46 -07001849('Module', [('Assign', (1, 0), [('Name', (1, 0), 'v', ('Store',))], ('Constant', (1, 4), 1, None), None)], []),
Guido van Rossumdcfcd142019-01-31 03:40:27 -08001850('Module', [('Assign', (1, 0), [('Tuple', (1, 0), [('Name', (1, 0), 'a', ('Store',)), ('Name', (1, 2), 'b', ('Store',))], ('Store',))], ('Name', (1, 6), 'c', ('Load',)), None)], []),
1851('Module', [('Assign', (1, 0), [('Tuple', (1, 0), [('Name', (1, 1), 'a', ('Store',)), ('Name', (1, 3), 'b', ('Store',))], ('Store',))], ('Name', (1, 8), 'c', ('Load',)), None)], []),
1852('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 -07001853('Module', [('AugAssign', (1, 0), ('Name', (1, 0), 'v', ('Store',)), ('Add',), ('Constant', (1, 5), 1, None))], []),
Guido van Rossumdcfcd142019-01-31 03:40:27 -08001854('Module', [('For', (1, 0), ('Name', (1, 4), 'v', ('Store',)), ('Name', (1, 9), 'v', ('Load',)), [('Pass', (1, 11))], [], None)], []),
1855('Module', [('While', (1, 0), ('Name', (1, 6), 'v', ('Load',)), [('Pass', (1, 8))], [])], []),
1856('Module', [('If', (1, 0), ('Name', (1, 3), 'v', ('Load',)), [('Pass', (1, 5))], [])], []),
Miss Islington (bot)3b18b172019-12-13 08:21:54 -08001857('Module', [('If', (1, 0), ('Name', (1, 3), 'a', ('Load',)), [('Pass', (2, 2))], [('If', (3, 0), ('Name', (3, 5), 'b', ('Load',)), [('Pass', (4, 2))], [])])], []),
Miss Islington (bot)ce333cd2019-12-14 02:43:42 -08001858('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 -08001859('Module', [('With', (1, 0), [('withitem', ('Name', (1, 5), 'x', ('Load',)), ('Name', (1, 10), 'y', ('Store',)))], [('Pass', (1, 13))], None)], []),
1860('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 -07001861('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 -08001862('Module', [('Try', (1, 0), [('Pass', (2, 2))], [('ExceptHandler', (3, 0), ('Name', (3, 7), 'Exception', ('Load',)), None, [('Pass', (4, 2))])], [], [])], []),
1863('Module', [('Try', (1, 0), [('Pass', (2, 2))], [], [], [('Pass', (4, 2))])], []),
1864('Module', [('Assert', (1, 0), ('Name', (1, 7), 'v', ('Load',)), None)], []),
1865('Module', [('Import', (1, 0), [('alias', 'sys', None)])], []),
1866('Module', [('ImportFrom', (1, 0), 'sys', [('alias', 'v', None)], 0)], []),
1867('Module', [('Global', (1, 0), ['v'])], []),
Guido van Rossum10f8ce62019-03-13 13:00:46 -07001868('Module', [('Expr', (1, 0), ('Constant', (1, 0), 1, None))], []),
Guido van Rossumdcfcd142019-01-31 03:40:27 -08001869('Module', [('Pass', (1, 0))], []),
1870('Module', [('For', (1, 0), ('Name', (1, 4), 'v', ('Store',)), ('Name', (1, 9), 'v', ('Load',)), [('Break', (1, 11))], [], None)], []),
1871('Module', [('For', (1, 0), ('Name', (1, 4), 'v', ('Store',)), ('Name', (1, 9), 'v', ('Load',)), [('Continue', (1, 11))], [], None)], []),
1872('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)], []),
1873('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)], []),
1874('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)], []),
1875('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)]))], []),
1876('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)]))], []),
1877('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)]))], []),
1878('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)]))], []),
1879('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 +01001880('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)], []),
1881('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)], []),
1882('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 -07001883('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)]))], []),
1884('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 +01001885('Module', [('AsyncFunctionDef', (1, 0), 'f', ('arguments', [], [], None, [], [], None, []), [('Expr', (2, 1), ('ListComp', (2, 1), ('Name', (2, 2), 'i', ('Load',)), [('comprehension', ('Name', (2, 14), 'b', ('Store',)), ('Name', (2, 19), 'c', ('Load',)), [], 1)]))], [], None, None)], []),
Miss Skeleton (bot)ba3a5662019-10-26 07:06:40 -07001886('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)], []),
1887('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)], []),
1888('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 +01001889('Module', [('FunctionDef', (2, 0), 'f', ('arguments', [], [], None, [], [], None, []), [('Pass', (2, 9))], [('Call', (1, 1), ('Name', (1, 1), 'deco', ('Load',)), [('GeneratorExp', (1, 5), ('Name', (1, 6), 'a', ('Load',)), [('comprehension', ('Name', (1, 12), 'a', ('Store',)), ('Name', (1, 17), 'b', ('Load',)), [], 0)])], [])], None, None)], []),
Lysandros Nikolaou8b9cebc2020-02-08 01:21:38 +01001890('Module', [('FunctionDef', (2, 0), 'f', ('arguments', [], [], None, [], [], None, []), [('Pass', (2, 9))], [('Attribute', (1, 1), ('Attribute', (1, 1), ('Name', (1, 1), 'a', ('Load',)), 'b', ('Load',)), 'c', ('Load',))], None, None)], []),
Pablo Galindo0c9258a2019-03-18 13:51:53 +00001891('Module', [('Expr', (1, 0), ('NamedExpr', (1, 1), ('Name', (1, 1), 'a', ('Store',)), ('Constant', (1, 6), 1, None)))], []),
Miss Islington (bot)cf9a63c2019-07-14 16:49:52 -07001892('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [('arg', (1, 6), 'a', None, None)], [], None, [], [], None, []), [('Pass', (1, 14))], [], None, None)], []),
1893('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)], []),
1894('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)], []),
1895('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)], []),
1896('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [('arg', (1, 6), 'a', None, None)], [], None, [], [], None, [('Constant', (1, 8), 1, None)]), [('Pass', (1, 16))], [], None, None)], []),
1897('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)], []),
1898('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)], []),
1899('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)], []),
1900('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)], []),
1901('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 +00001902]
1903single_results = [
Guido van Rossum10f8ce62019-03-13 13:00:46 -07001904('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 +00001905]
1906eval_results = [
Guido van Rossum10f8ce62019-03-13 13:00:46 -07001907('Expression', ('Constant', (1, 0), None, None)),
Martin v. Löwis49c5da12006-03-01 22:49:05 +00001908('Expression', ('BoolOp', (1, 0), ('And',), [('Name', (1, 0), 'a', ('Load',)), ('Name', (1, 6), 'b', ('Load',))])),
1909('Expression', ('BinOp', (1, 0), ('Name', (1, 0), 'a', ('Load',)), ('Add',), ('Name', (1, 4), 'b', ('Load',)))),
1910('Expression', ('UnaryOp', (1, 0), ('Not',), ('Name', (1, 4), 'v', ('Load',)))),
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01001911('Expression', ('Lambda', (1, 0), ('arguments', [], [], None, [], [], None, []), ('Constant', (1, 7), None, None))),
Guido van Rossum10f8ce62019-03-13 13:00:46 -07001912('Expression', ('Dict', (1, 0), [('Constant', (1, 2), 1, None)], [('Constant', (1, 4), 2, None)])),
Benjamin Peterson6ccfe852011-06-27 17:46:06 -05001913('Expression', ('Dict', (1, 0), [], [])),
Guido van Rossum10f8ce62019-03-13 13:00:46 -07001914('Expression', ('Set', (1, 0), [('Constant', (1, 1), None, None)])),
1915('Expression', ('Dict', (1, 0), [('Constant', (2, 6), 1, None)], [('Constant', (4, 10), 2, None)])),
Serhiy Storchakab619b092018-11-27 09:40:29 +02001916('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)])),
1917('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)])),
1918('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)])),
1919('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)])),
1920('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)])),
1921('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)])),
1922('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)])),
1923('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)])),
1924('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)])),
1925('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)])),
1926('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 -07001927('Expression', ('Compare', (1, 0), ('Constant', (1, 0), 1, None), [('Lt',), ('Lt',)], [('Constant', (1, 4), 2, None), ('Constant', (1, 8), 3, None)])),
1928('Expression', ('Call', (1, 0), ('Name', (1, 0), 'f', ('Load',)), [('Constant', (1, 2), 1, None), ('Constant', (1, 4), 2, None), ('Starred', (1, 10), ('Name', (1, 11), 'd', ('Load',)), ('Load',))], [('keyword', 'c', ('Constant', (1, 8), 3, None)), ('keyword', None, ('Name', (1, 15), 'e', ('Load',)))])),
Pablo Galindob1f20442019-12-18 01:41:58 +00001929('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 +02001930('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 -07001931('Expression', ('Constant', (1, 0), 10, None)),
1932('Expression', ('Constant', (1, 0), 'string', None)),
Benjamin Peterson7a66fc22015-02-02 10:51:20 -05001933('Expression', ('Attribute', (1, 0), ('Name', (1, 0), 'a', ('Load',)), 'b', ('Load',))),
1934('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 +00001935('Expression', ('Name', (1, 0), 'v', ('Load',))),
Guido van Rossum10f8ce62019-03-13 13:00:46 -07001936('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 -05001937('Expression', ('List', (1, 0), [], ('Load',))),
Guido van Rossum10f8ce62019-03-13 13:00:46 -07001938('Expression', ('Tuple', (1, 0), [('Constant', (1, 0), 1, None), ('Constant', (1, 2), 2, None), ('Constant', (1, 4), 3, None)], ('Load',))),
1939('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 -05001940('Expression', ('Tuple', (1, 0), [], ('Load',))),
Guido van Rossum10f8ce62019-03-13 13:00:46 -07001941('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 +00001942]
Neal Norwitzee9b10a2008-03-31 05:29:39 +00001943main()