blob: 0058e932f6a3f6e271d4ef2453029cde22ef7672 [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):
Serhiy Storchaka13d52c22020-03-10 18:52:34 +0200346 if name == 'Index':
347 # Index(value) just returns value now.
348 # The argument is required.
349 continue
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500350 x = item()
351 if isinstance(x, ast.AST):
352 self.assertEqual(type(x._fields), tuple)
353
354 def test_arguments(self):
355 x = ast.arguments()
Pablo Galindocd6e83b2019-07-15 01:32:18 +0200356 self.assertEqual(x._fields, ('posonlyargs', 'args', 'vararg', 'kwonlyargs',
357 'kw_defaults', 'kwarg', 'defaults'))
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500358
359 with self.assertRaises(AttributeError):
Serhiy Storchakab7e95252020-03-10 00:07:47 +0200360 x.args
361 self.assertIsNone(x.vararg)
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500362
Pablo Galindo8c77b8c2019-04-29 13:36:57 +0100363 x = ast.arguments(*range(1, 8))
Serhiy Storchakab7e95252020-03-10 00:07:47 +0200364 self.assertEqual(x.args, 2)
Pablo Galindo8c77b8c2019-04-29 13:36:57 +0100365 self.assertEqual(x.vararg, 3)
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500366
367 def test_field_attr_writable(self):
368 x = ast.Num()
369 # We can assign to _fields
370 x._fields = 666
371 self.assertEqual(x._fields, 666)
372
373 def test_classattrs(self):
374 x = ast.Num()
Guido van Rossum10f8ce62019-03-13 13:00:46 -0700375 self.assertEqual(x._fields, ('value', 'kind'))
Serhiy Storchaka3f228112018-09-27 17:42:37 +0300376
377 with self.assertRaises(AttributeError):
378 x.value
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500379
380 with self.assertRaises(AttributeError):
381 x.n
382
383 x = ast.Num(42)
Serhiy Storchaka3f228112018-09-27 17:42:37 +0300384 self.assertEqual(x.value, 42)
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500385 self.assertEqual(x.n, 42)
386
387 with self.assertRaises(AttributeError):
388 x.lineno
389
390 with self.assertRaises(AttributeError):
391 x.foobar
392
393 x = ast.Num(lineno=2)
394 self.assertEqual(x.lineno, 2)
395
396 x = ast.Num(42, lineno=0)
397 self.assertEqual(x.lineno, 0)
Guido van Rossum10f8ce62019-03-13 13:00:46 -0700398 self.assertEqual(x._fields, ('value', 'kind'))
Serhiy Storchaka3f228112018-09-27 17:42:37 +0300399 self.assertEqual(x.value, 42)
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500400 self.assertEqual(x.n, 42)
401
Guido van Rossum10f8ce62019-03-13 13:00:46 -0700402 self.assertRaises(TypeError, ast.Num, 1, None, 2)
403 self.assertRaises(TypeError, ast.Num, 1, None, 2, lineno=0)
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500404
Serhiy Storchaka3f228112018-09-27 17:42:37 +0300405 self.assertEqual(ast.Num(42).n, 42)
406 self.assertEqual(ast.Num(4.25).n, 4.25)
407 self.assertEqual(ast.Num(4.25j).n, 4.25j)
408 self.assertEqual(ast.Str('42').s, '42')
409 self.assertEqual(ast.Bytes(b'42').s, b'42')
410 self.assertIs(ast.NameConstant(True).value, True)
411 self.assertIs(ast.NameConstant(False).value, False)
412 self.assertIs(ast.NameConstant(None).value, None)
413
414 self.assertEqual(ast.Constant(42).value, 42)
415 self.assertEqual(ast.Constant(4.25).value, 4.25)
416 self.assertEqual(ast.Constant(4.25j).value, 4.25j)
417 self.assertEqual(ast.Constant('42').value, '42')
418 self.assertEqual(ast.Constant(b'42').value, b'42')
419 self.assertIs(ast.Constant(True).value, True)
420 self.assertIs(ast.Constant(False).value, False)
421 self.assertIs(ast.Constant(None).value, None)
422 self.assertIs(ast.Constant(...).value, ...)
423
424 def test_realtype(self):
425 self.assertEqual(type(ast.Num(42)), ast.Constant)
426 self.assertEqual(type(ast.Num(4.25)), ast.Constant)
427 self.assertEqual(type(ast.Num(4.25j)), ast.Constant)
428 self.assertEqual(type(ast.Str('42')), ast.Constant)
429 self.assertEqual(type(ast.Bytes(b'42')), ast.Constant)
430 self.assertEqual(type(ast.NameConstant(True)), ast.Constant)
431 self.assertEqual(type(ast.NameConstant(False)), ast.Constant)
432 self.assertEqual(type(ast.NameConstant(None)), ast.Constant)
433 self.assertEqual(type(ast.Ellipsis()), ast.Constant)
434
435 def test_isinstance(self):
436 self.assertTrue(isinstance(ast.Num(42), ast.Num))
437 self.assertTrue(isinstance(ast.Num(4.2), ast.Num))
438 self.assertTrue(isinstance(ast.Num(4.2j), ast.Num))
439 self.assertTrue(isinstance(ast.Str('42'), ast.Str))
440 self.assertTrue(isinstance(ast.Bytes(b'42'), ast.Bytes))
441 self.assertTrue(isinstance(ast.NameConstant(True), ast.NameConstant))
442 self.assertTrue(isinstance(ast.NameConstant(False), ast.NameConstant))
443 self.assertTrue(isinstance(ast.NameConstant(None), ast.NameConstant))
444 self.assertTrue(isinstance(ast.Ellipsis(), ast.Ellipsis))
445
446 self.assertTrue(isinstance(ast.Constant(42), ast.Num))
447 self.assertTrue(isinstance(ast.Constant(4.2), ast.Num))
448 self.assertTrue(isinstance(ast.Constant(4.2j), ast.Num))
449 self.assertTrue(isinstance(ast.Constant('42'), ast.Str))
450 self.assertTrue(isinstance(ast.Constant(b'42'), ast.Bytes))
451 self.assertTrue(isinstance(ast.Constant(True), ast.NameConstant))
452 self.assertTrue(isinstance(ast.Constant(False), ast.NameConstant))
453 self.assertTrue(isinstance(ast.Constant(None), ast.NameConstant))
454 self.assertTrue(isinstance(ast.Constant(...), ast.Ellipsis))
455
456 self.assertFalse(isinstance(ast.Str('42'), ast.Num))
457 self.assertFalse(isinstance(ast.Num(42), ast.Str))
458 self.assertFalse(isinstance(ast.Str('42'), ast.Bytes))
459 self.assertFalse(isinstance(ast.Num(42), ast.NameConstant))
460 self.assertFalse(isinstance(ast.Num(42), ast.Ellipsis))
Anthony Sottile74176222019-01-18 11:30:28 -0800461 self.assertFalse(isinstance(ast.NameConstant(True), ast.Num))
462 self.assertFalse(isinstance(ast.NameConstant(False), ast.Num))
Serhiy Storchaka3f228112018-09-27 17:42:37 +0300463
464 self.assertFalse(isinstance(ast.Constant('42'), ast.Num))
465 self.assertFalse(isinstance(ast.Constant(42), ast.Str))
466 self.assertFalse(isinstance(ast.Constant('42'), ast.Bytes))
467 self.assertFalse(isinstance(ast.Constant(42), ast.NameConstant))
468 self.assertFalse(isinstance(ast.Constant(42), ast.Ellipsis))
Anthony Sottile74176222019-01-18 11:30:28 -0800469 self.assertFalse(isinstance(ast.Constant(True), ast.Num))
470 self.assertFalse(isinstance(ast.Constant(False), ast.Num))
Serhiy Storchaka3f228112018-09-27 17:42:37 +0300471
472 self.assertFalse(isinstance(ast.Constant(), ast.Num))
473 self.assertFalse(isinstance(ast.Constant(), ast.Str))
474 self.assertFalse(isinstance(ast.Constant(), ast.Bytes))
475 self.assertFalse(isinstance(ast.Constant(), ast.NameConstant))
476 self.assertFalse(isinstance(ast.Constant(), ast.Ellipsis))
477
Serhiy Storchaka6015cc52018-10-28 13:43:03 +0200478 class S(str): pass
479 self.assertTrue(isinstance(ast.Constant(S('42')), ast.Str))
480 self.assertFalse(isinstance(ast.Constant(S('42')), ast.Num))
481
Serhiy Storchaka3f228112018-09-27 17:42:37 +0300482 def test_subclasses(self):
483 class N(ast.Num):
484 def __init__(self, *args, **kwargs):
485 super().__init__(*args, **kwargs)
486 self.z = 'spam'
487 class N2(ast.Num):
488 pass
489
490 n = N(42)
491 self.assertEqual(n.n, 42)
492 self.assertEqual(n.z, 'spam')
493 self.assertEqual(type(n), N)
494 self.assertTrue(isinstance(n, N))
495 self.assertTrue(isinstance(n, ast.Num))
496 self.assertFalse(isinstance(n, N2))
497 self.assertFalse(isinstance(ast.Num(42), N))
498 n = N(n=42)
499 self.assertEqual(n.n, 42)
500 self.assertEqual(type(n), N)
501
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500502 def test_module(self):
503 body = [ast.Num(42)]
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800504 x = ast.Module(body, [])
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500505 self.assertEqual(x.body, body)
506
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000507 def test_nodeclasses(self):
Florent Xicluna992d9e02011-11-11 19:35:42 +0100508 # Zero arguments constructor explicitly allowed
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500509 x = ast.BinOp()
510 self.assertEqual(x._fields, ('left', 'op', 'right'))
511
512 # Random attribute allowed too
513 x.foobarbaz = 5
514 self.assertEqual(x.foobarbaz, 5)
515
516 n1 = ast.Num(1)
517 n3 = ast.Num(3)
518 addop = ast.Add()
519 x = ast.BinOp(n1, addop, n3)
520 self.assertEqual(x.left, n1)
521 self.assertEqual(x.op, addop)
522 self.assertEqual(x.right, n3)
Benjamin Peterson68b543a2011-06-27 17:51:18 -0500523
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500524 x = ast.BinOp(1, 2, 3)
525 self.assertEqual(x.left, 1)
526 self.assertEqual(x.op, 2)
527 self.assertEqual(x.right, 3)
528
Georg Brandl0c77a822008-06-10 16:37:50 +0000529 x = ast.BinOp(1, 2, 3, lineno=0)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000530 self.assertEqual(x.left, 1)
531 self.assertEqual(x.op, 2)
532 self.assertEqual(x.right, 3)
533 self.assertEqual(x.lineno, 0)
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000534
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500535 # node raises exception when given too many arguments
536 self.assertRaises(TypeError, ast.BinOp, 1, 2, 3, 4)
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500537 # node raises exception when given too many arguments
538 self.assertRaises(TypeError, ast.BinOp, 1, 2, 3, 4, lineno=0)
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000539
540 # can set attributes through kwargs too
Georg Brandl0c77a822008-06-10 16:37:50 +0000541 x = ast.BinOp(left=1, op=2, right=3, lineno=0)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000542 self.assertEqual(x.left, 1)
543 self.assertEqual(x.op, 2)
544 self.assertEqual(x.right, 3)
545 self.assertEqual(x.lineno, 0)
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000546
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500547 # Random kwargs also allowed
548 x = ast.BinOp(1, 2, 3, foobarbaz=42)
549 self.assertEqual(x.foobarbaz, 42)
550
551 def test_no_fields(self):
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000552 # this used to fail because Sub._fields was None
Georg Brandl0c77a822008-06-10 16:37:50 +0000553 x = ast.Sub()
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500554 self.assertEqual(x._fields, ())
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000555
556 def test_pickling(self):
557 import pickle
558 mods = [pickle]
559 try:
560 import cPickle
561 mods.append(cPickle)
562 except ImportError:
563 pass
564 protocols = [0, 1, 2]
565 for mod in mods:
566 for protocol in protocols:
567 for ast in (compile(i, "?", "exec", 0x400) for i in exec_tests):
568 ast2 = mod.loads(mod.dumps(ast, protocol))
Ezio Melottib3aedd42010-11-20 19:04:17 +0000569 self.assertEqual(to_tuple(ast2), to_tuple(ast))
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000570
Benjamin Peterson5b066812010-11-20 01:38:49 +0000571 def test_invalid_sum(self):
572 pos = dict(lineno=2, col_offset=3)
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800573 m = ast.Module([ast.Expr(ast.expr(**pos), **pos)], [])
Benjamin Peterson5b066812010-11-20 01:38:49 +0000574 with self.assertRaises(TypeError) as cm:
575 compile(m, "<test>", "exec")
576 self.assertIn("but got <_ast.expr", str(cm.exception))
577
Min ho Kimc4cacc82019-07-31 08:16:13 +1000578 def test_invalid_identifier(self):
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800579 m = ast.Module([ast.Expr(ast.Name(42, ast.Load()))], [])
Benjamin Peterson2193d2b2011-07-22 10:50:23 -0500580 ast.fix_missing_locations(m)
581 with self.assertRaises(TypeError) as cm:
582 compile(m, "<test>", "exec")
583 self.assertIn("identifier must be of type str", str(cm.exception))
584
Mark Dickinsonded35ae2012-11-25 14:36:26 +0000585 def test_empty_yield_from(self):
586 # Issue 16546: yield from value is not optional.
587 empty_yield_from = ast.parse("def f():\n yield from g()")
588 empty_yield_from.body[0].body[0].value.value = None
589 with self.assertRaises(ValueError) as cm:
590 compile(empty_yield_from, "<test>", "exec")
591 self.assertIn("field value is required", str(cm.exception))
592
Oren Milman7dc46d82017-09-30 20:16:24 +0300593 @support.cpython_only
594 def test_issue31592(self):
595 # There shouldn't be an assertion failure in case of a bad
596 # unicodedata.normalize().
597 import unicodedata
598 def bad_normalize(*args):
599 return None
600 with support.swap_attr(unicodedata, 'normalize', bad_normalize):
601 self.assertRaises(TypeError, ast.parse, '\u03D5')
602
Carl Friedrich Bolz-Tereick110a47c2019-07-08 23:17:56 +0200603 def test_issue18374_binop_col_offset(self):
604 tree = ast.parse('4+5+6+7')
605 parent_binop = tree.body[0].value
606 child_binop = parent_binop.left
607 grandchild_binop = child_binop.left
608 self.assertEqual(parent_binop.col_offset, 0)
609 self.assertEqual(parent_binop.end_col_offset, 7)
610 self.assertEqual(child_binop.col_offset, 0)
611 self.assertEqual(child_binop.end_col_offset, 5)
612 self.assertEqual(grandchild_binop.col_offset, 0)
613 self.assertEqual(grandchild_binop.end_col_offset, 3)
614
615 tree = ast.parse('4+5-\\\n 6-7')
616 parent_binop = tree.body[0].value
617 child_binop = parent_binop.left
618 grandchild_binop = child_binop.left
619 self.assertEqual(parent_binop.col_offset, 0)
620 self.assertEqual(parent_binop.lineno, 1)
621 self.assertEqual(parent_binop.end_col_offset, 4)
622 self.assertEqual(parent_binop.end_lineno, 2)
623
624 self.assertEqual(child_binop.col_offset, 0)
Carl Friedrich Bolz-Tereick430a9f42019-07-09 14:20:01 +0200625 self.assertEqual(child_binop.lineno, 1)
Carl Friedrich Bolz-Tereick110a47c2019-07-08 23:17:56 +0200626 self.assertEqual(child_binop.end_col_offset, 2)
Carl Friedrich Bolz-Tereick430a9f42019-07-09 14:20:01 +0200627 self.assertEqual(child_binop.end_lineno, 2)
Carl Friedrich Bolz-Tereick110a47c2019-07-08 23:17:56 +0200628
629 self.assertEqual(grandchild_binop.col_offset, 0)
Carl Friedrich Bolz-Tereick430a9f42019-07-09 14:20:01 +0200630 self.assertEqual(grandchild_binop.lineno, 1)
Carl Friedrich Bolz-Tereick110a47c2019-07-08 23:17:56 +0200631 self.assertEqual(grandchild_binop.end_col_offset, 3)
Carl Friedrich Bolz-Tereick430a9f42019-07-09 14:20:01 +0200632 self.assertEqual(grandchild_binop.end_lineno, 1)
Georg Brandl0c77a822008-06-10 16:37:50 +0000633
Lysandros Nikolaoud2e10982020-02-08 00:36:32 +0100634 def test_issue39579_dotted_name_end_col_offset(self):
635 tree = ast.parse('@a.b.c\ndef f(): pass')
636 attr_b = tree.body[0].decorator_list[0].value
637 self.assertEqual(attr_b.end_col_offset, 4)
638
Georg Brandl0c77a822008-06-10 16:37:50 +0000639class ASTHelpers_Test(unittest.TestCase):
Guido van Rossum10f8ce62019-03-13 13:00:46 -0700640 maxDiff = None
Georg Brandl0c77a822008-06-10 16:37:50 +0000641
642 def test_parse(self):
643 a = ast.parse('foo(1 + 1)')
644 b = compile('foo(1 + 1)', '<unknown>', 'exec', ast.PyCF_ONLY_AST)
645 self.assertEqual(ast.dump(a), ast.dump(b))
646
Benjamin Peterson2e2c9032012-09-02 14:23:15 -0400647 def test_parse_in_error(self):
648 try:
649 1/0
650 except Exception:
Benjamin Petersonbd0df502012-09-02 15:04:51 -0400651 with self.assertRaises(SyntaxError) as e:
652 ast.literal_eval(r"'\U'")
653 self.assertIsNotNone(e.exception.__context__)
Benjamin Peterson2e2c9032012-09-02 14:23:15 -0400654
Georg Brandl0c77a822008-06-10 16:37:50 +0000655 def test_dump(self):
656 node = ast.parse('spam(eggs, "and cheese")')
657 self.assertEqual(ast.dump(node),
658 "Module(body=[Expr(value=Call(func=Name(id='spam', ctx=Load()), "
Serhiy Storchakab7e95252020-03-10 00:07:47 +0200659 "args=[Name(id='eggs', ctx=Load()), Constant(value='and cheese')], "
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800660 "keywords=[]))], type_ignores=[])"
Georg Brandl0c77a822008-06-10 16:37:50 +0000661 )
662 self.assertEqual(ast.dump(node, annotate_fields=False),
663 "Module([Expr(Call(Name('spam', Load()), [Name('eggs', Load()), "
Serhiy Storchakab7e95252020-03-10 00:07:47 +0200664 "Constant('and cheese')], []))], [])"
Georg Brandl0c77a822008-06-10 16:37:50 +0000665 )
666 self.assertEqual(ast.dump(node, include_attributes=True),
667 "Module(body=[Expr(value=Call(func=Name(id='spam', ctx=Load(), "
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000668 "lineno=1, col_offset=0, end_lineno=1, end_col_offset=4), "
669 "args=[Name(id='eggs', ctx=Load(), lineno=1, col_offset=5, "
Serhiy Storchakab7e95252020-03-10 00:07:47 +0200670 "end_lineno=1, end_col_offset=9), Constant(value='and cheese', "
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000671 "lineno=1, col_offset=11, end_lineno=1, end_col_offset=23)], keywords=[], "
672 "lineno=1, col_offset=0, end_lineno=1, end_col_offset=24), "
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800673 "lineno=1, col_offset=0, end_lineno=1, end_col_offset=24)], type_ignores=[])"
Georg Brandl0c77a822008-06-10 16:37:50 +0000674 )
675
Serhiy Storchaka850573b2019-09-09 19:33:13 +0300676 def test_dump_indent(self):
677 node = ast.parse('spam(eggs, "and cheese")')
678 self.assertEqual(ast.dump(node, indent=3), """\
679Module(
680 body=[
681 Expr(
682 value=Call(
683 func=Name(id='spam', ctx=Load()),
684 args=[
685 Name(id='eggs', ctx=Load()),
Serhiy Storchakab7e95252020-03-10 00:07:47 +0200686 Constant(value='and cheese')],
Serhiy Storchaka850573b2019-09-09 19:33:13 +0300687 keywords=[]))],
688 type_ignores=[])""")
689 self.assertEqual(ast.dump(node, annotate_fields=False, indent='\t'), """\
690Module(
691\t[
692\t\tExpr(
693\t\t\tCall(
694\t\t\t\tName('spam', Load()),
695\t\t\t\t[
696\t\t\t\t\tName('eggs', Load()),
Serhiy Storchakab7e95252020-03-10 00:07:47 +0200697\t\t\t\t\tConstant('and cheese')],
Serhiy Storchaka850573b2019-09-09 19:33:13 +0300698\t\t\t\t[]))],
699\t[])""")
700 self.assertEqual(ast.dump(node, include_attributes=True, indent=3), """\
701Module(
702 body=[
703 Expr(
704 value=Call(
705 func=Name(
706 id='spam',
707 ctx=Load(),
708 lineno=1,
709 col_offset=0,
710 end_lineno=1,
711 end_col_offset=4),
712 args=[
713 Name(
714 id='eggs',
715 ctx=Load(),
716 lineno=1,
717 col_offset=5,
718 end_lineno=1,
719 end_col_offset=9),
720 Constant(
721 value='and cheese',
Serhiy Storchaka850573b2019-09-09 19:33:13 +0300722 lineno=1,
723 col_offset=11,
724 end_lineno=1,
725 end_col_offset=23)],
726 keywords=[],
727 lineno=1,
728 col_offset=0,
729 end_lineno=1,
730 end_col_offset=24),
731 lineno=1,
732 col_offset=0,
733 end_lineno=1,
734 end_col_offset=24)],
735 type_ignores=[])""")
736
Serhiy Storchakae64f9482019-08-29 09:30:23 +0300737 def test_dump_incomplete(self):
738 node = ast.Raise(lineno=3, col_offset=4)
739 self.assertEqual(ast.dump(node),
740 "Raise()"
741 )
742 self.assertEqual(ast.dump(node, include_attributes=True),
743 "Raise(lineno=3, col_offset=4)"
744 )
745 node = ast.Raise(exc=ast.Name(id='e', ctx=ast.Load()), lineno=3, col_offset=4)
746 self.assertEqual(ast.dump(node),
747 "Raise(exc=Name(id='e', ctx=Load()))"
748 )
749 self.assertEqual(ast.dump(node, annotate_fields=False),
750 "Raise(Name('e', Load()))"
751 )
752 self.assertEqual(ast.dump(node, include_attributes=True),
753 "Raise(exc=Name(id='e', ctx=Load()), lineno=3, col_offset=4)"
754 )
755 self.assertEqual(ast.dump(node, annotate_fields=False, include_attributes=True),
756 "Raise(Name('e', Load()), lineno=3, col_offset=4)"
757 )
758 node = ast.Raise(cause=ast.Name(id='e', ctx=ast.Load()))
759 self.assertEqual(ast.dump(node),
760 "Raise(cause=Name(id='e', ctx=Load()))"
761 )
762 self.assertEqual(ast.dump(node, annotate_fields=False),
763 "Raise(cause=Name('e', Load()))"
764 )
765
Georg Brandl0c77a822008-06-10 16:37:50 +0000766 def test_copy_location(self):
767 src = ast.parse('1 + 1', mode='eval')
768 src.body.right = ast.copy_location(ast.Num(2), src.body.right)
769 self.assertEqual(ast.dump(src, include_attributes=True),
Serhiy Storchakab7e95252020-03-10 00:07:47 +0200770 'Expression(body=BinOp(left=Constant(value=1, lineno=1, col_offset=0, '
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000771 'end_lineno=1, end_col_offset=1), op=Add(), right=Constant(value=2, '
772 'lineno=1, col_offset=4, end_lineno=1, end_col_offset=5), lineno=1, '
773 'col_offset=0, end_lineno=1, end_col_offset=5))'
Georg Brandl0c77a822008-06-10 16:37:50 +0000774 )
775
776 def test_fix_missing_locations(self):
777 src = ast.parse('write("spam")')
778 src.body.append(ast.Expr(ast.Call(ast.Name('spam', ast.Load()),
Benjamin Peterson025e9eb2015-05-05 20:16:41 -0400779 [ast.Str('eggs')], [])))
Georg Brandl0c77a822008-06-10 16:37:50 +0000780 self.assertEqual(src, ast.fix_missing_locations(src))
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000781 self.maxDiff = None
Georg Brandl0c77a822008-06-10 16:37:50 +0000782 self.assertEqual(ast.dump(src, include_attributes=True),
783 "Module(body=[Expr(value=Call(func=Name(id='write', ctx=Load(), "
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000784 "lineno=1, col_offset=0, end_lineno=1, end_col_offset=5), "
Serhiy Storchakab7e95252020-03-10 00:07:47 +0200785 "args=[Constant(value='spam', lineno=1, col_offset=6, end_lineno=1, "
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000786 "end_col_offset=12)], keywords=[], lineno=1, col_offset=0, end_lineno=1, "
787 "end_col_offset=13), lineno=1, col_offset=0, end_lineno=1, "
788 "end_col_offset=13), Expr(value=Call(func=Name(id='spam', ctx=Load(), "
789 "lineno=1, col_offset=0, end_lineno=1, end_col_offset=0), "
790 "args=[Constant(value='eggs', lineno=1, col_offset=0, end_lineno=1, "
791 "end_col_offset=0)], keywords=[], lineno=1, col_offset=0, end_lineno=1, "
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800792 "end_col_offset=0), lineno=1, col_offset=0, end_lineno=1, end_col_offset=0)], "
793 "type_ignores=[])"
Georg Brandl0c77a822008-06-10 16:37:50 +0000794 )
795
796 def test_increment_lineno(self):
797 src = ast.parse('1 + 1', mode='eval')
798 self.assertEqual(ast.increment_lineno(src, n=3), src)
799 self.assertEqual(ast.dump(src, include_attributes=True),
Serhiy Storchakab7e95252020-03-10 00:07:47 +0200800 'Expression(body=BinOp(left=Constant(value=1, lineno=4, col_offset=0, '
801 'end_lineno=4, end_col_offset=1), op=Add(), right=Constant(value=1, '
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000802 'lineno=4, col_offset=4, end_lineno=4, end_col_offset=5), lineno=4, '
803 'col_offset=0, end_lineno=4, end_col_offset=5))'
Georg Brandl0c77a822008-06-10 16:37:50 +0000804 )
Georg Brandl619e7ba2011-01-09 07:38:51 +0000805 # issue10869: do not increment lineno of root twice
Georg Brandlefb69022011-01-09 07:50:48 +0000806 src = ast.parse('1 + 1', mode='eval')
Georg Brandl619e7ba2011-01-09 07:38:51 +0000807 self.assertEqual(ast.increment_lineno(src.body, n=3), src.body)
808 self.assertEqual(ast.dump(src, include_attributes=True),
Serhiy Storchakab7e95252020-03-10 00:07:47 +0200809 'Expression(body=BinOp(left=Constant(value=1, lineno=4, col_offset=0, '
810 'end_lineno=4, end_col_offset=1), op=Add(), right=Constant(value=1, '
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000811 'lineno=4, col_offset=4, end_lineno=4, end_col_offset=5), lineno=4, '
812 'col_offset=0, end_lineno=4, end_col_offset=5))'
Georg Brandl619e7ba2011-01-09 07:38:51 +0000813 )
Georg Brandl0c77a822008-06-10 16:37:50 +0000814
815 def test_iter_fields(self):
816 node = ast.parse('foo()', mode='eval')
817 d = dict(ast.iter_fields(node.body))
818 self.assertEqual(d.pop('func').id, 'foo')
Benjamin Peterson025e9eb2015-05-05 20:16:41 -0400819 self.assertEqual(d, {'keywords': [], 'args': []})
Georg Brandl0c77a822008-06-10 16:37:50 +0000820
821 def test_iter_child_nodes(self):
822 node = ast.parse("spam(23, 42, eggs='leek')", mode='eval')
823 self.assertEqual(len(list(ast.iter_child_nodes(node.body))), 4)
824 iterator = ast.iter_child_nodes(node.body)
825 self.assertEqual(next(iterator).id, 'spam')
Serhiy Storchaka3f228112018-09-27 17:42:37 +0300826 self.assertEqual(next(iterator).value, 23)
827 self.assertEqual(next(iterator).value, 42)
Georg Brandl0c77a822008-06-10 16:37:50 +0000828 self.assertEqual(ast.dump(next(iterator)),
Serhiy Storchakab7e95252020-03-10 00:07:47 +0200829 "keyword(arg='eggs', value=Constant(value='leek'))"
Georg Brandl0c77a822008-06-10 16:37:50 +0000830 )
831
832 def test_get_docstring(self):
Serhiy Storchaka08f127a2018-06-15 11:05:15 +0300833 node = ast.parse('"""line one\n line two"""')
834 self.assertEqual(ast.get_docstring(node),
835 'line one\nline two')
836
837 node = ast.parse('class foo:\n """line one\n line two"""')
838 self.assertEqual(ast.get_docstring(node.body[0]),
839 'line one\nline two')
840
Georg Brandl0c77a822008-06-10 16:37:50 +0000841 node = ast.parse('def foo():\n """line one\n line two"""')
842 self.assertEqual(ast.get_docstring(node.body[0]),
843 'line one\nline two')
844
Yury Selivanov2f07a662015-07-23 08:54:35 +0300845 node = ast.parse('async def foo():\n """spam\n ham"""')
846 self.assertEqual(ast.get_docstring(node.body[0]), 'spam\nham')
Serhiy Storchaka08f127a2018-06-15 11:05:15 +0300847
848 def test_get_docstring_none(self):
Matthias Bussonnier41cea702017-02-23 22:44:19 -0800849 self.assertIsNone(ast.get_docstring(ast.parse('')))
Serhiy Storchaka08f127a2018-06-15 11:05:15 +0300850 node = ast.parse('x = "not docstring"')
851 self.assertIsNone(ast.get_docstring(node))
852 node = ast.parse('def foo():\n pass')
853 self.assertIsNone(ast.get_docstring(node))
854
855 node = ast.parse('class foo:\n pass')
856 self.assertIsNone(ast.get_docstring(node.body[0]))
857 node = ast.parse('class foo:\n x = "not docstring"')
858 self.assertIsNone(ast.get_docstring(node.body[0]))
859 node = ast.parse('class foo:\n def bar(self): pass')
860 self.assertIsNone(ast.get_docstring(node.body[0]))
861
862 node = ast.parse('def foo():\n pass')
863 self.assertIsNone(ast.get_docstring(node.body[0]))
864 node = ast.parse('def foo():\n x = "not docstring"')
865 self.assertIsNone(ast.get_docstring(node.body[0]))
866
867 node = ast.parse('async def foo():\n pass')
868 self.assertIsNone(ast.get_docstring(node.body[0]))
869 node = ast.parse('async def foo():\n x = "not docstring"')
870 self.assertIsNone(ast.get_docstring(node.body[0]))
Yury Selivanov2f07a662015-07-23 08:54:35 +0300871
Anthony Sottile995d9b92019-01-12 20:05:13 -0800872 def test_multi_line_docstring_col_offset_and_lineno_issue16806(self):
873 node = ast.parse(
874 '"""line one\nline two"""\n\n'
875 'def foo():\n """line one\n line two"""\n\n'
876 ' def bar():\n """line one\n line two"""\n'
877 ' """line one\n line two"""\n'
878 '"""line one\nline two"""\n\n'
879 )
880 self.assertEqual(node.body[0].col_offset, 0)
881 self.assertEqual(node.body[0].lineno, 1)
882 self.assertEqual(node.body[1].body[0].col_offset, 2)
883 self.assertEqual(node.body[1].body[0].lineno, 5)
884 self.assertEqual(node.body[1].body[1].body[0].col_offset, 4)
885 self.assertEqual(node.body[1].body[1].body[0].lineno, 9)
886 self.assertEqual(node.body[1].body[2].col_offset, 2)
887 self.assertEqual(node.body[1].body[2].lineno, 11)
888 self.assertEqual(node.body[2].col_offset, 0)
889 self.assertEqual(node.body[2].lineno, 13)
890
Lysandros Nikolaou025a6022019-12-12 22:40:21 +0100891 def test_elif_stmt_start_position(self):
892 node = ast.parse('if a:\n pass\nelif b:\n pass\n')
893 elif_stmt = node.body[0].orelse[0]
894 self.assertEqual(elif_stmt.lineno, 3)
895 self.assertEqual(elif_stmt.col_offset, 0)
896
Lysandros Nikolaou5936a4c2019-12-14 11:24:57 +0100897 def test_elif_stmt_start_position_with_else(self):
898 node = ast.parse('if a:\n pass\nelif b:\n pass\nelse:\n pass\n')
899 elif_stmt = node.body[0].orelse[0]
900 self.assertEqual(elif_stmt.lineno, 3)
901 self.assertEqual(elif_stmt.col_offset, 0)
902
Lysandros Nikolaou50d4f122019-12-18 01:20:55 +0100903 def test_starred_expr_end_position_within_call(self):
904 node = ast.parse('f(*[0, 1])')
905 starred_expr = node.body[0].value.args[0]
906 self.assertEqual(starred_expr.end_lineno, 1)
907 self.assertEqual(starred_expr.end_col_offset, 9)
908
Georg Brandl0c77a822008-06-10 16:37:50 +0000909 def test_literal_eval(self):
910 self.assertEqual(ast.literal_eval('[1, 2, 3]'), [1, 2, 3])
911 self.assertEqual(ast.literal_eval('{"foo": 42}'), {"foo": 42})
912 self.assertEqual(ast.literal_eval('(True, False, None)'), (True, False, None))
Benjamin Peterson3e742892010-07-11 12:59:24 +0000913 self.assertEqual(ast.literal_eval('{1, 2, 3}'), {1, 2, 3})
Benjamin Peterson5ef96e52010-07-11 23:06:06 +0000914 self.assertEqual(ast.literal_eval('b"hi"'), b"hi")
Raymond Hettinger4fcf5c12020-01-02 22:21:18 -0700915 self.assertEqual(ast.literal_eval('set()'), set())
Georg Brandl0c77a822008-06-10 16:37:50 +0000916 self.assertRaises(ValueError, ast.literal_eval, 'foo()')
Serhiy Storchakad8ac4d12018-01-04 11:15:39 +0200917 self.assertEqual(ast.literal_eval('6'), 6)
918 self.assertEqual(ast.literal_eval('+6'), 6)
Raymond Hettingerbc959732010-10-08 00:47:45 +0000919 self.assertEqual(ast.literal_eval('-6'), -6)
Raymond Hettingerbc959732010-10-08 00:47:45 +0000920 self.assertEqual(ast.literal_eval('3.25'), 3.25)
Serhiy Storchakad8ac4d12018-01-04 11:15:39 +0200921 self.assertEqual(ast.literal_eval('+3.25'), 3.25)
922 self.assertEqual(ast.literal_eval('-3.25'), -3.25)
923 self.assertEqual(repr(ast.literal_eval('-0.0')), '-0.0')
924 self.assertRaises(ValueError, ast.literal_eval, '++6')
925 self.assertRaises(ValueError, ast.literal_eval, '+True')
926 self.assertRaises(ValueError, ast.literal_eval, '2+3')
Georg Brandl0c77a822008-06-10 16:37:50 +0000927
Serhiy Storchakad8ac4d12018-01-04 11:15:39 +0200928 def test_literal_eval_complex(self):
929 # Issue #4907
930 self.assertEqual(ast.literal_eval('6j'), 6j)
931 self.assertEqual(ast.literal_eval('-6j'), -6j)
932 self.assertEqual(ast.literal_eval('6.75j'), 6.75j)
933 self.assertEqual(ast.literal_eval('-6.75j'), -6.75j)
934 self.assertEqual(ast.literal_eval('3+6j'), 3+6j)
935 self.assertEqual(ast.literal_eval('-3+6j'), -3+6j)
936 self.assertEqual(ast.literal_eval('3-6j'), 3-6j)
937 self.assertEqual(ast.literal_eval('-3-6j'), -3-6j)
938 self.assertEqual(ast.literal_eval('3.25+6.75j'), 3.25+6.75j)
939 self.assertEqual(ast.literal_eval('-3.25+6.75j'), -3.25+6.75j)
940 self.assertEqual(ast.literal_eval('3.25-6.75j'), 3.25-6.75j)
941 self.assertEqual(ast.literal_eval('-3.25-6.75j'), -3.25-6.75j)
942 self.assertEqual(ast.literal_eval('(3+6j)'), 3+6j)
943 self.assertRaises(ValueError, ast.literal_eval, '-6j+3')
944 self.assertRaises(ValueError, ast.literal_eval, '-6j+3j')
945 self.assertRaises(ValueError, ast.literal_eval, '3+-6j')
946 self.assertRaises(ValueError, ast.literal_eval, '3+(0+6j)')
947 self.assertRaises(ValueError, ast.literal_eval, '-(3+6j)')
Benjamin Peterson058e31e2009-01-16 03:54:08 +0000948
Amaury Forgeot d'Arc58e87612011-11-22 21:51:55 +0100949 def test_bad_integer(self):
950 # issue13436: Bad error message with invalid numeric values
951 body = [ast.ImportFrom(module='time',
952 names=[ast.alias(name='sleep')],
953 level=None,
954 lineno=None, col_offset=None)]
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800955 mod = ast.Module(body, [])
Amaury Forgeot d'Arc58e87612011-11-22 21:51:55 +0100956 with self.assertRaises(ValueError) as cm:
957 compile(mod, 'test', 'exec')
958 self.assertIn("invalid integer value: None", str(cm.exception))
959
Berker Peksag0a5bd512016-04-29 19:50:02 +0300960 def test_level_as_none(self):
961 body = [ast.ImportFrom(module='time',
962 names=[ast.alias(name='sleep')],
963 level=None,
964 lineno=0, col_offset=0)]
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800965 mod = ast.Module(body, [])
Berker Peksag0a5bd512016-04-29 19:50:02 +0300966 code = compile(mod, 'test', 'exec')
967 ns = {}
968 exec(code, ns)
969 self.assertIn('sleep', ns)
970
Georg Brandl0c77a822008-06-10 16:37:50 +0000971
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500972class ASTValidatorTests(unittest.TestCase):
973
974 def mod(self, mod, msg=None, mode="exec", *, exc=ValueError):
975 mod.lineno = mod.col_offset = 0
976 ast.fix_missing_locations(mod)
Serhiy Storchaka3f228112018-09-27 17:42:37 +0300977 if msg is None:
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500978 compile(mod, "<test>", mode)
Serhiy Storchaka3f228112018-09-27 17:42:37 +0300979 else:
980 with self.assertRaises(exc) as cm:
981 compile(mod, "<test>", mode)
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500982 self.assertIn(msg, str(cm.exception))
983
984 def expr(self, node, msg=None, *, exc=ValueError):
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800985 mod = ast.Module([ast.Expr(node)], [])
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500986 self.mod(mod, msg, exc=exc)
987
988 def stmt(self, stmt, msg=None):
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800989 mod = ast.Module([stmt], [])
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500990 self.mod(mod, msg)
991
992 def test_module(self):
993 m = ast.Interactive([ast.Expr(ast.Name("x", ast.Store()))])
994 self.mod(m, "must have Load context", "single")
995 m = ast.Expression(ast.Name("x", ast.Store()))
996 self.mod(m, "must have Load context", "eval")
997
998 def _check_arguments(self, fac, check):
Pablo Galindo8c77b8c2019-04-29 13:36:57 +0100999 def arguments(args=None, posonlyargs=None, vararg=None,
Benjamin Petersoncda75be2013-03-18 10:48:58 -07001000 kwonlyargs=None, kwarg=None,
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001001 defaults=None, kw_defaults=None):
1002 if args is None:
1003 args = []
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01001004 if posonlyargs is None:
1005 posonlyargs = []
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001006 if kwonlyargs is None:
1007 kwonlyargs = []
1008 if defaults is None:
1009 defaults = []
1010 if kw_defaults is None:
1011 kw_defaults = []
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01001012 args = ast.arguments(args, posonlyargs, vararg, kwonlyargs,
1013 kw_defaults, kwarg, defaults)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001014 return fac(args)
1015 args = [ast.arg("x", ast.Name("x", ast.Store()))]
1016 check(arguments(args=args), "must have Load context")
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01001017 check(arguments(posonlyargs=args), "must have Load context")
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001018 check(arguments(kwonlyargs=args), "must have Load context")
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001019 check(arguments(defaults=[ast.Num(3)]),
1020 "more positional defaults than args")
1021 check(arguments(kw_defaults=[ast.Num(4)]),
1022 "length of kwonlyargs is not the same as kw_defaults")
1023 args = [ast.arg("x", ast.Name("x", ast.Load()))]
1024 check(arguments(args=args, defaults=[ast.Name("x", ast.Store())]),
1025 "must have Load context")
1026 args = [ast.arg("a", ast.Name("x", ast.Load())),
1027 ast.arg("b", ast.Name("y", ast.Load()))]
1028 check(arguments(kwonlyargs=args,
1029 kw_defaults=[None, ast.Name("x", ast.Store())]),
1030 "must have Load context")
1031
1032 def test_funcdef(self):
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01001033 a = ast.arguments([], [], None, [], [], None, [])
Serhiy Storchaka73cbe7a2018-05-29 12:04:55 +03001034 f = ast.FunctionDef("x", a, [], [], None)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001035 self.stmt(f, "empty body on FunctionDef")
1036 f = ast.FunctionDef("x", a, [ast.Pass()], [ast.Name("x", ast.Store())],
Serhiy Storchaka73cbe7a2018-05-29 12:04:55 +03001037 None)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001038 self.stmt(f, "must have Load context")
1039 f = ast.FunctionDef("x", a, [ast.Pass()], [],
Serhiy Storchaka73cbe7a2018-05-29 12:04:55 +03001040 ast.Name("x", ast.Store()))
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001041 self.stmt(f, "must have Load context")
1042 def fac(args):
Serhiy Storchaka73cbe7a2018-05-29 12:04:55 +03001043 return ast.FunctionDef("x", args, [ast.Pass()], [], None)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001044 self._check_arguments(fac, self.stmt)
1045
1046 def test_classdef(self):
Benjamin Peterson025e9eb2015-05-05 20:16:41 -04001047 def cls(bases=None, keywords=None, body=None, decorator_list=None):
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001048 if bases is None:
1049 bases = []
1050 if keywords is None:
1051 keywords = []
1052 if body is None:
1053 body = [ast.Pass()]
1054 if decorator_list is None:
1055 decorator_list = []
Benjamin Peterson025e9eb2015-05-05 20:16:41 -04001056 return ast.ClassDef("myclass", bases, keywords,
Serhiy Storchaka73cbe7a2018-05-29 12:04:55 +03001057 body, decorator_list)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001058 self.stmt(cls(bases=[ast.Name("x", ast.Store())]),
1059 "must have Load context")
1060 self.stmt(cls(keywords=[ast.keyword("x", ast.Name("x", ast.Store()))]),
1061 "must have Load context")
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001062 self.stmt(cls(body=[]), "empty body on ClassDef")
1063 self.stmt(cls(body=[None]), "None disallowed")
1064 self.stmt(cls(decorator_list=[ast.Name("x", ast.Store())]),
1065 "must have Load context")
1066
1067 def test_delete(self):
1068 self.stmt(ast.Delete([]), "empty targets on Delete")
1069 self.stmt(ast.Delete([None]), "None disallowed")
1070 self.stmt(ast.Delete([ast.Name("x", ast.Load())]),
1071 "must have Del context")
1072
1073 def test_assign(self):
1074 self.stmt(ast.Assign([], ast.Num(3)), "empty targets on Assign")
1075 self.stmt(ast.Assign([None], ast.Num(3)), "None disallowed")
1076 self.stmt(ast.Assign([ast.Name("x", ast.Load())], ast.Num(3)),
1077 "must have Store context")
1078 self.stmt(ast.Assign([ast.Name("x", ast.Store())],
1079 ast.Name("y", ast.Store())),
1080 "must have Load context")
1081
1082 def test_augassign(self):
1083 aug = ast.AugAssign(ast.Name("x", ast.Load()), ast.Add(),
1084 ast.Name("y", ast.Load()))
1085 self.stmt(aug, "must have Store context")
1086 aug = ast.AugAssign(ast.Name("x", ast.Store()), ast.Add(),
1087 ast.Name("y", ast.Store()))
1088 self.stmt(aug, "must have Load context")
1089
1090 def test_for(self):
1091 x = ast.Name("x", ast.Store())
1092 y = ast.Name("y", ast.Load())
1093 p = ast.Pass()
1094 self.stmt(ast.For(x, y, [], []), "empty body on For")
1095 self.stmt(ast.For(ast.Name("x", ast.Load()), y, [p], []),
1096 "must have Store context")
1097 self.stmt(ast.For(x, ast.Name("y", ast.Store()), [p], []),
1098 "must have Load context")
1099 e = ast.Expr(ast.Name("x", ast.Store()))
1100 self.stmt(ast.For(x, y, [e], []), "must have Load context")
1101 self.stmt(ast.For(x, y, [p], [e]), "must have Load context")
1102
1103 def test_while(self):
1104 self.stmt(ast.While(ast.Num(3), [], []), "empty body on While")
1105 self.stmt(ast.While(ast.Name("x", ast.Store()), [ast.Pass()], []),
1106 "must have Load context")
1107 self.stmt(ast.While(ast.Num(3), [ast.Pass()],
1108 [ast.Expr(ast.Name("x", ast.Store()))]),
1109 "must have Load context")
1110
1111 def test_if(self):
1112 self.stmt(ast.If(ast.Num(3), [], []), "empty body on If")
1113 i = ast.If(ast.Name("x", ast.Store()), [ast.Pass()], [])
1114 self.stmt(i, "must have Load context")
1115 i = ast.If(ast.Num(3), [ast.Expr(ast.Name("x", ast.Store()))], [])
1116 self.stmt(i, "must have Load context")
1117 i = ast.If(ast.Num(3), [ast.Pass()],
1118 [ast.Expr(ast.Name("x", ast.Store()))])
1119 self.stmt(i, "must have Load context")
1120
1121 def test_with(self):
1122 p = ast.Pass()
1123 self.stmt(ast.With([], [p]), "empty items on With")
1124 i = ast.withitem(ast.Num(3), None)
1125 self.stmt(ast.With([i], []), "empty body on With")
1126 i = ast.withitem(ast.Name("x", ast.Store()), None)
1127 self.stmt(ast.With([i], [p]), "must have Load context")
1128 i = ast.withitem(ast.Num(3), ast.Name("x", ast.Load()))
1129 self.stmt(ast.With([i], [p]), "must have Store context")
1130
1131 def test_raise(self):
1132 r = ast.Raise(None, ast.Num(3))
1133 self.stmt(r, "Raise with cause but no exception")
1134 r = ast.Raise(ast.Name("x", ast.Store()), None)
1135 self.stmt(r, "must have Load context")
1136 r = ast.Raise(ast.Num(4), ast.Name("x", ast.Store()))
1137 self.stmt(r, "must have Load context")
1138
1139 def test_try(self):
1140 p = ast.Pass()
1141 t = ast.Try([], [], [], [p])
1142 self.stmt(t, "empty body on Try")
1143 t = ast.Try([ast.Expr(ast.Name("x", ast.Store()))], [], [], [p])
1144 self.stmt(t, "must have Load context")
1145 t = ast.Try([p], [], [], [])
1146 self.stmt(t, "Try has neither except handlers nor finalbody")
1147 t = ast.Try([p], [], [p], [p])
1148 self.stmt(t, "Try has orelse but no except handlers")
1149 t = ast.Try([p], [ast.ExceptHandler(None, "x", [])], [], [])
1150 self.stmt(t, "empty body on ExceptHandler")
1151 e = [ast.ExceptHandler(ast.Name("x", ast.Store()), "y", [p])]
1152 self.stmt(ast.Try([p], e, [], []), "must have Load context")
1153 e = [ast.ExceptHandler(None, "x", [p])]
1154 t = ast.Try([p], e, [ast.Expr(ast.Name("x", ast.Store()))], [p])
1155 self.stmt(t, "must have Load context")
1156 t = ast.Try([p], e, [p], [ast.Expr(ast.Name("x", ast.Store()))])
1157 self.stmt(t, "must have Load context")
1158
1159 def test_assert(self):
1160 self.stmt(ast.Assert(ast.Name("x", ast.Store()), None),
1161 "must have Load context")
1162 assrt = ast.Assert(ast.Name("x", ast.Load()),
1163 ast.Name("y", ast.Store()))
1164 self.stmt(assrt, "must have Load context")
1165
1166 def test_import(self):
1167 self.stmt(ast.Import([]), "empty names on Import")
1168
1169 def test_importfrom(self):
1170 imp = ast.ImportFrom(None, [ast.alias("x", None)], -42)
Serhiy Storchaka7de28402016-06-27 23:40:43 +03001171 self.stmt(imp, "Negative ImportFrom level")
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001172 self.stmt(ast.ImportFrom(None, [], 0), "empty names on ImportFrom")
1173
1174 def test_global(self):
1175 self.stmt(ast.Global([]), "empty names on Global")
1176
1177 def test_nonlocal(self):
1178 self.stmt(ast.Nonlocal([]), "empty names on Nonlocal")
1179
1180 def test_expr(self):
1181 e = ast.Expr(ast.Name("x", ast.Store()))
1182 self.stmt(e, "must have Load context")
1183
1184 def test_boolop(self):
1185 b = ast.BoolOp(ast.And(), [])
1186 self.expr(b, "less than 2 values")
1187 b = ast.BoolOp(ast.And(), [ast.Num(3)])
1188 self.expr(b, "less than 2 values")
1189 b = ast.BoolOp(ast.And(), [ast.Num(4), None])
1190 self.expr(b, "None disallowed")
1191 b = ast.BoolOp(ast.And(), [ast.Num(4), ast.Name("x", ast.Store())])
1192 self.expr(b, "must have Load context")
1193
1194 def test_unaryop(self):
1195 u = ast.UnaryOp(ast.Not(), ast.Name("x", ast.Store()))
1196 self.expr(u, "must have Load context")
1197
1198 def test_lambda(self):
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01001199 a = ast.arguments([], [], None, [], [], None, [])
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001200 self.expr(ast.Lambda(a, ast.Name("x", ast.Store())),
1201 "must have Load context")
1202 def fac(args):
1203 return ast.Lambda(args, ast.Name("x", ast.Load()))
1204 self._check_arguments(fac, self.expr)
1205
1206 def test_ifexp(self):
1207 l = ast.Name("x", ast.Load())
1208 s = ast.Name("y", ast.Store())
1209 for args in (s, l, l), (l, s, l), (l, l, s):
Benjamin Peterson71ce8972011-08-09 16:17:12 -05001210 self.expr(ast.IfExp(*args), "must have Load context")
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001211
1212 def test_dict(self):
1213 d = ast.Dict([], [ast.Name("x", ast.Load())])
1214 self.expr(d, "same number of keys as values")
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001215 d = ast.Dict([ast.Name("x", ast.Load())], [None])
1216 self.expr(d, "None disallowed")
1217
1218 def test_set(self):
1219 self.expr(ast.Set([None]), "None disallowed")
1220 s = ast.Set([ast.Name("x", ast.Store())])
1221 self.expr(s, "must have Load context")
1222
1223 def _check_comprehension(self, fac):
1224 self.expr(fac([]), "comprehension with no generators")
1225 g = ast.comprehension(ast.Name("x", ast.Load()),
Yury Selivanov52c4e7c2016-09-09 10:36:01 -07001226 ast.Name("x", ast.Load()), [], 0)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001227 self.expr(fac([g]), "must have Store context")
1228 g = ast.comprehension(ast.Name("x", ast.Store()),
Yury Selivanov52c4e7c2016-09-09 10:36:01 -07001229 ast.Name("x", ast.Store()), [], 0)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001230 self.expr(fac([g]), "must have Load context")
1231 x = ast.Name("x", ast.Store())
1232 y = ast.Name("y", ast.Load())
Yury Selivanov52c4e7c2016-09-09 10:36:01 -07001233 g = ast.comprehension(x, y, [None], 0)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001234 self.expr(fac([g]), "None disallowed")
Yury Selivanov52c4e7c2016-09-09 10:36:01 -07001235 g = ast.comprehension(x, y, [ast.Name("x", ast.Store())], 0)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001236 self.expr(fac([g]), "must have Load context")
1237
1238 def _simple_comp(self, fac):
1239 g = ast.comprehension(ast.Name("x", ast.Store()),
Yury Selivanov52c4e7c2016-09-09 10:36:01 -07001240 ast.Name("x", ast.Load()), [], 0)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001241 self.expr(fac(ast.Name("x", ast.Store()), [g]),
1242 "must have Load context")
1243 def wrap(gens):
1244 return fac(ast.Name("x", ast.Store()), gens)
1245 self._check_comprehension(wrap)
1246
1247 def test_listcomp(self):
1248 self._simple_comp(ast.ListComp)
1249
1250 def test_setcomp(self):
1251 self._simple_comp(ast.SetComp)
1252
1253 def test_generatorexp(self):
1254 self._simple_comp(ast.GeneratorExp)
1255
1256 def test_dictcomp(self):
1257 g = ast.comprehension(ast.Name("y", ast.Store()),
Yury Selivanov52c4e7c2016-09-09 10:36:01 -07001258 ast.Name("p", ast.Load()), [], 0)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001259 c = ast.DictComp(ast.Name("x", ast.Store()),
1260 ast.Name("y", ast.Load()), [g])
1261 self.expr(c, "must have Load context")
1262 c = ast.DictComp(ast.Name("x", ast.Load()),
1263 ast.Name("y", ast.Store()), [g])
1264 self.expr(c, "must have Load context")
1265 def factory(comps):
1266 k = ast.Name("x", ast.Load())
1267 v = ast.Name("y", ast.Load())
1268 return ast.DictComp(k, v, comps)
1269 self._check_comprehension(factory)
1270
1271 def test_yield(self):
Benjamin Peterson527c6222012-01-14 08:58:23 -05001272 self.expr(ast.Yield(ast.Name("x", ast.Store())), "must have Load")
1273 self.expr(ast.YieldFrom(ast.Name("x", ast.Store())), "must have Load")
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001274
1275 def test_compare(self):
1276 left = ast.Name("x", ast.Load())
1277 comp = ast.Compare(left, [ast.In()], [])
1278 self.expr(comp, "no comparators")
1279 comp = ast.Compare(left, [ast.In()], [ast.Num(4), ast.Num(5)])
1280 self.expr(comp, "different number of comparators and operands")
1281 comp = ast.Compare(ast.Num("blah"), [ast.In()], [left])
Serhiy Storchaka3f228112018-09-27 17:42:37 +03001282 self.expr(comp)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001283 comp = ast.Compare(left, [ast.In()], [ast.Num("blah")])
Serhiy Storchaka3f228112018-09-27 17:42:37 +03001284 self.expr(comp)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001285
1286 def test_call(self):
1287 func = ast.Name("x", ast.Load())
1288 args = [ast.Name("y", ast.Load())]
1289 keywords = [ast.keyword("w", ast.Name("z", ast.Load()))]
Benjamin Peterson025e9eb2015-05-05 20:16:41 -04001290 call = ast.Call(ast.Name("x", ast.Store()), args, keywords)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001291 self.expr(call, "must have Load context")
Benjamin Peterson025e9eb2015-05-05 20:16:41 -04001292 call = ast.Call(func, [None], keywords)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001293 self.expr(call, "None disallowed")
1294 bad_keywords = [ast.keyword("w", ast.Name("z", ast.Store()))]
Benjamin Peterson025e9eb2015-05-05 20:16:41 -04001295 call = ast.Call(func, args, bad_keywords)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001296 self.expr(call, "must have Load context")
1297
1298 def test_num(self):
1299 class subint(int):
1300 pass
1301 class subfloat(float):
1302 pass
1303 class subcomplex(complex):
1304 pass
Serhiy Storchaka3f228112018-09-27 17:42:37 +03001305 for obj in "0", "hello":
1306 self.expr(ast.Num(obj))
1307 for obj in subint(), subfloat(), subcomplex():
1308 self.expr(ast.Num(obj), "invalid type", exc=TypeError)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001309
1310 def test_attribute(self):
1311 attr = ast.Attribute(ast.Name("x", ast.Store()), "y", ast.Load())
1312 self.expr(attr, "must have Load context")
1313
1314 def test_subscript(self):
Serhiy Storchaka13d52c22020-03-10 18:52:34 +02001315 sub = ast.Subscript(ast.Name("x", ast.Store()), ast.Num(3),
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001316 ast.Load())
1317 self.expr(sub, "must have Load context")
1318 x = ast.Name("x", ast.Load())
Serhiy Storchaka13d52c22020-03-10 18:52:34 +02001319 sub = ast.Subscript(x, ast.Name("y", ast.Store()),
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001320 ast.Load())
1321 self.expr(sub, "must have Load context")
1322 s = ast.Name("x", ast.Store())
1323 for args in (s, None, None), (None, s, None), (None, None, s):
1324 sl = ast.Slice(*args)
1325 self.expr(ast.Subscript(x, sl, ast.Load()),
1326 "must have Load context")
Serhiy Storchaka13d52c22020-03-10 18:52:34 +02001327 sl = ast.Tuple([], ast.Load())
1328 self.expr(ast.Subscript(x, sl, ast.Load()))
1329 sl = ast.Tuple([s], ast.Load())
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001330 self.expr(ast.Subscript(x, sl, ast.Load()), "must have Load context")
1331
1332 def test_starred(self):
1333 left = ast.List([ast.Starred(ast.Name("x", ast.Load()), ast.Store())],
1334 ast.Store())
1335 assign = ast.Assign([left], ast.Num(4))
1336 self.stmt(assign, "must have Store context")
1337
1338 def _sequence(self, fac):
1339 self.expr(fac([None], ast.Load()), "None disallowed")
1340 self.expr(fac([ast.Name("x", ast.Store())], ast.Load()),
1341 "must have Load context")
1342
1343 def test_list(self):
1344 self._sequence(ast.List)
1345
1346 def test_tuple(self):
1347 self._sequence(ast.Tuple)
1348
Benjamin Peterson442f2092012-12-06 17:41:04 -05001349 def test_nameconstant(self):
Serhiy Storchaka3f228112018-09-27 17:42:37 +03001350 self.expr(ast.NameConstant(4))
Benjamin Peterson442f2092012-12-06 17:41:04 -05001351
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001352 def test_stdlib_validates(self):
1353 stdlib = os.path.dirname(ast.__file__)
1354 tests = [fn for fn in os.listdir(stdlib) if fn.endswith(".py")]
1355 tests.extend(["test/test_grammar.py", "test/test_unpack_ex.py"])
1356 for module in tests:
Serhiy Storchaka3bcbedc2019-01-18 07:47:48 +02001357 with self.subTest(module):
1358 fn = os.path.join(stdlib, module)
1359 with open(fn, "r", encoding="utf-8") as fp:
1360 source = fp.read()
1361 mod = ast.parse(source, fn)
1362 compile(mod, fn, "exec")
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001363
1364
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001365class ConstantTests(unittest.TestCase):
1366 """Tests on the ast.Constant node type."""
1367
1368 def compile_constant(self, value):
1369 tree = ast.parse("x = 123")
1370
1371 node = tree.body[0].value
1372 new_node = ast.Constant(value=value)
1373 ast.copy_location(new_node, node)
1374 tree.body[0].value = new_node
1375
1376 code = compile(tree, "<string>", "exec")
1377
1378 ns = {}
1379 exec(code, ns)
1380 return ns['x']
1381
Victor Stinnerbe59d142016-01-27 00:39:12 +01001382 def test_validation(self):
1383 with self.assertRaises(TypeError) as cm:
1384 self.compile_constant([1, 2, 3])
1385 self.assertEqual(str(cm.exception),
1386 "got an invalid type in Constant: list")
1387
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001388 def test_singletons(self):
1389 for const in (None, False, True, Ellipsis, b'', frozenset()):
1390 with self.subTest(const=const):
1391 value = self.compile_constant(const)
1392 self.assertIs(value, const)
1393
1394 def test_values(self):
1395 nested_tuple = (1,)
1396 nested_frozenset = frozenset({1})
1397 for level in range(3):
1398 nested_tuple = (nested_tuple, 2)
1399 nested_frozenset = frozenset({nested_frozenset, 2})
1400 values = (123, 123.0, 123j,
1401 "unicode", b'bytes',
1402 tuple("tuple"), frozenset("frozenset"),
1403 nested_tuple, nested_frozenset)
1404 for value in values:
1405 with self.subTest(value=value):
1406 result = self.compile_constant(value)
1407 self.assertEqual(result, value)
1408
1409 def test_assign_to_constant(self):
1410 tree = ast.parse("x = 1")
1411
1412 target = tree.body[0].targets[0]
1413 new_target = ast.Constant(value=1)
1414 ast.copy_location(new_target, target)
1415 tree.body[0].targets[0] = new_target
1416
1417 with self.assertRaises(ValueError) as cm:
1418 compile(tree, "string", "exec")
1419 self.assertEqual(str(cm.exception),
1420 "expression which can't be assigned "
1421 "to in Store context")
1422
1423 def test_get_docstring(self):
1424 tree = ast.parse("'docstring'\nx = 1")
1425 self.assertEqual(ast.get_docstring(tree), 'docstring')
1426
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001427 def get_load_const(self, tree):
1428 # Compile to bytecode, disassemble and get parameter of LOAD_CONST
1429 # instructions
1430 co = compile(tree, '<string>', 'exec')
1431 consts = []
1432 for instr in dis.get_instructions(co):
1433 if instr.opname == 'LOAD_CONST':
1434 consts.append(instr.argval)
1435 return consts
1436
1437 @support.cpython_only
1438 def test_load_const(self):
1439 consts = [None,
1440 True, False,
1441 124,
1442 2.0,
1443 3j,
1444 "unicode",
1445 b'bytes',
1446 (1, 2, 3)]
1447
Victor Stinnera2724092016-02-08 18:17:58 +01001448 code = '\n'.join(['x={!r}'.format(const) for const in consts])
1449 code += '\nx = ...'
1450 consts.extend((Ellipsis, None))
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001451
1452 tree = ast.parse(code)
Victor Stinnera2724092016-02-08 18:17:58 +01001453 self.assertEqual(self.get_load_const(tree),
1454 consts)
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001455
1456 # Replace expression nodes with constants
Victor Stinnera2724092016-02-08 18:17:58 +01001457 for assign, const in zip(tree.body, consts):
1458 assert isinstance(assign, ast.Assign), ast.dump(assign)
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001459 new_node = ast.Constant(value=const)
Victor Stinnera2724092016-02-08 18:17:58 +01001460 ast.copy_location(new_node, assign.value)
1461 assign.value = new_node
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001462
Victor Stinnera2724092016-02-08 18:17:58 +01001463 self.assertEqual(self.get_load_const(tree),
1464 consts)
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001465
1466 def test_literal_eval(self):
1467 tree = ast.parse("1 + 2")
1468 binop = tree.body[0].value
1469
1470 new_left = ast.Constant(value=10)
1471 ast.copy_location(new_left, binop.left)
1472 binop.left = new_left
1473
Serhiy Storchakad8ac4d12018-01-04 11:15:39 +02001474 new_right = ast.Constant(value=20j)
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001475 ast.copy_location(new_right, binop.right)
1476 binop.right = new_right
1477
Serhiy Storchakad8ac4d12018-01-04 11:15:39 +02001478 self.assertEqual(ast.literal_eval(binop), 10+20j)
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001479
Guido van Rossum10f8ce62019-03-13 13:00:46 -07001480 def test_string_kind(self):
1481 c = ast.parse('"x"', mode='eval').body
1482 self.assertEqual(c.value, "x")
1483 self.assertEqual(c.kind, None)
1484
1485 c = ast.parse('u"x"', mode='eval').body
1486 self.assertEqual(c.value, "x")
1487 self.assertEqual(c.kind, "u")
1488
1489 c = ast.parse('r"x"', mode='eval').body
1490 self.assertEqual(c.value, "x")
1491 self.assertEqual(c.kind, None)
1492
1493 c = ast.parse('b"x"', mode='eval').body
1494 self.assertEqual(c.value, b"x")
1495 self.assertEqual(c.kind, None)
1496
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001497
Ivan Levkivskyi9932a222019-01-22 11:18:22 +00001498class EndPositionTests(unittest.TestCase):
1499 """Tests for end position of AST nodes.
1500
1501 Testing end positions of nodes requires a bit of extra care
1502 because of how LL parsers work.
1503 """
1504 def _check_end_pos(self, ast_node, end_lineno, end_col_offset):
1505 self.assertEqual(ast_node.end_lineno, end_lineno)
1506 self.assertEqual(ast_node.end_col_offset, end_col_offset)
1507
1508 def _check_content(self, source, ast_node, content):
1509 self.assertEqual(ast.get_source_segment(source, ast_node), content)
1510
1511 def _parse_value(self, s):
1512 # Use duck-typing to support both single expression
1513 # and a right hand side of an assignment statement.
1514 return ast.parse(s).body[0].value
1515
1516 def test_lambda(self):
1517 s = 'lambda x, *y: None'
1518 lam = self._parse_value(s)
1519 self._check_content(s, lam.body, 'None')
1520 self._check_content(s, lam.args.args[0], 'x')
1521 self._check_content(s, lam.args.vararg, 'y')
1522
1523 def test_func_def(self):
1524 s = dedent('''
1525 def func(x: int,
1526 *args: str,
1527 z: float = 0,
1528 **kwargs: Any) -> bool:
1529 return True
1530 ''').strip()
1531 fdef = ast.parse(s).body[0]
1532 self._check_end_pos(fdef, 5, 15)
1533 self._check_content(s, fdef.body[0], 'return True')
1534 self._check_content(s, fdef.args.args[0], 'x: int')
1535 self._check_content(s, fdef.args.args[0].annotation, 'int')
1536 self._check_content(s, fdef.args.kwarg, 'kwargs: Any')
1537 self._check_content(s, fdef.args.kwarg.annotation, 'Any')
1538
1539 def test_call(self):
1540 s = 'func(x, y=2, **kw)'
1541 call = self._parse_value(s)
1542 self._check_content(s, call.func, 'func')
1543 self._check_content(s, call.keywords[0].value, '2')
1544 self._check_content(s, call.keywords[1].value, 'kw')
1545
1546 def test_call_noargs(self):
1547 s = 'x[0]()'
1548 call = self._parse_value(s)
1549 self._check_content(s, call.func, 'x[0]')
1550 self._check_end_pos(call, 1, 6)
1551
1552 def test_class_def(self):
1553 s = dedent('''
1554 class C(A, B):
1555 x: int = 0
1556 ''').strip()
1557 cdef = ast.parse(s).body[0]
1558 self._check_end_pos(cdef, 2, 14)
1559 self._check_content(s, cdef.bases[1], 'B')
1560 self._check_content(s, cdef.body[0], 'x: int = 0')
1561
1562 def test_class_kw(self):
1563 s = 'class S(metaclass=abc.ABCMeta): pass'
1564 cdef = ast.parse(s).body[0]
1565 self._check_content(s, cdef.keywords[0].value, 'abc.ABCMeta')
1566
1567 def test_multi_line_str(self):
1568 s = dedent('''
1569 x = """Some multi-line text.
1570
1571 It goes on starting from same indent."""
1572 ''').strip()
1573 assign = ast.parse(s).body[0]
1574 self._check_end_pos(assign, 3, 40)
1575 self._check_end_pos(assign.value, 3, 40)
1576
1577 def test_continued_str(self):
1578 s = dedent('''
1579 x = "first part" \\
1580 "second part"
1581 ''').strip()
1582 assign = ast.parse(s).body[0]
1583 self._check_end_pos(assign, 2, 13)
1584 self._check_end_pos(assign.value, 2, 13)
1585
1586 def test_suites(self):
1587 # We intentionally put these into the same string to check
1588 # that empty lines are not part of the suite.
1589 s = dedent('''
1590 while True:
1591 pass
1592
1593 if one():
1594 x = None
1595 elif other():
1596 y = None
1597 else:
1598 z = None
1599
1600 for x, y in stuff:
1601 assert True
1602
1603 try:
1604 raise RuntimeError
1605 except TypeError as e:
1606 pass
1607
1608 pass
1609 ''').strip()
1610 mod = ast.parse(s)
1611 while_loop = mod.body[0]
1612 if_stmt = mod.body[1]
1613 for_loop = mod.body[2]
1614 try_stmt = mod.body[3]
1615 pass_stmt = mod.body[4]
1616
1617 self._check_end_pos(while_loop, 2, 8)
1618 self._check_end_pos(if_stmt, 9, 12)
1619 self._check_end_pos(for_loop, 12, 15)
1620 self._check_end_pos(try_stmt, 17, 8)
1621 self._check_end_pos(pass_stmt, 19, 4)
1622
1623 self._check_content(s, while_loop.test, 'True')
1624 self._check_content(s, if_stmt.body[0], 'x = None')
1625 self._check_content(s, if_stmt.orelse[0].test, 'other()')
1626 self._check_content(s, for_loop.target, 'x, y')
1627 self._check_content(s, try_stmt.body[0], 'raise RuntimeError')
1628 self._check_content(s, try_stmt.handlers[0].type, 'TypeError')
1629
1630 def test_fstring(self):
1631 s = 'x = f"abc {x + y} abc"'
1632 fstr = self._parse_value(s)
1633 binop = fstr.values[1].value
1634 self._check_content(s, binop, 'x + y')
1635
1636 def test_fstring_multi_line(self):
1637 s = dedent('''
1638 f"""Some multi-line text.
1639 {
1640 arg_one
1641 +
1642 arg_two
1643 }
1644 It goes on..."""
1645 ''').strip()
1646 fstr = self._parse_value(s)
1647 binop = fstr.values[1].value
1648 self._check_end_pos(binop, 5, 7)
1649 self._check_content(s, binop.left, 'arg_one')
1650 self._check_content(s, binop.right, 'arg_two')
1651
1652 def test_import_from_multi_line(self):
1653 s = dedent('''
1654 from x.y.z import (
1655 a, b, c as c
1656 )
1657 ''').strip()
1658 imp = ast.parse(s).body[0]
1659 self._check_end_pos(imp, 3, 1)
1660
1661 def test_slices(self):
1662 s1 = 'f()[1, 2] [0]'
1663 s2 = 'x[ a.b: c.d]'
1664 sm = dedent('''
1665 x[ a.b: f () ,
1666 g () : c.d
1667 ]
1668 ''').strip()
1669 i1, i2, im = map(self._parse_value, (s1, s2, sm))
1670 self._check_content(s1, i1.value, 'f()[1, 2]')
Serhiy Storchaka13d52c22020-03-10 18:52:34 +02001671 self._check_content(s1, i1.value.slice, '1, 2')
Ivan Levkivskyi9932a222019-01-22 11:18:22 +00001672 self._check_content(s2, i2.slice.lower, 'a.b')
1673 self._check_content(s2, i2.slice.upper, 'c.d')
Serhiy Storchaka13d52c22020-03-10 18:52:34 +02001674 self._check_content(sm, im.slice.elts[0].upper, 'f ()')
1675 self._check_content(sm, im.slice.elts[1].lower, 'g ()')
Ivan Levkivskyi9932a222019-01-22 11:18:22 +00001676 self._check_end_pos(im, 3, 3)
1677
1678 def test_binop(self):
1679 s = dedent('''
1680 (1 * 2 + (3 ) +
1681 4
1682 )
1683 ''').strip()
1684 binop = self._parse_value(s)
1685 self._check_end_pos(binop, 2, 6)
1686 self._check_content(s, binop.right, '4')
1687 self._check_content(s, binop.left, '1 * 2 + (3 )')
1688 self._check_content(s, binop.left.right, '3')
1689
1690 def test_boolop(self):
1691 s = dedent('''
1692 if (one_condition and
1693 (other_condition or yet_another_one)):
1694 pass
1695 ''').strip()
1696 bop = ast.parse(s).body[0].test
1697 self._check_end_pos(bop, 2, 44)
1698 self._check_content(s, bop.values[1],
1699 'other_condition or yet_another_one')
1700
1701 def test_tuples(self):
1702 s1 = 'x = () ;'
1703 s2 = 'x = 1 , ;'
1704 s3 = 'x = (1 , 2 ) ;'
1705 sm = dedent('''
1706 x = (
1707 a, b,
1708 )
1709 ''').strip()
1710 t1, t2, t3, tm = map(self._parse_value, (s1, s2, s3, sm))
1711 self._check_content(s1, t1, '()')
1712 self._check_content(s2, t2, '1 ,')
1713 self._check_content(s3, t3, '(1 , 2 )')
1714 self._check_end_pos(tm, 3, 1)
1715
1716 def test_attribute_spaces(self):
1717 s = 'func(x. y .z)'
1718 call = self._parse_value(s)
1719 self._check_content(s, call, s)
1720 self._check_content(s, call.args[0], 'x. y .z')
1721
Serhiy Storchaka6e619c42020-02-12 22:37:49 +02001722 def test_redundant_parenthesis(self):
1723 s = '( ( ( a + b ) ) )'
1724 v = ast.parse(s).body[0].value
1725 self.assertEqual(type(v).__name__, 'BinOp')
1726 self._check_content(s, v, 'a + b')
1727 s2 = 'await ' + s
1728 v = ast.parse(s2).body[0].value.value
1729 self.assertEqual(type(v).__name__, 'BinOp')
1730 self._check_content(s2, v, 'a + b')
1731
1732 def test_trailers_with_redundant_parenthesis(self):
1733 tests = (
1734 ('( ( ( a ) ) ) ( )', 'Call'),
1735 ('( ( ( a ) ) ) ( b )', 'Call'),
1736 ('( ( ( a ) ) ) [ b ]', 'Subscript'),
1737 ('( ( ( a ) ) ) . b', 'Attribute'),
1738 )
1739 for s, t in tests:
1740 with self.subTest(s):
1741 v = ast.parse(s).body[0].value
1742 self.assertEqual(type(v).__name__, t)
1743 self._check_content(s, v, s)
1744 s2 = 'await ' + s
1745 v = ast.parse(s2).body[0].value.value
1746 self.assertEqual(type(v).__name__, t)
1747 self._check_content(s2, v, s)
1748
Ivan Levkivskyi9932a222019-01-22 11:18:22 +00001749 def test_displays(self):
1750 s1 = '[{}, {1, }, {1, 2,} ]'
1751 s2 = '{a: b, f (): g () ,}'
1752 c1 = self._parse_value(s1)
1753 c2 = self._parse_value(s2)
1754 self._check_content(s1, c1.elts[0], '{}')
1755 self._check_content(s1, c1.elts[1], '{1, }')
1756 self._check_content(s1, c1.elts[2], '{1, 2,}')
1757 self._check_content(s2, c2.keys[1], 'f ()')
1758 self._check_content(s2, c2.values[1], 'g ()')
1759
1760 def test_comprehensions(self):
1761 s = dedent('''
1762 x = [{x for x, y in stuff
1763 if cond.x} for stuff in things]
1764 ''').strip()
1765 cmp = self._parse_value(s)
1766 self._check_end_pos(cmp, 2, 37)
1767 self._check_content(s, cmp.generators[0].iter, 'things')
1768 self._check_content(s, cmp.elt.generators[0].iter, 'stuff')
1769 self._check_content(s, cmp.elt.generators[0].ifs[0], 'cond.x')
1770 self._check_content(s, cmp.elt.generators[0].target, 'x, y')
1771
1772 def test_yield_await(self):
1773 s = dedent('''
1774 async def f():
1775 yield x
1776 await y
1777 ''').strip()
1778 fdef = ast.parse(s).body[0]
1779 self._check_content(s, fdef.body[0].value, 'yield x')
1780 self._check_content(s, fdef.body[1].value, 'await y')
1781
1782 def test_source_segment_multi(self):
1783 s_orig = dedent('''
1784 x = (
1785 a, b,
1786 ) + ()
1787 ''').strip()
1788 s_tuple = dedent('''
1789 (
1790 a, b,
1791 )
1792 ''').strip()
1793 binop = self._parse_value(s_orig)
1794 self.assertEqual(ast.get_source_segment(s_orig, binop.left), s_tuple)
1795
1796 def test_source_segment_padded(self):
1797 s_orig = dedent('''
1798 class C:
1799 def fun(self) -> None:
1800 "Đ–Đ–Đ–Đ–Đ–"
1801 ''').strip()
1802 s_method = ' def fun(self) -> None:\n' \
1803 ' "Đ–Đ–Đ–Đ–Đ–"'
1804 cdef = ast.parse(s_orig).body[0]
1805 self.assertEqual(ast.get_source_segment(s_orig, cdef.body[0], padded=True),
1806 s_method)
1807
1808 def test_source_segment_endings(self):
1809 s = 'v = 1\r\nw = 1\nx = 1\n\ry = 1\rz = 1\r\n'
1810 v, w, x, y, z = ast.parse(s).body
1811 self._check_content(s, v, 'v = 1')
1812 self._check_content(s, w, 'w = 1')
1813 self._check_content(s, x, 'x = 1')
1814 self._check_content(s, y, 'y = 1')
1815 self._check_content(s, z, 'z = 1')
1816
1817 def test_source_segment_tabs(self):
1818 s = dedent('''
1819 class C:
1820 \t\f def fun(self) -> None:
1821 \t\f pass
1822 ''').strip()
1823 s_method = ' \t\f def fun(self) -> None:\n' \
1824 ' \t\f pass'
1825
1826 cdef = ast.parse(s).body[0]
1827 self.assertEqual(ast.get_source_segment(s, cdef.body[0], padded=True), s_method)
1828
1829
Serhiy Storchakac3ea41e2019-08-26 10:13:19 +03001830class NodeVisitorTests(unittest.TestCase):
1831 def test_old_constant_nodes(self):
1832 class Visitor(ast.NodeVisitor):
1833 def visit_Num(self, node):
1834 log.append((node.lineno, 'Num', node.n))
1835 def visit_Str(self, node):
1836 log.append((node.lineno, 'Str', node.s))
1837 def visit_Bytes(self, node):
1838 log.append((node.lineno, 'Bytes', node.s))
1839 def visit_NameConstant(self, node):
1840 log.append((node.lineno, 'NameConstant', node.value))
1841 def visit_Ellipsis(self, node):
1842 log.append((node.lineno, 'Ellipsis', ...))
1843 mod = ast.parse(dedent('''\
1844 i = 42
1845 f = 4.25
1846 c = 4.25j
1847 s = 'string'
1848 b = b'bytes'
1849 t = True
1850 n = None
1851 e = ...
1852 '''))
1853 visitor = Visitor()
1854 log = []
1855 with warnings.catch_warnings(record=True) as wlog:
1856 warnings.filterwarnings('always', '', DeprecationWarning)
1857 visitor.visit(mod)
1858 self.assertEqual(log, [
1859 (1, 'Num', 42),
1860 (2, 'Num', 4.25),
1861 (3, 'Num', 4.25j),
1862 (4, 'Str', 'string'),
1863 (5, 'Bytes', b'bytes'),
1864 (6, 'NameConstant', True),
1865 (7, 'NameConstant', None),
1866 (8, 'Ellipsis', ...),
1867 ])
1868 self.assertEqual([str(w.message) for w in wlog], [
1869 'visit_Num is deprecated; add visit_Constant',
1870 'visit_Num is deprecated; add visit_Constant',
1871 'visit_Num is deprecated; add visit_Constant',
1872 'visit_Str is deprecated; add visit_Constant',
1873 'visit_Bytes is deprecated; add visit_Constant',
1874 'visit_NameConstant is deprecated; add visit_Constant',
1875 'visit_NameConstant is deprecated; add visit_Constant',
1876 'visit_Ellipsis is deprecated; add visit_Constant',
1877 ])
1878
1879
Neal Norwitzee9b10a2008-03-31 05:29:39 +00001880def main():
1881 if __name__ != '__main__':
Martin v. Löwis49c5da12006-03-01 22:49:05 +00001882 return
Neal Norwitzee9b10a2008-03-31 05:29:39 +00001883 if sys.argv[1:] == ['-g']:
1884 for statements, kind in ((exec_tests, "exec"), (single_tests, "single"),
1885 (eval_tests, "eval")):
1886 print(kind+"_results = [")
Victor Stinnerf0891962016-02-08 17:15:21 +01001887 for statement in statements:
1888 tree = ast.parse(statement, "?", kind)
1889 print("%r," % (to_tuple(tree),))
Neal Norwitzee9b10a2008-03-31 05:29:39 +00001890 print("]")
1891 print("main()")
1892 raise SystemExit
Brett Cannon3e9a9ae2013-06-12 21:25:59 -04001893 unittest.main()
Tim Peters400cbc32006-02-28 18:44:41 +00001894
Guido van Rossumdcfcd142019-01-31 03:40:27 -08001895#### EVERYTHING BELOW IS GENERATED BY python Lib/test/test_ast.py -g #####
Tim Peters400cbc32006-02-28 18:44:41 +00001896exec_results = [
Serhiy Storchaka850a8852020-01-10 10:12:55 +02001897('Module', [('Expr', (1, 0, 1, 4), ('Constant', (1, 0, 1, 4), None, None))], []),
1898('Module', [('Expr', (1, 0, 1, 18), ('Constant', (1, 0, 1, 18), 'module docstring', None))], []),
1899('Module', [('FunctionDef', (1, 0, 1, 13), 'f', ('arguments', [], [], None, [], [], None, []), [('Pass', (1, 9, 1, 13))], [], None, None)], []),
1900('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)], []),
1901('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)], []),
1902('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)], []),
1903('Module', [('FunctionDef', (1, 0, 1, 18), 'f', ('arguments', [], [], ('arg', (1, 7, 1, 11), 'args', None, None), [], [], None, []), [('Pass', (1, 14, 1, 18))], [], None, None)], []),
1904('Module', [('FunctionDef', (1, 0, 1, 21), 'f', ('arguments', [], [], None, [], [], ('arg', (1, 8, 1, 14), 'kwargs', None, None), []), [('Pass', (1, 17, 1, 21))], [], None, None)], []),
1905('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)], []),
1906('Module', [('ClassDef', (1, 0, 1, 12), 'C', [], [], [('Pass', (1, 8, 1, 12))], [])], []),
1907('Module', [('ClassDef', (1, 0, 1, 32), 'C', [], [], [('Expr', (1, 9, 1, 32), ('Constant', (1, 9, 1, 32), 'docstring for class C', None))], [])], []),
1908('Module', [('ClassDef', (1, 0, 1, 21), 'C', [('Name', (1, 8, 1, 14), 'object', ('Load',))], [], [('Pass', (1, 17, 1, 21))], [])], []),
1909('Module', [('FunctionDef', (1, 0, 1, 16), 'f', ('arguments', [], [], None, [], [], None, []), [('Return', (1, 8, 1, 16), ('Constant', (1, 15, 1, 16), 1, None))], [], None, None)], []),
1910('Module', [('Delete', (1, 0, 1, 5), [('Name', (1, 4, 1, 5), 'v', ('Del',))])], []),
1911('Module', [('Assign', (1, 0, 1, 5), [('Name', (1, 0, 1, 1), 'v', ('Store',))], ('Constant', (1, 4, 1, 5), 1, None), None)], []),
1912('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)], []),
1913('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)], []),
1914('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)], []),
1915('Module', [('AugAssign', (1, 0, 1, 6), ('Name', (1, 0, 1, 1), 'v', ('Store',)), ('Add',), ('Constant', (1, 5, 1, 6), 1, None))], []),
1916('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)], []),
1917('Module', [('While', (1, 0, 1, 12), ('Name', (1, 6, 1, 7), 'v', ('Load',)), [('Pass', (1, 8, 1, 12))], [])], []),
1918('Module', [('If', (1, 0, 1, 9), ('Name', (1, 3, 1, 4), 'v', ('Load',)), [('Pass', (1, 5, 1, 9))], [])], []),
1919('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))], [])])], []),
1920('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))])])], []),
1921('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)], []),
1922('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)], []),
1923('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)], []),
1924('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))])], [], [])], []),
1925('Module', [('Try', (1, 0, 4, 6), [('Pass', (2, 2, 2, 6))], [], [], [('Pass', (4, 2, 4, 6))])], []),
1926('Module', [('Assert', (1, 0, 1, 8), ('Name', (1, 7, 1, 8), 'v', ('Load',)), None)], []),
1927('Module', [('Import', (1, 0, 1, 10), [('alias', 'sys', None)])], []),
1928('Module', [('ImportFrom', (1, 0, 1, 17), 'sys', [('alias', 'v', None)], 0)], []),
1929('Module', [('Global', (1, 0, 1, 8), ['v'])], []),
1930('Module', [('Expr', (1, 0, 1, 1), ('Constant', (1, 0, 1, 1), 1, None))], []),
1931('Module', [('Pass', (1, 0, 1, 4))], []),
1932('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)], []),
1933('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)], []),
1934('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)], []),
1935('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)], []),
1936('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)], []),
1937('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)]))], []),
1938('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)]))], []),
1939('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)]))], []),
1940('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)]))], []),
1941('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)]))], []),
1942('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)], []),
1943('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)], []),
1944('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)], []),
1945('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)]))], []),
1946('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)]))], []),
1947('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)], []),
1948('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)], []),
1949('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)], []),
1950('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)], [])])], []),
1951('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 +01001952('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 +02001953('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)))], []),
1954('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)], []),
1955('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)], []),
1956('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)], []),
1957('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)], []),
1958('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)], []),
1959('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)], []),
1960('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)], []),
1961('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)], []),
1962('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)], []),
1963('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 +00001964]
1965single_results = [
Serhiy Storchaka850a8852020-01-10 10:12:55 +02001966('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 +00001967]
1968eval_results = [
Serhiy Storchaka850a8852020-01-10 10:12:55 +02001969('Expression', ('Constant', (1, 0, 1, 4), None, None)),
1970('Expression', ('BoolOp', (1, 0, 1, 7), ('And',), [('Name', (1, 0, 1, 1), 'a', ('Load',)), ('Name', (1, 6, 1, 7), 'b', ('Load',))])),
1971('Expression', ('BinOp', (1, 0, 1, 5), ('Name', (1, 0, 1, 1), 'a', ('Load',)), ('Add',), ('Name', (1, 4, 1, 5), 'b', ('Load',)))),
1972('Expression', ('UnaryOp', (1, 0, 1, 5), ('Not',), ('Name', (1, 4, 1, 5), 'v', ('Load',)))),
1973('Expression', ('Lambda', (1, 0, 1, 11), ('arguments', [], [], None, [], [], None, []), ('Constant', (1, 7, 1, 11), None, None))),
1974('Expression', ('Dict', (1, 0, 1, 7), [('Constant', (1, 2, 1, 3), 1, None)], [('Constant', (1, 4, 1, 5), 2, None)])),
1975('Expression', ('Dict', (1, 0, 1, 2), [], [])),
1976('Expression', ('Set', (1, 0, 1, 7), [('Constant', (1, 1, 1, 5), None, None)])),
1977('Expression', ('Dict', (1, 0, 5, 6), [('Constant', (2, 6, 2, 7), 1, None)], [('Constant', (4, 10, 4, 11), 2, None)])),
1978('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)])),
1979('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)])),
1980('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)])),
1981('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)])),
1982('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)])),
1983('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)])),
1984('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)])),
1985('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)])),
1986('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)])),
1987('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)])),
1988('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)])),
1989('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)])),
1990('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',)))])),
1991('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',))], [])),
1992('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)])], [])),
1993('Expression', ('Constant', (1, 0, 1, 2), 10, None)),
1994('Expression', ('Constant', (1, 0, 1, 8), 'string', None)),
1995('Expression', ('Attribute', (1, 0, 1, 3), ('Name', (1, 0, 1, 1), 'a', ('Load',)), 'b', ('Load',))),
Serhiy Storchaka13d52c22020-03-10 18:52:34 +02001996('Expression', ('Subscript', (1, 0, 1, 6), ('Name', (1, 0, 1, 1), 'a', ('Load',)), ('Slice', (1, 2, 1, 5), ('Name', (1, 2, 1, 3), 'b', ('Load',)), ('Name', (1, 4, 1, 5), 'c', ('Load',)), None), ('Load',))),
Serhiy Storchaka850a8852020-01-10 10:12:55 +02001997('Expression', ('Name', (1, 0, 1, 1), 'v', ('Load',))),
1998('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',))),
1999('Expression', ('List', (1, 0, 1, 2), [], ('Load',))),
2000('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',))),
2001('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',))),
2002('Expression', ('Tuple', (1, 0, 1, 2), [], ('Load',))),
Serhiy Storchaka13d52c22020-03-10 18:52:34 +02002003('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', (1, 12, 1, 15), ('Constant', (1, 12, 1, 13), 1, None), ('Constant', (1, 14, 1, 15), 2, None), None), ('Load',))], [])),
Tim Peters400cbc32006-02-28 18:44:41 +00002004]
Neal Norwitzee9b10a2008-03-31 05:29:39 +00002005main()