blob: e78848537d47a3ac2ad498ff1922ea79256f3cb1 [file] [log] [blame]
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001import ast
2import dis
Benjamin Peterson832bfe22011-08-09 16:15:04 -05003import os
4import sys
5import unittest
Serhiy Storchakac3ea41e2019-08-26 10:13:19 +03006import warnings
Benjamin Peterson9ed37432012-07-08 11:13:36 -07007import weakref
Ivan Levkivskyi9932a222019-01-22 11:18:22 +00008from textwrap import dedent
Benjamin Peterson9ed37432012-07-08 11:13:36 -07009
10from test import support
Tim Peters400cbc32006-02-28 18:44:41 +000011
12def to_tuple(t):
Guido van Rossum3172c5d2007-10-16 18:12:55 +000013 if t is None or isinstance(t, (str, int, complex)):
Tim Peters400cbc32006-02-28 18:44:41 +000014 return t
15 elif isinstance(t, list):
16 return [to_tuple(e) for e in t]
17 result = [t.__class__.__name__]
Martin v. Löwis49c5da12006-03-01 22:49:05 +000018 if hasattr(t, 'lineno') and hasattr(t, 'col_offset'):
19 result.append((t.lineno, t.col_offset))
Serhiy Storchaka850a8852020-01-10 10:12:55 +020020 if hasattr(t, 'end_lineno') and hasattr(t, 'end_col_offset'):
21 result[-1] += (t.end_lineno, t.end_col_offset)
Tim Peters400cbc32006-02-28 18:44:41 +000022 if t._fields is None:
23 return tuple(result)
24 for f in t._fields:
25 result.append(to_tuple(getattr(t, f)))
26 return tuple(result)
27
Neal Norwitzee9b10a2008-03-31 05:29:39 +000028
Tim Peters400cbc32006-02-28 18:44:41 +000029# These tests are compiled through "exec"
Ezio Melotti85a86292013-08-17 16:57:41 +030030# There should be at least one test per statement
Tim Peters400cbc32006-02-28 18:44:41 +000031exec_tests = [
Benjamin Peterson6ccfe852011-06-27 17:46:06 -050032 # None
33 "None",
INADA Naokicb41b272017-02-23 00:31:59 +090034 # Module docstring
35 "'module docstring'",
Tim Peters400cbc32006-02-28 18:44:41 +000036 # FunctionDef
37 "def f(): pass",
INADA Naokicb41b272017-02-23 00:31:59 +090038 # FunctionDef with docstring
39 "def f(): 'function docstring'",
Benjamin Peterson6ccfe852011-06-27 17:46:06 -050040 # FunctionDef with arg
41 "def f(a): pass",
42 # FunctionDef with arg and default value
43 "def f(a=0): pass",
44 # FunctionDef with varargs
45 "def f(*args): pass",
46 # FunctionDef with kwargs
47 "def f(**kwargs): pass",
INADA Naokicb41b272017-02-23 00:31:59 +090048 # FunctionDef with all kind of args and docstring
49 "def f(a, b=1, c=None, d=[], e={}, *args, f=42, **kwargs): 'doc for f()'",
Tim Peters400cbc32006-02-28 18:44:41 +000050 # ClassDef
51 "class C:pass",
INADA Naokicb41b272017-02-23 00:31:59 +090052 # ClassDef with docstring
53 "class C: 'docstring for class C'",
Benjamin Peterson6ccfe852011-06-27 17:46:06 -050054 # ClassDef, new style class
55 "class C(object): pass",
Tim Peters400cbc32006-02-28 18:44:41 +000056 # Return
57 "def f():return 1",
58 # Delete
59 "del v",
60 # Assign
61 "v = 1",
Serhiy Storchakab619b092018-11-27 09:40:29 +020062 "a,b = c",
63 "(a,b) = c",
64 "[a,b] = c",
Tim Peters400cbc32006-02-28 18:44:41 +000065 # AugAssign
66 "v += 1",
Tim Peters400cbc32006-02-28 18:44:41 +000067 # For
68 "for v in v:pass",
69 # While
70 "while v:pass",
71 # If
72 "if v:pass",
Lysandros Nikolaou025a6022019-12-12 22:40:21 +010073 # If-Elif
74 "if a:\n pass\nelif b:\n pass",
Lysandros Nikolaou5936a4c2019-12-14 11:24:57 +010075 # If-Elif-Else
76 "if a:\n pass\nelif b:\n pass\nelse:\n pass",
Benjamin Petersonaeabd5f2011-05-27 15:02:03 -050077 # With
78 "with x as y: pass",
79 "with x as y, z as q: pass",
Tim Peters400cbc32006-02-28 18:44:41 +000080 # Raise
Collin Winter828f04a2007-08-31 00:04:24 +000081 "raise Exception('string')",
Tim Peters400cbc32006-02-28 18:44:41 +000082 # TryExcept
83 "try:\n pass\nexcept Exception:\n pass",
84 # TryFinally
85 "try:\n pass\nfinally:\n pass",
86 # Assert
87 "assert v",
88 # Import
89 "import sys",
90 # ImportFrom
91 "from sys import v",
Tim Peters400cbc32006-02-28 18:44:41 +000092 # Global
93 "global v",
94 # Expr
95 "1",
96 # Pass,
97 "pass",
98 # Break
Yury Selivanovb3d53132015-09-01 16:10:49 -040099 "for v in v:break",
Tim Peters400cbc32006-02-28 18:44:41 +0000100 # Continue
Yury Selivanovb3d53132015-09-01 16:10:49 -0400101 "for v in v:continue",
Benjamin Peterson2e4b0e12009-09-11 22:36:20 +0000102 # for statements with naked tuples (see http://bugs.python.org/issue6704)
103 "for a,b in c: pass",
Serhiy Storchakab619b092018-11-27 09:40:29 +0200104 "for (a,b) in c: pass",
105 "for [a,b] in c: pass",
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500106 # Multiline generator expression (test for .lineno & .col_offset)
107 """(
108 (
109 Aa
110 ,
111 Bb
112 )
113 for
114 Aa
115 ,
116 Bb in Cc
117 )""",
118 # dictcomp
119 "{a : b for w in x for m in p if g}",
120 # dictcomp with naked tuple
121 "{a : b for v,w in x}",
122 # setcomp
123 "{r for l in x if g}",
124 # setcomp with naked tuple
125 "{r for l,m in x}",
Yury Selivanov75445082015-05-11 22:57:16 -0400126 # AsyncFunctionDef
INADA Naokicb41b272017-02-23 00:31:59 +0900127 "async def f():\n 'async function'\n await something()",
Yury Selivanov75445082015-05-11 22:57:16 -0400128 # AsyncFor
129 "async def f():\n async for e in i: 1\n else: 2",
130 # AsyncWith
131 "async def f():\n async with a as b: 1",
Yury Selivanovb3d53132015-09-01 16:10:49 -0400132 # PEP 448: Additional Unpacking Generalizations
133 "{**{1:2}, 2:3}",
134 "{*{1, 2}, 3}",
Yury Selivanov52c4e7c2016-09-09 10:36:01 -0700135 # Asynchronous comprehensions
136 "async def f():\n [i async for b in c]",
Serhiy Storchaka95b6acf2018-10-30 13:16:02 +0200137 # Decorated FunctionDef
Serhiy Storchaka26ae9f62019-10-26 16:46:05 +0300138 "@deco1\n@deco2()\n@deco3(1)\ndef f(): pass",
Serhiy Storchaka95b6acf2018-10-30 13:16:02 +0200139 # Decorated AsyncFunctionDef
Serhiy Storchaka26ae9f62019-10-26 16:46:05 +0300140 "@deco1\n@deco2()\n@deco3(1)\nasync def f(): pass",
Serhiy Storchaka95b6acf2018-10-30 13:16:02 +0200141 # Decorated ClassDef
Serhiy Storchaka26ae9f62019-10-26 16:46:05 +0300142 "@deco1\n@deco2()\n@deco3(1)\nclass C: pass",
Serhiy Storchakab619b092018-11-27 09:40:29 +0200143 # Decorator with generator argument
144 "@deco(a for a in b)\ndef f(): pass",
Lysandros Nikolaoud2e10982020-02-08 00:36:32 +0100145 # Decorator with attribute
146 "@a.b.c\ndef f(): pass",
Pablo Galindo0c9258a2019-03-18 13:51:53 +0000147 # Simple assignment expression
148 "(a := 1)",
Pablo Galindo2f58a842019-05-31 14:09:49 +0100149 # Positional-only arguments
150 "def f(a, /,): pass",
151 "def f(a, /, c, d, e): pass",
152 "def f(a, /, c, *, d, e): pass",
153 "def f(a, /, c, *, d, e, **kwargs): pass",
154 # Positional-only arguments with defaults
155 "def f(a=1, /,): pass",
156 "def f(a=1, /, b=2, c=4): pass",
157 "def f(a=1, /, b=2, *, c=4): pass",
158 "def f(a=1, /, b=2, *, c): pass",
159 "def f(a=1, /, b=2, *, c=4, **kwargs): pass",
160 "def f(a=1, /, b=2, *, c, **kwargs): pass",
Pablo Galindo0c9258a2019-03-18 13:51:53 +0000161
Tim Peters400cbc32006-02-28 18:44:41 +0000162]
163
164# These are compiled through "single"
165# because of overlap with "eval", it just tests what
166# can't be tested with "eval"
167single_tests = [
168 "1+2"
169]
170
171# These are compiled through "eval"
172# It should test all expressions
173eval_tests = [
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500174 # None
175 "None",
Tim Peters400cbc32006-02-28 18:44:41 +0000176 # BoolOp
177 "a and b",
178 # BinOp
179 "a + b",
180 # UnaryOp
181 "not v",
182 # Lambda
183 "lambda:None",
184 # Dict
185 "{ 1:2 }",
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500186 # Empty dict
187 "{}",
188 # Set
189 "{None,}",
190 # Multiline dict (test for .lineno & .col_offset)
191 """{
192 1
193 :
194 2
195 }""",
Tim Peters400cbc32006-02-28 18:44:41 +0000196 # ListComp
197 "[a for b in c if d]",
198 # GeneratorExp
199 "(a for b in c if d)",
Serhiy Storchakab619b092018-11-27 09:40:29 +0200200 # Comprehensions with multiple for targets
201 "[(a,b) for a,b in c]",
202 "[(a,b) for (a,b) in c]",
203 "[(a,b) for [a,b] in c]",
204 "{(a,b) for a,b in c}",
205 "{(a,b) for (a,b) in c}",
206 "{(a,b) for [a,b] in c}",
207 "((a,b) for a,b in c)",
208 "((a,b) for (a,b) in c)",
209 "((a,b) for [a,b] in c)",
Tim Peters400cbc32006-02-28 18:44:41 +0000210 # Yield - yield expressions can't work outside a function
211 #
212 # Compare
213 "1 < 2 < 3",
214 # Call
215 "f(1,2,c=3,*d,**e)",
Lysandros Nikolaou50d4f122019-12-18 01:20:55 +0100216 # Call with multi-character starred
217 "f(*[0, 1])",
Serhiy Storchakab619b092018-11-27 09:40:29 +0200218 # Call with a generator argument
219 "f(a for a in b)",
Tim Peters400cbc32006-02-28 18:44:41 +0000220 # Num
Guido van Rossume2a383d2007-01-15 16:59:06 +0000221 "10",
Tim Peters400cbc32006-02-28 18:44:41 +0000222 # Str
223 "'string'",
224 # Attribute
225 "a.b",
226 # Subscript
227 "a[b:c]",
228 # Name
229 "v",
230 # List
231 "[1,2,3]",
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500232 # Empty list
233 "[]",
Tim Peters400cbc32006-02-28 18:44:41 +0000234 # Tuple
Martin v. Löwis49c5da12006-03-01 22:49:05 +0000235 "1,2,3",
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500236 # Tuple
237 "(1,2,3)",
238 # Empty tuple
239 "()",
Martin v. Löwis49c5da12006-03-01 22:49:05 +0000240 # Combination
241 "a.b.c.d(a.b[1:2])",
242
Tim Peters400cbc32006-02-28 18:44:41 +0000243]
244
245# TODO: expr_context, slice, boolop, operator, unaryop, cmpop, comprehension
246# excepthandler, arguments, keywords, alias
247
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000248class AST_Tests(unittest.TestCase):
Tim Peters400cbc32006-02-28 18:44:41 +0000249
Batuhan TaĹźkaya397b96f2020-03-01 23:12:17 +0300250 def _is_ast_node(self, name, node):
251 if not isinstance(node, type):
252 return False
253 if "ast" not in node.__module__:
254 return False
255 return name != 'AST' and name[0].isupper()
256
Benjamin Peterson7a66fc22015-02-02 10:51:20 -0500257 def _assertTrueorder(self, ast_node, parent_pos):
Georg Brandl0c77a822008-06-10 16:37:50 +0000258 if not isinstance(ast_node, ast.AST) or ast_node._fields is None:
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000259 return
Georg Brandl0c77a822008-06-10 16:37:50 +0000260 if isinstance(ast_node, (ast.expr, ast.stmt, ast.excepthandler)):
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000261 node_pos = (ast_node.lineno, ast_node.col_offset)
Serhiy Storchaka95b6acf2018-10-30 13:16:02 +0200262 self.assertGreaterEqual(node_pos, parent_pos)
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000263 parent_pos = (ast_node.lineno, ast_node.col_offset)
264 for name in ast_node._fields:
265 value = getattr(ast_node, name)
266 if isinstance(value, list):
Serhiy Storchaka95b6acf2018-10-30 13:16:02 +0200267 first_pos = parent_pos
268 if value and name == 'decorator_list':
269 first_pos = (value[0].lineno, value[0].col_offset)
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000270 for child in value:
Serhiy Storchaka95b6acf2018-10-30 13:16:02 +0200271 self._assertTrueorder(child, first_pos)
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000272 elif value is not None:
Benjamin Peterson7a66fc22015-02-02 10:51:20 -0500273 self._assertTrueorder(value, parent_pos)
Tim Peters5ddfe412006-03-01 23:02:57 +0000274
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500275 def test_AST_objects(self):
276 x = ast.AST()
277 self.assertEqual(x._fields, ())
Benjamin Peterson7e0dbfb2012-03-12 09:46:44 -0700278 x.foobar = 42
279 self.assertEqual(x.foobar, 42)
280 self.assertEqual(x.__dict__["foobar"], 42)
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500281
282 with self.assertRaises(AttributeError):
283 x.vararg
284
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500285 with self.assertRaises(TypeError):
286 # "_ast.AST constructor takes 0 positional arguments"
287 ast.AST(2)
288
Benjamin Peterson9ed37432012-07-08 11:13:36 -0700289 def test_AST_garbage_collection(self):
290 class X:
291 pass
292 a = ast.AST()
293 a.x = X()
294 a.x.a = a
295 ref = weakref.ref(a.x)
296 del a
297 support.gc_collect()
298 self.assertIsNone(ref())
299
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000300 def test_snippets(self):
301 for input, output, kind in ((exec_tests, exec_results, "exec"),
302 (single_tests, single_results, "single"),
303 (eval_tests, eval_results, "eval")):
304 for i, o in zip(input, output):
Yury Selivanovb3d53132015-09-01 16:10:49 -0400305 with self.subTest(action="parsing", input=i):
306 ast_tree = compile(i, "?", kind, ast.PyCF_ONLY_AST)
307 self.assertEqual(to_tuple(ast_tree), o)
308 self._assertTrueorder(ast_tree, (0, 0))
Victor Stinner15a30952016-02-08 22:45:06 +0100309 with self.subTest(action="compiling", input=i, kind=kind):
310 compile(ast_tree, "?", kind)
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000311
Pablo Galindo0c9258a2019-03-18 13:51:53 +0000312 def test_ast_validation(self):
313 # compile() is the only function that calls PyAST_Validate
314 snippets_to_validate = exec_tests + single_tests + eval_tests
315 for snippet in snippets_to_validate:
316 tree = ast.parse(snippet)
317 compile(tree, '<string>', 'exec')
318
Benjamin Peterson78565b22009-06-28 19:19:51 +0000319 def test_slice(self):
320 slc = ast.parse("x[::]").body[0].value.slice
321 self.assertIsNone(slc.upper)
322 self.assertIsNone(slc.lower)
323 self.assertIsNone(slc.step)
324
325 def test_from_import(self):
326 im = ast.parse("from . import y").body[0]
327 self.assertIsNone(im.module)
328
Benjamin Petersona4e4e352012-03-22 08:19:04 -0400329 def test_non_interned_future_from_ast(self):
330 mod = ast.parse("from __future__ import division")
331 self.assertIsInstance(mod.body[0], ast.ImportFrom)
332 mod.body[0].module = " __future__ ".strip()
333 compile(mod, "<test>", "exec")
334
Benjamin Petersona0dfa822009-11-13 02:25:08 +0000335 def test_base_classes(self):
336 self.assertTrue(issubclass(ast.For, ast.stmt))
337 self.assertTrue(issubclass(ast.Name, ast.expr))
338 self.assertTrue(issubclass(ast.stmt, ast.AST))
339 self.assertTrue(issubclass(ast.expr, ast.AST))
340 self.assertTrue(issubclass(ast.comprehension, ast.AST))
341 self.assertTrue(issubclass(ast.Gt, ast.AST))
342
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500343 def test_field_attr_existence(self):
344 for name, item in ast.__dict__.items():
Batuhan TaĹźkaya397b96f2020-03-01 23:12:17 +0300345 if self._is_ast_node(name, item):
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500346 x = item()
347 if isinstance(x, ast.AST):
348 self.assertEqual(type(x._fields), tuple)
349
350 def test_arguments(self):
351 x = ast.arguments()
Pablo Galindocd6e83b2019-07-15 01:32:18 +0200352 self.assertEqual(x._fields, ('posonlyargs', 'args', 'vararg', 'kwonlyargs',
353 'kw_defaults', 'kwarg', 'defaults'))
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500354
355 with self.assertRaises(AttributeError):
356 x.vararg
357
Pablo Galindo8c77b8c2019-04-29 13:36:57 +0100358 x = ast.arguments(*range(1, 8))
359 self.assertEqual(x.vararg, 3)
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500360
361 def test_field_attr_writable(self):
362 x = ast.Num()
363 # We can assign to _fields
364 x._fields = 666
365 self.assertEqual(x._fields, 666)
366
367 def test_classattrs(self):
368 x = ast.Num()
Guido van Rossum10f8ce62019-03-13 13:00:46 -0700369 self.assertEqual(x._fields, ('value', 'kind'))
Serhiy Storchaka3f228112018-09-27 17:42:37 +0300370
371 with self.assertRaises(AttributeError):
372 x.value
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500373
374 with self.assertRaises(AttributeError):
375 x.n
376
377 x = ast.Num(42)
Serhiy Storchaka3f228112018-09-27 17:42:37 +0300378 self.assertEqual(x.value, 42)
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500379 self.assertEqual(x.n, 42)
380
381 with self.assertRaises(AttributeError):
382 x.lineno
383
384 with self.assertRaises(AttributeError):
385 x.foobar
386
387 x = ast.Num(lineno=2)
388 self.assertEqual(x.lineno, 2)
389
390 x = ast.Num(42, lineno=0)
391 self.assertEqual(x.lineno, 0)
Guido van Rossum10f8ce62019-03-13 13:00:46 -0700392 self.assertEqual(x._fields, ('value', 'kind'))
Serhiy Storchaka3f228112018-09-27 17:42:37 +0300393 self.assertEqual(x.value, 42)
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500394 self.assertEqual(x.n, 42)
395
Guido van Rossum10f8ce62019-03-13 13:00:46 -0700396 self.assertRaises(TypeError, ast.Num, 1, None, 2)
397 self.assertRaises(TypeError, ast.Num, 1, None, 2, lineno=0)
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500398
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
Min ho Kimc4cacc82019-07-31 08:16:13 +1000572 def test_invalid_identifier(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
Carl Friedrich Bolz-Tereick110a47c2019-07-08 23:17:56 +0200597 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)
Carl Friedrich Bolz-Tereick430a9f42019-07-09 14:20:01 +0200619 self.assertEqual(child_binop.lineno, 1)
Carl Friedrich Bolz-Tereick110a47c2019-07-08 23:17:56 +0200620 self.assertEqual(child_binop.end_col_offset, 2)
Carl Friedrich Bolz-Tereick430a9f42019-07-09 14:20:01 +0200621 self.assertEqual(child_binop.end_lineno, 2)
Carl Friedrich Bolz-Tereick110a47c2019-07-08 23:17:56 +0200622
623 self.assertEqual(grandchild_binop.col_offset, 0)
Carl Friedrich Bolz-Tereick430a9f42019-07-09 14:20:01 +0200624 self.assertEqual(grandchild_binop.lineno, 1)
Carl Friedrich Bolz-Tereick110a47c2019-07-08 23:17:56 +0200625 self.assertEqual(grandchild_binop.end_col_offset, 3)
Carl Friedrich Bolz-Tereick430a9f42019-07-09 14:20:01 +0200626 self.assertEqual(grandchild_binop.end_lineno, 1)
Georg Brandl0c77a822008-06-10 16:37:50 +0000627
Lysandros Nikolaoud2e10982020-02-08 00:36:32 +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 Storchaka850573b2019-09-09 19:33:13 +0300670 def test_dump_indent(self):
671 node = ast.parse('spam(eggs, "and cheese")')
672 self.assertEqual(ast.dump(node, indent=3), """\
673Module(
674 body=[
675 Expr(
676 value=Call(
677 func=Name(id='spam', ctx=Load()),
678 args=[
679 Name(id='eggs', ctx=Load()),
680 Constant(value='and cheese', kind=None)],
681 keywords=[]))],
682 type_ignores=[])""")
683 self.assertEqual(ast.dump(node, annotate_fields=False, indent='\t'), """\
684Module(
685\t[
686\t\tExpr(
687\t\t\tCall(
688\t\t\t\tName('spam', Load()),
689\t\t\t\t[
690\t\t\t\t\tName('eggs', Load()),
691\t\t\t\t\tConstant('and cheese', None)],
692\t\t\t\t[]))],
693\t[])""")
694 self.assertEqual(ast.dump(node, include_attributes=True, indent=3), """\
695Module(
696 body=[
697 Expr(
698 value=Call(
699 func=Name(
700 id='spam',
701 ctx=Load(),
702 lineno=1,
703 col_offset=0,
704 end_lineno=1,
705 end_col_offset=4),
706 args=[
707 Name(
708 id='eggs',
709 ctx=Load(),
710 lineno=1,
711 col_offset=5,
712 end_lineno=1,
713 end_col_offset=9),
714 Constant(
715 value='and cheese',
716 kind=None,
717 lineno=1,
718 col_offset=11,
719 end_lineno=1,
720 end_col_offset=23)],
721 keywords=[],
722 lineno=1,
723 col_offset=0,
724 end_lineno=1,
725 end_col_offset=24),
726 lineno=1,
727 col_offset=0,
728 end_lineno=1,
729 end_col_offset=24)],
730 type_ignores=[])""")
731
Serhiy Storchakae64f9482019-08-29 09:30:23 +0300732 def test_dump_incomplete(self):
733 node = ast.Raise(lineno=3, col_offset=4)
734 self.assertEqual(ast.dump(node),
735 "Raise()"
736 )
737 self.assertEqual(ast.dump(node, include_attributes=True),
738 "Raise(lineno=3, col_offset=4)"
739 )
740 node = ast.Raise(exc=ast.Name(id='e', ctx=ast.Load()), lineno=3, col_offset=4)
741 self.assertEqual(ast.dump(node),
742 "Raise(exc=Name(id='e', ctx=Load()))"
743 )
744 self.assertEqual(ast.dump(node, annotate_fields=False),
745 "Raise(Name('e', Load()))"
746 )
747 self.assertEqual(ast.dump(node, include_attributes=True),
748 "Raise(exc=Name(id='e', ctx=Load()), lineno=3, col_offset=4)"
749 )
750 self.assertEqual(ast.dump(node, annotate_fields=False, include_attributes=True),
751 "Raise(Name('e', Load()), lineno=3, col_offset=4)"
752 )
753 node = ast.Raise(cause=ast.Name(id='e', ctx=ast.Load()))
754 self.assertEqual(ast.dump(node),
755 "Raise(cause=Name(id='e', ctx=Load()))"
756 )
757 self.assertEqual(ast.dump(node, annotate_fields=False),
758 "Raise(cause=Name('e', Load()))"
759 )
760
Georg Brandl0c77a822008-06-10 16:37:50 +0000761 def test_copy_location(self):
762 src = ast.parse('1 + 1', mode='eval')
763 src.body.right = ast.copy_location(ast.Num(2), src.body.right)
764 self.assertEqual(ast.dump(src, include_attributes=True),
Guido van Rossum10f8ce62019-03-13 13:00:46 -0700765 'Expression(body=BinOp(left=Constant(value=1, kind=None, lineno=1, col_offset=0, '
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000766 'end_lineno=1, end_col_offset=1), op=Add(), right=Constant(value=2, '
767 'lineno=1, col_offset=4, end_lineno=1, end_col_offset=5), lineno=1, '
768 'col_offset=0, end_lineno=1, end_col_offset=5))'
Georg Brandl0c77a822008-06-10 16:37:50 +0000769 )
770
771 def test_fix_missing_locations(self):
772 src = ast.parse('write("spam")')
773 src.body.append(ast.Expr(ast.Call(ast.Name('spam', ast.Load()),
Benjamin Peterson025e9eb2015-05-05 20:16:41 -0400774 [ast.Str('eggs')], [])))
Georg Brandl0c77a822008-06-10 16:37:50 +0000775 self.assertEqual(src, ast.fix_missing_locations(src))
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000776 self.maxDiff = None
Georg Brandl0c77a822008-06-10 16:37:50 +0000777 self.assertEqual(ast.dump(src, include_attributes=True),
778 "Module(body=[Expr(value=Call(func=Name(id='write', ctx=Load(), "
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000779 "lineno=1, col_offset=0, end_lineno=1, end_col_offset=5), "
Guido van Rossum10f8ce62019-03-13 13:00:46 -0700780 "args=[Constant(value='spam', kind=None, lineno=1, col_offset=6, end_lineno=1, "
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000781 "end_col_offset=12)], keywords=[], lineno=1, col_offset=0, end_lineno=1, "
782 "end_col_offset=13), lineno=1, col_offset=0, end_lineno=1, "
783 "end_col_offset=13), Expr(value=Call(func=Name(id='spam', ctx=Load(), "
784 "lineno=1, col_offset=0, end_lineno=1, end_col_offset=0), "
785 "args=[Constant(value='eggs', lineno=1, col_offset=0, end_lineno=1, "
786 "end_col_offset=0)], keywords=[], lineno=1, col_offset=0, end_lineno=1, "
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800787 "end_col_offset=0), lineno=1, col_offset=0, end_lineno=1, end_col_offset=0)], "
788 "type_ignores=[])"
Georg Brandl0c77a822008-06-10 16:37:50 +0000789 )
790
791 def test_increment_lineno(self):
792 src = ast.parse('1 + 1', mode='eval')
793 self.assertEqual(ast.increment_lineno(src, n=3), src)
794 self.assertEqual(ast.dump(src, include_attributes=True),
Guido van Rossum10f8ce62019-03-13 13:00:46 -0700795 'Expression(body=BinOp(left=Constant(value=1, kind=None, lineno=4, col_offset=0, '
796 'end_lineno=4, end_col_offset=1), op=Add(), right=Constant(value=1, kind=None, '
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000797 'lineno=4, col_offset=4, end_lineno=4, end_col_offset=5), lineno=4, '
798 'col_offset=0, end_lineno=4, end_col_offset=5))'
Georg Brandl0c77a822008-06-10 16:37:50 +0000799 )
Georg Brandl619e7ba2011-01-09 07:38:51 +0000800 # issue10869: do not increment lineno of root twice
Georg Brandlefb69022011-01-09 07:50:48 +0000801 src = ast.parse('1 + 1', mode='eval')
Georg Brandl619e7ba2011-01-09 07:38:51 +0000802 self.assertEqual(ast.increment_lineno(src.body, n=3), src.body)
803 self.assertEqual(ast.dump(src, include_attributes=True),
Guido van Rossum10f8ce62019-03-13 13:00:46 -0700804 'Expression(body=BinOp(left=Constant(value=1, kind=None, lineno=4, col_offset=0, '
805 'end_lineno=4, end_col_offset=1), op=Add(), right=Constant(value=1, kind=None, '
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000806 'lineno=4, col_offset=4, end_lineno=4, end_col_offset=5), lineno=4, '
807 'col_offset=0, end_lineno=4, end_col_offset=5))'
Georg Brandl619e7ba2011-01-09 07:38:51 +0000808 )
Georg Brandl0c77a822008-06-10 16:37:50 +0000809
810 def test_iter_fields(self):
811 node = ast.parse('foo()', mode='eval')
812 d = dict(ast.iter_fields(node.body))
813 self.assertEqual(d.pop('func').id, 'foo')
Benjamin Peterson025e9eb2015-05-05 20:16:41 -0400814 self.assertEqual(d, {'keywords': [], 'args': []})
Georg Brandl0c77a822008-06-10 16:37:50 +0000815
816 def test_iter_child_nodes(self):
817 node = ast.parse("spam(23, 42, eggs='leek')", mode='eval')
818 self.assertEqual(len(list(ast.iter_child_nodes(node.body))), 4)
819 iterator = ast.iter_child_nodes(node.body)
820 self.assertEqual(next(iterator).id, 'spam')
Serhiy Storchaka3f228112018-09-27 17:42:37 +0300821 self.assertEqual(next(iterator).value, 23)
822 self.assertEqual(next(iterator).value, 42)
Georg Brandl0c77a822008-06-10 16:37:50 +0000823 self.assertEqual(ast.dump(next(iterator)),
Guido van Rossum10f8ce62019-03-13 13:00:46 -0700824 "keyword(arg='eggs', value=Constant(value='leek', kind=None))"
Georg Brandl0c77a822008-06-10 16:37:50 +0000825 )
826
827 def test_get_docstring(self):
Serhiy Storchaka08f127a2018-06-15 11:05:15 +0300828 node = ast.parse('"""line one\n line two"""')
829 self.assertEqual(ast.get_docstring(node),
830 'line one\nline two')
831
832 node = ast.parse('class foo:\n """line one\n line two"""')
833 self.assertEqual(ast.get_docstring(node.body[0]),
834 'line one\nline two')
835
Georg Brandl0c77a822008-06-10 16:37:50 +0000836 node = ast.parse('def foo():\n """line one\n line two"""')
837 self.assertEqual(ast.get_docstring(node.body[0]),
838 'line one\nline two')
839
Yury Selivanov2f07a662015-07-23 08:54:35 +0300840 node = ast.parse('async def foo():\n """spam\n ham"""')
841 self.assertEqual(ast.get_docstring(node.body[0]), 'spam\nham')
Serhiy Storchaka08f127a2018-06-15 11:05:15 +0300842
843 def test_get_docstring_none(self):
Matthias Bussonnier41cea702017-02-23 22:44:19 -0800844 self.assertIsNone(ast.get_docstring(ast.parse('')))
Serhiy Storchaka08f127a2018-06-15 11:05:15 +0300845 node = ast.parse('x = "not docstring"')
846 self.assertIsNone(ast.get_docstring(node))
847 node = ast.parse('def foo():\n pass')
848 self.assertIsNone(ast.get_docstring(node))
849
850 node = ast.parse('class foo:\n pass')
851 self.assertIsNone(ast.get_docstring(node.body[0]))
852 node = ast.parse('class foo:\n x = "not docstring"')
853 self.assertIsNone(ast.get_docstring(node.body[0]))
854 node = ast.parse('class foo:\n def bar(self): pass')
855 self.assertIsNone(ast.get_docstring(node.body[0]))
856
857 node = ast.parse('def foo():\n pass')
858 self.assertIsNone(ast.get_docstring(node.body[0]))
859 node = ast.parse('def foo():\n x = "not docstring"')
860 self.assertIsNone(ast.get_docstring(node.body[0]))
861
862 node = ast.parse('async def foo():\n pass')
863 self.assertIsNone(ast.get_docstring(node.body[0]))
864 node = ast.parse('async def foo():\n x = "not docstring"')
865 self.assertIsNone(ast.get_docstring(node.body[0]))
Yury Selivanov2f07a662015-07-23 08:54:35 +0300866
Anthony Sottile995d9b92019-01-12 20:05:13 -0800867 def test_multi_line_docstring_col_offset_and_lineno_issue16806(self):
868 node = ast.parse(
869 '"""line one\nline two"""\n\n'
870 'def foo():\n """line one\n line two"""\n\n'
871 ' def bar():\n """line one\n line two"""\n'
872 ' """line one\n line two"""\n'
873 '"""line one\nline two"""\n\n'
874 )
875 self.assertEqual(node.body[0].col_offset, 0)
876 self.assertEqual(node.body[0].lineno, 1)
877 self.assertEqual(node.body[1].body[0].col_offset, 2)
878 self.assertEqual(node.body[1].body[0].lineno, 5)
879 self.assertEqual(node.body[1].body[1].body[0].col_offset, 4)
880 self.assertEqual(node.body[1].body[1].body[0].lineno, 9)
881 self.assertEqual(node.body[1].body[2].col_offset, 2)
882 self.assertEqual(node.body[1].body[2].lineno, 11)
883 self.assertEqual(node.body[2].col_offset, 0)
884 self.assertEqual(node.body[2].lineno, 13)
885
Lysandros Nikolaou025a6022019-12-12 22:40:21 +0100886 def test_elif_stmt_start_position(self):
887 node = ast.parse('if a:\n pass\nelif b:\n pass\n')
888 elif_stmt = node.body[0].orelse[0]
889 self.assertEqual(elif_stmt.lineno, 3)
890 self.assertEqual(elif_stmt.col_offset, 0)
891
Lysandros Nikolaou5936a4c2019-12-14 11:24:57 +0100892 def test_elif_stmt_start_position_with_else(self):
893 node = ast.parse('if a:\n pass\nelif b:\n pass\nelse:\n pass\n')
894 elif_stmt = node.body[0].orelse[0]
895 self.assertEqual(elif_stmt.lineno, 3)
896 self.assertEqual(elif_stmt.col_offset, 0)
897
Lysandros Nikolaou50d4f122019-12-18 01:20:55 +0100898 def test_starred_expr_end_position_within_call(self):
899 node = ast.parse('f(*[0, 1])')
900 starred_expr = node.body[0].value.args[0]
901 self.assertEqual(starred_expr.end_lineno, 1)
902 self.assertEqual(starred_expr.end_col_offset, 9)
903
Georg Brandl0c77a822008-06-10 16:37:50 +0000904 def test_literal_eval(self):
905 self.assertEqual(ast.literal_eval('[1, 2, 3]'), [1, 2, 3])
906 self.assertEqual(ast.literal_eval('{"foo": 42}'), {"foo": 42})
907 self.assertEqual(ast.literal_eval('(True, False, None)'), (True, False, None))
Benjamin Peterson3e742892010-07-11 12:59:24 +0000908 self.assertEqual(ast.literal_eval('{1, 2, 3}'), {1, 2, 3})
Benjamin Peterson5ef96e52010-07-11 23:06:06 +0000909 self.assertEqual(ast.literal_eval('b"hi"'), b"hi")
Raymond Hettinger4fcf5c12020-01-02 22:21:18 -0700910 self.assertEqual(ast.literal_eval('set()'), set())
Georg Brandl0c77a822008-06-10 16:37:50 +0000911 self.assertRaises(ValueError, ast.literal_eval, 'foo()')
Serhiy Storchakad8ac4d12018-01-04 11:15:39 +0200912 self.assertEqual(ast.literal_eval('6'), 6)
913 self.assertEqual(ast.literal_eval('+6'), 6)
Raymond Hettingerbc959732010-10-08 00:47:45 +0000914 self.assertEqual(ast.literal_eval('-6'), -6)
Raymond Hettingerbc959732010-10-08 00:47:45 +0000915 self.assertEqual(ast.literal_eval('3.25'), 3.25)
Serhiy Storchakad8ac4d12018-01-04 11:15:39 +0200916 self.assertEqual(ast.literal_eval('+3.25'), 3.25)
917 self.assertEqual(ast.literal_eval('-3.25'), -3.25)
918 self.assertEqual(repr(ast.literal_eval('-0.0')), '-0.0')
919 self.assertRaises(ValueError, ast.literal_eval, '++6')
920 self.assertRaises(ValueError, ast.literal_eval, '+True')
921 self.assertRaises(ValueError, ast.literal_eval, '2+3')
Georg Brandl0c77a822008-06-10 16:37:50 +0000922
Serhiy Storchakad8ac4d12018-01-04 11:15:39 +0200923 def test_literal_eval_complex(self):
924 # Issue #4907
925 self.assertEqual(ast.literal_eval('6j'), 6j)
926 self.assertEqual(ast.literal_eval('-6j'), -6j)
927 self.assertEqual(ast.literal_eval('6.75j'), 6.75j)
928 self.assertEqual(ast.literal_eval('-6.75j'), -6.75j)
929 self.assertEqual(ast.literal_eval('3+6j'), 3+6j)
930 self.assertEqual(ast.literal_eval('-3+6j'), -3+6j)
931 self.assertEqual(ast.literal_eval('3-6j'), 3-6j)
932 self.assertEqual(ast.literal_eval('-3-6j'), -3-6j)
933 self.assertEqual(ast.literal_eval('3.25+6.75j'), 3.25+6.75j)
934 self.assertEqual(ast.literal_eval('-3.25+6.75j'), -3.25+6.75j)
935 self.assertEqual(ast.literal_eval('3.25-6.75j'), 3.25-6.75j)
936 self.assertEqual(ast.literal_eval('-3.25-6.75j'), -3.25-6.75j)
937 self.assertEqual(ast.literal_eval('(3+6j)'), 3+6j)
938 self.assertRaises(ValueError, ast.literal_eval, '-6j+3')
939 self.assertRaises(ValueError, ast.literal_eval, '-6j+3j')
940 self.assertRaises(ValueError, ast.literal_eval, '3+-6j')
941 self.assertRaises(ValueError, ast.literal_eval, '3+(0+6j)')
942 self.assertRaises(ValueError, ast.literal_eval, '-(3+6j)')
Benjamin Peterson058e31e2009-01-16 03:54:08 +0000943
Amaury Forgeot d'Arc58e87612011-11-22 21:51:55 +0100944 def test_bad_integer(self):
945 # issue13436: Bad error message with invalid numeric values
946 body = [ast.ImportFrom(module='time',
947 names=[ast.alias(name='sleep')],
948 level=None,
949 lineno=None, col_offset=None)]
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800950 mod = ast.Module(body, [])
Amaury Forgeot d'Arc58e87612011-11-22 21:51:55 +0100951 with self.assertRaises(ValueError) as cm:
952 compile(mod, 'test', 'exec')
953 self.assertIn("invalid integer value: None", str(cm.exception))
954
Berker Peksag0a5bd512016-04-29 19:50:02 +0300955 def test_level_as_none(self):
956 body = [ast.ImportFrom(module='time',
957 names=[ast.alias(name='sleep')],
958 level=None,
959 lineno=0, col_offset=0)]
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800960 mod = ast.Module(body, [])
Berker Peksag0a5bd512016-04-29 19:50:02 +0300961 code = compile(mod, 'test', 'exec')
962 ns = {}
963 exec(code, ns)
964 self.assertIn('sleep', ns)
965
Georg Brandl0c77a822008-06-10 16:37:50 +0000966
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500967class ASTValidatorTests(unittest.TestCase):
968
969 def mod(self, mod, msg=None, mode="exec", *, exc=ValueError):
970 mod.lineno = mod.col_offset = 0
971 ast.fix_missing_locations(mod)
Serhiy Storchaka3f228112018-09-27 17:42:37 +0300972 if msg is None:
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500973 compile(mod, "<test>", mode)
Serhiy Storchaka3f228112018-09-27 17:42:37 +0300974 else:
975 with self.assertRaises(exc) as cm:
976 compile(mod, "<test>", mode)
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500977 self.assertIn(msg, str(cm.exception))
978
979 def expr(self, node, msg=None, *, exc=ValueError):
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800980 mod = ast.Module([ast.Expr(node)], [])
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500981 self.mod(mod, msg, exc=exc)
982
983 def stmt(self, stmt, msg=None):
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800984 mod = ast.Module([stmt], [])
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500985 self.mod(mod, msg)
986
987 def test_module(self):
988 m = ast.Interactive([ast.Expr(ast.Name("x", ast.Store()))])
989 self.mod(m, "must have Load context", "single")
990 m = ast.Expression(ast.Name("x", ast.Store()))
991 self.mod(m, "must have Load context", "eval")
992
993 def _check_arguments(self, fac, check):
Pablo Galindo8c77b8c2019-04-29 13:36:57 +0100994 def arguments(args=None, posonlyargs=None, vararg=None,
Benjamin Petersoncda75be2013-03-18 10:48:58 -0700995 kwonlyargs=None, kwarg=None,
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500996 defaults=None, kw_defaults=None):
997 if args is None:
998 args = []
Pablo Galindo8c77b8c2019-04-29 13:36:57 +0100999 if posonlyargs is None:
1000 posonlyargs = []
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001001 if kwonlyargs is None:
1002 kwonlyargs = []
1003 if defaults is None:
1004 defaults = []
1005 if kw_defaults is None:
1006 kw_defaults = []
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01001007 args = ast.arguments(args, posonlyargs, vararg, kwonlyargs,
1008 kw_defaults, kwarg, defaults)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001009 return fac(args)
1010 args = [ast.arg("x", ast.Name("x", ast.Store()))]
1011 check(arguments(args=args), "must have Load context")
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01001012 check(arguments(posonlyargs=args), "must have Load context")
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001013 check(arguments(kwonlyargs=args), "must have Load context")
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001014 check(arguments(defaults=[ast.Num(3)]),
1015 "more positional defaults than args")
1016 check(arguments(kw_defaults=[ast.Num(4)]),
1017 "length of kwonlyargs is not the same as kw_defaults")
1018 args = [ast.arg("x", ast.Name("x", ast.Load()))]
1019 check(arguments(args=args, defaults=[ast.Name("x", ast.Store())]),
1020 "must have Load context")
1021 args = [ast.arg("a", ast.Name("x", ast.Load())),
1022 ast.arg("b", ast.Name("y", ast.Load()))]
1023 check(arguments(kwonlyargs=args,
1024 kw_defaults=[None, ast.Name("x", ast.Store())]),
1025 "must have Load context")
1026
1027 def test_funcdef(self):
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01001028 a = ast.arguments([], [], None, [], [], None, [])
Serhiy Storchaka73cbe7a2018-05-29 12:04:55 +03001029 f = ast.FunctionDef("x", a, [], [], None)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001030 self.stmt(f, "empty body on FunctionDef")
1031 f = ast.FunctionDef("x", a, [ast.Pass()], [ast.Name("x", ast.Store())],
Serhiy Storchaka73cbe7a2018-05-29 12:04:55 +03001032 None)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001033 self.stmt(f, "must have Load context")
1034 f = ast.FunctionDef("x", a, [ast.Pass()], [],
Serhiy Storchaka73cbe7a2018-05-29 12:04:55 +03001035 ast.Name("x", ast.Store()))
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001036 self.stmt(f, "must have Load context")
1037 def fac(args):
Serhiy Storchaka73cbe7a2018-05-29 12:04:55 +03001038 return ast.FunctionDef("x", args, [ast.Pass()], [], None)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001039 self._check_arguments(fac, self.stmt)
1040
1041 def test_classdef(self):
Benjamin Peterson025e9eb2015-05-05 20:16:41 -04001042 def cls(bases=None, keywords=None, body=None, decorator_list=None):
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001043 if bases is None:
1044 bases = []
1045 if keywords is None:
1046 keywords = []
1047 if body is None:
1048 body = [ast.Pass()]
1049 if decorator_list is None:
1050 decorator_list = []
Benjamin Peterson025e9eb2015-05-05 20:16:41 -04001051 return ast.ClassDef("myclass", bases, keywords,
Serhiy Storchaka73cbe7a2018-05-29 12:04:55 +03001052 body, decorator_list)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001053 self.stmt(cls(bases=[ast.Name("x", ast.Store())]),
1054 "must have Load context")
1055 self.stmt(cls(keywords=[ast.keyword("x", ast.Name("x", ast.Store()))]),
1056 "must have Load context")
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001057 self.stmt(cls(body=[]), "empty body on ClassDef")
1058 self.stmt(cls(body=[None]), "None disallowed")
1059 self.stmt(cls(decorator_list=[ast.Name("x", ast.Store())]),
1060 "must have Load context")
1061
1062 def test_delete(self):
1063 self.stmt(ast.Delete([]), "empty targets on Delete")
1064 self.stmt(ast.Delete([None]), "None disallowed")
1065 self.stmt(ast.Delete([ast.Name("x", ast.Load())]),
1066 "must have Del context")
1067
1068 def test_assign(self):
1069 self.stmt(ast.Assign([], ast.Num(3)), "empty targets on Assign")
1070 self.stmt(ast.Assign([None], ast.Num(3)), "None disallowed")
1071 self.stmt(ast.Assign([ast.Name("x", ast.Load())], ast.Num(3)),
1072 "must have Store context")
1073 self.stmt(ast.Assign([ast.Name("x", ast.Store())],
1074 ast.Name("y", ast.Store())),
1075 "must have Load context")
1076
1077 def test_augassign(self):
1078 aug = ast.AugAssign(ast.Name("x", ast.Load()), ast.Add(),
1079 ast.Name("y", ast.Load()))
1080 self.stmt(aug, "must have Store context")
1081 aug = ast.AugAssign(ast.Name("x", ast.Store()), ast.Add(),
1082 ast.Name("y", ast.Store()))
1083 self.stmt(aug, "must have Load context")
1084
1085 def test_for(self):
1086 x = ast.Name("x", ast.Store())
1087 y = ast.Name("y", ast.Load())
1088 p = ast.Pass()
1089 self.stmt(ast.For(x, y, [], []), "empty body on For")
1090 self.stmt(ast.For(ast.Name("x", ast.Load()), y, [p], []),
1091 "must have Store context")
1092 self.stmt(ast.For(x, ast.Name("y", ast.Store()), [p], []),
1093 "must have Load context")
1094 e = ast.Expr(ast.Name("x", ast.Store()))
1095 self.stmt(ast.For(x, y, [e], []), "must have Load context")
1096 self.stmt(ast.For(x, y, [p], [e]), "must have Load context")
1097
1098 def test_while(self):
1099 self.stmt(ast.While(ast.Num(3), [], []), "empty body on While")
1100 self.stmt(ast.While(ast.Name("x", ast.Store()), [ast.Pass()], []),
1101 "must have Load context")
1102 self.stmt(ast.While(ast.Num(3), [ast.Pass()],
1103 [ast.Expr(ast.Name("x", ast.Store()))]),
1104 "must have Load context")
1105
1106 def test_if(self):
1107 self.stmt(ast.If(ast.Num(3), [], []), "empty body on If")
1108 i = ast.If(ast.Name("x", ast.Store()), [ast.Pass()], [])
1109 self.stmt(i, "must have Load context")
1110 i = ast.If(ast.Num(3), [ast.Expr(ast.Name("x", ast.Store()))], [])
1111 self.stmt(i, "must have Load context")
1112 i = ast.If(ast.Num(3), [ast.Pass()],
1113 [ast.Expr(ast.Name("x", ast.Store()))])
1114 self.stmt(i, "must have Load context")
1115
1116 def test_with(self):
1117 p = ast.Pass()
1118 self.stmt(ast.With([], [p]), "empty items on With")
1119 i = ast.withitem(ast.Num(3), None)
1120 self.stmt(ast.With([i], []), "empty body on With")
1121 i = ast.withitem(ast.Name("x", ast.Store()), None)
1122 self.stmt(ast.With([i], [p]), "must have Load context")
1123 i = ast.withitem(ast.Num(3), ast.Name("x", ast.Load()))
1124 self.stmt(ast.With([i], [p]), "must have Store context")
1125
1126 def test_raise(self):
1127 r = ast.Raise(None, ast.Num(3))
1128 self.stmt(r, "Raise with cause but no exception")
1129 r = ast.Raise(ast.Name("x", ast.Store()), None)
1130 self.stmt(r, "must have Load context")
1131 r = ast.Raise(ast.Num(4), ast.Name("x", ast.Store()))
1132 self.stmt(r, "must have Load context")
1133
1134 def test_try(self):
1135 p = ast.Pass()
1136 t = ast.Try([], [], [], [p])
1137 self.stmt(t, "empty body on Try")
1138 t = ast.Try([ast.Expr(ast.Name("x", ast.Store()))], [], [], [p])
1139 self.stmt(t, "must have Load context")
1140 t = ast.Try([p], [], [], [])
1141 self.stmt(t, "Try has neither except handlers nor finalbody")
1142 t = ast.Try([p], [], [p], [p])
1143 self.stmt(t, "Try has orelse but no except handlers")
1144 t = ast.Try([p], [ast.ExceptHandler(None, "x", [])], [], [])
1145 self.stmt(t, "empty body on ExceptHandler")
1146 e = [ast.ExceptHandler(ast.Name("x", ast.Store()), "y", [p])]
1147 self.stmt(ast.Try([p], e, [], []), "must have Load context")
1148 e = [ast.ExceptHandler(None, "x", [p])]
1149 t = ast.Try([p], e, [ast.Expr(ast.Name("x", ast.Store()))], [p])
1150 self.stmt(t, "must have Load context")
1151 t = ast.Try([p], e, [p], [ast.Expr(ast.Name("x", ast.Store()))])
1152 self.stmt(t, "must have Load context")
1153
1154 def test_assert(self):
1155 self.stmt(ast.Assert(ast.Name("x", ast.Store()), None),
1156 "must have Load context")
1157 assrt = ast.Assert(ast.Name("x", ast.Load()),
1158 ast.Name("y", ast.Store()))
1159 self.stmt(assrt, "must have Load context")
1160
1161 def test_import(self):
1162 self.stmt(ast.Import([]), "empty names on Import")
1163
1164 def test_importfrom(self):
1165 imp = ast.ImportFrom(None, [ast.alias("x", None)], -42)
Serhiy Storchaka7de28402016-06-27 23:40:43 +03001166 self.stmt(imp, "Negative ImportFrom level")
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001167 self.stmt(ast.ImportFrom(None, [], 0), "empty names on ImportFrom")
1168
1169 def test_global(self):
1170 self.stmt(ast.Global([]), "empty names on Global")
1171
1172 def test_nonlocal(self):
1173 self.stmt(ast.Nonlocal([]), "empty names on Nonlocal")
1174
1175 def test_expr(self):
1176 e = ast.Expr(ast.Name("x", ast.Store()))
1177 self.stmt(e, "must have Load context")
1178
1179 def test_boolop(self):
1180 b = ast.BoolOp(ast.And(), [])
1181 self.expr(b, "less than 2 values")
1182 b = ast.BoolOp(ast.And(), [ast.Num(3)])
1183 self.expr(b, "less than 2 values")
1184 b = ast.BoolOp(ast.And(), [ast.Num(4), None])
1185 self.expr(b, "None disallowed")
1186 b = ast.BoolOp(ast.And(), [ast.Num(4), ast.Name("x", ast.Store())])
1187 self.expr(b, "must have Load context")
1188
1189 def test_unaryop(self):
1190 u = ast.UnaryOp(ast.Not(), ast.Name("x", ast.Store()))
1191 self.expr(u, "must have Load context")
1192
1193 def test_lambda(self):
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01001194 a = ast.arguments([], [], None, [], [], None, [])
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001195 self.expr(ast.Lambda(a, ast.Name("x", ast.Store())),
1196 "must have Load context")
1197 def fac(args):
1198 return ast.Lambda(args, ast.Name("x", ast.Load()))
1199 self._check_arguments(fac, self.expr)
1200
1201 def test_ifexp(self):
1202 l = ast.Name("x", ast.Load())
1203 s = ast.Name("y", ast.Store())
1204 for args in (s, l, l), (l, s, l), (l, l, s):
Benjamin Peterson71ce8972011-08-09 16:17:12 -05001205 self.expr(ast.IfExp(*args), "must have Load context")
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001206
1207 def test_dict(self):
1208 d = ast.Dict([], [ast.Name("x", ast.Load())])
1209 self.expr(d, "same number of keys as values")
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001210 d = ast.Dict([ast.Name("x", ast.Load())], [None])
1211 self.expr(d, "None disallowed")
1212
1213 def test_set(self):
1214 self.expr(ast.Set([None]), "None disallowed")
1215 s = ast.Set([ast.Name("x", ast.Store())])
1216 self.expr(s, "must have Load context")
1217
1218 def _check_comprehension(self, fac):
1219 self.expr(fac([]), "comprehension with no generators")
1220 g = ast.comprehension(ast.Name("x", ast.Load()),
Yury Selivanov52c4e7c2016-09-09 10:36:01 -07001221 ast.Name("x", ast.Load()), [], 0)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001222 self.expr(fac([g]), "must have Store context")
1223 g = ast.comprehension(ast.Name("x", ast.Store()),
Yury Selivanov52c4e7c2016-09-09 10:36:01 -07001224 ast.Name("x", ast.Store()), [], 0)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001225 self.expr(fac([g]), "must have Load context")
1226 x = ast.Name("x", ast.Store())
1227 y = ast.Name("y", ast.Load())
Yury Selivanov52c4e7c2016-09-09 10:36:01 -07001228 g = ast.comprehension(x, y, [None], 0)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001229 self.expr(fac([g]), "None disallowed")
Yury Selivanov52c4e7c2016-09-09 10:36:01 -07001230 g = ast.comprehension(x, y, [ast.Name("x", ast.Store())], 0)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001231 self.expr(fac([g]), "must have Load context")
1232
1233 def _simple_comp(self, fac):
1234 g = ast.comprehension(ast.Name("x", ast.Store()),
Yury Selivanov52c4e7c2016-09-09 10:36:01 -07001235 ast.Name("x", ast.Load()), [], 0)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001236 self.expr(fac(ast.Name("x", ast.Store()), [g]),
1237 "must have Load context")
1238 def wrap(gens):
1239 return fac(ast.Name("x", ast.Store()), gens)
1240 self._check_comprehension(wrap)
1241
1242 def test_listcomp(self):
1243 self._simple_comp(ast.ListComp)
1244
1245 def test_setcomp(self):
1246 self._simple_comp(ast.SetComp)
1247
1248 def test_generatorexp(self):
1249 self._simple_comp(ast.GeneratorExp)
1250
1251 def test_dictcomp(self):
1252 g = ast.comprehension(ast.Name("y", ast.Store()),
Yury Selivanov52c4e7c2016-09-09 10:36:01 -07001253 ast.Name("p", ast.Load()), [], 0)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001254 c = ast.DictComp(ast.Name("x", ast.Store()),
1255 ast.Name("y", ast.Load()), [g])
1256 self.expr(c, "must have Load context")
1257 c = ast.DictComp(ast.Name("x", ast.Load()),
1258 ast.Name("y", ast.Store()), [g])
1259 self.expr(c, "must have Load context")
1260 def factory(comps):
1261 k = ast.Name("x", ast.Load())
1262 v = ast.Name("y", ast.Load())
1263 return ast.DictComp(k, v, comps)
1264 self._check_comprehension(factory)
1265
1266 def test_yield(self):
Benjamin Peterson527c6222012-01-14 08:58:23 -05001267 self.expr(ast.Yield(ast.Name("x", ast.Store())), "must have Load")
1268 self.expr(ast.YieldFrom(ast.Name("x", ast.Store())), "must have Load")
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001269
1270 def test_compare(self):
1271 left = ast.Name("x", ast.Load())
1272 comp = ast.Compare(left, [ast.In()], [])
1273 self.expr(comp, "no comparators")
1274 comp = ast.Compare(left, [ast.In()], [ast.Num(4), ast.Num(5)])
1275 self.expr(comp, "different number of comparators and operands")
1276 comp = ast.Compare(ast.Num("blah"), [ast.In()], [left])
Serhiy Storchaka3f228112018-09-27 17:42:37 +03001277 self.expr(comp)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001278 comp = ast.Compare(left, [ast.In()], [ast.Num("blah")])
Serhiy Storchaka3f228112018-09-27 17:42:37 +03001279 self.expr(comp)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001280
1281 def test_call(self):
1282 func = ast.Name("x", ast.Load())
1283 args = [ast.Name("y", ast.Load())]
1284 keywords = [ast.keyword("w", ast.Name("z", ast.Load()))]
Benjamin Peterson025e9eb2015-05-05 20:16:41 -04001285 call = ast.Call(ast.Name("x", ast.Store()), args, keywords)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001286 self.expr(call, "must have Load context")
Benjamin Peterson025e9eb2015-05-05 20:16:41 -04001287 call = ast.Call(func, [None], keywords)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001288 self.expr(call, "None disallowed")
1289 bad_keywords = [ast.keyword("w", ast.Name("z", ast.Store()))]
Benjamin Peterson025e9eb2015-05-05 20:16:41 -04001290 call = ast.Call(func, args, bad_keywords)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001291 self.expr(call, "must have Load context")
1292
1293 def test_num(self):
1294 class subint(int):
1295 pass
1296 class subfloat(float):
1297 pass
1298 class subcomplex(complex):
1299 pass
Serhiy Storchaka3f228112018-09-27 17:42:37 +03001300 for obj in "0", "hello":
1301 self.expr(ast.Num(obj))
1302 for obj in subint(), subfloat(), subcomplex():
1303 self.expr(ast.Num(obj), "invalid type", exc=TypeError)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001304
1305 def test_attribute(self):
1306 attr = ast.Attribute(ast.Name("x", ast.Store()), "y", ast.Load())
1307 self.expr(attr, "must have Load context")
1308
1309 def test_subscript(self):
1310 sub = ast.Subscript(ast.Name("x", ast.Store()), ast.Index(ast.Num(3)),
1311 ast.Load())
1312 self.expr(sub, "must have Load context")
1313 x = ast.Name("x", ast.Load())
1314 sub = ast.Subscript(x, ast.Index(ast.Name("y", ast.Store())),
1315 ast.Load())
1316 self.expr(sub, "must have Load context")
1317 s = ast.Name("x", ast.Store())
1318 for args in (s, None, None), (None, s, None), (None, None, s):
1319 sl = ast.Slice(*args)
1320 self.expr(ast.Subscript(x, sl, ast.Load()),
1321 "must have Load context")
1322 sl = ast.ExtSlice([])
1323 self.expr(ast.Subscript(x, sl, ast.Load()), "empty dims on ExtSlice")
1324 sl = ast.ExtSlice([ast.Index(s)])
1325 self.expr(ast.Subscript(x, sl, ast.Load()), "must have Load context")
1326
1327 def test_starred(self):
1328 left = ast.List([ast.Starred(ast.Name("x", ast.Load()), ast.Store())],
1329 ast.Store())
1330 assign = ast.Assign([left], ast.Num(4))
1331 self.stmt(assign, "must have Store context")
1332
1333 def _sequence(self, fac):
1334 self.expr(fac([None], ast.Load()), "None disallowed")
1335 self.expr(fac([ast.Name("x", ast.Store())], ast.Load()),
1336 "must have Load context")
1337
1338 def test_list(self):
1339 self._sequence(ast.List)
1340
1341 def test_tuple(self):
1342 self._sequence(ast.Tuple)
1343
Benjamin Peterson442f2092012-12-06 17:41:04 -05001344 def test_nameconstant(self):
Serhiy Storchaka3f228112018-09-27 17:42:37 +03001345 self.expr(ast.NameConstant(4))
Benjamin Peterson442f2092012-12-06 17:41:04 -05001346
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001347 def test_stdlib_validates(self):
1348 stdlib = os.path.dirname(ast.__file__)
1349 tests = [fn for fn in os.listdir(stdlib) if fn.endswith(".py")]
1350 tests.extend(["test/test_grammar.py", "test/test_unpack_ex.py"])
1351 for module in tests:
Serhiy Storchaka3bcbedc2019-01-18 07:47:48 +02001352 with self.subTest(module):
1353 fn = os.path.join(stdlib, module)
1354 with open(fn, "r", encoding="utf-8") as fp:
1355 source = fp.read()
1356 mod = ast.parse(source, fn)
1357 compile(mod, fn, "exec")
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001358
1359
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001360class ConstantTests(unittest.TestCase):
1361 """Tests on the ast.Constant node type."""
1362
1363 def compile_constant(self, value):
1364 tree = ast.parse("x = 123")
1365
1366 node = tree.body[0].value
1367 new_node = ast.Constant(value=value)
1368 ast.copy_location(new_node, node)
1369 tree.body[0].value = new_node
1370
1371 code = compile(tree, "<string>", "exec")
1372
1373 ns = {}
1374 exec(code, ns)
1375 return ns['x']
1376
Victor Stinnerbe59d142016-01-27 00:39:12 +01001377 def test_validation(self):
1378 with self.assertRaises(TypeError) as cm:
1379 self.compile_constant([1, 2, 3])
1380 self.assertEqual(str(cm.exception),
1381 "got an invalid type in Constant: list")
1382
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001383 def test_singletons(self):
1384 for const in (None, False, True, Ellipsis, b'', frozenset()):
1385 with self.subTest(const=const):
1386 value = self.compile_constant(const)
1387 self.assertIs(value, const)
1388
1389 def test_values(self):
1390 nested_tuple = (1,)
1391 nested_frozenset = frozenset({1})
1392 for level in range(3):
1393 nested_tuple = (nested_tuple, 2)
1394 nested_frozenset = frozenset({nested_frozenset, 2})
1395 values = (123, 123.0, 123j,
1396 "unicode", b'bytes',
1397 tuple("tuple"), frozenset("frozenset"),
1398 nested_tuple, nested_frozenset)
1399 for value in values:
1400 with self.subTest(value=value):
1401 result = self.compile_constant(value)
1402 self.assertEqual(result, value)
1403
1404 def test_assign_to_constant(self):
1405 tree = ast.parse("x = 1")
1406
1407 target = tree.body[0].targets[0]
1408 new_target = ast.Constant(value=1)
1409 ast.copy_location(new_target, target)
1410 tree.body[0].targets[0] = new_target
1411
1412 with self.assertRaises(ValueError) as cm:
1413 compile(tree, "string", "exec")
1414 self.assertEqual(str(cm.exception),
1415 "expression which can't be assigned "
1416 "to in Store context")
1417
1418 def test_get_docstring(self):
1419 tree = ast.parse("'docstring'\nx = 1")
1420 self.assertEqual(ast.get_docstring(tree), 'docstring')
1421
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001422 def get_load_const(self, tree):
1423 # Compile to bytecode, disassemble and get parameter of LOAD_CONST
1424 # instructions
1425 co = compile(tree, '<string>', 'exec')
1426 consts = []
1427 for instr in dis.get_instructions(co):
1428 if instr.opname == 'LOAD_CONST':
1429 consts.append(instr.argval)
1430 return consts
1431
1432 @support.cpython_only
1433 def test_load_const(self):
1434 consts = [None,
1435 True, False,
1436 124,
1437 2.0,
1438 3j,
1439 "unicode",
1440 b'bytes',
1441 (1, 2, 3)]
1442
Victor Stinnera2724092016-02-08 18:17:58 +01001443 code = '\n'.join(['x={!r}'.format(const) for const in consts])
1444 code += '\nx = ...'
1445 consts.extend((Ellipsis, None))
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001446
1447 tree = ast.parse(code)
Victor Stinnera2724092016-02-08 18:17:58 +01001448 self.assertEqual(self.get_load_const(tree),
1449 consts)
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001450
1451 # Replace expression nodes with constants
Victor Stinnera2724092016-02-08 18:17:58 +01001452 for assign, const in zip(tree.body, consts):
1453 assert isinstance(assign, ast.Assign), ast.dump(assign)
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001454 new_node = ast.Constant(value=const)
Victor Stinnera2724092016-02-08 18:17:58 +01001455 ast.copy_location(new_node, assign.value)
1456 assign.value = new_node
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001457
Victor Stinnera2724092016-02-08 18:17:58 +01001458 self.assertEqual(self.get_load_const(tree),
1459 consts)
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001460
1461 def test_literal_eval(self):
1462 tree = ast.parse("1 + 2")
1463 binop = tree.body[0].value
1464
1465 new_left = ast.Constant(value=10)
1466 ast.copy_location(new_left, binop.left)
1467 binop.left = new_left
1468
Serhiy Storchakad8ac4d12018-01-04 11:15:39 +02001469 new_right = ast.Constant(value=20j)
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001470 ast.copy_location(new_right, binop.right)
1471 binop.right = new_right
1472
Serhiy Storchakad8ac4d12018-01-04 11:15:39 +02001473 self.assertEqual(ast.literal_eval(binop), 10+20j)
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001474
Guido van Rossum10f8ce62019-03-13 13:00:46 -07001475 def test_string_kind(self):
1476 c = ast.parse('"x"', mode='eval').body
1477 self.assertEqual(c.value, "x")
1478 self.assertEqual(c.kind, None)
1479
1480 c = ast.parse('u"x"', mode='eval').body
1481 self.assertEqual(c.value, "x")
1482 self.assertEqual(c.kind, "u")
1483
1484 c = ast.parse('r"x"', mode='eval').body
1485 self.assertEqual(c.value, "x")
1486 self.assertEqual(c.kind, None)
1487
1488 c = ast.parse('b"x"', mode='eval').body
1489 self.assertEqual(c.value, b"x")
1490 self.assertEqual(c.kind, None)
1491
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001492
Ivan Levkivskyi9932a222019-01-22 11:18:22 +00001493class EndPositionTests(unittest.TestCase):
1494 """Tests for end position of AST nodes.
1495
1496 Testing end positions of nodes requires a bit of extra care
1497 because of how LL parsers work.
1498 """
1499 def _check_end_pos(self, ast_node, end_lineno, end_col_offset):
1500 self.assertEqual(ast_node.end_lineno, end_lineno)
1501 self.assertEqual(ast_node.end_col_offset, end_col_offset)
1502
1503 def _check_content(self, source, ast_node, content):
1504 self.assertEqual(ast.get_source_segment(source, ast_node), content)
1505
1506 def _parse_value(self, s):
1507 # Use duck-typing to support both single expression
1508 # and a right hand side of an assignment statement.
1509 return ast.parse(s).body[0].value
1510
1511 def test_lambda(self):
1512 s = 'lambda x, *y: None'
1513 lam = self._parse_value(s)
1514 self._check_content(s, lam.body, 'None')
1515 self._check_content(s, lam.args.args[0], 'x')
1516 self._check_content(s, lam.args.vararg, 'y')
1517
1518 def test_func_def(self):
1519 s = dedent('''
1520 def func(x: int,
1521 *args: str,
1522 z: float = 0,
1523 **kwargs: Any) -> bool:
1524 return True
1525 ''').strip()
1526 fdef = ast.parse(s).body[0]
1527 self._check_end_pos(fdef, 5, 15)
1528 self._check_content(s, fdef.body[0], 'return True')
1529 self._check_content(s, fdef.args.args[0], 'x: int')
1530 self._check_content(s, fdef.args.args[0].annotation, 'int')
1531 self._check_content(s, fdef.args.kwarg, 'kwargs: Any')
1532 self._check_content(s, fdef.args.kwarg.annotation, 'Any')
1533
1534 def test_call(self):
1535 s = 'func(x, y=2, **kw)'
1536 call = self._parse_value(s)
1537 self._check_content(s, call.func, 'func')
1538 self._check_content(s, call.keywords[0].value, '2')
1539 self._check_content(s, call.keywords[1].value, 'kw')
1540
1541 def test_call_noargs(self):
1542 s = 'x[0]()'
1543 call = self._parse_value(s)
1544 self._check_content(s, call.func, 'x[0]')
1545 self._check_end_pos(call, 1, 6)
1546
1547 def test_class_def(self):
1548 s = dedent('''
1549 class C(A, B):
1550 x: int = 0
1551 ''').strip()
1552 cdef = ast.parse(s).body[0]
1553 self._check_end_pos(cdef, 2, 14)
1554 self._check_content(s, cdef.bases[1], 'B')
1555 self._check_content(s, cdef.body[0], 'x: int = 0')
1556
1557 def test_class_kw(self):
1558 s = 'class S(metaclass=abc.ABCMeta): pass'
1559 cdef = ast.parse(s).body[0]
1560 self._check_content(s, cdef.keywords[0].value, 'abc.ABCMeta')
1561
1562 def test_multi_line_str(self):
1563 s = dedent('''
1564 x = """Some multi-line text.
1565
1566 It goes on starting from same indent."""
1567 ''').strip()
1568 assign = ast.parse(s).body[0]
1569 self._check_end_pos(assign, 3, 40)
1570 self._check_end_pos(assign.value, 3, 40)
1571
1572 def test_continued_str(self):
1573 s = dedent('''
1574 x = "first part" \\
1575 "second part"
1576 ''').strip()
1577 assign = ast.parse(s).body[0]
1578 self._check_end_pos(assign, 2, 13)
1579 self._check_end_pos(assign.value, 2, 13)
1580
1581 def test_suites(self):
1582 # We intentionally put these into the same string to check
1583 # that empty lines are not part of the suite.
1584 s = dedent('''
1585 while True:
1586 pass
1587
1588 if one():
1589 x = None
1590 elif other():
1591 y = None
1592 else:
1593 z = None
1594
1595 for x, y in stuff:
1596 assert True
1597
1598 try:
1599 raise RuntimeError
1600 except TypeError as e:
1601 pass
1602
1603 pass
1604 ''').strip()
1605 mod = ast.parse(s)
1606 while_loop = mod.body[0]
1607 if_stmt = mod.body[1]
1608 for_loop = mod.body[2]
1609 try_stmt = mod.body[3]
1610 pass_stmt = mod.body[4]
1611
1612 self._check_end_pos(while_loop, 2, 8)
1613 self._check_end_pos(if_stmt, 9, 12)
1614 self._check_end_pos(for_loop, 12, 15)
1615 self._check_end_pos(try_stmt, 17, 8)
1616 self._check_end_pos(pass_stmt, 19, 4)
1617
1618 self._check_content(s, while_loop.test, 'True')
1619 self._check_content(s, if_stmt.body[0], 'x = None')
1620 self._check_content(s, if_stmt.orelse[0].test, 'other()')
1621 self._check_content(s, for_loop.target, 'x, y')
1622 self._check_content(s, try_stmt.body[0], 'raise RuntimeError')
1623 self._check_content(s, try_stmt.handlers[0].type, 'TypeError')
1624
1625 def test_fstring(self):
1626 s = 'x = f"abc {x + y} abc"'
1627 fstr = self._parse_value(s)
1628 binop = fstr.values[1].value
1629 self._check_content(s, binop, 'x + y')
1630
1631 def test_fstring_multi_line(self):
1632 s = dedent('''
1633 f"""Some multi-line text.
1634 {
1635 arg_one
1636 +
1637 arg_two
1638 }
1639 It goes on..."""
1640 ''').strip()
1641 fstr = self._parse_value(s)
1642 binop = fstr.values[1].value
1643 self._check_end_pos(binop, 5, 7)
1644 self._check_content(s, binop.left, 'arg_one')
1645 self._check_content(s, binop.right, 'arg_two')
1646
1647 def test_import_from_multi_line(self):
1648 s = dedent('''
1649 from x.y.z import (
1650 a, b, c as c
1651 )
1652 ''').strip()
1653 imp = ast.parse(s).body[0]
1654 self._check_end_pos(imp, 3, 1)
1655
1656 def test_slices(self):
1657 s1 = 'f()[1, 2] [0]'
1658 s2 = 'x[ a.b: c.d]'
1659 sm = dedent('''
1660 x[ a.b: f () ,
1661 g () : c.d
1662 ]
1663 ''').strip()
1664 i1, i2, im = map(self._parse_value, (s1, s2, sm))
1665 self._check_content(s1, i1.value, 'f()[1, 2]')
1666 self._check_content(s1, i1.value.slice.value, '1, 2')
1667 self._check_content(s2, i2.slice.lower, 'a.b')
1668 self._check_content(s2, i2.slice.upper, 'c.d')
1669 self._check_content(sm, im.slice.dims[0].upper, 'f ()')
1670 self._check_content(sm, im.slice.dims[1].lower, 'g ()')
1671 self._check_end_pos(im, 3, 3)
1672
1673 def test_binop(self):
1674 s = dedent('''
1675 (1 * 2 + (3 ) +
1676 4
1677 )
1678 ''').strip()
1679 binop = self._parse_value(s)
1680 self._check_end_pos(binop, 2, 6)
1681 self._check_content(s, binop.right, '4')
1682 self._check_content(s, binop.left, '1 * 2 + (3 )')
1683 self._check_content(s, binop.left.right, '3')
1684
1685 def test_boolop(self):
1686 s = dedent('''
1687 if (one_condition and
1688 (other_condition or yet_another_one)):
1689 pass
1690 ''').strip()
1691 bop = ast.parse(s).body[0].test
1692 self._check_end_pos(bop, 2, 44)
1693 self._check_content(s, bop.values[1],
1694 'other_condition or yet_another_one')
1695
1696 def test_tuples(self):
1697 s1 = 'x = () ;'
1698 s2 = 'x = 1 , ;'
1699 s3 = 'x = (1 , 2 ) ;'
1700 sm = dedent('''
1701 x = (
1702 a, b,
1703 )
1704 ''').strip()
1705 t1, t2, t3, tm = map(self._parse_value, (s1, s2, s3, sm))
1706 self._check_content(s1, t1, '()')
1707 self._check_content(s2, t2, '1 ,')
1708 self._check_content(s3, t3, '(1 , 2 )')
1709 self._check_end_pos(tm, 3, 1)
1710
1711 def test_attribute_spaces(self):
1712 s = 'func(x. y .z)'
1713 call = self._parse_value(s)
1714 self._check_content(s, call, s)
1715 self._check_content(s, call.args[0], 'x. y .z')
1716
Serhiy Storchaka6e619c42020-02-12 22:37:49 +02001717 def test_redundant_parenthesis(self):
1718 s = '( ( ( a + b ) ) )'
1719 v = ast.parse(s).body[0].value
1720 self.assertEqual(type(v).__name__, 'BinOp')
1721 self._check_content(s, v, 'a + b')
1722 s2 = 'await ' + s
1723 v = ast.parse(s2).body[0].value.value
1724 self.assertEqual(type(v).__name__, 'BinOp')
1725 self._check_content(s2, v, 'a + b')
1726
1727 def test_trailers_with_redundant_parenthesis(self):
1728 tests = (
1729 ('( ( ( a ) ) ) ( )', 'Call'),
1730 ('( ( ( a ) ) ) ( b )', 'Call'),
1731 ('( ( ( a ) ) ) [ b ]', 'Subscript'),
1732 ('( ( ( a ) ) ) . b', 'Attribute'),
1733 )
1734 for s, t in tests:
1735 with self.subTest(s):
1736 v = ast.parse(s).body[0].value
1737 self.assertEqual(type(v).__name__, t)
1738 self._check_content(s, v, s)
1739 s2 = 'await ' + s
1740 v = ast.parse(s2).body[0].value.value
1741 self.assertEqual(type(v).__name__, t)
1742 self._check_content(s2, v, s)
1743
Ivan Levkivskyi9932a222019-01-22 11:18:22 +00001744 def test_displays(self):
1745 s1 = '[{}, {1, }, {1, 2,} ]'
1746 s2 = '{a: b, f (): g () ,}'
1747 c1 = self._parse_value(s1)
1748 c2 = self._parse_value(s2)
1749 self._check_content(s1, c1.elts[0], '{}')
1750 self._check_content(s1, c1.elts[1], '{1, }')
1751 self._check_content(s1, c1.elts[2], '{1, 2,}')
1752 self._check_content(s2, c2.keys[1], 'f ()')
1753 self._check_content(s2, c2.values[1], 'g ()')
1754
1755 def test_comprehensions(self):
1756 s = dedent('''
1757 x = [{x for x, y in stuff
1758 if cond.x} for stuff in things]
1759 ''').strip()
1760 cmp = self._parse_value(s)
1761 self._check_end_pos(cmp, 2, 37)
1762 self._check_content(s, cmp.generators[0].iter, 'things')
1763 self._check_content(s, cmp.elt.generators[0].iter, 'stuff')
1764 self._check_content(s, cmp.elt.generators[0].ifs[0], 'cond.x')
1765 self._check_content(s, cmp.elt.generators[0].target, 'x, y')
1766
1767 def test_yield_await(self):
1768 s = dedent('''
1769 async def f():
1770 yield x
1771 await y
1772 ''').strip()
1773 fdef = ast.parse(s).body[0]
1774 self._check_content(s, fdef.body[0].value, 'yield x')
1775 self._check_content(s, fdef.body[1].value, 'await y')
1776
1777 def test_source_segment_multi(self):
1778 s_orig = dedent('''
1779 x = (
1780 a, b,
1781 ) + ()
1782 ''').strip()
1783 s_tuple = dedent('''
1784 (
1785 a, b,
1786 )
1787 ''').strip()
1788 binop = self._parse_value(s_orig)
1789 self.assertEqual(ast.get_source_segment(s_orig, binop.left), s_tuple)
1790
1791 def test_source_segment_padded(self):
1792 s_orig = dedent('''
1793 class C:
1794 def fun(self) -> None:
1795 "Đ–Đ–Đ–Đ–Đ–"
1796 ''').strip()
1797 s_method = ' def fun(self) -> None:\n' \
1798 ' "Đ–Đ–Đ–Đ–Đ–"'
1799 cdef = ast.parse(s_orig).body[0]
1800 self.assertEqual(ast.get_source_segment(s_orig, cdef.body[0], padded=True),
1801 s_method)
1802
1803 def test_source_segment_endings(self):
1804 s = 'v = 1\r\nw = 1\nx = 1\n\ry = 1\rz = 1\r\n'
1805 v, w, x, y, z = ast.parse(s).body
1806 self._check_content(s, v, 'v = 1')
1807 self._check_content(s, w, 'w = 1')
1808 self._check_content(s, x, 'x = 1')
1809 self._check_content(s, y, 'y = 1')
1810 self._check_content(s, z, 'z = 1')
1811
1812 def test_source_segment_tabs(self):
1813 s = dedent('''
1814 class C:
1815 \t\f def fun(self) -> None:
1816 \t\f pass
1817 ''').strip()
1818 s_method = ' \t\f def fun(self) -> None:\n' \
1819 ' \t\f pass'
1820
1821 cdef = ast.parse(s).body[0]
1822 self.assertEqual(ast.get_source_segment(s, cdef.body[0], padded=True), s_method)
1823
1824
Serhiy Storchakac3ea41e2019-08-26 10:13:19 +03001825class NodeVisitorTests(unittest.TestCase):
1826 def test_old_constant_nodes(self):
1827 class Visitor(ast.NodeVisitor):
1828 def visit_Num(self, node):
1829 log.append((node.lineno, 'Num', node.n))
1830 def visit_Str(self, node):
1831 log.append((node.lineno, 'Str', node.s))
1832 def visit_Bytes(self, node):
1833 log.append((node.lineno, 'Bytes', node.s))
1834 def visit_NameConstant(self, node):
1835 log.append((node.lineno, 'NameConstant', node.value))
1836 def visit_Ellipsis(self, node):
1837 log.append((node.lineno, 'Ellipsis', ...))
1838 mod = ast.parse(dedent('''\
1839 i = 42
1840 f = 4.25
1841 c = 4.25j
1842 s = 'string'
1843 b = b'bytes'
1844 t = True
1845 n = None
1846 e = ...
1847 '''))
1848 visitor = Visitor()
1849 log = []
1850 with warnings.catch_warnings(record=True) as wlog:
1851 warnings.filterwarnings('always', '', DeprecationWarning)
1852 visitor.visit(mod)
1853 self.assertEqual(log, [
1854 (1, 'Num', 42),
1855 (2, 'Num', 4.25),
1856 (3, 'Num', 4.25j),
1857 (4, 'Str', 'string'),
1858 (5, 'Bytes', b'bytes'),
1859 (6, 'NameConstant', True),
1860 (7, 'NameConstant', None),
1861 (8, 'Ellipsis', ...),
1862 ])
1863 self.assertEqual([str(w.message) for w in wlog], [
1864 'visit_Num is deprecated; add visit_Constant',
1865 'visit_Num is deprecated; add visit_Constant',
1866 'visit_Num is deprecated; add visit_Constant',
1867 'visit_Str is deprecated; add visit_Constant',
1868 'visit_Bytes is deprecated; add visit_Constant',
1869 'visit_NameConstant is deprecated; add visit_Constant',
1870 'visit_NameConstant is deprecated; add visit_Constant',
1871 'visit_Ellipsis is deprecated; add visit_Constant',
1872 ])
1873
1874
Neal Norwitzee9b10a2008-03-31 05:29:39 +00001875def main():
1876 if __name__ != '__main__':
Martin v. Löwis49c5da12006-03-01 22:49:05 +00001877 return
Neal Norwitzee9b10a2008-03-31 05:29:39 +00001878 if sys.argv[1:] == ['-g']:
1879 for statements, kind in ((exec_tests, "exec"), (single_tests, "single"),
1880 (eval_tests, "eval")):
1881 print(kind+"_results = [")
Victor Stinnerf0891962016-02-08 17:15:21 +01001882 for statement in statements:
1883 tree = ast.parse(statement, "?", kind)
1884 print("%r," % (to_tuple(tree),))
Neal Norwitzee9b10a2008-03-31 05:29:39 +00001885 print("]")
1886 print("main()")
1887 raise SystemExit
Brett Cannon3e9a9ae2013-06-12 21:25:59 -04001888 unittest.main()
Tim Peters400cbc32006-02-28 18:44:41 +00001889
Guido van Rossumdcfcd142019-01-31 03:40:27 -08001890#### EVERYTHING BELOW IS GENERATED BY python Lib/test/test_ast.py -g #####
Tim Peters400cbc32006-02-28 18:44:41 +00001891exec_results = [
Serhiy Storchaka850a8852020-01-10 10:12:55 +02001892('Module', [('Expr', (1, 0, 1, 4), ('Constant', (1, 0, 1, 4), None, None))], []),
1893('Module', [('Expr', (1, 0, 1, 18), ('Constant', (1, 0, 1, 18), 'module docstring', None))], []),
1894('Module', [('FunctionDef', (1, 0, 1, 13), 'f', ('arguments', [], [], None, [], [], None, []), [('Pass', (1, 9, 1, 13))], [], None, None)], []),
1895('Module', [('FunctionDef', (1, 0, 1, 29), 'f', ('arguments', [], [], None, [], [], None, []), [('Expr', (1, 9, 1, 29), ('Constant', (1, 9, 1, 29), 'function docstring', None))], [], None, None)], []),
1896('Module', [('FunctionDef', (1, 0, 1, 14), 'f', ('arguments', [], [('arg', (1, 6, 1, 7), 'a', None, None)], None, [], [], None, []), [('Pass', (1, 10, 1, 14))], [], None, None)], []),
1897('Module', [('FunctionDef', (1, 0, 1, 16), 'f', ('arguments', [], [('arg', (1, 6, 1, 7), 'a', None, None)], None, [], [], None, [('Constant', (1, 8, 1, 9), 0, None)]), [('Pass', (1, 12, 1, 16))], [], None, None)], []),
1898('Module', [('FunctionDef', (1, 0, 1, 18), 'f', ('arguments', [], [], ('arg', (1, 7, 1, 11), 'args', None, None), [], [], None, []), [('Pass', (1, 14, 1, 18))], [], None, None)], []),
1899('Module', [('FunctionDef', (1, 0, 1, 21), 'f', ('arguments', [], [], None, [], [], ('arg', (1, 8, 1, 14), 'kwargs', None, None), []), [('Pass', (1, 17, 1, 21))], [], None, None)], []),
1900('Module', [('FunctionDef', (1, 0, 1, 71), 'f', ('arguments', [], [('arg', (1, 6, 1, 7), 'a', None, None), ('arg', (1, 9, 1, 10), 'b', None, None), ('arg', (1, 14, 1, 15), 'c', None, None), ('arg', (1, 22, 1, 23), 'd', None, None), ('arg', (1, 28, 1, 29), 'e', None, None)], ('arg', (1, 35, 1, 39), 'args', None, None), [('arg', (1, 41, 1, 42), 'f', None, None)], [('Constant', (1, 43, 1, 45), 42, None)], ('arg', (1, 49, 1, 55), 'kwargs', None, None), [('Constant', (1, 11, 1, 12), 1, None), ('Constant', (1, 16, 1, 20), None, None), ('List', (1, 24, 1, 26), [], ('Load',)), ('Dict', (1, 30, 1, 32), [], [])]), [('Expr', (1, 58, 1, 71), ('Constant', (1, 58, 1, 71), 'doc for f()', None))], [], None, None)], []),
1901('Module', [('ClassDef', (1, 0, 1, 12), 'C', [], [], [('Pass', (1, 8, 1, 12))], [])], []),
1902('Module', [('ClassDef', (1, 0, 1, 32), 'C', [], [], [('Expr', (1, 9, 1, 32), ('Constant', (1, 9, 1, 32), 'docstring for class C', None))], [])], []),
1903('Module', [('ClassDef', (1, 0, 1, 21), 'C', [('Name', (1, 8, 1, 14), 'object', ('Load',))], [], [('Pass', (1, 17, 1, 21))], [])], []),
1904('Module', [('FunctionDef', (1, 0, 1, 16), 'f', ('arguments', [], [], None, [], [], None, []), [('Return', (1, 8, 1, 16), ('Constant', (1, 15, 1, 16), 1, None))], [], None, None)], []),
1905('Module', [('Delete', (1, 0, 1, 5), [('Name', (1, 4, 1, 5), 'v', ('Del',))])], []),
1906('Module', [('Assign', (1, 0, 1, 5), [('Name', (1, 0, 1, 1), 'v', ('Store',))], ('Constant', (1, 4, 1, 5), 1, None), None)], []),
1907('Module', [('Assign', (1, 0, 1, 7), [('Tuple', (1, 0, 1, 3), [('Name', (1, 0, 1, 1), 'a', ('Store',)), ('Name', (1, 2, 1, 3), 'b', ('Store',))], ('Store',))], ('Name', (1, 6, 1, 7), 'c', ('Load',)), None)], []),
1908('Module', [('Assign', (1, 0, 1, 9), [('Tuple', (1, 0, 1, 5), [('Name', (1, 1, 1, 2), 'a', ('Store',)), ('Name', (1, 3, 1, 4), 'b', ('Store',))], ('Store',))], ('Name', (1, 8, 1, 9), 'c', ('Load',)), None)], []),
1909('Module', [('Assign', (1, 0, 1, 9), [('List', (1, 0, 1, 5), [('Name', (1, 1, 1, 2), 'a', ('Store',)), ('Name', (1, 3, 1, 4), 'b', ('Store',))], ('Store',))], ('Name', (1, 8, 1, 9), 'c', ('Load',)), None)], []),
1910('Module', [('AugAssign', (1, 0, 1, 6), ('Name', (1, 0, 1, 1), 'v', ('Store',)), ('Add',), ('Constant', (1, 5, 1, 6), 1, None))], []),
1911('Module', [('For', (1, 0, 1, 15), ('Name', (1, 4, 1, 5), 'v', ('Store',)), ('Name', (1, 9, 1, 10), 'v', ('Load',)), [('Pass', (1, 11, 1, 15))], [], None)], []),
1912('Module', [('While', (1, 0, 1, 12), ('Name', (1, 6, 1, 7), 'v', ('Load',)), [('Pass', (1, 8, 1, 12))], [])], []),
1913('Module', [('If', (1, 0, 1, 9), ('Name', (1, 3, 1, 4), 'v', ('Load',)), [('Pass', (1, 5, 1, 9))], [])], []),
1914('Module', [('If', (1, 0, 4, 6), ('Name', (1, 3, 1, 4), 'a', ('Load',)), [('Pass', (2, 2, 2, 6))], [('If', (3, 0, 4, 6), ('Name', (3, 5, 3, 6), 'b', ('Load',)), [('Pass', (4, 2, 4, 6))], [])])], []),
1915('Module', [('If', (1, 0, 6, 6), ('Name', (1, 3, 1, 4), 'a', ('Load',)), [('Pass', (2, 2, 2, 6))], [('If', (3, 0, 6, 6), ('Name', (3, 5, 3, 6), 'b', ('Load',)), [('Pass', (4, 2, 4, 6))], [('Pass', (6, 2, 6, 6))])])], []),
1916('Module', [('With', (1, 0, 1, 17), [('withitem', ('Name', (1, 5, 1, 6), 'x', ('Load',)), ('Name', (1, 10, 1, 11), 'y', ('Store',)))], [('Pass', (1, 13, 1, 17))], None)], []),
1917('Module', [('With', (1, 0, 1, 25), [('withitem', ('Name', (1, 5, 1, 6), 'x', ('Load',)), ('Name', (1, 10, 1, 11), 'y', ('Store',))), ('withitem', ('Name', (1, 13, 1, 14), 'z', ('Load',)), ('Name', (1, 18, 1, 19), 'q', ('Store',)))], [('Pass', (1, 21, 1, 25))], None)], []),
1918('Module', [('Raise', (1, 0, 1, 25), ('Call', (1, 6, 1, 25), ('Name', (1, 6, 1, 15), 'Exception', ('Load',)), [('Constant', (1, 16, 1, 24), 'string', None)], []), None)], []),
1919('Module', [('Try', (1, 0, 4, 6), [('Pass', (2, 2, 2, 6))], [('ExceptHandler', (3, 0, 4, 6), ('Name', (3, 7, 3, 16), 'Exception', ('Load',)), None, [('Pass', (4, 2, 4, 6))])], [], [])], []),
1920('Module', [('Try', (1, 0, 4, 6), [('Pass', (2, 2, 2, 6))], [], [], [('Pass', (4, 2, 4, 6))])], []),
1921('Module', [('Assert', (1, 0, 1, 8), ('Name', (1, 7, 1, 8), 'v', ('Load',)), None)], []),
1922('Module', [('Import', (1, 0, 1, 10), [('alias', 'sys', None)])], []),
1923('Module', [('ImportFrom', (1, 0, 1, 17), 'sys', [('alias', 'v', None)], 0)], []),
1924('Module', [('Global', (1, 0, 1, 8), ['v'])], []),
1925('Module', [('Expr', (1, 0, 1, 1), ('Constant', (1, 0, 1, 1), 1, None))], []),
1926('Module', [('Pass', (1, 0, 1, 4))], []),
1927('Module', [('For', (1, 0, 1, 16), ('Name', (1, 4, 1, 5), 'v', ('Store',)), ('Name', (1, 9, 1, 10), 'v', ('Load',)), [('Break', (1, 11, 1, 16))], [], None)], []),
1928('Module', [('For', (1, 0, 1, 19), ('Name', (1, 4, 1, 5), 'v', ('Store',)), ('Name', (1, 9, 1, 10), 'v', ('Load',)), [('Continue', (1, 11, 1, 19))], [], None)], []),
1929('Module', [('For', (1, 0, 1, 18), ('Tuple', (1, 4, 1, 7), [('Name', (1, 4, 1, 5), 'a', ('Store',)), ('Name', (1, 6, 1, 7), 'b', ('Store',))], ('Store',)), ('Name', (1, 11, 1, 12), 'c', ('Load',)), [('Pass', (1, 14, 1, 18))], [], None)], []),
1930('Module', [('For', (1, 0, 1, 20), ('Tuple', (1, 4, 1, 9), [('Name', (1, 5, 1, 6), 'a', ('Store',)), ('Name', (1, 7, 1, 8), 'b', ('Store',))], ('Store',)), ('Name', (1, 13, 1, 14), 'c', ('Load',)), [('Pass', (1, 16, 1, 20))], [], None)], []),
1931('Module', [('For', (1, 0, 1, 20), ('List', (1, 4, 1, 9), [('Name', (1, 5, 1, 6), 'a', ('Store',)), ('Name', (1, 7, 1, 8), 'b', ('Store',))], ('Store',)), ('Name', (1, 13, 1, 14), 'c', ('Load',)), [('Pass', (1, 16, 1, 20))], [], None)], []),
1932('Module', [('Expr', (1, 0, 11, 5), ('GeneratorExp', (1, 0, 11, 5), ('Tuple', (2, 4, 6, 5), [('Name', (3, 4, 3, 6), 'Aa', ('Load',)), ('Name', (5, 7, 5, 9), 'Bb', ('Load',))], ('Load',)), [('comprehension', ('Tuple', (8, 4, 10, 6), [('Name', (8, 4, 8, 6), 'Aa', ('Store',)), ('Name', (10, 4, 10, 6), 'Bb', ('Store',))], ('Store',)), ('Name', (10, 10, 10, 12), 'Cc', ('Load',)), [], 0)]))], []),
1933('Module', [('Expr', (1, 0, 1, 34), ('DictComp', (1, 0, 1, 34), ('Name', (1, 1, 1, 2), 'a', ('Load',)), ('Name', (1, 5, 1, 6), 'b', ('Load',)), [('comprehension', ('Name', (1, 11, 1, 12), 'w', ('Store',)), ('Name', (1, 16, 1, 17), 'x', ('Load',)), [], 0), ('comprehension', ('Name', (1, 22, 1, 23), 'm', ('Store',)), ('Name', (1, 27, 1, 28), 'p', ('Load',)), [('Name', (1, 32, 1, 33), 'g', ('Load',))], 0)]))], []),
1934('Module', [('Expr', (1, 0, 1, 20), ('DictComp', (1, 0, 1, 20), ('Name', (1, 1, 1, 2), 'a', ('Load',)), ('Name', (1, 5, 1, 6), 'b', ('Load',)), [('comprehension', ('Tuple', (1, 11, 1, 14), [('Name', (1, 11, 1, 12), 'v', ('Store',)), ('Name', (1, 13, 1, 14), 'w', ('Store',))], ('Store',)), ('Name', (1, 18, 1, 19), 'x', ('Load',)), [], 0)]))], []),
1935('Module', [('Expr', (1, 0, 1, 19), ('SetComp', (1, 0, 1, 19), ('Name', (1, 1, 1, 2), 'r', ('Load',)), [('comprehension', ('Name', (1, 7, 1, 8), 'l', ('Store',)), ('Name', (1, 12, 1, 13), 'x', ('Load',)), [('Name', (1, 17, 1, 18), 'g', ('Load',))], 0)]))], []),
1936('Module', [('Expr', (1, 0, 1, 16), ('SetComp', (1, 0, 1, 16), ('Name', (1, 1, 1, 2), 'r', ('Load',)), [('comprehension', ('Tuple', (1, 7, 1, 10), [('Name', (1, 7, 1, 8), 'l', ('Store',)), ('Name', (1, 9, 1, 10), 'm', ('Store',))], ('Store',)), ('Name', (1, 14, 1, 15), 'x', ('Load',)), [], 0)]))], []),
1937('Module', [('AsyncFunctionDef', (1, 0, 3, 18), 'f', ('arguments', [], [], None, [], [], None, []), [('Expr', (2, 1, 2, 17), ('Constant', (2, 1, 2, 17), 'async function', None)), ('Expr', (3, 1, 3, 18), ('Await', (3, 1, 3, 18), ('Call', (3, 7, 3, 18), ('Name', (3, 7, 3, 16), 'something', ('Load',)), [], [])))], [], None, None)], []),
1938('Module', [('AsyncFunctionDef', (1, 0, 3, 8), 'f', ('arguments', [], [], None, [], [], None, []), [('AsyncFor', (2, 1, 3, 8), ('Name', (2, 11, 2, 12), 'e', ('Store',)), ('Name', (2, 16, 2, 17), 'i', ('Load',)), [('Expr', (2, 19, 2, 20), ('Constant', (2, 19, 2, 20), 1, None))], [('Expr', (3, 7, 3, 8), ('Constant', (3, 7, 3, 8), 2, None))], None)], [], None, None)], []),
1939('Module', [('AsyncFunctionDef', (1, 0, 2, 21), 'f', ('arguments', [], [], None, [], [], None, []), [('AsyncWith', (2, 1, 2, 21), [('withitem', ('Name', (2, 12, 2, 13), 'a', ('Load',)), ('Name', (2, 17, 2, 18), 'b', ('Store',)))], [('Expr', (2, 20, 2, 21), ('Constant', (2, 20, 2, 21), 1, None))], None)], [], None, None)], []),
1940('Module', [('Expr', (1, 0, 1, 14), ('Dict', (1, 0, 1, 14), [None, ('Constant', (1, 10, 1, 11), 2, None)], [('Dict', (1, 3, 1, 8), [('Constant', (1, 4, 1, 5), 1, None)], [('Constant', (1, 6, 1, 7), 2, None)]), ('Constant', (1, 12, 1, 13), 3, None)]))], []),
1941('Module', [('Expr', (1, 0, 1, 12), ('Set', (1, 0, 1, 12), [('Starred', (1, 1, 1, 8), ('Set', (1, 2, 1, 8), [('Constant', (1, 3, 1, 4), 1, None), ('Constant', (1, 6, 1, 7), 2, None)]), ('Load',)), ('Constant', (1, 10, 1, 11), 3, None)]))], []),
1942('Module', [('AsyncFunctionDef', (1, 0, 2, 21), 'f', ('arguments', [], [], None, [], [], None, []), [('Expr', (2, 1, 2, 21), ('ListComp', (2, 1, 2, 21), ('Name', (2, 2, 2, 3), 'i', ('Load',)), [('comprehension', ('Name', (2, 14, 2, 15), 'b', ('Store',)), ('Name', (2, 19, 2, 20), 'c', ('Load',)), [], 1)]))], [], None, None)], []),
1943('Module', [('FunctionDef', (4, 0, 4, 13), 'f', ('arguments', [], [], None, [], [], None, []), [('Pass', (4, 9, 4, 13))], [('Name', (1, 1, 1, 6), 'deco1', ('Load',)), ('Call', (2, 1, 2, 8), ('Name', (2, 1, 2, 6), 'deco2', ('Load',)), [], []), ('Call', (3, 1, 3, 9), ('Name', (3, 1, 3, 6), 'deco3', ('Load',)), [('Constant', (3, 7, 3, 8), 1, None)], [])], None, None)], []),
1944('Module', [('AsyncFunctionDef', (4, 0, 4, 19), 'f', ('arguments', [], [], None, [], [], None, []), [('Pass', (4, 15, 4, 19))], [('Name', (1, 1, 1, 6), 'deco1', ('Load',)), ('Call', (2, 1, 2, 8), ('Name', (2, 1, 2, 6), 'deco2', ('Load',)), [], []), ('Call', (3, 1, 3, 9), ('Name', (3, 1, 3, 6), 'deco3', ('Load',)), [('Constant', (3, 7, 3, 8), 1, None)], [])], None, None)], []),
1945('Module', [('ClassDef', (4, 0, 4, 13), 'C', [], [], [('Pass', (4, 9, 4, 13))], [('Name', (1, 1, 1, 6), 'deco1', ('Load',)), ('Call', (2, 1, 2, 8), ('Name', (2, 1, 2, 6), 'deco2', ('Load',)), [], []), ('Call', (3, 1, 3, 9), ('Name', (3, 1, 3, 6), 'deco3', ('Load',)), [('Constant', (3, 7, 3, 8), 1, None)], [])])], []),
1946('Module', [('FunctionDef', (2, 0, 2, 13), 'f', ('arguments', [], [], None, [], [], None, []), [('Pass', (2, 9, 2, 13))], [('Call', (1, 1, 1, 19), ('Name', (1, 1, 1, 5), 'deco', ('Load',)), [('GeneratorExp', (1, 5, 1, 19), ('Name', (1, 6, 1, 7), 'a', ('Load',)), [('comprehension', ('Name', (1, 12, 1, 13), 'a', ('Store',)), ('Name', (1, 17, 1, 18), 'b', ('Load',)), [], 0)])], [])], None, None)], []),
Lysandros Nikolaoud2e10982020-02-08 00:36:32 +01001947('Module', [('FunctionDef', (2, 0, 2, 13), 'f', ('arguments', [], [], None, [], [], None, []), [('Pass', (2, 9, 2, 13))], [('Attribute', (1, 1, 1, 6), ('Attribute', (1, 1, 1, 4), ('Name', (1, 1, 1, 2), 'a', ('Load',)), 'b', ('Load',)), 'c', ('Load',))], None, None)], []),
Serhiy Storchaka850a8852020-01-10 10:12:55 +02001948('Module', [('Expr', (1, 0, 1, 8), ('NamedExpr', (1, 1, 1, 7), ('Name', (1, 1, 1, 2), 'a', ('Store',)), ('Constant', (1, 6, 1, 7), 1, None)))], []),
1949('Module', [('FunctionDef', (1, 0, 1, 18), 'f', ('arguments', [('arg', (1, 6, 1, 7), 'a', None, None)], [], None, [], [], None, []), [('Pass', (1, 14, 1, 18))], [], None, None)], []),
1950('Module', [('FunctionDef', (1, 0, 1, 26), 'f', ('arguments', [('arg', (1, 6, 1, 7), 'a', None, None)], [('arg', (1, 12, 1, 13), 'c', None, None), ('arg', (1, 15, 1, 16), 'd', None, None), ('arg', (1, 18, 1, 19), 'e', None, None)], None, [], [], None, []), [('Pass', (1, 22, 1, 26))], [], None, None)], []),
1951('Module', [('FunctionDef', (1, 0, 1, 29), 'f', ('arguments', [('arg', (1, 6, 1, 7), 'a', None, None)], [('arg', (1, 12, 1, 13), 'c', None, None)], None, [('arg', (1, 18, 1, 19), 'd', None, None), ('arg', (1, 21, 1, 22), 'e', None, None)], [None, None], None, []), [('Pass', (1, 25, 1, 29))], [], None, None)], []),
1952('Module', [('FunctionDef', (1, 0, 1, 39), 'f', ('arguments', [('arg', (1, 6, 1, 7), 'a', None, None)], [('arg', (1, 12, 1, 13), 'c', None, None)], None, [('arg', (1, 18, 1, 19), 'd', None, None), ('arg', (1, 21, 1, 22), 'e', None, None)], [None, None], ('arg', (1, 26, 1, 32), 'kwargs', None, None), []), [('Pass', (1, 35, 1, 39))], [], None, None)], []),
1953('Module', [('FunctionDef', (1, 0, 1, 20), 'f', ('arguments', [('arg', (1, 6, 1, 7), 'a', None, None)], [], None, [], [], None, [('Constant', (1, 8, 1, 9), 1, None)]), [('Pass', (1, 16, 1, 20))], [], None, None)], []),
1954('Module', [('FunctionDef', (1, 0, 1, 29), 'f', ('arguments', [('arg', (1, 6, 1, 7), 'a', None, None)], [('arg', (1, 14, 1, 15), 'b', None, None), ('arg', (1, 19, 1, 20), 'c', None, None)], None, [], [], None, [('Constant', (1, 8, 1, 9), 1, None), ('Constant', (1, 16, 1, 17), 2, None), ('Constant', (1, 21, 1, 22), 4, None)]), [('Pass', (1, 25, 1, 29))], [], None, None)], []),
1955('Module', [('FunctionDef', (1, 0, 1, 32), 'f', ('arguments', [('arg', (1, 6, 1, 7), 'a', None, None)], [('arg', (1, 14, 1, 15), 'b', None, None)], None, [('arg', (1, 22, 1, 23), 'c', None, None)], [('Constant', (1, 24, 1, 25), 4, None)], None, [('Constant', (1, 8, 1, 9), 1, None), ('Constant', (1, 16, 1, 17), 2, None)]), [('Pass', (1, 28, 1, 32))], [], None, None)], []),
1956('Module', [('FunctionDef', (1, 0, 1, 30), 'f', ('arguments', [('arg', (1, 6, 1, 7), 'a', None, None)], [('arg', (1, 14, 1, 15), 'b', None, None)], None, [('arg', (1, 22, 1, 23), 'c', None, None)], [None], None, [('Constant', (1, 8, 1, 9), 1, None), ('Constant', (1, 16, 1, 17), 2, None)]), [('Pass', (1, 26, 1, 30))], [], None, None)], []),
1957('Module', [('FunctionDef', (1, 0, 1, 42), 'f', ('arguments', [('arg', (1, 6, 1, 7), 'a', None, None)], [('arg', (1, 14, 1, 15), 'b', None, None)], None, [('arg', (1, 22, 1, 23), 'c', None, None)], [('Constant', (1, 24, 1, 25), 4, None)], ('arg', (1, 29, 1, 35), 'kwargs', None, None), [('Constant', (1, 8, 1, 9), 1, None), ('Constant', (1, 16, 1, 17), 2, None)]), [('Pass', (1, 38, 1, 42))], [], None, None)], []),
1958('Module', [('FunctionDef', (1, 0, 1, 40), 'f', ('arguments', [('arg', (1, 6, 1, 7), 'a', None, None)], [('arg', (1, 14, 1, 15), 'b', None, None)], None, [('arg', (1, 22, 1, 23), 'c', None, None)], [None], ('arg', (1, 27, 1, 33), 'kwargs', None, None), [('Constant', (1, 8, 1, 9), 1, None), ('Constant', (1, 16, 1, 17), 2, None)]), [('Pass', (1, 36, 1, 40))], [], None, None)], []),
Tim Peters400cbc32006-02-28 18:44:41 +00001959]
1960single_results = [
Serhiy Storchaka850a8852020-01-10 10:12:55 +02001961('Interactive', [('Expr', (1, 0, 1, 3), ('BinOp', (1, 0, 1, 3), ('Constant', (1, 0, 1, 1), 1, None), ('Add',), ('Constant', (1, 2, 1, 3), 2, None)))]),
Tim Peters400cbc32006-02-28 18:44:41 +00001962]
1963eval_results = [
Serhiy Storchaka850a8852020-01-10 10:12:55 +02001964('Expression', ('Constant', (1, 0, 1, 4), None, None)),
1965('Expression', ('BoolOp', (1, 0, 1, 7), ('And',), [('Name', (1, 0, 1, 1), 'a', ('Load',)), ('Name', (1, 6, 1, 7), 'b', ('Load',))])),
1966('Expression', ('BinOp', (1, 0, 1, 5), ('Name', (1, 0, 1, 1), 'a', ('Load',)), ('Add',), ('Name', (1, 4, 1, 5), 'b', ('Load',)))),
1967('Expression', ('UnaryOp', (1, 0, 1, 5), ('Not',), ('Name', (1, 4, 1, 5), 'v', ('Load',)))),
1968('Expression', ('Lambda', (1, 0, 1, 11), ('arguments', [], [], None, [], [], None, []), ('Constant', (1, 7, 1, 11), None, None))),
1969('Expression', ('Dict', (1, 0, 1, 7), [('Constant', (1, 2, 1, 3), 1, None)], [('Constant', (1, 4, 1, 5), 2, None)])),
1970('Expression', ('Dict', (1, 0, 1, 2), [], [])),
1971('Expression', ('Set', (1, 0, 1, 7), [('Constant', (1, 1, 1, 5), None, None)])),
1972('Expression', ('Dict', (1, 0, 5, 6), [('Constant', (2, 6, 2, 7), 1, None)], [('Constant', (4, 10, 4, 11), 2, None)])),
1973('Expression', ('ListComp', (1, 0, 1, 19), ('Name', (1, 1, 1, 2), 'a', ('Load',)), [('comprehension', ('Name', (1, 7, 1, 8), 'b', ('Store',)), ('Name', (1, 12, 1, 13), 'c', ('Load',)), [('Name', (1, 17, 1, 18), 'd', ('Load',))], 0)])),
1974('Expression', ('GeneratorExp', (1, 0, 1, 19), ('Name', (1, 1, 1, 2), 'a', ('Load',)), [('comprehension', ('Name', (1, 7, 1, 8), 'b', ('Store',)), ('Name', (1, 12, 1, 13), 'c', ('Load',)), [('Name', (1, 17, 1, 18), 'd', ('Load',))], 0)])),
1975('Expression', ('ListComp', (1, 0, 1, 20), ('Tuple', (1, 1, 1, 6), [('Name', (1, 2, 1, 3), 'a', ('Load',)), ('Name', (1, 4, 1, 5), 'b', ('Load',))], ('Load',)), [('comprehension', ('Tuple', (1, 11, 1, 14), [('Name', (1, 11, 1, 12), 'a', ('Store',)), ('Name', (1, 13, 1, 14), 'b', ('Store',))], ('Store',)), ('Name', (1, 18, 1, 19), 'c', ('Load',)), [], 0)])),
1976('Expression', ('ListComp', (1, 0, 1, 22), ('Tuple', (1, 1, 1, 6), [('Name', (1, 2, 1, 3), 'a', ('Load',)), ('Name', (1, 4, 1, 5), 'b', ('Load',))], ('Load',)), [('comprehension', ('Tuple', (1, 11, 1, 16), [('Name', (1, 12, 1, 13), 'a', ('Store',)), ('Name', (1, 14, 1, 15), 'b', ('Store',))], ('Store',)), ('Name', (1, 20, 1, 21), 'c', ('Load',)), [], 0)])),
1977('Expression', ('ListComp', (1, 0, 1, 22), ('Tuple', (1, 1, 1, 6), [('Name', (1, 2, 1, 3), 'a', ('Load',)), ('Name', (1, 4, 1, 5), 'b', ('Load',))], ('Load',)), [('comprehension', ('List', (1, 11, 1, 16), [('Name', (1, 12, 1, 13), 'a', ('Store',)), ('Name', (1, 14, 1, 15), 'b', ('Store',))], ('Store',)), ('Name', (1, 20, 1, 21), 'c', ('Load',)), [], 0)])),
1978('Expression', ('SetComp', (1, 0, 1, 20), ('Tuple', (1, 1, 1, 6), [('Name', (1, 2, 1, 3), 'a', ('Load',)), ('Name', (1, 4, 1, 5), 'b', ('Load',))], ('Load',)), [('comprehension', ('Tuple', (1, 11, 1, 14), [('Name', (1, 11, 1, 12), 'a', ('Store',)), ('Name', (1, 13, 1, 14), 'b', ('Store',))], ('Store',)), ('Name', (1, 18, 1, 19), 'c', ('Load',)), [], 0)])),
1979('Expression', ('SetComp', (1, 0, 1, 22), ('Tuple', (1, 1, 1, 6), [('Name', (1, 2, 1, 3), 'a', ('Load',)), ('Name', (1, 4, 1, 5), 'b', ('Load',))], ('Load',)), [('comprehension', ('Tuple', (1, 11, 1, 16), [('Name', (1, 12, 1, 13), 'a', ('Store',)), ('Name', (1, 14, 1, 15), 'b', ('Store',))], ('Store',)), ('Name', (1, 20, 1, 21), 'c', ('Load',)), [], 0)])),
1980('Expression', ('SetComp', (1, 0, 1, 22), ('Tuple', (1, 1, 1, 6), [('Name', (1, 2, 1, 3), 'a', ('Load',)), ('Name', (1, 4, 1, 5), 'b', ('Load',))], ('Load',)), [('comprehension', ('List', (1, 11, 1, 16), [('Name', (1, 12, 1, 13), 'a', ('Store',)), ('Name', (1, 14, 1, 15), 'b', ('Store',))], ('Store',)), ('Name', (1, 20, 1, 21), 'c', ('Load',)), [], 0)])),
1981('Expression', ('GeneratorExp', (1, 0, 1, 20), ('Tuple', (1, 1, 1, 6), [('Name', (1, 2, 1, 3), 'a', ('Load',)), ('Name', (1, 4, 1, 5), 'b', ('Load',))], ('Load',)), [('comprehension', ('Tuple', (1, 11, 1, 14), [('Name', (1, 11, 1, 12), 'a', ('Store',)), ('Name', (1, 13, 1, 14), 'b', ('Store',))], ('Store',)), ('Name', (1, 18, 1, 19), 'c', ('Load',)), [], 0)])),
1982('Expression', ('GeneratorExp', (1, 0, 1, 22), ('Tuple', (1, 1, 1, 6), [('Name', (1, 2, 1, 3), 'a', ('Load',)), ('Name', (1, 4, 1, 5), 'b', ('Load',))], ('Load',)), [('comprehension', ('Tuple', (1, 11, 1, 16), [('Name', (1, 12, 1, 13), 'a', ('Store',)), ('Name', (1, 14, 1, 15), 'b', ('Store',))], ('Store',)), ('Name', (1, 20, 1, 21), 'c', ('Load',)), [], 0)])),
1983('Expression', ('GeneratorExp', (1, 0, 1, 22), ('Tuple', (1, 1, 1, 6), [('Name', (1, 2, 1, 3), 'a', ('Load',)), ('Name', (1, 4, 1, 5), 'b', ('Load',))], ('Load',)), [('comprehension', ('List', (1, 11, 1, 16), [('Name', (1, 12, 1, 13), 'a', ('Store',)), ('Name', (1, 14, 1, 15), 'b', ('Store',))], ('Store',)), ('Name', (1, 20, 1, 21), 'c', ('Load',)), [], 0)])),
1984('Expression', ('Compare', (1, 0, 1, 9), ('Constant', (1, 0, 1, 1), 1, None), [('Lt',), ('Lt',)], [('Constant', (1, 4, 1, 5), 2, None), ('Constant', (1, 8, 1, 9), 3, None)])),
1985('Expression', ('Call', (1, 0, 1, 17), ('Name', (1, 0, 1, 1), 'f', ('Load',)), [('Constant', (1, 2, 1, 3), 1, None), ('Constant', (1, 4, 1, 5), 2, None), ('Starred', (1, 10, 1, 12), ('Name', (1, 11, 1, 12), 'd', ('Load',)), ('Load',))], [('keyword', 'c', ('Constant', (1, 8, 1, 9), 3, None)), ('keyword', None, ('Name', (1, 15, 1, 16), 'e', ('Load',)))])),
1986('Expression', ('Call', (1, 0, 1, 10), ('Name', (1, 0, 1, 1), 'f', ('Load',)), [('Starred', (1, 2, 1, 9), ('List', (1, 3, 1, 9), [('Constant', (1, 4, 1, 5), 0, None), ('Constant', (1, 7, 1, 8), 1, None)], ('Load',)), ('Load',))], [])),
1987('Expression', ('Call', (1, 0, 1, 15), ('Name', (1, 0, 1, 1), 'f', ('Load',)), [('GeneratorExp', (1, 1, 1, 15), ('Name', (1, 2, 1, 3), 'a', ('Load',)), [('comprehension', ('Name', (1, 8, 1, 9), 'a', ('Store',)), ('Name', (1, 13, 1, 14), 'b', ('Load',)), [], 0)])], [])),
1988('Expression', ('Constant', (1, 0, 1, 2), 10, None)),
1989('Expression', ('Constant', (1, 0, 1, 8), 'string', None)),
1990('Expression', ('Attribute', (1, 0, 1, 3), ('Name', (1, 0, 1, 1), 'a', ('Load',)), 'b', ('Load',))),
1991('Expression', ('Subscript', (1, 0, 1, 6), ('Name', (1, 0, 1, 1), 'a', ('Load',)), ('Slice', ('Name', (1, 2, 1, 3), 'b', ('Load',)), ('Name', (1, 4, 1, 5), 'c', ('Load',)), None), ('Load',))),
1992('Expression', ('Name', (1, 0, 1, 1), 'v', ('Load',))),
1993('Expression', ('List', (1, 0, 1, 7), [('Constant', (1, 1, 1, 2), 1, None), ('Constant', (1, 3, 1, 4), 2, None), ('Constant', (1, 5, 1, 6), 3, None)], ('Load',))),
1994('Expression', ('List', (1, 0, 1, 2), [], ('Load',))),
1995('Expression', ('Tuple', (1, 0, 1, 5), [('Constant', (1, 0, 1, 1), 1, None), ('Constant', (1, 2, 1, 3), 2, None), ('Constant', (1, 4, 1, 5), 3, None)], ('Load',))),
1996('Expression', ('Tuple', (1, 0, 1, 7), [('Constant', (1, 1, 1, 2), 1, None), ('Constant', (1, 3, 1, 4), 2, None), ('Constant', (1, 5, 1, 6), 3, None)], ('Load',))),
1997('Expression', ('Tuple', (1, 0, 1, 2), [], ('Load',))),
1998('Expression', ('Call', (1, 0, 1, 17), ('Attribute', (1, 0, 1, 7), ('Attribute', (1, 0, 1, 5), ('Attribute', (1, 0, 1, 3), ('Name', (1, 0, 1, 1), 'a', ('Load',)), 'b', ('Load',)), 'c', ('Load',)), 'd', ('Load',)), [('Subscript', (1, 8, 1, 16), ('Attribute', (1, 8, 1, 11), ('Name', (1, 8, 1, 9), 'a', ('Load',)), 'b', ('Load',)), ('Slice', ('Constant', (1, 12, 1, 13), 1, None), ('Constant', (1, 14, 1, 15), 2, None), None), ('Load',))], [])),
Tim Peters400cbc32006-02-28 18:44:41 +00001999]
Neal Norwitzee9b10a2008-03-31 05:29:39 +00002000main()