blob: c1e9f002811152cf2997c5a55113de0e6a47dae1 [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):
Serhiy Storchakab7e95252020-03-10 00:07:47 +0200356 x.args
357 self.assertIsNone(x.vararg)
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500358
Pablo Galindo8c77b8c2019-04-29 13:36:57 +0100359 x = ast.arguments(*range(1, 8))
Serhiy Storchakab7e95252020-03-10 00:07:47 +0200360 self.assertEqual(x.args, 2)
Pablo Galindo8c77b8c2019-04-29 13:36:57 +0100361 self.assertEqual(x.vararg, 3)
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500362
363 def test_field_attr_writable(self):
364 x = ast.Num()
365 # We can assign to _fields
366 x._fields = 666
367 self.assertEqual(x._fields, 666)
368
369 def test_classattrs(self):
370 x = ast.Num()
Guido van Rossum10f8ce62019-03-13 13:00:46 -0700371 self.assertEqual(x._fields, ('value', 'kind'))
Serhiy Storchaka3f228112018-09-27 17:42:37 +0300372
373 with self.assertRaises(AttributeError):
374 x.value
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500375
376 with self.assertRaises(AttributeError):
377 x.n
378
379 x = ast.Num(42)
Serhiy Storchaka3f228112018-09-27 17:42:37 +0300380 self.assertEqual(x.value, 42)
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500381 self.assertEqual(x.n, 42)
382
383 with self.assertRaises(AttributeError):
384 x.lineno
385
386 with self.assertRaises(AttributeError):
387 x.foobar
388
389 x = ast.Num(lineno=2)
390 self.assertEqual(x.lineno, 2)
391
392 x = ast.Num(42, lineno=0)
393 self.assertEqual(x.lineno, 0)
Guido van Rossum10f8ce62019-03-13 13:00:46 -0700394 self.assertEqual(x._fields, ('value', 'kind'))
Serhiy Storchaka3f228112018-09-27 17:42:37 +0300395 self.assertEqual(x.value, 42)
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500396 self.assertEqual(x.n, 42)
397
Guido van Rossum10f8ce62019-03-13 13:00:46 -0700398 self.assertRaises(TypeError, ast.Num, 1, None, 2)
399 self.assertRaises(TypeError, ast.Num, 1, None, 2, lineno=0)
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500400
Serhiy Storchaka3f228112018-09-27 17:42:37 +0300401 self.assertEqual(ast.Num(42).n, 42)
402 self.assertEqual(ast.Num(4.25).n, 4.25)
403 self.assertEqual(ast.Num(4.25j).n, 4.25j)
404 self.assertEqual(ast.Str('42').s, '42')
405 self.assertEqual(ast.Bytes(b'42').s, b'42')
406 self.assertIs(ast.NameConstant(True).value, True)
407 self.assertIs(ast.NameConstant(False).value, False)
408 self.assertIs(ast.NameConstant(None).value, None)
409
410 self.assertEqual(ast.Constant(42).value, 42)
411 self.assertEqual(ast.Constant(4.25).value, 4.25)
412 self.assertEqual(ast.Constant(4.25j).value, 4.25j)
413 self.assertEqual(ast.Constant('42').value, '42')
414 self.assertEqual(ast.Constant(b'42').value, b'42')
415 self.assertIs(ast.Constant(True).value, True)
416 self.assertIs(ast.Constant(False).value, False)
417 self.assertIs(ast.Constant(None).value, None)
418 self.assertIs(ast.Constant(...).value, ...)
419
420 def test_realtype(self):
421 self.assertEqual(type(ast.Num(42)), ast.Constant)
422 self.assertEqual(type(ast.Num(4.25)), ast.Constant)
423 self.assertEqual(type(ast.Num(4.25j)), ast.Constant)
424 self.assertEqual(type(ast.Str('42')), ast.Constant)
425 self.assertEqual(type(ast.Bytes(b'42')), ast.Constant)
426 self.assertEqual(type(ast.NameConstant(True)), ast.Constant)
427 self.assertEqual(type(ast.NameConstant(False)), ast.Constant)
428 self.assertEqual(type(ast.NameConstant(None)), ast.Constant)
429 self.assertEqual(type(ast.Ellipsis()), ast.Constant)
430
431 def test_isinstance(self):
432 self.assertTrue(isinstance(ast.Num(42), ast.Num))
433 self.assertTrue(isinstance(ast.Num(4.2), ast.Num))
434 self.assertTrue(isinstance(ast.Num(4.2j), ast.Num))
435 self.assertTrue(isinstance(ast.Str('42'), ast.Str))
436 self.assertTrue(isinstance(ast.Bytes(b'42'), ast.Bytes))
437 self.assertTrue(isinstance(ast.NameConstant(True), ast.NameConstant))
438 self.assertTrue(isinstance(ast.NameConstant(False), ast.NameConstant))
439 self.assertTrue(isinstance(ast.NameConstant(None), ast.NameConstant))
440 self.assertTrue(isinstance(ast.Ellipsis(), ast.Ellipsis))
441
442 self.assertTrue(isinstance(ast.Constant(42), ast.Num))
443 self.assertTrue(isinstance(ast.Constant(4.2), ast.Num))
444 self.assertTrue(isinstance(ast.Constant(4.2j), ast.Num))
445 self.assertTrue(isinstance(ast.Constant('42'), ast.Str))
446 self.assertTrue(isinstance(ast.Constant(b'42'), ast.Bytes))
447 self.assertTrue(isinstance(ast.Constant(True), ast.NameConstant))
448 self.assertTrue(isinstance(ast.Constant(False), ast.NameConstant))
449 self.assertTrue(isinstance(ast.Constant(None), ast.NameConstant))
450 self.assertTrue(isinstance(ast.Constant(...), ast.Ellipsis))
451
452 self.assertFalse(isinstance(ast.Str('42'), ast.Num))
453 self.assertFalse(isinstance(ast.Num(42), ast.Str))
454 self.assertFalse(isinstance(ast.Str('42'), ast.Bytes))
455 self.assertFalse(isinstance(ast.Num(42), ast.NameConstant))
456 self.assertFalse(isinstance(ast.Num(42), ast.Ellipsis))
Anthony Sottile74176222019-01-18 11:30:28 -0800457 self.assertFalse(isinstance(ast.NameConstant(True), ast.Num))
458 self.assertFalse(isinstance(ast.NameConstant(False), ast.Num))
Serhiy Storchaka3f228112018-09-27 17:42:37 +0300459
460 self.assertFalse(isinstance(ast.Constant('42'), ast.Num))
461 self.assertFalse(isinstance(ast.Constant(42), ast.Str))
462 self.assertFalse(isinstance(ast.Constant('42'), ast.Bytes))
463 self.assertFalse(isinstance(ast.Constant(42), ast.NameConstant))
464 self.assertFalse(isinstance(ast.Constant(42), ast.Ellipsis))
Anthony Sottile74176222019-01-18 11:30:28 -0800465 self.assertFalse(isinstance(ast.Constant(True), ast.Num))
466 self.assertFalse(isinstance(ast.Constant(False), ast.Num))
Serhiy Storchaka3f228112018-09-27 17:42:37 +0300467
468 self.assertFalse(isinstance(ast.Constant(), ast.Num))
469 self.assertFalse(isinstance(ast.Constant(), ast.Str))
470 self.assertFalse(isinstance(ast.Constant(), ast.Bytes))
471 self.assertFalse(isinstance(ast.Constant(), ast.NameConstant))
472 self.assertFalse(isinstance(ast.Constant(), ast.Ellipsis))
473
Serhiy Storchaka6015cc52018-10-28 13:43:03 +0200474 class S(str): pass
475 self.assertTrue(isinstance(ast.Constant(S('42')), ast.Str))
476 self.assertFalse(isinstance(ast.Constant(S('42')), ast.Num))
477
Serhiy Storchaka3f228112018-09-27 17:42:37 +0300478 def test_subclasses(self):
479 class N(ast.Num):
480 def __init__(self, *args, **kwargs):
481 super().__init__(*args, **kwargs)
482 self.z = 'spam'
483 class N2(ast.Num):
484 pass
485
486 n = N(42)
487 self.assertEqual(n.n, 42)
488 self.assertEqual(n.z, 'spam')
489 self.assertEqual(type(n), N)
490 self.assertTrue(isinstance(n, N))
491 self.assertTrue(isinstance(n, ast.Num))
492 self.assertFalse(isinstance(n, N2))
493 self.assertFalse(isinstance(ast.Num(42), N))
494 n = N(n=42)
495 self.assertEqual(n.n, 42)
496 self.assertEqual(type(n), N)
497
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500498 def test_module(self):
499 body = [ast.Num(42)]
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800500 x = ast.Module(body, [])
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500501 self.assertEqual(x.body, body)
502
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000503 def test_nodeclasses(self):
Florent Xicluna992d9e02011-11-11 19:35:42 +0100504 # Zero arguments constructor explicitly allowed
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500505 x = ast.BinOp()
506 self.assertEqual(x._fields, ('left', 'op', 'right'))
507
508 # Random attribute allowed too
509 x.foobarbaz = 5
510 self.assertEqual(x.foobarbaz, 5)
511
512 n1 = ast.Num(1)
513 n3 = ast.Num(3)
514 addop = ast.Add()
515 x = ast.BinOp(n1, addop, n3)
516 self.assertEqual(x.left, n1)
517 self.assertEqual(x.op, addop)
518 self.assertEqual(x.right, n3)
Benjamin Peterson68b543a2011-06-27 17:51:18 -0500519
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500520 x = ast.BinOp(1, 2, 3)
521 self.assertEqual(x.left, 1)
522 self.assertEqual(x.op, 2)
523 self.assertEqual(x.right, 3)
524
Georg Brandl0c77a822008-06-10 16:37:50 +0000525 x = ast.BinOp(1, 2, 3, lineno=0)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000526 self.assertEqual(x.left, 1)
527 self.assertEqual(x.op, 2)
528 self.assertEqual(x.right, 3)
529 self.assertEqual(x.lineno, 0)
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000530
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)
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500533 # node raises exception when given too many arguments
534 self.assertRaises(TypeError, ast.BinOp, 1, 2, 3, 4, lineno=0)
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000535
536 # can set attributes through kwargs too
Georg Brandl0c77a822008-06-10 16:37:50 +0000537 x = ast.BinOp(left=1, op=2, right=3, lineno=0)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000538 self.assertEqual(x.left, 1)
539 self.assertEqual(x.op, 2)
540 self.assertEqual(x.right, 3)
541 self.assertEqual(x.lineno, 0)
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000542
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500543 # Random kwargs also allowed
544 x = ast.BinOp(1, 2, 3, foobarbaz=42)
545 self.assertEqual(x.foobarbaz, 42)
546
547 def test_no_fields(self):
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000548 # this used to fail because Sub._fields was None
Georg Brandl0c77a822008-06-10 16:37:50 +0000549 x = ast.Sub()
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500550 self.assertEqual(x._fields, ())
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000551
552 def test_pickling(self):
553 import pickle
554 mods = [pickle]
555 try:
556 import cPickle
557 mods.append(cPickle)
558 except ImportError:
559 pass
560 protocols = [0, 1, 2]
561 for mod in mods:
562 for protocol in protocols:
563 for ast in (compile(i, "?", "exec", 0x400) for i in exec_tests):
564 ast2 = mod.loads(mod.dumps(ast, protocol))
Ezio Melottib3aedd42010-11-20 19:04:17 +0000565 self.assertEqual(to_tuple(ast2), to_tuple(ast))
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000566
Benjamin Peterson5b066812010-11-20 01:38:49 +0000567 def test_invalid_sum(self):
568 pos = dict(lineno=2, col_offset=3)
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800569 m = ast.Module([ast.Expr(ast.expr(**pos), **pos)], [])
Benjamin Peterson5b066812010-11-20 01:38:49 +0000570 with self.assertRaises(TypeError) as cm:
571 compile(m, "<test>", "exec")
572 self.assertIn("but got <_ast.expr", str(cm.exception))
573
Min ho Kimc4cacc82019-07-31 08:16:13 +1000574 def test_invalid_identifier(self):
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800575 m = ast.Module([ast.Expr(ast.Name(42, ast.Load()))], [])
Benjamin Peterson2193d2b2011-07-22 10:50:23 -0500576 ast.fix_missing_locations(m)
577 with self.assertRaises(TypeError) as cm:
578 compile(m, "<test>", "exec")
579 self.assertIn("identifier must be of type str", str(cm.exception))
580
Mark Dickinsonded35ae2012-11-25 14:36:26 +0000581 def test_empty_yield_from(self):
582 # Issue 16546: yield from value is not optional.
583 empty_yield_from = ast.parse("def f():\n yield from g()")
584 empty_yield_from.body[0].body[0].value.value = None
585 with self.assertRaises(ValueError) as cm:
586 compile(empty_yield_from, "<test>", "exec")
587 self.assertIn("field value is required", str(cm.exception))
588
Oren Milman7dc46d82017-09-30 20:16:24 +0300589 @support.cpython_only
590 def test_issue31592(self):
591 # There shouldn't be an assertion failure in case of a bad
592 # unicodedata.normalize().
593 import unicodedata
594 def bad_normalize(*args):
595 return None
596 with support.swap_attr(unicodedata, 'normalize', bad_normalize):
597 self.assertRaises(TypeError, ast.parse, '\u03D5')
598
Carl Friedrich Bolz-Tereick110a47c2019-07-08 23:17:56 +0200599 def test_issue18374_binop_col_offset(self):
600 tree = ast.parse('4+5+6+7')
601 parent_binop = tree.body[0].value
602 child_binop = parent_binop.left
603 grandchild_binop = child_binop.left
604 self.assertEqual(parent_binop.col_offset, 0)
605 self.assertEqual(parent_binop.end_col_offset, 7)
606 self.assertEqual(child_binop.col_offset, 0)
607 self.assertEqual(child_binop.end_col_offset, 5)
608 self.assertEqual(grandchild_binop.col_offset, 0)
609 self.assertEqual(grandchild_binop.end_col_offset, 3)
610
611 tree = ast.parse('4+5-\\\n 6-7')
612 parent_binop = tree.body[0].value
613 child_binop = parent_binop.left
614 grandchild_binop = child_binop.left
615 self.assertEqual(parent_binop.col_offset, 0)
616 self.assertEqual(parent_binop.lineno, 1)
617 self.assertEqual(parent_binop.end_col_offset, 4)
618 self.assertEqual(parent_binop.end_lineno, 2)
619
620 self.assertEqual(child_binop.col_offset, 0)
Carl Friedrich Bolz-Tereick430a9f42019-07-09 14:20:01 +0200621 self.assertEqual(child_binop.lineno, 1)
Carl Friedrich Bolz-Tereick110a47c2019-07-08 23:17:56 +0200622 self.assertEqual(child_binop.end_col_offset, 2)
Carl Friedrich Bolz-Tereick430a9f42019-07-09 14:20:01 +0200623 self.assertEqual(child_binop.end_lineno, 2)
Carl Friedrich Bolz-Tereick110a47c2019-07-08 23:17:56 +0200624
625 self.assertEqual(grandchild_binop.col_offset, 0)
Carl Friedrich Bolz-Tereick430a9f42019-07-09 14:20:01 +0200626 self.assertEqual(grandchild_binop.lineno, 1)
Carl Friedrich Bolz-Tereick110a47c2019-07-08 23:17:56 +0200627 self.assertEqual(grandchild_binop.end_col_offset, 3)
Carl Friedrich Bolz-Tereick430a9f42019-07-09 14:20:01 +0200628 self.assertEqual(grandchild_binop.end_lineno, 1)
Georg Brandl0c77a822008-06-10 16:37:50 +0000629
Lysandros Nikolaoud2e10982020-02-08 00:36:32 +0100630 def test_issue39579_dotted_name_end_col_offset(self):
631 tree = ast.parse('@a.b.c\ndef f(): pass')
632 attr_b = tree.body[0].decorator_list[0].value
633 self.assertEqual(attr_b.end_col_offset, 4)
634
Georg Brandl0c77a822008-06-10 16:37:50 +0000635class ASTHelpers_Test(unittest.TestCase):
Guido van Rossum10f8ce62019-03-13 13:00:46 -0700636 maxDiff = None
Georg Brandl0c77a822008-06-10 16:37:50 +0000637
638 def test_parse(self):
639 a = ast.parse('foo(1 + 1)')
640 b = compile('foo(1 + 1)', '<unknown>', 'exec', ast.PyCF_ONLY_AST)
641 self.assertEqual(ast.dump(a), ast.dump(b))
642
Benjamin Peterson2e2c9032012-09-02 14:23:15 -0400643 def test_parse_in_error(self):
644 try:
645 1/0
646 except Exception:
Benjamin Petersonbd0df502012-09-02 15:04:51 -0400647 with self.assertRaises(SyntaxError) as e:
648 ast.literal_eval(r"'\U'")
649 self.assertIsNotNone(e.exception.__context__)
Benjamin Peterson2e2c9032012-09-02 14:23:15 -0400650
Georg Brandl0c77a822008-06-10 16:37:50 +0000651 def test_dump(self):
652 node = ast.parse('spam(eggs, "and cheese")')
653 self.assertEqual(ast.dump(node),
654 "Module(body=[Expr(value=Call(func=Name(id='spam', ctx=Load()), "
Serhiy Storchakab7e95252020-03-10 00:07:47 +0200655 "args=[Name(id='eggs', ctx=Load()), Constant(value='and cheese')], "
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800656 "keywords=[]))], type_ignores=[])"
Georg Brandl0c77a822008-06-10 16:37:50 +0000657 )
658 self.assertEqual(ast.dump(node, annotate_fields=False),
659 "Module([Expr(Call(Name('spam', Load()), [Name('eggs', Load()), "
Serhiy Storchakab7e95252020-03-10 00:07:47 +0200660 "Constant('and cheese')], []))], [])"
Georg Brandl0c77a822008-06-10 16:37:50 +0000661 )
662 self.assertEqual(ast.dump(node, include_attributes=True),
663 "Module(body=[Expr(value=Call(func=Name(id='spam', ctx=Load(), "
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000664 "lineno=1, col_offset=0, end_lineno=1, end_col_offset=4), "
665 "args=[Name(id='eggs', ctx=Load(), lineno=1, col_offset=5, "
Serhiy Storchakab7e95252020-03-10 00:07:47 +0200666 "end_lineno=1, end_col_offset=9), Constant(value='and cheese', "
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000667 "lineno=1, col_offset=11, end_lineno=1, end_col_offset=23)], keywords=[], "
668 "lineno=1, col_offset=0, end_lineno=1, end_col_offset=24), "
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800669 "lineno=1, col_offset=0, end_lineno=1, end_col_offset=24)], type_ignores=[])"
Georg Brandl0c77a822008-06-10 16:37:50 +0000670 )
671
Serhiy Storchaka850573b2019-09-09 19:33:13 +0300672 def test_dump_indent(self):
673 node = ast.parse('spam(eggs, "and cheese")')
674 self.assertEqual(ast.dump(node, indent=3), """\
675Module(
676 body=[
677 Expr(
678 value=Call(
679 func=Name(id='spam', ctx=Load()),
680 args=[
681 Name(id='eggs', ctx=Load()),
Serhiy Storchakab7e95252020-03-10 00:07:47 +0200682 Constant(value='and cheese')],
Serhiy Storchaka850573b2019-09-09 19:33:13 +0300683 keywords=[]))],
684 type_ignores=[])""")
685 self.assertEqual(ast.dump(node, annotate_fields=False, indent='\t'), """\
686Module(
687\t[
688\t\tExpr(
689\t\t\tCall(
690\t\t\t\tName('spam', Load()),
691\t\t\t\t[
692\t\t\t\t\tName('eggs', Load()),
Serhiy Storchakab7e95252020-03-10 00:07:47 +0200693\t\t\t\t\tConstant('and cheese')],
Serhiy Storchaka850573b2019-09-09 19:33:13 +0300694\t\t\t\t[]))],
695\t[])""")
696 self.assertEqual(ast.dump(node, include_attributes=True, indent=3), """\
697Module(
698 body=[
699 Expr(
700 value=Call(
701 func=Name(
702 id='spam',
703 ctx=Load(),
704 lineno=1,
705 col_offset=0,
706 end_lineno=1,
707 end_col_offset=4),
708 args=[
709 Name(
710 id='eggs',
711 ctx=Load(),
712 lineno=1,
713 col_offset=5,
714 end_lineno=1,
715 end_col_offset=9),
716 Constant(
717 value='and cheese',
Serhiy Storchaka850573b2019-09-09 19:33:13 +0300718 lineno=1,
719 col_offset=11,
720 end_lineno=1,
721 end_col_offset=23)],
722 keywords=[],
723 lineno=1,
724 col_offset=0,
725 end_lineno=1,
726 end_col_offset=24),
727 lineno=1,
728 col_offset=0,
729 end_lineno=1,
730 end_col_offset=24)],
731 type_ignores=[])""")
732
Serhiy Storchakae64f9482019-08-29 09:30:23 +0300733 def test_dump_incomplete(self):
734 node = ast.Raise(lineno=3, col_offset=4)
735 self.assertEqual(ast.dump(node),
736 "Raise()"
737 )
738 self.assertEqual(ast.dump(node, include_attributes=True),
739 "Raise(lineno=3, col_offset=4)"
740 )
741 node = ast.Raise(exc=ast.Name(id='e', ctx=ast.Load()), lineno=3, col_offset=4)
742 self.assertEqual(ast.dump(node),
743 "Raise(exc=Name(id='e', ctx=Load()))"
744 )
745 self.assertEqual(ast.dump(node, annotate_fields=False),
746 "Raise(Name('e', Load()))"
747 )
748 self.assertEqual(ast.dump(node, include_attributes=True),
749 "Raise(exc=Name(id='e', ctx=Load()), lineno=3, col_offset=4)"
750 )
751 self.assertEqual(ast.dump(node, annotate_fields=False, include_attributes=True),
752 "Raise(Name('e', Load()), lineno=3, col_offset=4)"
753 )
754 node = ast.Raise(cause=ast.Name(id='e', ctx=ast.Load()))
755 self.assertEqual(ast.dump(node),
756 "Raise(cause=Name(id='e', ctx=Load()))"
757 )
758 self.assertEqual(ast.dump(node, annotate_fields=False),
759 "Raise(cause=Name('e', Load()))"
760 )
761
Georg Brandl0c77a822008-06-10 16:37:50 +0000762 def test_copy_location(self):
763 src = ast.parse('1 + 1', mode='eval')
764 src.body.right = ast.copy_location(ast.Num(2), src.body.right)
765 self.assertEqual(ast.dump(src, include_attributes=True),
Serhiy Storchakab7e95252020-03-10 00:07:47 +0200766 'Expression(body=BinOp(left=Constant(value=1, lineno=1, col_offset=0, '
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000767 'end_lineno=1, end_col_offset=1), op=Add(), right=Constant(value=2, '
768 'lineno=1, col_offset=4, end_lineno=1, end_col_offset=5), lineno=1, '
769 'col_offset=0, end_lineno=1, end_col_offset=5))'
Georg Brandl0c77a822008-06-10 16:37:50 +0000770 )
771
772 def test_fix_missing_locations(self):
773 src = ast.parse('write("spam")')
774 src.body.append(ast.Expr(ast.Call(ast.Name('spam', ast.Load()),
Benjamin Peterson025e9eb2015-05-05 20:16:41 -0400775 [ast.Str('eggs')], [])))
Georg Brandl0c77a822008-06-10 16:37:50 +0000776 self.assertEqual(src, ast.fix_missing_locations(src))
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000777 self.maxDiff = None
Georg Brandl0c77a822008-06-10 16:37:50 +0000778 self.assertEqual(ast.dump(src, include_attributes=True),
779 "Module(body=[Expr(value=Call(func=Name(id='write', ctx=Load(), "
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000780 "lineno=1, col_offset=0, end_lineno=1, end_col_offset=5), "
Serhiy Storchakab7e95252020-03-10 00:07:47 +0200781 "args=[Constant(value='spam', lineno=1, col_offset=6, end_lineno=1, "
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000782 "end_col_offset=12)], keywords=[], lineno=1, col_offset=0, end_lineno=1, "
783 "end_col_offset=13), lineno=1, col_offset=0, end_lineno=1, "
784 "end_col_offset=13), Expr(value=Call(func=Name(id='spam', ctx=Load(), "
785 "lineno=1, col_offset=0, end_lineno=1, end_col_offset=0), "
786 "args=[Constant(value='eggs', lineno=1, col_offset=0, end_lineno=1, "
787 "end_col_offset=0)], keywords=[], lineno=1, col_offset=0, end_lineno=1, "
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800788 "end_col_offset=0), lineno=1, col_offset=0, end_lineno=1, end_col_offset=0)], "
789 "type_ignores=[])"
Georg Brandl0c77a822008-06-10 16:37:50 +0000790 )
791
792 def test_increment_lineno(self):
793 src = ast.parse('1 + 1', mode='eval')
794 self.assertEqual(ast.increment_lineno(src, n=3), src)
795 self.assertEqual(ast.dump(src, include_attributes=True),
Serhiy Storchakab7e95252020-03-10 00:07:47 +0200796 'Expression(body=BinOp(left=Constant(value=1, lineno=4, col_offset=0, '
797 'end_lineno=4, end_col_offset=1), op=Add(), right=Constant(value=1, '
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000798 'lineno=4, col_offset=4, end_lineno=4, end_col_offset=5), lineno=4, '
799 'col_offset=0, end_lineno=4, end_col_offset=5))'
Georg Brandl0c77a822008-06-10 16:37:50 +0000800 )
Georg Brandl619e7ba2011-01-09 07:38:51 +0000801 # issue10869: do not increment lineno of root twice
Georg Brandlefb69022011-01-09 07:50:48 +0000802 src = ast.parse('1 + 1', mode='eval')
Georg Brandl619e7ba2011-01-09 07:38:51 +0000803 self.assertEqual(ast.increment_lineno(src.body, n=3), src.body)
804 self.assertEqual(ast.dump(src, include_attributes=True),
Serhiy Storchakab7e95252020-03-10 00:07:47 +0200805 'Expression(body=BinOp(left=Constant(value=1, lineno=4, col_offset=0, '
806 'end_lineno=4, end_col_offset=1), op=Add(), right=Constant(value=1, '
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000807 'lineno=4, col_offset=4, end_lineno=4, end_col_offset=5), lineno=4, '
808 'col_offset=0, end_lineno=4, end_col_offset=5))'
Georg Brandl619e7ba2011-01-09 07:38:51 +0000809 )
Georg Brandl0c77a822008-06-10 16:37:50 +0000810
811 def test_iter_fields(self):
812 node = ast.parse('foo()', mode='eval')
813 d = dict(ast.iter_fields(node.body))
814 self.assertEqual(d.pop('func').id, 'foo')
Benjamin Peterson025e9eb2015-05-05 20:16:41 -0400815 self.assertEqual(d, {'keywords': [], 'args': []})
Georg Brandl0c77a822008-06-10 16:37:50 +0000816
817 def test_iter_child_nodes(self):
818 node = ast.parse("spam(23, 42, eggs='leek')", mode='eval')
819 self.assertEqual(len(list(ast.iter_child_nodes(node.body))), 4)
820 iterator = ast.iter_child_nodes(node.body)
821 self.assertEqual(next(iterator).id, 'spam')
Serhiy Storchaka3f228112018-09-27 17:42:37 +0300822 self.assertEqual(next(iterator).value, 23)
823 self.assertEqual(next(iterator).value, 42)
Georg Brandl0c77a822008-06-10 16:37:50 +0000824 self.assertEqual(ast.dump(next(iterator)),
Serhiy Storchakab7e95252020-03-10 00:07:47 +0200825 "keyword(arg='eggs', value=Constant(value='leek'))"
Georg Brandl0c77a822008-06-10 16:37:50 +0000826 )
827
828 def test_get_docstring(self):
Serhiy Storchaka08f127a2018-06-15 11:05:15 +0300829 node = ast.parse('"""line one\n line two"""')
830 self.assertEqual(ast.get_docstring(node),
831 'line one\nline two')
832
833 node = ast.parse('class foo:\n """line one\n line two"""')
834 self.assertEqual(ast.get_docstring(node.body[0]),
835 'line one\nline two')
836
Georg Brandl0c77a822008-06-10 16:37:50 +0000837 node = ast.parse('def foo():\n """line one\n line two"""')
838 self.assertEqual(ast.get_docstring(node.body[0]),
839 'line one\nline two')
840
Yury Selivanov2f07a662015-07-23 08:54:35 +0300841 node = ast.parse('async def foo():\n """spam\n ham"""')
842 self.assertEqual(ast.get_docstring(node.body[0]), 'spam\nham')
Serhiy Storchaka08f127a2018-06-15 11:05:15 +0300843
844 def test_get_docstring_none(self):
Matthias Bussonnier41cea702017-02-23 22:44:19 -0800845 self.assertIsNone(ast.get_docstring(ast.parse('')))
Serhiy Storchaka08f127a2018-06-15 11:05:15 +0300846 node = ast.parse('x = "not docstring"')
847 self.assertIsNone(ast.get_docstring(node))
848 node = ast.parse('def foo():\n pass')
849 self.assertIsNone(ast.get_docstring(node))
850
851 node = ast.parse('class foo:\n pass')
852 self.assertIsNone(ast.get_docstring(node.body[0]))
853 node = ast.parse('class foo:\n x = "not docstring"')
854 self.assertIsNone(ast.get_docstring(node.body[0]))
855 node = ast.parse('class foo:\n def bar(self): pass')
856 self.assertIsNone(ast.get_docstring(node.body[0]))
857
858 node = ast.parse('def foo():\n pass')
859 self.assertIsNone(ast.get_docstring(node.body[0]))
860 node = ast.parse('def foo():\n x = "not docstring"')
861 self.assertIsNone(ast.get_docstring(node.body[0]))
862
863 node = ast.parse('async def foo():\n pass')
864 self.assertIsNone(ast.get_docstring(node.body[0]))
865 node = ast.parse('async def foo():\n x = "not docstring"')
866 self.assertIsNone(ast.get_docstring(node.body[0]))
Yury Selivanov2f07a662015-07-23 08:54:35 +0300867
Anthony Sottile995d9b92019-01-12 20:05:13 -0800868 def test_multi_line_docstring_col_offset_and_lineno_issue16806(self):
869 node = ast.parse(
870 '"""line one\nline two"""\n\n'
871 'def foo():\n """line one\n line two"""\n\n'
872 ' def bar():\n """line one\n line two"""\n'
873 ' """line one\n line two"""\n'
874 '"""line one\nline two"""\n\n'
875 )
876 self.assertEqual(node.body[0].col_offset, 0)
877 self.assertEqual(node.body[0].lineno, 1)
878 self.assertEqual(node.body[1].body[0].col_offset, 2)
879 self.assertEqual(node.body[1].body[0].lineno, 5)
880 self.assertEqual(node.body[1].body[1].body[0].col_offset, 4)
881 self.assertEqual(node.body[1].body[1].body[0].lineno, 9)
882 self.assertEqual(node.body[1].body[2].col_offset, 2)
883 self.assertEqual(node.body[1].body[2].lineno, 11)
884 self.assertEqual(node.body[2].col_offset, 0)
885 self.assertEqual(node.body[2].lineno, 13)
886
Lysandros Nikolaou025a6022019-12-12 22:40:21 +0100887 def test_elif_stmt_start_position(self):
888 node = ast.parse('if a:\n pass\nelif b:\n pass\n')
889 elif_stmt = node.body[0].orelse[0]
890 self.assertEqual(elif_stmt.lineno, 3)
891 self.assertEqual(elif_stmt.col_offset, 0)
892
Lysandros Nikolaou5936a4c2019-12-14 11:24:57 +0100893 def test_elif_stmt_start_position_with_else(self):
894 node = ast.parse('if a:\n pass\nelif b:\n pass\nelse:\n pass\n')
895 elif_stmt = node.body[0].orelse[0]
896 self.assertEqual(elif_stmt.lineno, 3)
897 self.assertEqual(elif_stmt.col_offset, 0)
898
Lysandros Nikolaou50d4f122019-12-18 01:20:55 +0100899 def test_starred_expr_end_position_within_call(self):
900 node = ast.parse('f(*[0, 1])')
901 starred_expr = node.body[0].value.args[0]
902 self.assertEqual(starred_expr.end_lineno, 1)
903 self.assertEqual(starred_expr.end_col_offset, 9)
904
Georg Brandl0c77a822008-06-10 16:37:50 +0000905 def test_literal_eval(self):
906 self.assertEqual(ast.literal_eval('[1, 2, 3]'), [1, 2, 3])
907 self.assertEqual(ast.literal_eval('{"foo": 42}'), {"foo": 42})
908 self.assertEqual(ast.literal_eval('(True, False, None)'), (True, False, None))
Benjamin Peterson3e742892010-07-11 12:59:24 +0000909 self.assertEqual(ast.literal_eval('{1, 2, 3}'), {1, 2, 3})
Benjamin Peterson5ef96e52010-07-11 23:06:06 +0000910 self.assertEqual(ast.literal_eval('b"hi"'), b"hi")
Raymond Hettinger4fcf5c12020-01-02 22:21:18 -0700911 self.assertEqual(ast.literal_eval('set()'), set())
Georg Brandl0c77a822008-06-10 16:37:50 +0000912 self.assertRaises(ValueError, ast.literal_eval, 'foo()')
Serhiy Storchakad8ac4d12018-01-04 11:15:39 +0200913 self.assertEqual(ast.literal_eval('6'), 6)
914 self.assertEqual(ast.literal_eval('+6'), 6)
Raymond Hettingerbc959732010-10-08 00:47:45 +0000915 self.assertEqual(ast.literal_eval('-6'), -6)
Raymond Hettingerbc959732010-10-08 00:47:45 +0000916 self.assertEqual(ast.literal_eval('3.25'), 3.25)
Serhiy Storchakad8ac4d12018-01-04 11:15:39 +0200917 self.assertEqual(ast.literal_eval('+3.25'), 3.25)
918 self.assertEqual(ast.literal_eval('-3.25'), -3.25)
919 self.assertEqual(repr(ast.literal_eval('-0.0')), '-0.0')
920 self.assertRaises(ValueError, ast.literal_eval, '++6')
921 self.assertRaises(ValueError, ast.literal_eval, '+True')
922 self.assertRaises(ValueError, ast.literal_eval, '2+3')
Georg Brandl0c77a822008-06-10 16:37:50 +0000923
Serhiy Storchakad8ac4d12018-01-04 11:15:39 +0200924 def test_literal_eval_complex(self):
925 # Issue #4907
926 self.assertEqual(ast.literal_eval('6j'), 6j)
927 self.assertEqual(ast.literal_eval('-6j'), -6j)
928 self.assertEqual(ast.literal_eval('6.75j'), 6.75j)
929 self.assertEqual(ast.literal_eval('-6.75j'), -6.75j)
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-6j'), -3-6j)
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.25-6.75j'), -3.25-6.75j)
938 self.assertEqual(ast.literal_eval('(3+6j)'), 3+6j)
939 self.assertRaises(ValueError, ast.literal_eval, '-6j+3')
940 self.assertRaises(ValueError, ast.literal_eval, '-6j+3j')
941 self.assertRaises(ValueError, ast.literal_eval, '3+-6j')
942 self.assertRaises(ValueError, ast.literal_eval, '3+(0+6j)')
943 self.assertRaises(ValueError, ast.literal_eval, '-(3+6j)')
Benjamin Peterson058e31e2009-01-16 03:54:08 +0000944
Amaury Forgeot d'Arc58e87612011-11-22 21:51:55 +0100945 def test_bad_integer(self):
946 # issue13436: Bad error message with invalid numeric values
947 body = [ast.ImportFrom(module='time',
948 names=[ast.alias(name='sleep')],
949 level=None,
950 lineno=None, col_offset=None)]
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800951 mod = ast.Module(body, [])
Amaury Forgeot d'Arc58e87612011-11-22 21:51:55 +0100952 with self.assertRaises(ValueError) as cm:
953 compile(mod, 'test', 'exec')
954 self.assertIn("invalid integer value: None", str(cm.exception))
955
Berker Peksag0a5bd512016-04-29 19:50:02 +0300956 def test_level_as_none(self):
957 body = [ast.ImportFrom(module='time',
958 names=[ast.alias(name='sleep')],
959 level=None,
960 lineno=0, col_offset=0)]
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800961 mod = ast.Module(body, [])
Berker Peksag0a5bd512016-04-29 19:50:02 +0300962 code = compile(mod, 'test', 'exec')
963 ns = {}
964 exec(code, ns)
965 self.assertIn('sleep', ns)
966
Georg Brandl0c77a822008-06-10 16:37:50 +0000967
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500968class ASTValidatorTests(unittest.TestCase):
969
970 def mod(self, mod, msg=None, mode="exec", *, exc=ValueError):
971 mod.lineno = mod.col_offset = 0
972 ast.fix_missing_locations(mod)
Serhiy Storchaka3f228112018-09-27 17:42:37 +0300973 if msg is None:
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500974 compile(mod, "<test>", mode)
Serhiy Storchaka3f228112018-09-27 17:42:37 +0300975 else:
976 with self.assertRaises(exc) as cm:
977 compile(mod, "<test>", mode)
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500978 self.assertIn(msg, str(cm.exception))
979
980 def expr(self, node, msg=None, *, exc=ValueError):
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800981 mod = ast.Module([ast.Expr(node)], [])
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500982 self.mod(mod, msg, exc=exc)
983
984 def stmt(self, stmt, msg=None):
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800985 mod = ast.Module([stmt], [])
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500986 self.mod(mod, msg)
987
988 def test_module(self):
989 m = ast.Interactive([ast.Expr(ast.Name("x", ast.Store()))])
990 self.mod(m, "must have Load context", "single")
991 m = ast.Expression(ast.Name("x", ast.Store()))
992 self.mod(m, "must have Load context", "eval")
993
994 def _check_arguments(self, fac, check):
Pablo Galindo8c77b8c2019-04-29 13:36:57 +0100995 def arguments(args=None, posonlyargs=None, vararg=None,
Benjamin Petersoncda75be2013-03-18 10:48:58 -0700996 kwonlyargs=None, kwarg=None,
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500997 defaults=None, kw_defaults=None):
998 if args is None:
999 args = []
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01001000 if posonlyargs is None:
1001 posonlyargs = []
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001002 if kwonlyargs is None:
1003 kwonlyargs = []
1004 if defaults is None:
1005 defaults = []
1006 if kw_defaults is None:
1007 kw_defaults = []
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01001008 args = ast.arguments(args, posonlyargs, vararg, kwonlyargs,
1009 kw_defaults, kwarg, defaults)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001010 return fac(args)
1011 args = [ast.arg("x", ast.Name("x", ast.Store()))]
1012 check(arguments(args=args), "must have Load context")
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01001013 check(arguments(posonlyargs=args), "must have Load context")
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001014 check(arguments(kwonlyargs=args), "must have Load context")
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001015 check(arguments(defaults=[ast.Num(3)]),
1016 "more positional defaults than args")
1017 check(arguments(kw_defaults=[ast.Num(4)]),
1018 "length of kwonlyargs is not the same as kw_defaults")
1019 args = [ast.arg("x", ast.Name("x", ast.Load()))]
1020 check(arguments(args=args, defaults=[ast.Name("x", ast.Store())]),
1021 "must have Load context")
1022 args = [ast.arg("a", ast.Name("x", ast.Load())),
1023 ast.arg("b", ast.Name("y", ast.Load()))]
1024 check(arguments(kwonlyargs=args,
1025 kw_defaults=[None, ast.Name("x", ast.Store())]),
1026 "must have Load context")
1027
1028 def test_funcdef(self):
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01001029 a = ast.arguments([], [], None, [], [], None, [])
Serhiy Storchaka73cbe7a2018-05-29 12:04:55 +03001030 f = ast.FunctionDef("x", a, [], [], None)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001031 self.stmt(f, "empty body on FunctionDef")
1032 f = ast.FunctionDef("x", a, [ast.Pass()], [ast.Name("x", ast.Store())],
Serhiy Storchaka73cbe7a2018-05-29 12:04:55 +03001033 None)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001034 self.stmt(f, "must have Load context")
1035 f = ast.FunctionDef("x", a, [ast.Pass()], [],
Serhiy Storchaka73cbe7a2018-05-29 12:04:55 +03001036 ast.Name("x", ast.Store()))
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001037 self.stmt(f, "must have Load context")
1038 def fac(args):
Serhiy Storchaka73cbe7a2018-05-29 12:04:55 +03001039 return ast.FunctionDef("x", args, [ast.Pass()], [], None)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001040 self._check_arguments(fac, self.stmt)
1041
1042 def test_classdef(self):
Benjamin Peterson025e9eb2015-05-05 20:16:41 -04001043 def cls(bases=None, keywords=None, body=None, decorator_list=None):
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001044 if bases is None:
1045 bases = []
1046 if keywords is None:
1047 keywords = []
1048 if body is None:
1049 body = [ast.Pass()]
1050 if decorator_list is None:
1051 decorator_list = []
Benjamin Peterson025e9eb2015-05-05 20:16:41 -04001052 return ast.ClassDef("myclass", bases, keywords,
Serhiy Storchaka73cbe7a2018-05-29 12:04:55 +03001053 body, decorator_list)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001054 self.stmt(cls(bases=[ast.Name("x", ast.Store())]),
1055 "must have Load context")
1056 self.stmt(cls(keywords=[ast.keyword("x", ast.Name("x", ast.Store()))]),
1057 "must have Load context")
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001058 self.stmt(cls(body=[]), "empty body on ClassDef")
1059 self.stmt(cls(body=[None]), "None disallowed")
1060 self.stmt(cls(decorator_list=[ast.Name("x", ast.Store())]),
1061 "must have Load context")
1062
1063 def test_delete(self):
1064 self.stmt(ast.Delete([]), "empty targets on Delete")
1065 self.stmt(ast.Delete([None]), "None disallowed")
1066 self.stmt(ast.Delete([ast.Name("x", ast.Load())]),
1067 "must have Del context")
1068
1069 def test_assign(self):
1070 self.stmt(ast.Assign([], ast.Num(3)), "empty targets on Assign")
1071 self.stmt(ast.Assign([None], ast.Num(3)), "None disallowed")
1072 self.stmt(ast.Assign([ast.Name("x", ast.Load())], ast.Num(3)),
1073 "must have Store context")
1074 self.stmt(ast.Assign([ast.Name("x", ast.Store())],
1075 ast.Name("y", ast.Store())),
1076 "must have Load context")
1077
1078 def test_augassign(self):
1079 aug = ast.AugAssign(ast.Name("x", ast.Load()), ast.Add(),
1080 ast.Name("y", ast.Load()))
1081 self.stmt(aug, "must have Store context")
1082 aug = ast.AugAssign(ast.Name("x", ast.Store()), ast.Add(),
1083 ast.Name("y", ast.Store()))
1084 self.stmt(aug, "must have Load context")
1085
1086 def test_for(self):
1087 x = ast.Name("x", ast.Store())
1088 y = ast.Name("y", ast.Load())
1089 p = ast.Pass()
1090 self.stmt(ast.For(x, y, [], []), "empty body on For")
1091 self.stmt(ast.For(ast.Name("x", ast.Load()), y, [p], []),
1092 "must have Store context")
1093 self.stmt(ast.For(x, ast.Name("y", ast.Store()), [p], []),
1094 "must have Load context")
1095 e = ast.Expr(ast.Name("x", ast.Store()))
1096 self.stmt(ast.For(x, y, [e], []), "must have Load context")
1097 self.stmt(ast.For(x, y, [p], [e]), "must have Load context")
1098
1099 def test_while(self):
1100 self.stmt(ast.While(ast.Num(3), [], []), "empty body on While")
1101 self.stmt(ast.While(ast.Name("x", ast.Store()), [ast.Pass()], []),
1102 "must have Load context")
1103 self.stmt(ast.While(ast.Num(3), [ast.Pass()],
1104 [ast.Expr(ast.Name("x", ast.Store()))]),
1105 "must have Load context")
1106
1107 def test_if(self):
1108 self.stmt(ast.If(ast.Num(3), [], []), "empty body on If")
1109 i = ast.If(ast.Name("x", ast.Store()), [ast.Pass()], [])
1110 self.stmt(i, "must have Load context")
1111 i = ast.If(ast.Num(3), [ast.Expr(ast.Name("x", ast.Store()))], [])
1112 self.stmt(i, "must have Load context")
1113 i = ast.If(ast.Num(3), [ast.Pass()],
1114 [ast.Expr(ast.Name("x", ast.Store()))])
1115 self.stmt(i, "must have Load context")
1116
1117 def test_with(self):
1118 p = ast.Pass()
1119 self.stmt(ast.With([], [p]), "empty items on With")
1120 i = ast.withitem(ast.Num(3), None)
1121 self.stmt(ast.With([i], []), "empty body on With")
1122 i = ast.withitem(ast.Name("x", ast.Store()), None)
1123 self.stmt(ast.With([i], [p]), "must have Load context")
1124 i = ast.withitem(ast.Num(3), ast.Name("x", ast.Load()))
1125 self.stmt(ast.With([i], [p]), "must have Store context")
1126
1127 def test_raise(self):
1128 r = ast.Raise(None, ast.Num(3))
1129 self.stmt(r, "Raise with cause but no exception")
1130 r = ast.Raise(ast.Name("x", ast.Store()), None)
1131 self.stmt(r, "must have Load context")
1132 r = ast.Raise(ast.Num(4), ast.Name("x", ast.Store()))
1133 self.stmt(r, "must have Load context")
1134
1135 def test_try(self):
1136 p = ast.Pass()
1137 t = ast.Try([], [], [], [p])
1138 self.stmt(t, "empty body on Try")
1139 t = ast.Try([ast.Expr(ast.Name("x", ast.Store()))], [], [], [p])
1140 self.stmt(t, "must have Load context")
1141 t = ast.Try([p], [], [], [])
1142 self.stmt(t, "Try has neither except handlers nor finalbody")
1143 t = ast.Try([p], [], [p], [p])
1144 self.stmt(t, "Try has orelse but no except handlers")
1145 t = ast.Try([p], [ast.ExceptHandler(None, "x", [])], [], [])
1146 self.stmt(t, "empty body on ExceptHandler")
1147 e = [ast.ExceptHandler(ast.Name("x", ast.Store()), "y", [p])]
1148 self.stmt(ast.Try([p], e, [], []), "must have Load context")
1149 e = [ast.ExceptHandler(None, "x", [p])]
1150 t = ast.Try([p], e, [ast.Expr(ast.Name("x", ast.Store()))], [p])
1151 self.stmt(t, "must have Load context")
1152 t = ast.Try([p], e, [p], [ast.Expr(ast.Name("x", ast.Store()))])
1153 self.stmt(t, "must have Load context")
1154
1155 def test_assert(self):
1156 self.stmt(ast.Assert(ast.Name("x", ast.Store()), None),
1157 "must have Load context")
1158 assrt = ast.Assert(ast.Name("x", ast.Load()),
1159 ast.Name("y", ast.Store()))
1160 self.stmt(assrt, "must have Load context")
1161
1162 def test_import(self):
1163 self.stmt(ast.Import([]), "empty names on Import")
1164
1165 def test_importfrom(self):
1166 imp = ast.ImportFrom(None, [ast.alias("x", None)], -42)
Serhiy Storchaka7de28402016-06-27 23:40:43 +03001167 self.stmt(imp, "Negative ImportFrom level")
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001168 self.stmt(ast.ImportFrom(None, [], 0), "empty names on ImportFrom")
1169
1170 def test_global(self):
1171 self.stmt(ast.Global([]), "empty names on Global")
1172
1173 def test_nonlocal(self):
1174 self.stmt(ast.Nonlocal([]), "empty names on Nonlocal")
1175
1176 def test_expr(self):
1177 e = ast.Expr(ast.Name("x", ast.Store()))
1178 self.stmt(e, "must have Load context")
1179
1180 def test_boolop(self):
1181 b = ast.BoolOp(ast.And(), [])
1182 self.expr(b, "less than 2 values")
1183 b = ast.BoolOp(ast.And(), [ast.Num(3)])
1184 self.expr(b, "less than 2 values")
1185 b = ast.BoolOp(ast.And(), [ast.Num(4), None])
1186 self.expr(b, "None disallowed")
1187 b = ast.BoolOp(ast.And(), [ast.Num(4), ast.Name("x", ast.Store())])
1188 self.expr(b, "must have Load context")
1189
1190 def test_unaryop(self):
1191 u = ast.UnaryOp(ast.Not(), ast.Name("x", ast.Store()))
1192 self.expr(u, "must have Load context")
1193
1194 def test_lambda(self):
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01001195 a = ast.arguments([], [], None, [], [], None, [])
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001196 self.expr(ast.Lambda(a, ast.Name("x", ast.Store())),
1197 "must have Load context")
1198 def fac(args):
1199 return ast.Lambda(args, ast.Name("x", ast.Load()))
1200 self._check_arguments(fac, self.expr)
1201
1202 def test_ifexp(self):
1203 l = ast.Name("x", ast.Load())
1204 s = ast.Name("y", ast.Store())
1205 for args in (s, l, l), (l, s, l), (l, l, s):
Benjamin Peterson71ce8972011-08-09 16:17:12 -05001206 self.expr(ast.IfExp(*args), "must have Load context")
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001207
1208 def test_dict(self):
1209 d = ast.Dict([], [ast.Name("x", ast.Load())])
1210 self.expr(d, "same number of keys as values")
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001211 d = ast.Dict([ast.Name("x", ast.Load())], [None])
1212 self.expr(d, "None disallowed")
1213
1214 def test_set(self):
1215 self.expr(ast.Set([None]), "None disallowed")
1216 s = ast.Set([ast.Name("x", ast.Store())])
1217 self.expr(s, "must have Load context")
1218
1219 def _check_comprehension(self, fac):
1220 self.expr(fac([]), "comprehension with no generators")
1221 g = ast.comprehension(ast.Name("x", ast.Load()),
Yury Selivanov52c4e7c2016-09-09 10:36:01 -07001222 ast.Name("x", ast.Load()), [], 0)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001223 self.expr(fac([g]), "must have Store context")
1224 g = ast.comprehension(ast.Name("x", ast.Store()),
Yury Selivanov52c4e7c2016-09-09 10:36:01 -07001225 ast.Name("x", ast.Store()), [], 0)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001226 self.expr(fac([g]), "must have Load context")
1227 x = ast.Name("x", ast.Store())
1228 y = ast.Name("y", ast.Load())
Yury Selivanov52c4e7c2016-09-09 10:36:01 -07001229 g = ast.comprehension(x, y, [None], 0)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001230 self.expr(fac([g]), "None disallowed")
Yury Selivanov52c4e7c2016-09-09 10:36:01 -07001231 g = ast.comprehension(x, y, [ast.Name("x", ast.Store())], 0)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001232 self.expr(fac([g]), "must have Load context")
1233
1234 def _simple_comp(self, fac):
1235 g = ast.comprehension(ast.Name("x", ast.Store()),
Yury Selivanov52c4e7c2016-09-09 10:36:01 -07001236 ast.Name("x", ast.Load()), [], 0)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001237 self.expr(fac(ast.Name("x", ast.Store()), [g]),
1238 "must have Load context")
1239 def wrap(gens):
1240 return fac(ast.Name("x", ast.Store()), gens)
1241 self._check_comprehension(wrap)
1242
1243 def test_listcomp(self):
1244 self._simple_comp(ast.ListComp)
1245
1246 def test_setcomp(self):
1247 self._simple_comp(ast.SetComp)
1248
1249 def test_generatorexp(self):
1250 self._simple_comp(ast.GeneratorExp)
1251
1252 def test_dictcomp(self):
1253 g = ast.comprehension(ast.Name("y", ast.Store()),
Yury Selivanov52c4e7c2016-09-09 10:36:01 -07001254 ast.Name("p", ast.Load()), [], 0)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001255 c = ast.DictComp(ast.Name("x", ast.Store()),
1256 ast.Name("y", ast.Load()), [g])
1257 self.expr(c, "must have Load context")
1258 c = ast.DictComp(ast.Name("x", ast.Load()),
1259 ast.Name("y", ast.Store()), [g])
1260 self.expr(c, "must have Load context")
1261 def factory(comps):
1262 k = ast.Name("x", ast.Load())
1263 v = ast.Name("y", ast.Load())
1264 return ast.DictComp(k, v, comps)
1265 self._check_comprehension(factory)
1266
1267 def test_yield(self):
Benjamin Peterson527c6222012-01-14 08:58:23 -05001268 self.expr(ast.Yield(ast.Name("x", ast.Store())), "must have Load")
1269 self.expr(ast.YieldFrom(ast.Name("x", ast.Store())), "must have Load")
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001270
1271 def test_compare(self):
1272 left = ast.Name("x", ast.Load())
1273 comp = ast.Compare(left, [ast.In()], [])
1274 self.expr(comp, "no comparators")
1275 comp = ast.Compare(left, [ast.In()], [ast.Num(4), ast.Num(5)])
1276 self.expr(comp, "different number of comparators and operands")
1277 comp = ast.Compare(ast.Num("blah"), [ast.In()], [left])
Serhiy Storchaka3f228112018-09-27 17:42:37 +03001278 self.expr(comp)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001279 comp = ast.Compare(left, [ast.In()], [ast.Num("blah")])
Serhiy Storchaka3f228112018-09-27 17:42:37 +03001280 self.expr(comp)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001281
1282 def test_call(self):
1283 func = ast.Name("x", ast.Load())
1284 args = [ast.Name("y", ast.Load())]
1285 keywords = [ast.keyword("w", ast.Name("z", ast.Load()))]
Benjamin Peterson025e9eb2015-05-05 20:16:41 -04001286 call = ast.Call(ast.Name("x", ast.Store()), args, keywords)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001287 self.expr(call, "must have Load context")
Benjamin Peterson025e9eb2015-05-05 20:16:41 -04001288 call = ast.Call(func, [None], keywords)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001289 self.expr(call, "None disallowed")
1290 bad_keywords = [ast.keyword("w", ast.Name("z", ast.Store()))]
Benjamin Peterson025e9eb2015-05-05 20:16:41 -04001291 call = ast.Call(func, args, bad_keywords)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001292 self.expr(call, "must have Load context")
1293
1294 def test_num(self):
1295 class subint(int):
1296 pass
1297 class subfloat(float):
1298 pass
1299 class subcomplex(complex):
1300 pass
Serhiy Storchaka3f228112018-09-27 17:42:37 +03001301 for obj in "0", "hello":
1302 self.expr(ast.Num(obj))
1303 for obj in subint(), subfloat(), subcomplex():
1304 self.expr(ast.Num(obj), "invalid type", exc=TypeError)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001305
1306 def test_attribute(self):
1307 attr = ast.Attribute(ast.Name("x", ast.Store()), "y", ast.Load())
1308 self.expr(attr, "must have Load context")
1309
1310 def test_subscript(self):
1311 sub = ast.Subscript(ast.Name("x", ast.Store()), ast.Index(ast.Num(3)),
1312 ast.Load())
1313 self.expr(sub, "must have Load context")
1314 x = ast.Name("x", ast.Load())
1315 sub = ast.Subscript(x, ast.Index(ast.Name("y", ast.Store())),
1316 ast.Load())
1317 self.expr(sub, "must have Load context")
1318 s = ast.Name("x", ast.Store())
1319 for args in (s, None, None), (None, s, None), (None, None, s):
1320 sl = ast.Slice(*args)
1321 self.expr(ast.Subscript(x, sl, ast.Load()),
1322 "must have Load context")
1323 sl = ast.ExtSlice([])
1324 self.expr(ast.Subscript(x, sl, ast.Load()), "empty dims on ExtSlice")
1325 sl = ast.ExtSlice([ast.Index(s)])
1326 self.expr(ast.Subscript(x, sl, ast.Load()), "must have Load context")
1327
1328 def test_starred(self):
1329 left = ast.List([ast.Starred(ast.Name("x", ast.Load()), ast.Store())],
1330 ast.Store())
1331 assign = ast.Assign([left], ast.Num(4))
1332 self.stmt(assign, "must have Store context")
1333
1334 def _sequence(self, fac):
1335 self.expr(fac([None], ast.Load()), "None disallowed")
1336 self.expr(fac([ast.Name("x", ast.Store())], ast.Load()),
1337 "must have Load context")
1338
1339 def test_list(self):
1340 self._sequence(ast.List)
1341
1342 def test_tuple(self):
1343 self._sequence(ast.Tuple)
1344
Benjamin Peterson442f2092012-12-06 17:41:04 -05001345 def test_nameconstant(self):
Serhiy Storchaka3f228112018-09-27 17:42:37 +03001346 self.expr(ast.NameConstant(4))
Benjamin Peterson442f2092012-12-06 17:41:04 -05001347
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001348 def test_stdlib_validates(self):
1349 stdlib = os.path.dirname(ast.__file__)
1350 tests = [fn for fn in os.listdir(stdlib) if fn.endswith(".py")]
1351 tests.extend(["test/test_grammar.py", "test/test_unpack_ex.py"])
1352 for module in tests:
Serhiy Storchaka3bcbedc2019-01-18 07:47:48 +02001353 with self.subTest(module):
1354 fn = os.path.join(stdlib, module)
1355 with open(fn, "r", encoding="utf-8") as fp:
1356 source = fp.read()
1357 mod = ast.parse(source, fn)
1358 compile(mod, fn, "exec")
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001359
1360
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001361class ConstantTests(unittest.TestCase):
1362 """Tests on the ast.Constant node type."""
1363
1364 def compile_constant(self, value):
1365 tree = ast.parse("x = 123")
1366
1367 node = tree.body[0].value
1368 new_node = ast.Constant(value=value)
1369 ast.copy_location(new_node, node)
1370 tree.body[0].value = new_node
1371
1372 code = compile(tree, "<string>", "exec")
1373
1374 ns = {}
1375 exec(code, ns)
1376 return ns['x']
1377
Victor Stinnerbe59d142016-01-27 00:39:12 +01001378 def test_validation(self):
1379 with self.assertRaises(TypeError) as cm:
1380 self.compile_constant([1, 2, 3])
1381 self.assertEqual(str(cm.exception),
1382 "got an invalid type in Constant: list")
1383
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001384 def test_singletons(self):
1385 for const in (None, False, True, Ellipsis, b'', frozenset()):
1386 with self.subTest(const=const):
1387 value = self.compile_constant(const)
1388 self.assertIs(value, const)
1389
1390 def test_values(self):
1391 nested_tuple = (1,)
1392 nested_frozenset = frozenset({1})
1393 for level in range(3):
1394 nested_tuple = (nested_tuple, 2)
1395 nested_frozenset = frozenset({nested_frozenset, 2})
1396 values = (123, 123.0, 123j,
1397 "unicode", b'bytes',
1398 tuple("tuple"), frozenset("frozenset"),
1399 nested_tuple, nested_frozenset)
1400 for value in values:
1401 with self.subTest(value=value):
1402 result = self.compile_constant(value)
1403 self.assertEqual(result, value)
1404
1405 def test_assign_to_constant(self):
1406 tree = ast.parse("x = 1")
1407
1408 target = tree.body[0].targets[0]
1409 new_target = ast.Constant(value=1)
1410 ast.copy_location(new_target, target)
1411 tree.body[0].targets[0] = new_target
1412
1413 with self.assertRaises(ValueError) as cm:
1414 compile(tree, "string", "exec")
1415 self.assertEqual(str(cm.exception),
1416 "expression which can't be assigned "
1417 "to in Store context")
1418
1419 def test_get_docstring(self):
1420 tree = ast.parse("'docstring'\nx = 1")
1421 self.assertEqual(ast.get_docstring(tree), 'docstring')
1422
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001423 def get_load_const(self, tree):
1424 # Compile to bytecode, disassemble and get parameter of LOAD_CONST
1425 # instructions
1426 co = compile(tree, '<string>', 'exec')
1427 consts = []
1428 for instr in dis.get_instructions(co):
1429 if instr.opname == 'LOAD_CONST':
1430 consts.append(instr.argval)
1431 return consts
1432
1433 @support.cpython_only
1434 def test_load_const(self):
1435 consts = [None,
1436 True, False,
1437 124,
1438 2.0,
1439 3j,
1440 "unicode",
1441 b'bytes',
1442 (1, 2, 3)]
1443
Victor Stinnera2724092016-02-08 18:17:58 +01001444 code = '\n'.join(['x={!r}'.format(const) for const in consts])
1445 code += '\nx = ...'
1446 consts.extend((Ellipsis, None))
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001447
1448 tree = ast.parse(code)
Victor Stinnera2724092016-02-08 18:17:58 +01001449 self.assertEqual(self.get_load_const(tree),
1450 consts)
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001451
1452 # Replace expression nodes with constants
Victor Stinnera2724092016-02-08 18:17:58 +01001453 for assign, const in zip(tree.body, consts):
1454 assert isinstance(assign, ast.Assign), ast.dump(assign)
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001455 new_node = ast.Constant(value=const)
Victor Stinnera2724092016-02-08 18:17:58 +01001456 ast.copy_location(new_node, assign.value)
1457 assign.value = new_node
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001458
Victor Stinnera2724092016-02-08 18:17:58 +01001459 self.assertEqual(self.get_load_const(tree),
1460 consts)
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001461
1462 def test_literal_eval(self):
1463 tree = ast.parse("1 + 2")
1464 binop = tree.body[0].value
1465
1466 new_left = ast.Constant(value=10)
1467 ast.copy_location(new_left, binop.left)
1468 binop.left = new_left
1469
Serhiy Storchakad8ac4d12018-01-04 11:15:39 +02001470 new_right = ast.Constant(value=20j)
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001471 ast.copy_location(new_right, binop.right)
1472 binop.right = new_right
1473
Serhiy Storchakad8ac4d12018-01-04 11:15:39 +02001474 self.assertEqual(ast.literal_eval(binop), 10+20j)
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001475
Guido van Rossum10f8ce62019-03-13 13:00:46 -07001476 def test_string_kind(self):
1477 c = ast.parse('"x"', mode='eval').body
1478 self.assertEqual(c.value, "x")
1479 self.assertEqual(c.kind, None)
1480
1481 c = ast.parse('u"x"', mode='eval').body
1482 self.assertEqual(c.value, "x")
1483 self.assertEqual(c.kind, "u")
1484
1485 c = ast.parse('r"x"', mode='eval').body
1486 self.assertEqual(c.value, "x")
1487 self.assertEqual(c.kind, None)
1488
1489 c = ast.parse('b"x"', mode='eval').body
1490 self.assertEqual(c.value, b"x")
1491 self.assertEqual(c.kind, None)
1492
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001493
Ivan Levkivskyi9932a222019-01-22 11:18:22 +00001494class EndPositionTests(unittest.TestCase):
1495 """Tests for end position of AST nodes.
1496
1497 Testing end positions of nodes requires a bit of extra care
1498 because of how LL parsers work.
1499 """
1500 def _check_end_pos(self, ast_node, end_lineno, end_col_offset):
1501 self.assertEqual(ast_node.end_lineno, end_lineno)
1502 self.assertEqual(ast_node.end_col_offset, end_col_offset)
1503
1504 def _check_content(self, source, ast_node, content):
1505 self.assertEqual(ast.get_source_segment(source, ast_node), content)
1506
1507 def _parse_value(self, s):
1508 # Use duck-typing to support both single expression
1509 # and a right hand side of an assignment statement.
1510 return ast.parse(s).body[0].value
1511
1512 def test_lambda(self):
1513 s = 'lambda x, *y: None'
1514 lam = self._parse_value(s)
1515 self._check_content(s, lam.body, 'None')
1516 self._check_content(s, lam.args.args[0], 'x')
1517 self._check_content(s, lam.args.vararg, 'y')
1518
1519 def test_func_def(self):
1520 s = dedent('''
1521 def func(x: int,
1522 *args: str,
1523 z: float = 0,
1524 **kwargs: Any) -> bool:
1525 return True
1526 ''').strip()
1527 fdef = ast.parse(s).body[0]
1528 self._check_end_pos(fdef, 5, 15)
1529 self._check_content(s, fdef.body[0], 'return True')
1530 self._check_content(s, fdef.args.args[0], 'x: int')
1531 self._check_content(s, fdef.args.args[0].annotation, 'int')
1532 self._check_content(s, fdef.args.kwarg, 'kwargs: Any')
1533 self._check_content(s, fdef.args.kwarg.annotation, 'Any')
1534
1535 def test_call(self):
1536 s = 'func(x, y=2, **kw)'
1537 call = self._parse_value(s)
1538 self._check_content(s, call.func, 'func')
1539 self._check_content(s, call.keywords[0].value, '2')
1540 self._check_content(s, call.keywords[1].value, 'kw')
1541
1542 def test_call_noargs(self):
1543 s = 'x[0]()'
1544 call = self._parse_value(s)
1545 self._check_content(s, call.func, 'x[0]')
1546 self._check_end_pos(call, 1, 6)
1547
1548 def test_class_def(self):
1549 s = dedent('''
1550 class C(A, B):
1551 x: int = 0
1552 ''').strip()
1553 cdef = ast.parse(s).body[0]
1554 self._check_end_pos(cdef, 2, 14)
1555 self._check_content(s, cdef.bases[1], 'B')
1556 self._check_content(s, cdef.body[0], 'x: int = 0')
1557
1558 def test_class_kw(self):
1559 s = 'class S(metaclass=abc.ABCMeta): pass'
1560 cdef = ast.parse(s).body[0]
1561 self._check_content(s, cdef.keywords[0].value, 'abc.ABCMeta')
1562
1563 def test_multi_line_str(self):
1564 s = dedent('''
1565 x = """Some multi-line text.
1566
1567 It goes on starting from same indent."""
1568 ''').strip()
1569 assign = ast.parse(s).body[0]
1570 self._check_end_pos(assign, 3, 40)
1571 self._check_end_pos(assign.value, 3, 40)
1572
1573 def test_continued_str(self):
1574 s = dedent('''
1575 x = "first part" \\
1576 "second part"
1577 ''').strip()
1578 assign = ast.parse(s).body[0]
1579 self._check_end_pos(assign, 2, 13)
1580 self._check_end_pos(assign.value, 2, 13)
1581
1582 def test_suites(self):
1583 # We intentionally put these into the same string to check
1584 # that empty lines are not part of the suite.
1585 s = dedent('''
1586 while True:
1587 pass
1588
1589 if one():
1590 x = None
1591 elif other():
1592 y = None
1593 else:
1594 z = None
1595
1596 for x, y in stuff:
1597 assert True
1598
1599 try:
1600 raise RuntimeError
1601 except TypeError as e:
1602 pass
1603
1604 pass
1605 ''').strip()
1606 mod = ast.parse(s)
1607 while_loop = mod.body[0]
1608 if_stmt = mod.body[1]
1609 for_loop = mod.body[2]
1610 try_stmt = mod.body[3]
1611 pass_stmt = mod.body[4]
1612
1613 self._check_end_pos(while_loop, 2, 8)
1614 self._check_end_pos(if_stmt, 9, 12)
1615 self._check_end_pos(for_loop, 12, 15)
1616 self._check_end_pos(try_stmt, 17, 8)
1617 self._check_end_pos(pass_stmt, 19, 4)
1618
1619 self._check_content(s, while_loop.test, 'True')
1620 self._check_content(s, if_stmt.body[0], 'x = None')
1621 self._check_content(s, if_stmt.orelse[0].test, 'other()')
1622 self._check_content(s, for_loop.target, 'x, y')
1623 self._check_content(s, try_stmt.body[0], 'raise RuntimeError')
1624 self._check_content(s, try_stmt.handlers[0].type, 'TypeError')
1625
1626 def test_fstring(self):
1627 s = 'x = f"abc {x + y} abc"'
1628 fstr = self._parse_value(s)
1629 binop = fstr.values[1].value
1630 self._check_content(s, binop, 'x + y')
1631
1632 def test_fstring_multi_line(self):
1633 s = dedent('''
1634 f"""Some multi-line text.
1635 {
1636 arg_one
1637 +
1638 arg_two
1639 }
1640 It goes on..."""
1641 ''').strip()
1642 fstr = self._parse_value(s)
1643 binop = fstr.values[1].value
1644 self._check_end_pos(binop, 5, 7)
1645 self._check_content(s, binop.left, 'arg_one')
1646 self._check_content(s, binop.right, 'arg_two')
1647
1648 def test_import_from_multi_line(self):
1649 s = dedent('''
1650 from x.y.z import (
1651 a, b, c as c
1652 )
1653 ''').strip()
1654 imp = ast.parse(s).body[0]
1655 self._check_end_pos(imp, 3, 1)
1656
1657 def test_slices(self):
1658 s1 = 'f()[1, 2] [0]'
1659 s2 = 'x[ a.b: c.d]'
1660 sm = dedent('''
1661 x[ a.b: f () ,
1662 g () : c.d
1663 ]
1664 ''').strip()
1665 i1, i2, im = map(self._parse_value, (s1, s2, sm))
1666 self._check_content(s1, i1.value, 'f()[1, 2]')
1667 self._check_content(s1, i1.value.slice.value, '1, 2')
1668 self._check_content(s2, i2.slice.lower, 'a.b')
1669 self._check_content(s2, i2.slice.upper, 'c.d')
1670 self._check_content(sm, im.slice.dims[0].upper, 'f ()')
1671 self._check_content(sm, im.slice.dims[1].lower, 'g ()')
1672 self._check_end_pos(im, 3, 3)
1673
1674 def test_binop(self):
1675 s = dedent('''
1676 (1 * 2 + (3 ) +
1677 4
1678 )
1679 ''').strip()
1680 binop = self._parse_value(s)
1681 self._check_end_pos(binop, 2, 6)
1682 self._check_content(s, binop.right, '4')
1683 self._check_content(s, binop.left, '1 * 2 + (3 )')
1684 self._check_content(s, binop.left.right, '3')
1685
1686 def test_boolop(self):
1687 s = dedent('''
1688 if (one_condition and
1689 (other_condition or yet_another_one)):
1690 pass
1691 ''').strip()
1692 bop = ast.parse(s).body[0].test
1693 self._check_end_pos(bop, 2, 44)
1694 self._check_content(s, bop.values[1],
1695 'other_condition or yet_another_one')
1696
1697 def test_tuples(self):
1698 s1 = 'x = () ;'
1699 s2 = 'x = 1 , ;'
1700 s3 = 'x = (1 , 2 ) ;'
1701 sm = dedent('''
1702 x = (
1703 a, b,
1704 )
1705 ''').strip()
1706 t1, t2, t3, tm = map(self._parse_value, (s1, s2, s3, sm))
1707 self._check_content(s1, t1, '()')
1708 self._check_content(s2, t2, '1 ,')
1709 self._check_content(s3, t3, '(1 , 2 )')
1710 self._check_end_pos(tm, 3, 1)
1711
1712 def test_attribute_spaces(self):
1713 s = 'func(x. y .z)'
1714 call = self._parse_value(s)
1715 self._check_content(s, call, s)
1716 self._check_content(s, call.args[0], 'x. y .z')
1717
Serhiy Storchaka6e619c42020-02-12 22:37:49 +02001718 def test_redundant_parenthesis(self):
1719 s = '( ( ( a + b ) ) )'
1720 v = ast.parse(s).body[0].value
1721 self.assertEqual(type(v).__name__, 'BinOp')
1722 self._check_content(s, v, 'a + b')
1723 s2 = 'await ' + s
1724 v = ast.parse(s2).body[0].value.value
1725 self.assertEqual(type(v).__name__, 'BinOp')
1726 self._check_content(s2, v, 'a + b')
1727
1728 def test_trailers_with_redundant_parenthesis(self):
1729 tests = (
1730 ('( ( ( a ) ) ) ( )', 'Call'),
1731 ('( ( ( a ) ) ) ( b )', 'Call'),
1732 ('( ( ( a ) ) ) [ b ]', 'Subscript'),
1733 ('( ( ( a ) ) ) . b', 'Attribute'),
1734 )
1735 for s, t in tests:
1736 with self.subTest(s):
1737 v = ast.parse(s).body[0].value
1738 self.assertEqual(type(v).__name__, t)
1739 self._check_content(s, v, s)
1740 s2 = 'await ' + s
1741 v = ast.parse(s2).body[0].value.value
1742 self.assertEqual(type(v).__name__, t)
1743 self._check_content(s2, v, s)
1744
Ivan Levkivskyi9932a222019-01-22 11:18:22 +00001745 def test_displays(self):
1746 s1 = '[{}, {1, }, {1, 2,} ]'
1747 s2 = '{a: b, f (): g () ,}'
1748 c1 = self._parse_value(s1)
1749 c2 = self._parse_value(s2)
1750 self._check_content(s1, c1.elts[0], '{}')
1751 self._check_content(s1, c1.elts[1], '{1, }')
1752 self._check_content(s1, c1.elts[2], '{1, 2,}')
1753 self._check_content(s2, c2.keys[1], 'f ()')
1754 self._check_content(s2, c2.values[1], 'g ()')
1755
1756 def test_comprehensions(self):
1757 s = dedent('''
1758 x = [{x for x, y in stuff
1759 if cond.x} for stuff in things]
1760 ''').strip()
1761 cmp = self._parse_value(s)
1762 self._check_end_pos(cmp, 2, 37)
1763 self._check_content(s, cmp.generators[0].iter, 'things')
1764 self._check_content(s, cmp.elt.generators[0].iter, 'stuff')
1765 self._check_content(s, cmp.elt.generators[0].ifs[0], 'cond.x')
1766 self._check_content(s, cmp.elt.generators[0].target, 'x, y')
1767
1768 def test_yield_await(self):
1769 s = dedent('''
1770 async def f():
1771 yield x
1772 await y
1773 ''').strip()
1774 fdef = ast.parse(s).body[0]
1775 self._check_content(s, fdef.body[0].value, 'yield x')
1776 self._check_content(s, fdef.body[1].value, 'await y')
1777
1778 def test_source_segment_multi(self):
1779 s_orig = dedent('''
1780 x = (
1781 a, b,
1782 ) + ()
1783 ''').strip()
1784 s_tuple = dedent('''
1785 (
1786 a, b,
1787 )
1788 ''').strip()
1789 binop = self._parse_value(s_orig)
1790 self.assertEqual(ast.get_source_segment(s_orig, binop.left), s_tuple)
1791
1792 def test_source_segment_padded(self):
1793 s_orig = dedent('''
1794 class C:
1795 def fun(self) -> None:
1796 "Đ–Đ–Đ–Đ–Đ–"
1797 ''').strip()
1798 s_method = ' def fun(self) -> None:\n' \
1799 ' "Đ–Đ–Đ–Đ–Đ–"'
1800 cdef = ast.parse(s_orig).body[0]
1801 self.assertEqual(ast.get_source_segment(s_orig, cdef.body[0], padded=True),
1802 s_method)
1803
1804 def test_source_segment_endings(self):
1805 s = 'v = 1\r\nw = 1\nx = 1\n\ry = 1\rz = 1\r\n'
1806 v, w, x, y, z = ast.parse(s).body
1807 self._check_content(s, v, 'v = 1')
1808 self._check_content(s, w, 'w = 1')
1809 self._check_content(s, x, 'x = 1')
1810 self._check_content(s, y, 'y = 1')
1811 self._check_content(s, z, 'z = 1')
1812
1813 def test_source_segment_tabs(self):
1814 s = dedent('''
1815 class C:
1816 \t\f def fun(self) -> None:
1817 \t\f pass
1818 ''').strip()
1819 s_method = ' \t\f def fun(self) -> None:\n' \
1820 ' \t\f pass'
1821
1822 cdef = ast.parse(s).body[0]
1823 self.assertEqual(ast.get_source_segment(s, cdef.body[0], padded=True), s_method)
1824
1825
Serhiy Storchakac3ea41e2019-08-26 10:13:19 +03001826class NodeVisitorTests(unittest.TestCase):
1827 def test_old_constant_nodes(self):
1828 class Visitor(ast.NodeVisitor):
1829 def visit_Num(self, node):
1830 log.append((node.lineno, 'Num', node.n))
1831 def visit_Str(self, node):
1832 log.append((node.lineno, 'Str', node.s))
1833 def visit_Bytes(self, node):
1834 log.append((node.lineno, 'Bytes', node.s))
1835 def visit_NameConstant(self, node):
1836 log.append((node.lineno, 'NameConstant', node.value))
1837 def visit_Ellipsis(self, node):
1838 log.append((node.lineno, 'Ellipsis', ...))
1839 mod = ast.parse(dedent('''\
1840 i = 42
1841 f = 4.25
1842 c = 4.25j
1843 s = 'string'
1844 b = b'bytes'
1845 t = True
1846 n = None
1847 e = ...
1848 '''))
1849 visitor = Visitor()
1850 log = []
1851 with warnings.catch_warnings(record=True) as wlog:
1852 warnings.filterwarnings('always', '', DeprecationWarning)
1853 visitor.visit(mod)
1854 self.assertEqual(log, [
1855 (1, 'Num', 42),
1856 (2, 'Num', 4.25),
1857 (3, 'Num', 4.25j),
1858 (4, 'Str', 'string'),
1859 (5, 'Bytes', b'bytes'),
1860 (6, 'NameConstant', True),
1861 (7, 'NameConstant', None),
1862 (8, 'Ellipsis', ...),
1863 ])
1864 self.assertEqual([str(w.message) for w in wlog], [
1865 'visit_Num is deprecated; add visit_Constant',
1866 'visit_Num is deprecated; add visit_Constant',
1867 'visit_Num is deprecated; add visit_Constant',
1868 'visit_Str is deprecated; add visit_Constant',
1869 'visit_Bytes is deprecated; add visit_Constant',
1870 'visit_NameConstant is deprecated; add visit_Constant',
1871 'visit_NameConstant is deprecated; add visit_Constant',
1872 'visit_Ellipsis is deprecated; add visit_Constant',
1873 ])
1874
1875
Neal Norwitzee9b10a2008-03-31 05:29:39 +00001876def main():
1877 if __name__ != '__main__':
Martin v. Löwis49c5da12006-03-01 22:49:05 +00001878 return
Neal Norwitzee9b10a2008-03-31 05:29:39 +00001879 if sys.argv[1:] == ['-g']:
1880 for statements, kind in ((exec_tests, "exec"), (single_tests, "single"),
1881 (eval_tests, "eval")):
1882 print(kind+"_results = [")
Victor Stinnerf0891962016-02-08 17:15:21 +01001883 for statement in statements:
1884 tree = ast.parse(statement, "?", kind)
1885 print("%r," % (to_tuple(tree),))
Neal Norwitzee9b10a2008-03-31 05:29:39 +00001886 print("]")
1887 print("main()")
1888 raise SystemExit
Brett Cannon3e9a9ae2013-06-12 21:25:59 -04001889 unittest.main()
Tim Peters400cbc32006-02-28 18:44:41 +00001890
Guido van Rossumdcfcd142019-01-31 03:40:27 -08001891#### EVERYTHING BELOW IS GENERATED BY python Lib/test/test_ast.py -g #####
Tim Peters400cbc32006-02-28 18:44:41 +00001892exec_results = [
Serhiy Storchaka850a8852020-01-10 10:12:55 +02001893('Module', [('Expr', (1, 0, 1, 4), ('Constant', (1, 0, 1, 4), None, None))], []),
1894('Module', [('Expr', (1, 0, 1, 18), ('Constant', (1, 0, 1, 18), 'module docstring', None))], []),
1895('Module', [('FunctionDef', (1, 0, 1, 13), 'f', ('arguments', [], [], None, [], [], None, []), [('Pass', (1, 9, 1, 13))], [], None, None)], []),
1896('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)], []),
1897('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)], []),
1898('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)], []),
1899('Module', [('FunctionDef', (1, 0, 1, 18), 'f', ('arguments', [], [], ('arg', (1, 7, 1, 11), 'args', None, None), [], [], None, []), [('Pass', (1, 14, 1, 18))], [], None, None)], []),
1900('Module', [('FunctionDef', (1, 0, 1, 21), 'f', ('arguments', [], [], None, [], [], ('arg', (1, 8, 1, 14), 'kwargs', None, None), []), [('Pass', (1, 17, 1, 21))], [], None, None)], []),
1901('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)], []),
1902('Module', [('ClassDef', (1, 0, 1, 12), 'C', [], [], [('Pass', (1, 8, 1, 12))], [])], []),
1903('Module', [('ClassDef', (1, 0, 1, 32), 'C', [], [], [('Expr', (1, 9, 1, 32), ('Constant', (1, 9, 1, 32), 'docstring for class C', None))], [])], []),
1904('Module', [('ClassDef', (1, 0, 1, 21), 'C', [('Name', (1, 8, 1, 14), 'object', ('Load',))], [], [('Pass', (1, 17, 1, 21))], [])], []),
1905('Module', [('FunctionDef', (1, 0, 1, 16), 'f', ('arguments', [], [], None, [], [], None, []), [('Return', (1, 8, 1, 16), ('Constant', (1, 15, 1, 16), 1, None))], [], None, None)], []),
1906('Module', [('Delete', (1, 0, 1, 5), [('Name', (1, 4, 1, 5), 'v', ('Del',))])], []),
1907('Module', [('Assign', (1, 0, 1, 5), [('Name', (1, 0, 1, 1), 'v', ('Store',))], ('Constant', (1, 4, 1, 5), 1, None), None)], []),
1908('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)], []),
1909('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)], []),
1910('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)], []),
1911('Module', [('AugAssign', (1, 0, 1, 6), ('Name', (1, 0, 1, 1), 'v', ('Store',)), ('Add',), ('Constant', (1, 5, 1, 6), 1, None))], []),
1912('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)], []),
1913('Module', [('While', (1, 0, 1, 12), ('Name', (1, 6, 1, 7), 'v', ('Load',)), [('Pass', (1, 8, 1, 12))], [])], []),
1914('Module', [('If', (1, 0, 1, 9), ('Name', (1, 3, 1, 4), 'v', ('Load',)), [('Pass', (1, 5, 1, 9))], [])], []),
1915('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))], [])])], []),
1916('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))])])], []),
1917('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)], []),
1918('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)], []),
1919('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)], []),
1920('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))])], [], [])], []),
1921('Module', [('Try', (1, 0, 4, 6), [('Pass', (2, 2, 2, 6))], [], [], [('Pass', (4, 2, 4, 6))])], []),
1922('Module', [('Assert', (1, 0, 1, 8), ('Name', (1, 7, 1, 8), 'v', ('Load',)), None)], []),
1923('Module', [('Import', (1, 0, 1, 10), [('alias', 'sys', None)])], []),
1924('Module', [('ImportFrom', (1, 0, 1, 17), 'sys', [('alias', 'v', None)], 0)], []),
1925('Module', [('Global', (1, 0, 1, 8), ['v'])], []),
1926('Module', [('Expr', (1, 0, 1, 1), ('Constant', (1, 0, 1, 1), 1, None))], []),
1927('Module', [('Pass', (1, 0, 1, 4))], []),
1928('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)], []),
1929('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)], []),
1930('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)], []),
1931('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)], []),
1932('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)], []),
1933('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)]))], []),
1934('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)]))], []),
1935('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)]))], []),
1936('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)]))], []),
1937('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)]))], []),
1938('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)], []),
1939('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)], []),
1940('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)], []),
1941('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)]))], []),
1942('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)]))], []),
1943('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)], []),
1944('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)], []),
1945('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)], []),
1946('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)], [])])], []),
1947('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 +01001948('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 +02001949('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)))], []),
1950('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)], []),
1951('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)], []),
1952('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)], []),
1953('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)], []),
1954('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)], []),
1955('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)], []),
1956('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)], []),
1957('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)], []),
1958('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)], []),
1959('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 +00001960]
1961single_results = [
Serhiy Storchaka850a8852020-01-10 10:12:55 +02001962('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 +00001963]
1964eval_results = [
Serhiy Storchaka850a8852020-01-10 10:12:55 +02001965('Expression', ('Constant', (1, 0, 1, 4), None, None)),
1966('Expression', ('BoolOp', (1, 0, 1, 7), ('And',), [('Name', (1, 0, 1, 1), 'a', ('Load',)), ('Name', (1, 6, 1, 7), 'b', ('Load',))])),
1967('Expression', ('BinOp', (1, 0, 1, 5), ('Name', (1, 0, 1, 1), 'a', ('Load',)), ('Add',), ('Name', (1, 4, 1, 5), 'b', ('Load',)))),
1968('Expression', ('UnaryOp', (1, 0, 1, 5), ('Not',), ('Name', (1, 4, 1, 5), 'v', ('Load',)))),
1969('Expression', ('Lambda', (1, 0, 1, 11), ('arguments', [], [], None, [], [], None, []), ('Constant', (1, 7, 1, 11), None, None))),
1970('Expression', ('Dict', (1, 0, 1, 7), [('Constant', (1, 2, 1, 3), 1, None)], [('Constant', (1, 4, 1, 5), 2, None)])),
1971('Expression', ('Dict', (1, 0, 1, 2), [], [])),
1972('Expression', ('Set', (1, 0, 1, 7), [('Constant', (1, 1, 1, 5), None, None)])),
1973('Expression', ('Dict', (1, 0, 5, 6), [('Constant', (2, 6, 2, 7), 1, None)], [('Constant', (4, 10, 4, 11), 2, None)])),
1974('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)])),
1975('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)])),
1976('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)])),
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', ('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)])),
1978('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)])),
1979('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)])),
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', ('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)])),
1981('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)])),
1982('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)])),
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', ('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)])),
1984('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)])),
1985('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)])),
1986('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',)))])),
1987('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',))], [])),
1988('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)])], [])),
1989('Expression', ('Constant', (1, 0, 1, 2), 10, None)),
1990('Expression', ('Constant', (1, 0, 1, 8), 'string', None)),
1991('Expression', ('Attribute', (1, 0, 1, 3), ('Name', (1, 0, 1, 1), 'a', ('Load',)), 'b', ('Load',))),
1992('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',))),
1993('Expression', ('Name', (1, 0, 1, 1), 'v', ('Load',))),
1994('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',))),
1995('Expression', ('List', (1, 0, 1, 2), [], ('Load',))),
1996('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',))),
1997('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',))),
1998('Expression', ('Tuple', (1, 0, 1, 2), [], ('Load',))),
1999('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 +00002000]
Neal Norwitzee9b10a2008-03-31 05:29:39 +00002001main()