blob: e251e254afddaa2bfe1c202c76a3bd38959c4230 [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
Benjamin Peterson9ed37432012-07-08 11:13:36 -07006import weakref
Ivan Levkivskyi9932a222019-01-22 11:18:22 +00007from textwrap import dedent
Benjamin Peterson9ed37432012-07-08 11:13:36 -07008
9from test import support
Tim Peters400cbc32006-02-28 18:44:41 +000010
11def to_tuple(t):
Guido van Rossum3172c5d2007-10-16 18:12:55 +000012 if t is None or isinstance(t, (str, int, complex)):
Tim Peters400cbc32006-02-28 18:44:41 +000013 return t
14 elif isinstance(t, list):
15 return [to_tuple(e) for e in t]
16 result = [t.__class__.__name__]
Martin v. Löwis49c5da12006-03-01 22:49:05 +000017 if hasattr(t, 'lineno') and hasattr(t, 'col_offset'):
18 result.append((t.lineno, t.col_offset))
Tim Peters400cbc32006-02-28 18:44:41 +000019 if t._fields is None:
20 return tuple(result)
21 for f in t._fields:
22 result.append(to_tuple(getattr(t, f)))
23 return tuple(result)
24
Neal Norwitzee9b10a2008-03-31 05:29:39 +000025
Tim Peters400cbc32006-02-28 18:44:41 +000026# These tests are compiled through "exec"
Ezio Melotti85a86292013-08-17 16:57:41 +030027# There should be at least one test per statement
Tim Peters400cbc32006-02-28 18:44:41 +000028exec_tests = [
Benjamin Peterson6ccfe852011-06-27 17:46:06 -050029 # None
30 "None",
INADA Naokicb41b272017-02-23 00:31:59 +090031 # Module docstring
32 "'module docstring'",
Tim Peters400cbc32006-02-28 18:44:41 +000033 # FunctionDef
34 "def f(): pass",
INADA Naokicb41b272017-02-23 00:31:59 +090035 # FunctionDef with docstring
36 "def f(): 'function docstring'",
Benjamin Peterson6ccfe852011-06-27 17:46:06 -050037 # FunctionDef with arg
38 "def f(a): pass",
39 # FunctionDef with arg and default value
40 "def f(a=0): pass",
41 # FunctionDef with varargs
42 "def f(*args): pass",
43 # FunctionDef with kwargs
44 "def f(**kwargs): pass",
INADA Naokicb41b272017-02-23 00:31:59 +090045 # FunctionDef with all kind of args and docstring
46 "def f(a, b=1, c=None, d=[], e={}, *args, f=42, **kwargs): 'doc for f()'",
Tim Peters400cbc32006-02-28 18:44:41 +000047 # ClassDef
48 "class C:pass",
INADA Naokicb41b272017-02-23 00:31:59 +090049 # ClassDef with docstring
50 "class C: 'docstring for class C'",
Benjamin Peterson6ccfe852011-06-27 17:46:06 -050051 # ClassDef, new style class
52 "class C(object): pass",
Tim Peters400cbc32006-02-28 18:44:41 +000053 # Return
54 "def f():return 1",
55 # Delete
56 "del v",
57 # Assign
58 "v = 1",
Serhiy Storchakab619b092018-11-27 09:40:29 +020059 "a,b = c",
60 "(a,b) = c",
61 "[a,b] = c",
Tim Peters400cbc32006-02-28 18:44:41 +000062 # AugAssign
63 "v += 1",
Tim Peters400cbc32006-02-28 18:44:41 +000064 # For
65 "for v in v:pass",
66 # While
67 "while v:pass",
68 # If
69 "if v:pass",
Benjamin Petersonaeabd5f2011-05-27 15:02:03 -050070 # With
71 "with x as y: pass",
72 "with x as y, z as q: pass",
Tim Peters400cbc32006-02-28 18:44:41 +000073 # Raise
Collin Winter828f04a2007-08-31 00:04:24 +000074 "raise Exception('string')",
Tim Peters400cbc32006-02-28 18:44:41 +000075 # TryExcept
76 "try:\n pass\nexcept Exception:\n pass",
77 # TryFinally
78 "try:\n pass\nfinally:\n pass",
79 # Assert
80 "assert v",
81 # Import
82 "import sys",
83 # ImportFrom
84 "from sys import v",
Tim Peters400cbc32006-02-28 18:44:41 +000085 # Global
86 "global v",
87 # Expr
88 "1",
89 # Pass,
90 "pass",
91 # Break
Yury Selivanovb3d53132015-09-01 16:10:49 -040092 "for v in v:break",
Tim Peters400cbc32006-02-28 18:44:41 +000093 # Continue
Yury Selivanovb3d53132015-09-01 16:10:49 -040094 "for v in v:continue",
Benjamin Peterson2e4b0e12009-09-11 22:36:20 +000095 # for statements with naked tuples (see http://bugs.python.org/issue6704)
96 "for a,b in c: pass",
Serhiy Storchakab619b092018-11-27 09:40:29 +020097 "for (a,b) in c: pass",
98 "for [a,b] in c: pass",
Benjamin Peterson6ccfe852011-06-27 17:46:06 -050099 # Multiline generator expression (test for .lineno & .col_offset)
100 """(
101 (
102 Aa
103 ,
104 Bb
105 )
106 for
107 Aa
108 ,
109 Bb in Cc
110 )""",
111 # dictcomp
112 "{a : b for w in x for m in p if g}",
113 # dictcomp with naked tuple
114 "{a : b for v,w in x}",
115 # setcomp
116 "{r for l in x if g}",
117 # setcomp with naked tuple
118 "{r for l,m in x}",
Yury Selivanov75445082015-05-11 22:57:16 -0400119 # AsyncFunctionDef
INADA Naokicb41b272017-02-23 00:31:59 +0900120 "async def f():\n 'async function'\n await something()",
Yury Selivanov75445082015-05-11 22:57:16 -0400121 # AsyncFor
122 "async def f():\n async for e in i: 1\n else: 2",
123 # AsyncWith
124 "async def f():\n async with a as b: 1",
Yury Selivanovb3d53132015-09-01 16:10:49 -0400125 # PEP 448: Additional Unpacking Generalizations
126 "{**{1:2}, 2:3}",
127 "{*{1, 2}, 3}",
Yury Selivanov52c4e7c2016-09-09 10:36:01 -0700128 # Asynchronous comprehensions
129 "async def f():\n [i async for b in c]",
Serhiy Storchaka95b6acf2018-10-30 13:16:02 +0200130 # Decorated FunctionDef
131 "@deco1\n@deco2()\ndef f(): pass",
132 # Decorated AsyncFunctionDef
133 "@deco1\n@deco2()\nasync def f(): pass",
134 # Decorated ClassDef
135 "@deco1\n@deco2()\nclass C: pass",
Serhiy Storchakab619b092018-11-27 09:40:29 +0200136 # Decorator with generator argument
137 "@deco(a for a in b)\ndef f(): pass",
Pablo Galindo0c9258a2019-03-18 13:51:53 +0000138 # Simple assignment expression
139 "(a := 1)",
Pablo Galindo2f58a842019-05-31 14:09:49 +0100140 # Positional-only arguments
141 "def f(a, /,): pass",
142 "def f(a, /, c, d, e): pass",
143 "def f(a, /, c, *, d, e): pass",
144 "def f(a, /, c, *, d, e, **kwargs): pass",
145 # Positional-only arguments with defaults
146 "def f(a=1, /,): pass",
147 "def f(a=1, /, b=2, c=4): pass",
148 "def f(a=1, /, b=2, *, c=4): pass",
149 "def f(a=1, /, b=2, *, c): pass",
150 "def f(a=1, /, b=2, *, c=4, **kwargs): pass",
151 "def f(a=1, /, b=2, *, c, **kwargs): pass",
Pablo Galindo0c9258a2019-03-18 13:51:53 +0000152
Tim Peters400cbc32006-02-28 18:44:41 +0000153]
154
155# These are compiled through "single"
156# because of overlap with "eval", it just tests what
157# can't be tested with "eval"
158single_tests = [
159 "1+2"
160]
161
162# These are compiled through "eval"
163# It should test all expressions
164eval_tests = [
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500165 # None
166 "None",
Tim Peters400cbc32006-02-28 18:44:41 +0000167 # BoolOp
168 "a and b",
169 # BinOp
170 "a + b",
171 # UnaryOp
172 "not v",
173 # Lambda
174 "lambda:None",
175 # Dict
176 "{ 1:2 }",
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500177 # Empty dict
178 "{}",
179 # Set
180 "{None,}",
181 # Multiline dict (test for .lineno & .col_offset)
182 """{
183 1
184 :
185 2
186 }""",
Tim Peters400cbc32006-02-28 18:44:41 +0000187 # ListComp
188 "[a for b in c if d]",
189 # GeneratorExp
190 "(a for b in c if d)",
Serhiy Storchakab619b092018-11-27 09:40:29 +0200191 # Comprehensions with multiple for targets
192 "[(a,b) for a,b in c]",
193 "[(a,b) for (a,b) in c]",
194 "[(a,b) for [a,b] in c]",
195 "{(a,b) for a,b in c}",
196 "{(a,b) for (a,b) in c}",
197 "{(a,b) for [a,b] in c}",
198 "((a,b) for a,b in c)",
199 "((a,b) for (a,b) in c)",
200 "((a,b) for [a,b] in c)",
Tim Peters400cbc32006-02-28 18:44:41 +0000201 # Yield - yield expressions can't work outside a function
202 #
203 # Compare
204 "1 < 2 < 3",
205 # Call
206 "f(1,2,c=3,*d,**e)",
Serhiy Storchakab619b092018-11-27 09:40:29 +0200207 # Call with a generator argument
208 "f(a for a in b)",
Tim Peters400cbc32006-02-28 18:44:41 +0000209 # Num
Guido van Rossume2a383d2007-01-15 16:59:06 +0000210 "10",
Tim Peters400cbc32006-02-28 18:44:41 +0000211 # Str
212 "'string'",
213 # Attribute
214 "a.b",
215 # Subscript
216 "a[b:c]",
217 # Name
218 "v",
219 # List
220 "[1,2,3]",
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500221 # Empty list
222 "[]",
Tim Peters400cbc32006-02-28 18:44:41 +0000223 # Tuple
Martin v. Löwis49c5da12006-03-01 22:49:05 +0000224 "1,2,3",
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500225 # Tuple
226 "(1,2,3)",
227 # Empty tuple
228 "()",
Martin v. Löwis49c5da12006-03-01 22:49:05 +0000229 # Combination
230 "a.b.c.d(a.b[1:2])",
231
Tim Peters400cbc32006-02-28 18:44:41 +0000232]
233
234# TODO: expr_context, slice, boolop, operator, unaryop, cmpop, comprehension
235# excepthandler, arguments, keywords, alias
236
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000237class AST_Tests(unittest.TestCase):
Tim Peters400cbc32006-02-28 18:44:41 +0000238
Benjamin Peterson7a66fc22015-02-02 10:51:20 -0500239 def _assertTrueorder(self, ast_node, parent_pos):
Georg Brandl0c77a822008-06-10 16:37:50 +0000240 if not isinstance(ast_node, ast.AST) or ast_node._fields is None:
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000241 return
Georg Brandl0c77a822008-06-10 16:37:50 +0000242 if isinstance(ast_node, (ast.expr, ast.stmt, ast.excepthandler)):
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000243 node_pos = (ast_node.lineno, ast_node.col_offset)
Serhiy Storchaka95b6acf2018-10-30 13:16:02 +0200244 self.assertGreaterEqual(node_pos, parent_pos)
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000245 parent_pos = (ast_node.lineno, ast_node.col_offset)
246 for name in ast_node._fields:
247 value = getattr(ast_node, name)
248 if isinstance(value, list):
Serhiy Storchaka95b6acf2018-10-30 13:16:02 +0200249 first_pos = parent_pos
250 if value and name == 'decorator_list':
251 first_pos = (value[0].lineno, value[0].col_offset)
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000252 for child in value:
Serhiy Storchaka95b6acf2018-10-30 13:16:02 +0200253 self._assertTrueorder(child, first_pos)
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000254 elif value is not None:
Benjamin Peterson7a66fc22015-02-02 10:51:20 -0500255 self._assertTrueorder(value, parent_pos)
Tim Peters5ddfe412006-03-01 23:02:57 +0000256
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500257 def test_AST_objects(self):
258 x = ast.AST()
259 self.assertEqual(x._fields, ())
Benjamin Peterson7e0dbfb2012-03-12 09:46:44 -0700260 x.foobar = 42
261 self.assertEqual(x.foobar, 42)
262 self.assertEqual(x.__dict__["foobar"], 42)
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500263
264 with self.assertRaises(AttributeError):
265 x.vararg
266
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500267 with self.assertRaises(TypeError):
268 # "_ast.AST constructor takes 0 positional arguments"
269 ast.AST(2)
270
Benjamin Peterson9ed37432012-07-08 11:13:36 -0700271 def test_AST_garbage_collection(self):
272 class X:
273 pass
274 a = ast.AST()
275 a.x = X()
276 a.x.a = a
277 ref = weakref.ref(a.x)
278 del a
279 support.gc_collect()
280 self.assertIsNone(ref())
281
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000282 def test_snippets(self):
283 for input, output, kind in ((exec_tests, exec_results, "exec"),
284 (single_tests, single_results, "single"),
285 (eval_tests, eval_results, "eval")):
286 for i, o in zip(input, output):
Yury Selivanovb3d53132015-09-01 16:10:49 -0400287 with self.subTest(action="parsing", input=i):
288 ast_tree = compile(i, "?", kind, ast.PyCF_ONLY_AST)
289 self.assertEqual(to_tuple(ast_tree), o)
290 self._assertTrueorder(ast_tree, (0, 0))
Victor Stinner15a30952016-02-08 22:45:06 +0100291 with self.subTest(action="compiling", input=i, kind=kind):
292 compile(ast_tree, "?", kind)
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000293
Pablo Galindo0c9258a2019-03-18 13:51:53 +0000294 def test_ast_validation(self):
295 # compile() is the only function that calls PyAST_Validate
296 snippets_to_validate = exec_tests + single_tests + eval_tests
297 for snippet in snippets_to_validate:
298 tree = ast.parse(snippet)
299 compile(tree, '<string>', 'exec')
300
Benjamin Peterson78565b22009-06-28 19:19:51 +0000301 def test_slice(self):
302 slc = ast.parse("x[::]").body[0].value.slice
303 self.assertIsNone(slc.upper)
304 self.assertIsNone(slc.lower)
305 self.assertIsNone(slc.step)
306
307 def test_from_import(self):
308 im = ast.parse("from . import y").body[0]
309 self.assertIsNone(im.module)
310
Benjamin Petersona4e4e352012-03-22 08:19:04 -0400311 def test_non_interned_future_from_ast(self):
312 mod = ast.parse("from __future__ import division")
313 self.assertIsInstance(mod.body[0], ast.ImportFrom)
314 mod.body[0].module = " __future__ ".strip()
315 compile(mod, "<test>", "exec")
316
Benjamin Petersona0dfa822009-11-13 02:25:08 +0000317 def test_base_classes(self):
318 self.assertTrue(issubclass(ast.For, ast.stmt))
319 self.assertTrue(issubclass(ast.Name, ast.expr))
320 self.assertTrue(issubclass(ast.stmt, ast.AST))
321 self.assertTrue(issubclass(ast.expr, ast.AST))
322 self.assertTrue(issubclass(ast.comprehension, ast.AST))
323 self.assertTrue(issubclass(ast.Gt, ast.AST))
324
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500325 def test_field_attr_existence(self):
326 for name, item in ast.__dict__.items():
327 if isinstance(item, type) and name != 'AST' and name[0].isupper():
328 x = item()
329 if isinstance(x, ast.AST):
330 self.assertEqual(type(x._fields), tuple)
331
332 def test_arguments(self):
333 x = ast.arguments()
Pablo Galindo8c77b8c2019-04-29 13:36:57 +0100334 self.assertEqual(x._fields, ('args', 'posonlyargs', 'vararg', 'kwonlyargs',
Benjamin Peterson7a66fc22015-02-02 10:51:20 -0500335 'kw_defaults', 'kwarg', 'defaults'))
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500336
337 with self.assertRaises(AttributeError):
338 x.vararg
339
Pablo Galindo8c77b8c2019-04-29 13:36:57 +0100340 x = ast.arguments(*range(1, 8))
341 self.assertEqual(x.vararg, 3)
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500342
343 def test_field_attr_writable(self):
344 x = ast.Num()
345 # We can assign to _fields
346 x._fields = 666
347 self.assertEqual(x._fields, 666)
348
349 def test_classattrs(self):
350 x = ast.Num()
Guido van Rossum10f8ce62019-03-13 13:00:46 -0700351 self.assertEqual(x._fields, ('value', 'kind'))
Serhiy Storchaka3f228112018-09-27 17:42:37 +0300352
353 with self.assertRaises(AttributeError):
354 x.value
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500355
356 with self.assertRaises(AttributeError):
357 x.n
358
359 x = ast.Num(42)
Serhiy Storchaka3f228112018-09-27 17:42:37 +0300360 self.assertEqual(x.value, 42)
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500361 self.assertEqual(x.n, 42)
362
363 with self.assertRaises(AttributeError):
364 x.lineno
365
366 with self.assertRaises(AttributeError):
367 x.foobar
368
369 x = ast.Num(lineno=2)
370 self.assertEqual(x.lineno, 2)
371
372 x = ast.Num(42, lineno=0)
373 self.assertEqual(x.lineno, 0)
Guido van Rossum10f8ce62019-03-13 13:00:46 -0700374 self.assertEqual(x._fields, ('value', 'kind'))
Serhiy Storchaka3f228112018-09-27 17:42:37 +0300375 self.assertEqual(x.value, 42)
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500376 self.assertEqual(x.n, 42)
377
Guido van Rossum10f8ce62019-03-13 13:00:46 -0700378 self.assertRaises(TypeError, ast.Num, 1, None, 2)
379 self.assertRaises(TypeError, ast.Num, 1, None, 2, lineno=0)
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500380
Serhiy Storchaka3f228112018-09-27 17:42:37 +0300381 self.assertEqual(ast.Num(42).n, 42)
382 self.assertEqual(ast.Num(4.25).n, 4.25)
383 self.assertEqual(ast.Num(4.25j).n, 4.25j)
384 self.assertEqual(ast.Str('42').s, '42')
385 self.assertEqual(ast.Bytes(b'42').s, b'42')
386 self.assertIs(ast.NameConstant(True).value, True)
387 self.assertIs(ast.NameConstant(False).value, False)
388 self.assertIs(ast.NameConstant(None).value, None)
389
390 self.assertEqual(ast.Constant(42).value, 42)
391 self.assertEqual(ast.Constant(4.25).value, 4.25)
392 self.assertEqual(ast.Constant(4.25j).value, 4.25j)
393 self.assertEqual(ast.Constant('42').value, '42')
394 self.assertEqual(ast.Constant(b'42').value, b'42')
395 self.assertIs(ast.Constant(True).value, True)
396 self.assertIs(ast.Constant(False).value, False)
397 self.assertIs(ast.Constant(None).value, None)
398 self.assertIs(ast.Constant(...).value, ...)
399
400 def test_realtype(self):
401 self.assertEqual(type(ast.Num(42)), ast.Constant)
402 self.assertEqual(type(ast.Num(4.25)), ast.Constant)
403 self.assertEqual(type(ast.Num(4.25j)), ast.Constant)
404 self.assertEqual(type(ast.Str('42')), ast.Constant)
405 self.assertEqual(type(ast.Bytes(b'42')), ast.Constant)
406 self.assertEqual(type(ast.NameConstant(True)), ast.Constant)
407 self.assertEqual(type(ast.NameConstant(False)), ast.Constant)
408 self.assertEqual(type(ast.NameConstant(None)), ast.Constant)
409 self.assertEqual(type(ast.Ellipsis()), ast.Constant)
410
411 def test_isinstance(self):
412 self.assertTrue(isinstance(ast.Num(42), ast.Num))
413 self.assertTrue(isinstance(ast.Num(4.2), ast.Num))
414 self.assertTrue(isinstance(ast.Num(4.2j), ast.Num))
415 self.assertTrue(isinstance(ast.Str('42'), ast.Str))
416 self.assertTrue(isinstance(ast.Bytes(b'42'), ast.Bytes))
417 self.assertTrue(isinstance(ast.NameConstant(True), ast.NameConstant))
418 self.assertTrue(isinstance(ast.NameConstant(False), ast.NameConstant))
419 self.assertTrue(isinstance(ast.NameConstant(None), ast.NameConstant))
420 self.assertTrue(isinstance(ast.Ellipsis(), ast.Ellipsis))
421
422 self.assertTrue(isinstance(ast.Constant(42), ast.Num))
423 self.assertTrue(isinstance(ast.Constant(4.2), ast.Num))
424 self.assertTrue(isinstance(ast.Constant(4.2j), ast.Num))
425 self.assertTrue(isinstance(ast.Constant('42'), ast.Str))
426 self.assertTrue(isinstance(ast.Constant(b'42'), ast.Bytes))
427 self.assertTrue(isinstance(ast.Constant(True), ast.NameConstant))
428 self.assertTrue(isinstance(ast.Constant(False), ast.NameConstant))
429 self.assertTrue(isinstance(ast.Constant(None), ast.NameConstant))
430 self.assertTrue(isinstance(ast.Constant(...), ast.Ellipsis))
431
432 self.assertFalse(isinstance(ast.Str('42'), ast.Num))
433 self.assertFalse(isinstance(ast.Num(42), ast.Str))
434 self.assertFalse(isinstance(ast.Str('42'), ast.Bytes))
435 self.assertFalse(isinstance(ast.Num(42), ast.NameConstant))
436 self.assertFalse(isinstance(ast.Num(42), ast.Ellipsis))
Anthony Sottile74176222019-01-18 11:30:28 -0800437 self.assertFalse(isinstance(ast.NameConstant(True), ast.Num))
438 self.assertFalse(isinstance(ast.NameConstant(False), ast.Num))
Serhiy Storchaka3f228112018-09-27 17:42:37 +0300439
440 self.assertFalse(isinstance(ast.Constant('42'), ast.Num))
441 self.assertFalse(isinstance(ast.Constant(42), ast.Str))
442 self.assertFalse(isinstance(ast.Constant('42'), ast.Bytes))
443 self.assertFalse(isinstance(ast.Constant(42), ast.NameConstant))
444 self.assertFalse(isinstance(ast.Constant(42), ast.Ellipsis))
Anthony Sottile74176222019-01-18 11:30:28 -0800445 self.assertFalse(isinstance(ast.Constant(True), ast.Num))
446 self.assertFalse(isinstance(ast.Constant(False), ast.Num))
Serhiy Storchaka3f228112018-09-27 17:42:37 +0300447
448 self.assertFalse(isinstance(ast.Constant(), ast.Num))
449 self.assertFalse(isinstance(ast.Constant(), ast.Str))
450 self.assertFalse(isinstance(ast.Constant(), ast.Bytes))
451 self.assertFalse(isinstance(ast.Constant(), ast.NameConstant))
452 self.assertFalse(isinstance(ast.Constant(), ast.Ellipsis))
453
Serhiy Storchaka6015cc52018-10-28 13:43:03 +0200454 class S(str): pass
455 self.assertTrue(isinstance(ast.Constant(S('42')), ast.Str))
456 self.assertFalse(isinstance(ast.Constant(S('42')), ast.Num))
457
Serhiy Storchaka3f228112018-09-27 17:42:37 +0300458 def test_subclasses(self):
459 class N(ast.Num):
460 def __init__(self, *args, **kwargs):
461 super().__init__(*args, **kwargs)
462 self.z = 'spam'
463 class N2(ast.Num):
464 pass
465
466 n = N(42)
467 self.assertEqual(n.n, 42)
468 self.assertEqual(n.z, 'spam')
469 self.assertEqual(type(n), N)
470 self.assertTrue(isinstance(n, N))
471 self.assertTrue(isinstance(n, ast.Num))
472 self.assertFalse(isinstance(n, N2))
473 self.assertFalse(isinstance(ast.Num(42), N))
474 n = N(n=42)
475 self.assertEqual(n.n, 42)
476 self.assertEqual(type(n), N)
477
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500478 def test_module(self):
479 body = [ast.Num(42)]
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800480 x = ast.Module(body, [])
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500481 self.assertEqual(x.body, body)
482
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000483 def test_nodeclasses(self):
Florent Xicluna992d9e02011-11-11 19:35:42 +0100484 # Zero arguments constructor explicitly allowed
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500485 x = ast.BinOp()
486 self.assertEqual(x._fields, ('left', 'op', 'right'))
487
488 # Random attribute allowed too
489 x.foobarbaz = 5
490 self.assertEqual(x.foobarbaz, 5)
491
492 n1 = ast.Num(1)
493 n3 = ast.Num(3)
494 addop = ast.Add()
495 x = ast.BinOp(n1, addop, n3)
496 self.assertEqual(x.left, n1)
497 self.assertEqual(x.op, addop)
498 self.assertEqual(x.right, n3)
Benjamin Peterson68b543a2011-06-27 17:51:18 -0500499
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500500 x = ast.BinOp(1, 2, 3)
501 self.assertEqual(x.left, 1)
502 self.assertEqual(x.op, 2)
503 self.assertEqual(x.right, 3)
504
Georg Brandl0c77a822008-06-10 16:37:50 +0000505 x = ast.BinOp(1, 2, 3, lineno=0)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000506 self.assertEqual(x.left, 1)
507 self.assertEqual(x.op, 2)
508 self.assertEqual(x.right, 3)
509 self.assertEqual(x.lineno, 0)
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000510
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500511 # node raises exception when given too many arguments
512 self.assertRaises(TypeError, ast.BinOp, 1, 2, 3, 4)
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500513 # node raises exception when given too many arguments
514 self.assertRaises(TypeError, ast.BinOp, 1, 2, 3, 4, lineno=0)
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000515
516 # can set attributes through kwargs too
Georg Brandl0c77a822008-06-10 16:37:50 +0000517 x = ast.BinOp(left=1, op=2, right=3, lineno=0)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000518 self.assertEqual(x.left, 1)
519 self.assertEqual(x.op, 2)
520 self.assertEqual(x.right, 3)
521 self.assertEqual(x.lineno, 0)
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000522
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500523 # Random kwargs also allowed
524 x = ast.BinOp(1, 2, 3, foobarbaz=42)
525 self.assertEqual(x.foobarbaz, 42)
526
527 def test_no_fields(self):
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000528 # this used to fail because Sub._fields was None
Georg Brandl0c77a822008-06-10 16:37:50 +0000529 x = ast.Sub()
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500530 self.assertEqual(x._fields, ())
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000531
532 def test_pickling(self):
533 import pickle
534 mods = [pickle]
535 try:
536 import cPickle
537 mods.append(cPickle)
538 except ImportError:
539 pass
540 protocols = [0, 1, 2]
541 for mod in mods:
542 for protocol in protocols:
543 for ast in (compile(i, "?", "exec", 0x400) for i in exec_tests):
544 ast2 = mod.loads(mod.dumps(ast, protocol))
Ezio Melottib3aedd42010-11-20 19:04:17 +0000545 self.assertEqual(to_tuple(ast2), to_tuple(ast))
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000546
Benjamin Peterson5b066812010-11-20 01:38:49 +0000547 def test_invalid_sum(self):
548 pos = dict(lineno=2, col_offset=3)
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800549 m = ast.Module([ast.Expr(ast.expr(**pos), **pos)], [])
Benjamin Peterson5b066812010-11-20 01:38:49 +0000550 with self.assertRaises(TypeError) as cm:
551 compile(m, "<test>", "exec")
552 self.assertIn("but got <_ast.expr", str(cm.exception))
553
Benjamin Peterson2193d2b2011-07-22 10:50:23 -0500554 def test_invalid_identitifer(self):
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800555 m = ast.Module([ast.Expr(ast.Name(42, ast.Load()))], [])
Benjamin Peterson2193d2b2011-07-22 10:50:23 -0500556 ast.fix_missing_locations(m)
557 with self.assertRaises(TypeError) as cm:
558 compile(m, "<test>", "exec")
559 self.assertIn("identifier must be of type str", str(cm.exception))
560
Mark Dickinsonded35ae2012-11-25 14:36:26 +0000561 def test_empty_yield_from(self):
562 # Issue 16546: yield from value is not optional.
563 empty_yield_from = ast.parse("def f():\n yield from g()")
564 empty_yield_from.body[0].body[0].value.value = None
565 with self.assertRaises(ValueError) as cm:
566 compile(empty_yield_from, "<test>", "exec")
567 self.assertIn("field value is required", str(cm.exception))
568
Oren Milman7dc46d82017-09-30 20:16:24 +0300569 @support.cpython_only
570 def test_issue31592(self):
571 # There shouldn't be an assertion failure in case of a bad
572 # unicodedata.normalize().
573 import unicodedata
574 def bad_normalize(*args):
575 return None
576 with support.swap_attr(unicodedata, 'normalize', bad_normalize):
577 self.assertRaises(TypeError, ast.parse, '\u03D5')
578
Georg Brandl0c77a822008-06-10 16:37:50 +0000579
580class ASTHelpers_Test(unittest.TestCase):
Guido van Rossum10f8ce62019-03-13 13:00:46 -0700581 maxDiff = None
Georg Brandl0c77a822008-06-10 16:37:50 +0000582
583 def test_parse(self):
584 a = ast.parse('foo(1 + 1)')
585 b = compile('foo(1 + 1)', '<unknown>', 'exec', ast.PyCF_ONLY_AST)
586 self.assertEqual(ast.dump(a), ast.dump(b))
587
Benjamin Peterson2e2c9032012-09-02 14:23:15 -0400588 def test_parse_in_error(self):
589 try:
590 1/0
591 except Exception:
Benjamin Petersonbd0df502012-09-02 15:04:51 -0400592 with self.assertRaises(SyntaxError) as e:
593 ast.literal_eval(r"'\U'")
594 self.assertIsNotNone(e.exception.__context__)
Benjamin Peterson2e2c9032012-09-02 14:23:15 -0400595
Georg Brandl0c77a822008-06-10 16:37:50 +0000596 def test_dump(self):
597 node = ast.parse('spam(eggs, "and cheese")')
598 self.assertEqual(ast.dump(node),
599 "Module(body=[Expr(value=Call(func=Name(id='spam', ctx=Load()), "
Guido van Rossum10f8ce62019-03-13 13:00:46 -0700600 "args=[Name(id='eggs', ctx=Load()), Constant(value='and cheese', kind=None)], "
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800601 "keywords=[]))], type_ignores=[])"
Georg Brandl0c77a822008-06-10 16:37:50 +0000602 )
603 self.assertEqual(ast.dump(node, annotate_fields=False),
604 "Module([Expr(Call(Name('spam', Load()), [Name('eggs', Load()), "
Guido van Rossum10f8ce62019-03-13 13:00:46 -0700605 "Constant('and cheese', None)], []))], [])"
Georg Brandl0c77a822008-06-10 16:37:50 +0000606 )
607 self.assertEqual(ast.dump(node, include_attributes=True),
608 "Module(body=[Expr(value=Call(func=Name(id='spam', ctx=Load(), "
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000609 "lineno=1, col_offset=0, end_lineno=1, end_col_offset=4), "
610 "args=[Name(id='eggs', ctx=Load(), lineno=1, col_offset=5, "
Guido van Rossum10f8ce62019-03-13 13:00:46 -0700611 "end_lineno=1, end_col_offset=9), Constant(value='and cheese', kind=None, "
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000612 "lineno=1, col_offset=11, end_lineno=1, end_col_offset=23)], keywords=[], "
613 "lineno=1, col_offset=0, end_lineno=1, end_col_offset=24), "
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800614 "lineno=1, col_offset=0, end_lineno=1, end_col_offset=24)], type_ignores=[])"
Georg Brandl0c77a822008-06-10 16:37:50 +0000615 )
616
617 def test_copy_location(self):
618 src = ast.parse('1 + 1', mode='eval')
619 src.body.right = ast.copy_location(ast.Num(2), src.body.right)
620 self.assertEqual(ast.dump(src, include_attributes=True),
Guido van Rossum10f8ce62019-03-13 13:00:46 -0700621 'Expression(body=BinOp(left=Constant(value=1, kind=None, lineno=1, col_offset=0, '
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000622 'end_lineno=1, end_col_offset=1), op=Add(), right=Constant(value=2, '
623 'lineno=1, col_offset=4, end_lineno=1, end_col_offset=5), lineno=1, '
624 'col_offset=0, end_lineno=1, end_col_offset=5))'
Georg Brandl0c77a822008-06-10 16:37:50 +0000625 )
626
627 def test_fix_missing_locations(self):
628 src = ast.parse('write("spam")')
629 src.body.append(ast.Expr(ast.Call(ast.Name('spam', ast.Load()),
Benjamin Peterson025e9eb2015-05-05 20:16:41 -0400630 [ast.Str('eggs')], [])))
Georg Brandl0c77a822008-06-10 16:37:50 +0000631 self.assertEqual(src, ast.fix_missing_locations(src))
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000632 self.maxDiff = None
Georg Brandl0c77a822008-06-10 16:37:50 +0000633 self.assertEqual(ast.dump(src, include_attributes=True),
634 "Module(body=[Expr(value=Call(func=Name(id='write', ctx=Load(), "
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000635 "lineno=1, col_offset=0, end_lineno=1, end_col_offset=5), "
Guido van Rossum10f8ce62019-03-13 13:00:46 -0700636 "args=[Constant(value='spam', kind=None, lineno=1, col_offset=6, end_lineno=1, "
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000637 "end_col_offset=12)], keywords=[], lineno=1, col_offset=0, end_lineno=1, "
638 "end_col_offset=13), lineno=1, col_offset=0, end_lineno=1, "
639 "end_col_offset=13), Expr(value=Call(func=Name(id='spam', ctx=Load(), "
640 "lineno=1, col_offset=0, end_lineno=1, end_col_offset=0), "
641 "args=[Constant(value='eggs', lineno=1, col_offset=0, end_lineno=1, "
642 "end_col_offset=0)], keywords=[], lineno=1, col_offset=0, end_lineno=1, "
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800643 "end_col_offset=0), lineno=1, col_offset=0, end_lineno=1, end_col_offset=0)], "
644 "type_ignores=[])"
Georg Brandl0c77a822008-06-10 16:37:50 +0000645 )
646
647 def test_increment_lineno(self):
648 src = ast.parse('1 + 1', mode='eval')
649 self.assertEqual(ast.increment_lineno(src, n=3), src)
650 self.assertEqual(ast.dump(src, include_attributes=True),
Guido van Rossum10f8ce62019-03-13 13:00:46 -0700651 'Expression(body=BinOp(left=Constant(value=1, kind=None, lineno=4, col_offset=0, '
652 'end_lineno=4, end_col_offset=1), op=Add(), right=Constant(value=1, kind=None, '
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000653 'lineno=4, col_offset=4, end_lineno=4, end_col_offset=5), lineno=4, '
654 'col_offset=0, end_lineno=4, end_col_offset=5))'
Georg Brandl0c77a822008-06-10 16:37:50 +0000655 )
Georg Brandl619e7ba2011-01-09 07:38:51 +0000656 # issue10869: do not increment lineno of root twice
Georg Brandlefb69022011-01-09 07:50:48 +0000657 src = ast.parse('1 + 1', mode='eval')
Georg Brandl619e7ba2011-01-09 07:38:51 +0000658 self.assertEqual(ast.increment_lineno(src.body, n=3), src.body)
659 self.assertEqual(ast.dump(src, include_attributes=True),
Guido van Rossum10f8ce62019-03-13 13:00:46 -0700660 'Expression(body=BinOp(left=Constant(value=1, kind=None, lineno=4, col_offset=0, '
661 'end_lineno=4, end_col_offset=1), op=Add(), right=Constant(value=1, kind=None, '
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000662 'lineno=4, col_offset=4, end_lineno=4, end_col_offset=5), lineno=4, '
663 'col_offset=0, end_lineno=4, end_col_offset=5))'
Georg Brandl619e7ba2011-01-09 07:38:51 +0000664 )
Georg Brandl0c77a822008-06-10 16:37:50 +0000665
666 def test_iter_fields(self):
667 node = ast.parse('foo()', mode='eval')
668 d = dict(ast.iter_fields(node.body))
669 self.assertEqual(d.pop('func').id, 'foo')
Benjamin Peterson025e9eb2015-05-05 20:16:41 -0400670 self.assertEqual(d, {'keywords': [], 'args': []})
Georg Brandl0c77a822008-06-10 16:37:50 +0000671
672 def test_iter_child_nodes(self):
673 node = ast.parse("spam(23, 42, eggs='leek')", mode='eval')
674 self.assertEqual(len(list(ast.iter_child_nodes(node.body))), 4)
675 iterator = ast.iter_child_nodes(node.body)
676 self.assertEqual(next(iterator).id, 'spam')
Serhiy Storchaka3f228112018-09-27 17:42:37 +0300677 self.assertEqual(next(iterator).value, 23)
678 self.assertEqual(next(iterator).value, 42)
Georg Brandl0c77a822008-06-10 16:37:50 +0000679 self.assertEqual(ast.dump(next(iterator)),
Guido van Rossum10f8ce62019-03-13 13:00:46 -0700680 "keyword(arg='eggs', value=Constant(value='leek', kind=None))"
Georg Brandl0c77a822008-06-10 16:37:50 +0000681 )
682
683 def test_get_docstring(self):
Serhiy Storchaka08f127a2018-06-15 11:05:15 +0300684 node = ast.parse('"""line one\n line two"""')
685 self.assertEqual(ast.get_docstring(node),
686 'line one\nline two')
687
688 node = ast.parse('class foo:\n """line one\n line two"""')
689 self.assertEqual(ast.get_docstring(node.body[0]),
690 'line one\nline two')
691
Georg Brandl0c77a822008-06-10 16:37:50 +0000692 node = ast.parse('def foo():\n """line one\n line two"""')
693 self.assertEqual(ast.get_docstring(node.body[0]),
694 'line one\nline two')
695
Yury Selivanov2f07a662015-07-23 08:54:35 +0300696 node = ast.parse('async def foo():\n """spam\n ham"""')
697 self.assertEqual(ast.get_docstring(node.body[0]), 'spam\nham')
Serhiy Storchaka08f127a2018-06-15 11:05:15 +0300698
699 def test_get_docstring_none(self):
Matthias Bussonnier41cea702017-02-23 22:44:19 -0800700 self.assertIsNone(ast.get_docstring(ast.parse('')))
Serhiy Storchaka08f127a2018-06-15 11:05:15 +0300701 node = ast.parse('x = "not docstring"')
702 self.assertIsNone(ast.get_docstring(node))
703 node = ast.parse('def foo():\n pass')
704 self.assertIsNone(ast.get_docstring(node))
705
706 node = ast.parse('class foo:\n pass')
707 self.assertIsNone(ast.get_docstring(node.body[0]))
708 node = ast.parse('class foo:\n x = "not docstring"')
709 self.assertIsNone(ast.get_docstring(node.body[0]))
710 node = ast.parse('class foo:\n def bar(self): pass')
711 self.assertIsNone(ast.get_docstring(node.body[0]))
712
713 node = ast.parse('def foo():\n pass')
714 self.assertIsNone(ast.get_docstring(node.body[0]))
715 node = ast.parse('def foo():\n x = "not docstring"')
716 self.assertIsNone(ast.get_docstring(node.body[0]))
717
718 node = ast.parse('async def foo():\n pass')
719 self.assertIsNone(ast.get_docstring(node.body[0]))
720 node = ast.parse('async def foo():\n x = "not docstring"')
721 self.assertIsNone(ast.get_docstring(node.body[0]))
Yury Selivanov2f07a662015-07-23 08:54:35 +0300722
Anthony Sottile995d9b92019-01-12 20:05:13 -0800723 def test_multi_line_docstring_col_offset_and_lineno_issue16806(self):
724 node = ast.parse(
725 '"""line one\nline two"""\n\n'
726 'def foo():\n """line one\n line two"""\n\n'
727 ' def bar():\n """line one\n line two"""\n'
728 ' """line one\n line two"""\n'
729 '"""line one\nline two"""\n\n'
730 )
731 self.assertEqual(node.body[0].col_offset, 0)
732 self.assertEqual(node.body[0].lineno, 1)
733 self.assertEqual(node.body[1].body[0].col_offset, 2)
734 self.assertEqual(node.body[1].body[0].lineno, 5)
735 self.assertEqual(node.body[1].body[1].body[0].col_offset, 4)
736 self.assertEqual(node.body[1].body[1].body[0].lineno, 9)
737 self.assertEqual(node.body[1].body[2].col_offset, 2)
738 self.assertEqual(node.body[1].body[2].lineno, 11)
739 self.assertEqual(node.body[2].col_offset, 0)
740 self.assertEqual(node.body[2].lineno, 13)
741
Georg Brandl0c77a822008-06-10 16:37:50 +0000742 def test_literal_eval(self):
743 self.assertEqual(ast.literal_eval('[1, 2, 3]'), [1, 2, 3])
744 self.assertEqual(ast.literal_eval('{"foo": 42}'), {"foo": 42})
745 self.assertEqual(ast.literal_eval('(True, False, None)'), (True, False, None))
Benjamin Peterson3e742892010-07-11 12:59:24 +0000746 self.assertEqual(ast.literal_eval('{1, 2, 3}'), {1, 2, 3})
Benjamin Peterson5ef96e52010-07-11 23:06:06 +0000747 self.assertEqual(ast.literal_eval('b"hi"'), b"hi")
Georg Brandl0c77a822008-06-10 16:37:50 +0000748 self.assertRaises(ValueError, ast.literal_eval, 'foo()')
Serhiy Storchakad8ac4d12018-01-04 11:15:39 +0200749 self.assertEqual(ast.literal_eval('6'), 6)
750 self.assertEqual(ast.literal_eval('+6'), 6)
Raymond Hettingerbc959732010-10-08 00:47:45 +0000751 self.assertEqual(ast.literal_eval('-6'), -6)
Raymond Hettingerbc959732010-10-08 00:47:45 +0000752 self.assertEqual(ast.literal_eval('3.25'), 3.25)
Serhiy Storchakad8ac4d12018-01-04 11:15:39 +0200753 self.assertEqual(ast.literal_eval('+3.25'), 3.25)
754 self.assertEqual(ast.literal_eval('-3.25'), -3.25)
755 self.assertEqual(repr(ast.literal_eval('-0.0')), '-0.0')
756 self.assertRaises(ValueError, ast.literal_eval, '++6')
757 self.assertRaises(ValueError, ast.literal_eval, '+True')
758 self.assertRaises(ValueError, ast.literal_eval, '2+3')
Georg Brandl0c77a822008-06-10 16:37:50 +0000759
Serhiy Storchakad8ac4d12018-01-04 11:15:39 +0200760 def test_literal_eval_complex(self):
761 # Issue #4907
762 self.assertEqual(ast.literal_eval('6j'), 6j)
763 self.assertEqual(ast.literal_eval('-6j'), -6j)
764 self.assertEqual(ast.literal_eval('6.75j'), 6.75j)
765 self.assertEqual(ast.literal_eval('-6.75j'), -6.75j)
766 self.assertEqual(ast.literal_eval('3+6j'), 3+6j)
767 self.assertEqual(ast.literal_eval('-3+6j'), -3+6j)
768 self.assertEqual(ast.literal_eval('3-6j'), 3-6j)
769 self.assertEqual(ast.literal_eval('-3-6j'), -3-6j)
770 self.assertEqual(ast.literal_eval('3.25+6.75j'), 3.25+6.75j)
771 self.assertEqual(ast.literal_eval('-3.25+6.75j'), -3.25+6.75j)
772 self.assertEqual(ast.literal_eval('3.25-6.75j'), 3.25-6.75j)
773 self.assertEqual(ast.literal_eval('-3.25-6.75j'), -3.25-6.75j)
774 self.assertEqual(ast.literal_eval('(3+6j)'), 3+6j)
775 self.assertRaises(ValueError, ast.literal_eval, '-6j+3')
776 self.assertRaises(ValueError, ast.literal_eval, '-6j+3j')
777 self.assertRaises(ValueError, ast.literal_eval, '3+-6j')
778 self.assertRaises(ValueError, ast.literal_eval, '3+(0+6j)')
779 self.assertRaises(ValueError, ast.literal_eval, '-(3+6j)')
Benjamin Peterson058e31e2009-01-16 03:54:08 +0000780
Amaury Forgeot d'Arc58e87612011-11-22 21:51:55 +0100781 def test_bad_integer(self):
782 # issue13436: Bad error message with invalid numeric values
783 body = [ast.ImportFrom(module='time',
784 names=[ast.alias(name='sleep')],
785 level=None,
786 lineno=None, col_offset=None)]
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800787 mod = ast.Module(body, [])
Amaury Forgeot d'Arc58e87612011-11-22 21:51:55 +0100788 with self.assertRaises(ValueError) as cm:
789 compile(mod, 'test', 'exec')
790 self.assertIn("invalid integer value: None", str(cm.exception))
791
Berker Peksag0a5bd512016-04-29 19:50:02 +0300792 def test_level_as_none(self):
793 body = [ast.ImportFrom(module='time',
794 names=[ast.alias(name='sleep')],
795 level=None,
796 lineno=0, col_offset=0)]
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800797 mod = ast.Module(body, [])
Berker Peksag0a5bd512016-04-29 19:50:02 +0300798 code = compile(mod, 'test', 'exec')
799 ns = {}
800 exec(code, ns)
801 self.assertIn('sleep', ns)
802
Georg Brandl0c77a822008-06-10 16:37:50 +0000803
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500804class ASTValidatorTests(unittest.TestCase):
805
806 def mod(self, mod, msg=None, mode="exec", *, exc=ValueError):
807 mod.lineno = mod.col_offset = 0
808 ast.fix_missing_locations(mod)
Serhiy Storchaka3f228112018-09-27 17:42:37 +0300809 if msg is None:
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500810 compile(mod, "<test>", mode)
Serhiy Storchaka3f228112018-09-27 17:42:37 +0300811 else:
812 with self.assertRaises(exc) as cm:
813 compile(mod, "<test>", mode)
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500814 self.assertIn(msg, str(cm.exception))
815
816 def expr(self, node, msg=None, *, exc=ValueError):
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800817 mod = ast.Module([ast.Expr(node)], [])
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500818 self.mod(mod, msg, exc=exc)
819
820 def stmt(self, stmt, msg=None):
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800821 mod = ast.Module([stmt], [])
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500822 self.mod(mod, msg)
823
824 def test_module(self):
825 m = ast.Interactive([ast.Expr(ast.Name("x", ast.Store()))])
826 self.mod(m, "must have Load context", "single")
827 m = ast.Expression(ast.Name("x", ast.Store()))
828 self.mod(m, "must have Load context", "eval")
829
830 def _check_arguments(self, fac, check):
Pablo Galindo8c77b8c2019-04-29 13:36:57 +0100831 def arguments(args=None, posonlyargs=None, vararg=None,
Benjamin Petersoncda75be2013-03-18 10:48:58 -0700832 kwonlyargs=None, kwarg=None,
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500833 defaults=None, kw_defaults=None):
834 if args is None:
835 args = []
Pablo Galindo8c77b8c2019-04-29 13:36:57 +0100836 if posonlyargs is None:
837 posonlyargs = []
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500838 if kwonlyargs is None:
839 kwonlyargs = []
840 if defaults is None:
841 defaults = []
842 if kw_defaults is None:
843 kw_defaults = []
Pablo Galindo8c77b8c2019-04-29 13:36:57 +0100844 args = ast.arguments(args, posonlyargs, vararg, kwonlyargs,
845 kw_defaults, kwarg, defaults)
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500846 return fac(args)
847 args = [ast.arg("x", ast.Name("x", ast.Store()))]
848 check(arguments(args=args), "must have Load context")
Pablo Galindo8c77b8c2019-04-29 13:36:57 +0100849 check(arguments(posonlyargs=args), "must have Load context")
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500850 check(arguments(kwonlyargs=args), "must have Load context")
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500851 check(arguments(defaults=[ast.Num(3)]),
852 "more positional defaults than args")
853 check(arguments(kw_defaults=[ast.Num(4)]),
854 "length of kwonlyargs is not the same as kw_defaults")
855 args = [ast.arg("x", ast.Name("x", ast.Load()))]
856 check(arguments(args=args, defaults=[ast.Name("x", ast.Store())]),
857 "must have Load context")
858 args = [ast.arg("a", ast.Name("x", ast.Load())),
859 ast.arg("b", ast.Name("y", ast.Load()))]
860 check(arguments(kwonlyargs=args,
861 kw_defaults=[None, ast.Name("x", ast.Store())]),
862 "must have Load context")
863
864 def test_funcdef(self):
Pablo Galindo8c77b8c2019-04-29 13:36:57 +0100865 a = ast.arguments([], [], None, [], [], None, [])
Serhiy Storchaka73cbe7a2018-05-29 12:04:55 +0300866 f = ast.FunctionDef("x", a, [], [], None)
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500867 self.stmt(f, "empty body on FunctionDef")
868 f = ast.FunctionDef("x", a, [ast.Pass()], [ast.Name("x", ast.Store())],
Serhiy Storchaka73cbe7a2018-05-29 12:04:55 +0300869 None)
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500870 self.stmt(f, "must have Load context")
871 f = ast.FunctionDef("x", a, [ast.Pass()], [],
Serhiy Storchaka73cbe7a2018-05-29 12:04:55 +0300872 ast.Name("x", ast.Store()))
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500873 self.stmt(f, "must have Load context")
874 def fac(args):
Serhiy Storchaka73cbe7a2018-05-29 12:04:55 +0300875 return ast.FunctionDef("x", args, [ast.Pass()], [], None)
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500876 self._check_arguments(fac, self.stmt)
877
878 def test_classdef(self):
Benjamin Peterson025e9eb2015-05-05 20:16:41 -0400879 def cls(bases=None, keywords=None, body=None, decorator_list=None):
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500880 if bases is None:
881 bases = []
882 if keywords is None:
883 keywords = []
884 if body is None:
885 body = [ast.Pass()]
886 if decorator_list is None:
887 decorator_list = []
Benjamin Peterson025e9eb2015-05-05 20:16:41 -0400888 return ast.ClassDef("myclass", bases, keywords,
Serhiy Storchaka73cbe7a2018-05-29 12:04:55 +0300889 body, decorator_list)
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500890 self.stmt(cls(bases=[ast.Name("x", ast.Store())]),
891 "must have Load context")
892 self.stmt(cls(keywords=[ast.keyword("x", ast.Name("x", ast.Store()))]),
893 "must have Load context")
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500894 self.stmt(cls(body=[]), "empty body on ClassDef")
895 self.stmt(cls(body=[None]), "None disallowed")
896 self.stmt(cls(decorator_list=[ast.Name("x", ast.Store())]),
897 "must have Load context")
898
899 def test_delete(self):
900 self.stmt(ast.Delete([]), "empty targets on Delete")
901 self.stmt(ast.Delete([None]), "None disallowed")
902 self.stmt(ast.Delete([ast.Name("x", ast.Load())]),
903 "must have Del context")
904
905 def test_assign(self):
906 self.stmt(ast.Assign([], ast.Num(3)), "empty targets on Assign")
907 self.stmt(ast.Assign([None], ast.Num(3)), "None disallowed")
908 self.stmt(ast.Assign([ast.Name("x", ast.Load())], ast.Num(3)),
909 "must have Store context")
910 self.stmt(ast.Assign([ast.Name("x", ast.Store())],
911 ast.Name("y", ast.Store())),
912 "must have Load context")
913
914 def test_augassign(self):
915 aug = ast.AugAssign(ast.Name("x", ast.Load()), ast.Add(),
916 ast.Name("y", ast.Load()))
917 self.stmt(aug, "must have Store context")
918 aug = ast.AugAssign(ast.Name("x", ast.Store()), ast.Add(),
919 ast.Name("y", ast.Store()))
920 self.stmt(aug, "must have Load context")
921
922 def test_for(self):
923 x = ast.Name("x", ast.Store())
924 y = ast.Name("y", ast.Load())
925 p = ast.Pass()
926 self.stmt(ast.For(x, y, [], []), "empty body on For")
927 self.stmt(ast.For(ast.Name("x", ast.Load()), y, [p], []),
928 "must have Store context")
929 self.stmt(ast.For(x, ast.Name("y", ast.Store()), [p], []),
930 "must have Load context")
931 e = ast.Expr(ast.Name("x", ast.Store()))
932 self.stmt(ast.For(x, y, [e], []), "must have Load context")
933 self.stmt(ast.For(x, y, [p], [e]), "must have Load context")
934
935 def test_while(self):
936 self.stmt(ast.While(ast.Num(3), [], []), "empty body on While")
937 self.stmt(ast.While(ast.Name("x", ast.Store()), [ast.Pass()], []),
938 "must have Load context")
939 self.stmt(ast.While(ast.Num(3), [ast.Pass()],
940 [ast.Expr(ast.Name("x", ast.Store()))]),
941 "must have Load context")
942
943 def test_if(self):
944 self.stmt(ast.If(ast.Num(3), [], []), "empty body on If")
945 i = ast.If(ast.Name("x", ast.Store()), [ast.Pass()], [])
946 self.stmt(i, "must have Load context")
947 i = ast.If(ast.Num(3), [ast.Expr(ast.Name("x", ast.Store()))], [])
948 self.stmt(i, "must have Load context")
949 i = ast.If(ast.Num(3), [ast.Pass()],
950 [ast.Expr(ast.Name("x", ast.Store()))])
951 self.stmt(i, "must have Load context")
952
953 def test_with(self):
954 p = ast.Pass()
955 self.stmt(ast.With([], [p]), "empty items on With")
956 i = ast.withitem(ast.Num(3), None)
957 self.stmt(ast.With([i], []), "empty body on With")
958 i = ast.withitem(ast.Name("x", ast.Store()), None)
959 self.stmt(ast.With([i], [p]), "must have Load context")
960 i = ast.withitem(ast.Num(3), ast.Name("x", ast.Load()))
961 self.stmt(ast.With([i], [p]), "must have Store context")
962
963 def test_raise(self):
964 r = ast.Raise(None, ast.Num(3))
965 self.stmt(r, "Raise with cause but no exception")
966 r = ast.Raise(ast.Name("x", ast.Store()), None)
967 self.stmt(r, "must have Load context")
968 r = ast.Raise(ast.Num(4), ast.Name("x", ast.Store()))
969 self.stmt(r, "must have Load context")
970
971 def test_try(self):
972 p = ast.Pass()
973 t = ast.Try([], [], [], [p])
974 self.stmt(t, "empty body on Try")
975 t = ast.Try([ast.Expr(ast.Name("x", ast.Store()))], [], [], [p])
976 self.stmt(t, "must have Load context")
977 t = ast.Try([p], [], [], [])
978 self.stmt(t, "Try has neither except handlers nor finalbody")
979 t = ast.Try([p], [], [p], [p])
980 self.stmt(t, "Try has orelse but no except handlers")
981 t = ast.Try([p], [ast.ExceptHandler(None, "x", [])], [], [])
982 self.stmt(t, "empty body on ExceptHandler")
983 e = [ast.ExceptHandler(ast.Name("x", ast.Store()), "y", [p])]
984 self.stmt(ast.Try([p], e, [], []), "must have Load context")
985 e = [ast.ExceptHandler(None, "x", [p])]
986 t = ast.Try([p], e, [ast.Expr(ast.Name("x", ast.Store()))], [p])
987 self.stmt(t, "must have Load context")
988 t = ast.Try([p], e, [p], [ast.Expr(ast.Name("x", ast.Store()))])
989 self.stmt(t, "must have Load context")
990
991 def test_assert(self):
992 self.stmt(ast.Assert(ast.Name("x", ast.Store()), None),
993 "must have Load context")
994 assrt = ast.Assert(ast.Name("x", ast.Load()),
995 ast.Name("y", ast.Store()))
996 self.stmt(assrt, "must have Load context")
997
998 def test_import(self):
999 self.stmt(ast.Import([]), "empty names on Import")
1000
1001 def test_importfrom(self):
1002 imp = ast.ImportFrom(None, [ast.alias("x", None)], -42)
Serhiy Storchaka7de28402016-06-27 23:40:43 +03001003 self.stmt(imp, "Negative ImportFrom level")
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001004 self.stmt(ast.ImportFrom(None, [], 0), "empty names on ImportFrom")
1005
1006 def test_global(self):
1007 self.stmt(ast.Global([]), "empty names on Global")
1008
1009 def test_nonlocal(self):
1010 self.stmt(ast.Nonlocal([]), "empty names on Nonlocal")
1011
1012 def test_expr(self):
1013 e = ast.Expr(ast.Name("x", ast.Store()))
1014 self.stmt(e, "must have Load context")
1015
1016 def test_boolop(self):
1017 b = ast.BoolOp(ast.And(), [])
1018 self.expr(b, "less than 2 values")
1019 b = ast.BoolOp(ast.And(), [ast.Num(3)])
1020 self.expr(b, "less than 2 values")
1021 b = ast.BoolOp(ast.And(), [ast.Num(4), None])
1022 self.expr(b, "None disallowed")
1023 b = ast.BoolOp(ast.And(), [ast.Num(4), ast.Name("x", ast.Store())])
1024 self.expr(b, "must have Load context")
1025
1026 def test_unaryop(self):
1027 u = ast.UnaryOp(ast.Not(), ast.Name("x", ast.Store()))
1028 self.expr(u, "must have Load context")
1029
1030 def test_lambda(self):
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01001031 a = ast.arguments([], [], None, [], [], None, [])
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001032 self.expr(ast.Lambda(a, ast.Name("x", ast.Store())),
1033 "must have Load context")
1034 def fac(args):
1035 return ast.Lambda(args, ast.Name("x", ast.Load()))
1036 self._check_arguments(fac, self.expr)
1037
1038 def test_ifexp(self):
1039 l = ast.Name("x", ast.Load())
1040 s = ast.Name("y", ast.Store())
1041 for args in (s, l, l), (l, s, l), (l, l, s):
Benjamin Peterson71ce8972011-08-09 16:17:12 -05001042 self.expr(ast.IfExp(*args), "must have Load context")
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001043
1044 def test_dict(self):
1045 d = ast.Dict([], [ast.Name("x", ast.Load())])
1046 self.expr(d, "same number of keys as values")
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001047 d = ast.Dict([ast.Name("x", ast.Load())], [None])
1048 self.expr(d, "None disallowed")
1049
1050 def test_set(self):
1051 self.expr(ast.Set([None]), "None disallowed")
1052 s = ast.Set([ast.Name("x", ast.Store())])
1053 self.expr(s, "must have Load context")
1054
1055 def _check_comprehension(self, fac):
1056 self.expr(fac([]), "comprehension with no generators")
1057 g = ast.comprehension(ast.Name("x", ast.Load()),
Yury Selivanov52c4e7c2016-09-09 10:36:01 -07001058 ast.Name("x", ast.Load()), [], 0)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001059 self.expr(fac([g]), "must have Store context")
1060 g = ast.comprehension(ast.Name("x", ast.Store()),
Yury Selivanov52c4e7c2016-09-09 10:36:01 -07001061 ast.Name("x", ast.Store()), [], 0)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001062 self.expr(fac([g]), "must have Load context")
1063 x = ast.Name("x", ast.Store())
1064 y = ast.Name("y", ast.Load())
Yury Selivanov52c4e7c2016-09-09 10:36:01 -07001065 g = ast.comprehension(x, y, [None], 0)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001066 self.expr(fac([g]), "None disallowed")
Yury Selivanov52c4e7c2016-09-09 10:36:01 -07001067 g = ast.comprehension(x, y, [ast.Name("x", ast.Store())], 0)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001068 self.expr(fac([g]), "must have Load context")
1069
1070 def _simple_comp(self, fac):
1071 g = ast.comprehension(ast.Name("x", ast.Store()),
Yury Selivanov52c4e7c2016-09-09 10:36:01 -07001072 ast.Name("x", ast.Load()), [], 0)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001073 self.expr(fac(ast.Name("x", ast.Store()), [g]),
1074 "must have Load context")
1075 def wrap(gens):
1076 return fac(ast.Name("x", ast.Store()), gens)
1077 self._check_comprehension(wrap)
1078
1079 def test_listcomp(self):
1080 self._simple_comp(ast.ListComp)
1081
1082 def test_setcomp(self):
1083 self._simple_comp(ast.SetComp)
1084
1085 def test_generatorexp(self):
1086 self._simple_comp(ast.GeneratorExp)
1087
1088 def test_dictcomp(self):
1089 g = ast.comprehension(ast.Name("y", ast.Store()),
Yury Selivanov52c4e7c2016-09-09 10:36:01 -07001090 ast.Name("p", ast.Load()), [], 0)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001091 c = ast.DictComp(ast.Name("x", ast.Store()),
1092 ast.Name("y", ast.Load()), [g])
1093 self.expr(c, "must have Load context")
1094 c = ast.DictComp(ast.Name("x", ast.Load()),
1095 ast.Name("y", ast.Store()), [g])
1096 self.expr(c, "must have Load context")
1097 def factory(comps):
1098 k = ast.Name("x", ast.Load())
1099 v = ast.Name("y", ast.Load())
1100 return ast.DictComp(k, v, comps)
1101 self._check_comprehension(factory)
1102
1103 def test_yield(self):
Benjamin Peterson527c6222012-01-14 08:58:23 -05001104 self.expr(ast.Yield(ast.Name("x", ast.Store())), "must have Load")
1105 self.expr(ast.YieldFrom(ast.Name("x", ast.Store())), "must have Load")
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001106
1107 def test_compare(self):
1108 left = ast.Name("x", ast.Load())
1109 comp = ast.Compare(left, [ast.In()], [])
1110 self.expr(comp, "no comparators")
1111 comp = ast.Compare(left, [ast.In()], [ast.Num(4), ast.Num(5)])
1112 self.expr(comp, "different number of comparators and operands")
1113 comp = ast.Compare(ast.Num("blah"), [ast.In()], [left])
Serhiy Storchaka3f228112018-09-27 17:42:37 +03001114 self.expr(comp)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001115 comp = ast.Compare(left, [ast.In()], [ast.Num("blah")])
Serhiy Storchaka3f228112018-09-27 17:42:37 +03001116 self.expr(comp)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001117
1118 def test_call(self):
1119 func = ast.Name("x", ast.Load())
1120 args = [ast.Name("y", ast.Load())]
1121 keywords = [ast.keyword("w", ast.Name("z", ast.Load()))]
Benjamin Peterson025e9eb2015-05-05 20:16:41 -04001122 call = ast.Call(ast.Name("x", ast.Store()), args, keywords)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001123 self.expr(call, "must have Load context")
Benjamin Peterson025e9eb2015-05-05 20:16:41 -04001124 call = ast.Call(func, [None], keywords)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001125 self.expr(call, "None disallowed")
1126 bad_keywords = [ast.keyword("w", ast.Name("z", ast.Store()))]
Benjamin Peterson025e9eb2015-05-05 20:16:41 -04001127 call = ast.Call(func, args, bad_keywords)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001128 self.expr(call, "must have Load context")
1129
1130 def test_num(self):
1131 class subint(int):
1132 pass
1133 class subfloat(float):
1134 pass
1135 class subcomplex(complex):
1136 pass
Serhiy Storchaka3f228112018-09-27 17:42:37 +03001137 for obj in "0", "hello":
1138 self.expr(ast.Num(obj))
1139 for obj in subint(), subfloat(), subcomplex():
1140 self.expr(ast.Num(obj), "invalid type", exc=TypeError)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001141
1142 def test_attribute(self):
1143 attr = ast.Attribute(ast.Name("x", ast.Store()), "y", ast.Load())
1144 self.expr(attr, "must have Load context")
1145
1146 def test_subscript(self):
1147 sub = ast.Subscript(ast.Name("x", ast.Store()), ast.Index(ast.Num(3)),
1148 ast.Load())
1149 self.expr(sub, "must have Load context")
1150 x = ast.Name("x", ast.Load())
1151 sub = ast.Subscript(x, ast.Index(ast.Name("y", ast.Store())),
1152 ast.Load())
1153 self.expr(sub, "must have Load context")
1154 s = ast.Name("x", ast.Store())
1155 for args in (s, None, None), (None, s, None), (None, None, s):
1156 sl = ast.Slice(*args)
1157 self.expr(ast.Subscript(x, sl, ast.Load()),
1158 "must have Load context")
1159 sl = ast.ExtSlice([])
1160 self.expr(ast.Subscript(x, sl, ast.Load()), "empty dims on ExtSlice")
1161 sl = ast.ExtSlice([ast.Index(s)])
1162 self.expr(ast.Subscript(x, sl, ast.Load()), "must have Load context")
1163
1164 def test_starred(self):
1165 left = ast.List([ast.Starred(ast.Name("x", ast.Load()), ast.Store())],
1166 ast.Store())
1167 assign = ast.Assign([left], ast.Num(4))
1168 self.stmt(assign, "must have Store context")
1169
1170 def _sequence(self, fac):
1171 self.expr(fac([None], ast.Load()), "None disallowed")
1172 self.expr(fac([ast.Name("x", ast.Store())], ast.Load()),
1173 "must have Load context")
1174
1175 def test_list(self):
1176 self._sequence(ast.List)
1177
1178 def test_tuple(self):
1179 self._sequence(ast.Tuple)
1180
Benjamin Peterson442f2092012-12-06 17:41:04 -05001181 def test_nameconstant(self):
Serhiy Storchaka3f228112018-09-27 17:42:37 +03001182 self.expr(ast.NameConstant(4))
Benjamin Peterson442f2092012-12-06 17:41:04 -05001183
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001184 def test_stdlib_validates(self):
1185 stdlib = os.path.dirname(ast.__file__)
1186 tests = [fn for fn in os.listdir(stdlib) if fn.endswith(".py")]
1187 tests.extend(["test/test_grammar.py", "test/test_unpack_ex.py"])
1188 for module in tests:
Serhiy Storchaka3bcbedc2019-01-18 07:47:48 +02001189 with self.subTest(module):
1190 fn = os.path.join(stdlib, module)
1191 with open(fn, "r", encoding="utf-8") as fp:
1192 source = fp.read()
1193 mod = ast.parse(source, fn)
1194 compile(mod, fn, "exec")
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001195
1196
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001197class ConstantTests(unittest.TestCase):
1198 """Tests on the ast.Constant node type."""
1199
1200 def compile_constant(self, value):
1201 tree = ast.parse("x = 123")
1202
1203 node = tree.body[0].value
1204 new_node = ast.Constant(value=value)
1205 ast.copy_location(new_node, node)
1206 tree.body[0].value = new_node
1207
1208 code = compile(tree, "<string>", "exec")
1209
1210 ns = {}
1211 exec(code, ns)
1212 return ns['x']
1213
Victor Stinnerbe59d142016-01-27 00:39:12 +01001214 def test_validation(self):
1215 with self.assertRaises(TypeError) as cm:
1216 self.compile_constant([1, 2, 3])
1217 self.assertEqual(str(cm.exception),
1218 "got an invalid type in Constant: list")
1219
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001220 def test_singletons(self):
1221 for const in (None, False, True, Ellipsis, b'', frozenset()):
1222 with self.subTest(const=const):
1223 value = self.compile_constant(const)
1224 self.assertIs(value, const)
1225
1226 def test_values(self):
1227 nested_tuple = (1,)
1228 nested_frozenset = frozenset({1})
1229 for level in range(3):
1230 nested_tuple = (nested_tuple, 2)
1231 nested_frozenset = frozenset({nested_frozenset, 2})
1232 values = (123, 123.0, 123j,
1233 "unicode", b'bytes',
1234 tuple("tuple"), frozenset("frozenset"),
1235 nested_tuple, nested_frozenset)
1236 for value in values:
1237 with self.subTest(value=value):
1238 result = self.compile_constant(value)
1239 self.assertEqual(result, value)
1240
1241 def test_assign_to_constant(self):
1242 tree = ast.parse("x = 1")
1243
1244 target = tree.body[0].targets[0]
1245 new_target = ast.Constant(value=1)
1246 ast.copy_location(new_target, target)
1247 tree.body[0].targets[0] = new_target
1248
1249 with self.assertRaises(ValueError) as cm:
1250 compile(tree, "string", "exec")
1251 self.assertEqual(str(cm.exception),
1252 "expression which can't be assigned "
1253 "to in Store context")
1254
1255 def test_get_docstring(self):
1256 tree = ast.parse("'docstring'\nx = 1")
1257 self.assertEqual(ast.get_docstring(tree), 'docstring')
1258
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001259 def get_load_const(self, tree):
1260 # Compile to bytecode, disassemble and get parameter of LOAD_CONST
1261 # instructions
1262 co = compile(tree, '<string>', 'exec')
1263 consts = []
1264 for instr in dis.get_instructions(co):
1265 if instr.opname == 'LOAD_CONST':
1266 consts.append(instr.argval)
1267 return consts
1268
1269 @support.cpython_only
1270 def test_load_const(self):
1271 consts = [None,
1272 True, False,
1273 124,
1274 2.0,
1275 3j,
1276 "unicode",
1277 b'bytes',
1278 (1, 2, 3)]
1279
Victor Stinnera2724092016-02-08 18:17:58 +01001280 code = '\n'.join(['x={!r}'.format(const) for const in consts])
1281 code += '\nx = ...'
1282 consts.extend((Ellipsis, None))
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001283
1284 tree = ast.parse(code)
Victor Stinnera2724092016-02-08 18:17:58 +01001285 self.assertEqual(self.get_load_const(tree),
1286 consts)
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001287
1288 # Replace expression nodes with constants
Victor Stinnera2724092016-02-08 18:17:58 +01001289 for assign, const in zip(tree.body, consts):
1290 assert isinstance(assign, ast.Assign), ast.dump(assign)
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001291 new_node = ast.Constant(value=const)
Victor Stinnera2724092016-02-08 18:17:58 +01001292 ast.copy_location(new_node, assign.value)
1293 assign.value = new_node
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001294
Victor Stinnera2724092016-02-08 18:17:58 +01001295 self.assertEqual(self.get_load_const(tree),
1296 consts)
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001297
1298 def test_literal_eval(self):
1299 tree = ast.parse("1 + 2")
1300 binop = tree.body[0].value
1301
1302 new_left = ast.Constant(value=10)
1303 ast.copy_location(new_left, binop.left)
1304 binop.left = new_left
1305
Serhiy Storchakad8ac4d12018-01-04 11:15:39 +02001306 new_right = ast.Constant(value=20j)
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001307 ast.copy_location(new_right, binop.right)
1308 binop.right = new_right
1309
Serhiy Storchakad8ac4d12018-01-04 11:15:39 +02001310 self.assertEqual(ast.literal_eval(binop), 10+20j)
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001311
Guido van Rossum10f8ce62019-03-13 13:00:46 -07001312 def test_string_kind(self):
1313 c = ast.parse('"x"', mode='eval').body
1314 self.assertEqual(c.value, "x")
1315 self.assertEqual(c.kind, None)
1316
1317 c = ast.parse('u"x"', mode='eval').body
1318 self.assertEqual(c.value, "x")
1319 self.assertEqual(c.kind, "u")
1320
1321 c = ast.parse('r"x"', mode='eval').body
1322 self.assertEqual(c.value, "x")
1323 self.assertEqual(c.kind, None)
1324
1325 c = ast.parse('b"x"', mode='eval').body
1326 self.assertEqual(c.value, b"x")
1327 self.assertEqual(c.kind, None)
1328
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001329
Ivan Levkivskyi9932a222019-01-22 11:18:22 +00001330class EndPositionTests(unittest.TestCase):
1331 """Tests for end position of AST nodes.
1332
1333 Testing end positions of nodes requires a bit of extra care
1334 because of how LL parsers work.
1335 """
1336 def _check_end_pos(self, ast_node, end_lineno, end_col_offset):
1337 self.assertEqual(ast_node.end_lineno, end_lineno)
1338 self.assertEqual(ast_node.end_col_offset, end_col_offset)
1339
1340 def _check_content(self, source, ast_node, content):
1341 self.assertEqual(ast.get_source_segment(source, ast_node), content)
1342
1343 def _parse_value(self, s):
1344 # Use duck-typing to support both single expression
1345 # and a right hand side of an assignment statement.
1346 return ast.parse(s).body[0].value
1347
1348 def test_lambda(self):
1349 s = 'lambda x, *y: None'
1350 lam = self._parse_value(s)
1351 self._check_content(s, lam.body, 'None')
1352 self._check_content(s, lam.args.args[0], 'x')
1353 self._check_content(s, lam.args.vararg, 'y')
1354
1355 def test_func_def(self):
1356 s = dedent('''
1357 def func(x: int,
1358 *args: str,
1359 z: float = 0,
1360 **kwargs: Any) -> bool:
1361 return True
1362 ''').strip()
1363 fdef = ast.parse(s).body[0]
1364 self._check_end_pos(fdef, 5, 15)
1365 self._check_content(s, fdef.body[0], 'return True')
1366 self._check_content(s, fdef.args.args[0], 'x: int')
1367 self._check_content(s, fdef.args.args[0].annotation, 'int')
1368 self._check_content(s, fdef.args.kwarg, 'kwargs: Any')
1369 self._check_content(s, fdef.args.kwarg.annotation, 'Any')
1370
1371 def test_call(self):
1372 s = 'func(x, y=2, **kw)'
1373 call = self._parse_value(s)
1374 self._check_content(s, call.func, 'func')
1375 self._check_content(s, call.keywords[0].value, '2')
1376 self._check_content(s, call.keywords[1].value, 'kw')
1377
1378 def test_call_noargs(self):
1379 s = 'x[0]()'
1380 call = self._parse_value(s)
1381 self._check_content(s, call.func, 'x[0]')
1382 self._check_end_pos(call, 1, 6)
1383
1384 def test_class_def(self):
1385 s = dedent('''
1386 class C(A, B):
1387 x: int = 0
1388 ''').strip()
1389 cdef = ast.parse(s).body[0]
1390 self._check_end_pos(cdef, 2, 14)
1391 self._check_content(s, cdef.bases[1], 'B')
1392 self._check_content(s, cdef.body[0], 'x: int = 0')
1393
1394 def test_class_kw(self):
1395 s = 'class S(metaclass=abc.ABCMeta): pass'
1396 cdef = ast.parse(s).body[0]
1397 self._check_content(s, cdef.keywords[0].value, 'abc.ABCMeta')
1398
1399 def test_multi_line_str(self):
1400 s = dedent('''
1401 x = """Some multi-line text.
1402
1403 It goes on starting from same indent."""
1404 ''').strip()
1405 assign = ast.parse(s).body[0]
1406 self._check_end_pos(assign, 3, 40)
1407 self._check_end_pos(assign.value, 3, 40)
1408
1409 def test_continued_str(self):
1410 s = dedent('''
1411 x = "first part" \\
1412 "second part"
1413 ''').strip()
1414 assign = ast.parse(s).body[0]
1415 self._check_end_pos(assign, 2, 13)
1416 self._check_end_pos(assign.value, 2, 13)
1417
1418 def test_suites(self):
1419 # We intentionally put these into the same string to check
1420 # that empty lines are not part of the suite.
1421 s = dedent('''
1422 while True:
1423 pass
1424
1425 if one():
1426 x = None
1427 elif other():
1428 y = None
1429 else:
1430 z = None
1431
1432 for x, y in stuff:
1433 assert True
1434
1435 try:
1436 raise RuntimeError
1437 except TypeError as e:
1438 pass
1439
1440 pass
1441 ''').strip()
1442 mod = ast.parse(s)
1443 while_loop = mod.body[0]
1444 if_stmt = mod.body[1]
1445 for_loop = mod.body[2]
1446 try_stmt = mod.body[3]
1447 pass_stmt = mod.body[4]
1448
1449 self._check_end_pos(while_loop, 2, 8)
1450 self._check_end_pos(if_stmt, 9, 12)
1451 self._check_end_pos(for_loop, 12, 15)
1452 self._check_end_pos(try_stmt, 17, 8)
1453 self._check_end_pos(pass_stmt, 19, 4)
1454
1455 self._check_content(s, while_loop.test, 'True')
1456 self._check_content(s, if_stmt.body[0], 'x = None')
1457 self._check_content(s, if_stmt.orelse[0].test, 'other()')
1458 self._check_content(s, for_loop.target, 'x, y')
1459 self._check_content(s, try_stmt.body[0], 'raise RuntimeError')
1460 self._check_content(s, try_stmt.handlers[0].type, 'TypeError')
1461
1462 def test_fstring(self):
1463 s = 'x = f"abc {x + y} abc"'
1464 fstr = self._parse_value(s)
1465 binop = fstr.values[1].value
1466 self._check_content(s, binop, 'x + y')
1467
1468 def test_fstring_multi_line(self):
1469 s = dedent('''
1470 f"""Some multi-line text.
1471 {
1472 arg_one
1473 +
1474 arg_two
1475 }
1476 It goes on..."""
1477 ''').strip()
1478 fstr = self._parse_value(s)
1479 binop = fstr.values[1].value
1480 self._check_end_pos(binop, 5, 7)
1481 self._check_content(s, binop.left, 'arg_one')
1482 self._check_content(s, binop.right, 'arg_two')
1483
1484 def test_import_from_multi_line(self):
1485 s = dedent('''
1486 from x.y.z import (
1487 a, b, c as c
1488 )
1489 ''').strip()
1490 imp = ast.parse(s).body[0]
1491 self._check_end_pos(imp, 3, 1)
1492
1493 def test_slices(self):
1494 s1 = 'f()[1, 2] [0]'
1495 s2 = 'x[ a.b: c.d]'
1496 sm = dedent('''
1497 x[ a.b: f () ,
1498 g () : c.d
1499 ]
1500 ''').strip()
1501 i1, i2, im = map(self._parse_value, (s1, s2, sm))
1502 self._check_content(s1, i1.value, 'f()[1, 2]')
1503 self._check_content(s1, i1.value.slice.value, '1, 2')
1504 self._check_content(s2, i2.slice.lower, 'a.b')
1505 self._check_content(s2, i2.slice.upper, 'c.d')
1506 self._check_content(sm, im.slice.dims[0].upper, 'f ()')
1507 self._check_content(sm, im.slice.dims[1].lower, 'g ()')
1508 self._check_end_pos(im, 3, 3)
1509
1510 def test_binop(self):
1511 s = dedent('''
1512 (1 * 2 + (3 ) +
1513 4
1514 )
1515 ''').strip()
1516 binop = self._parse_value(s)
1517 self._check_end_pos(binop, 2, 6)
1518 self._check_content(s, binop.right, '4')
1519 self._check_content(s, binop.left, '1 * 2 + (3 )')
1520 self._check_content(s, binop.left.right, '3')
1521
1522 def test_boolop(self):
1523 s = dedent('''
1524 if (one_condition and
1525 (other_condition or yet_another_one)):
1526 pass
1527 ''').strip()
1528 bop = ast.parse(s).body[0].test
1529 self._check_end_pos(bop, 2, 44)
1530 self._check_content(s, bop.values[1],
1531 'other_condition or yet_another_one')
1532
1533 def test_tuples(self):
1534 s1 = 'x = () ;'
1535 s2 = 'x = 1 , ;'
1536 s3 = 'x = (1 , 2 ) ;'
1537 sm = dedent('''
1538 x = (
1539 a, b,
1540 )
1541 ''').strip()
1542 t1, t2, t3, tm = map(self._parse_value, (s1, s2, s3, sm))
1543 self._check_content(s1, t1, '()')
1544 self._check_content(s2, t2, '1 ,')
1545 self._check_content(s3, t3, '(1 , 2 )')
1546 self._check_end_pos(tm, 3, 1)
1547
1548 def test_attribute_spaces(self):
1549 s = 'func(x. y .z)'
1550 call = self._parse_value(s)
1551 self._check_content(s, call, s)
1552 self._check_content(s, call.args[0], 'x. y .z')
1553
1554 def test_displays(self):
1555 s1 = '[{}, {1, }, {1, 2,} ]'
1556 s2 = '{a: b, f (): g () ,}'
1557 c1 = self._parse_value(s1)
1558 c2 = self._parse_value(s2)
1559 self._check_content(s1, c1.elts[0], '{}')
1560 self._check_content(s1, c1.elts[1], '{1, }')
1561 self._check_content(s1, c1.elts[2], '{1, 2,}')
1562 self._check_content(s2, c2.keys[1], 'f ()')
1563 self._check_content(s2, c2.values[1], 'g ()')
1564
1565 def test_comprehensions(self):
1566 s = dedent('''
1567 x = [{x for x, y in stuff
1568 if cond.x} for stuff in things]
1569 ''').strip()
1570 cmp = self._parse_value(s)
1571 self._check_end_pos(cmp, 2, 37)
1572 self._check_content(s, cmp.generators[0].iter, 'things')
1573 self._check_content(s, cmp.elt.generators[0].iter, 'stuff')
1574 self._check_content(s, cmp.elt.generators[0].ifs[0], 'cond.x')
1575 self._check_content(s, cmp.elt.generators[0].target, 'x, y')
1576
1577 def test_yield_await(self):
1578 s = dedent('''
1579 async def f():
1580 yield x
1581 await y
1582 ''').strip()
1583 fdef = ast.parse(s).body[0]
1584 self._check_content(s, fdef.body[0].value, 'yield x')
1585 self._check_content(s, fdef.body[1].value, 'await y')
1586
1587 def test_source_segment_multi(self):
1588 s_orig = dedent('''
1589 x = (
1590 a, b,
1591 ) + ()
1592 ''').strip()
1593 s_tuple = dedent('''
1594 (
1595 a, b,
1596 )
1597 ''').strip()
1598 binop = self._parse_value(s_orig)
1599 self.assertEqual(ast.get_source_segment(s_orig, binop.left), s_tuple)
1600
1601 def test_source_segment_padded(self):
1602 s_orig = dedent('''
1603 class C:
1604 def fun(self) -> None:
1605 "ЖЖЖЖЖ"
1606 ''').strip()
1607 s_method = ' def fun(self) -> None:\n' \
1608 ' "ЖЖЖЖЖ"'
1609 cdef = ast.parse(s_orig).body[0]
1610 self.assertEqual(ast.get_source_segment(s_orig, cdef.body[0], padded=True),
1611 s_method)
1612
1613 def test_source_segment_endings(self):
1614 s = 'v = 1\r\nw = 1\nx = 1\n\ry = 1\rz = 1\r\n'
1615 v, w, x, y, z = ast.parse(s).body
1616 self._check_content(s, v, 'v = 1')
1617 self._check_content(s, w, 'w = 1')
1618 self._check_content(s, x, 'x = 1')
1619 self._check_content(s, y, 'y = 1')
1620 self._check_content(s, z, 'z = 1')
1621
1622 def test_source_segment_tabs(self):
1623 s = dedent('''
1624 class C:
1625 \t\f def fun(self) -> None:
1626 \t\f pass
1627 ''').strip()
1628 s_method = ' \t\f def fun(self) -> None:\n' \
1629 ' \t\f pass'
1630
1631 cdef = ast.parse(s).body[0]
1632 self.assertEqual(ast.get_source_segment(s, cdef.body[0], padded=True), s_method)
1633
1634
Neal Norwitzee9b10a2008-03-31 05:29:39 +00001635def main():
1636 if __name__ != '__main__':
Martin v. Löwis49c5da12006-03-01 22:49:05 +00001637 return
Neal Norwitzee9b10a2008-03-31 05:29:39 +00001638 if sys.argv[1:] == ['-g']:
1639 for statements, kind in ((exec_tests, "exec"), (single_tests, "single"),
1640 (eval_tests, "eval")):
1641 print(kind+"_results = [")
Victor Stinnerf0891962016-02-08 17:15:21 +01001642 for statement in statements:
1643 tree = ast.parse(statement, "?", kind)
1644 print("%r," % (to_tuple(tree),))
Neal Norwitzee9b10a2008-03-31 05:29:39 +00001645 print("]")
1646 print("main()")
1647 raise SystemExit
Brett Cannon3e9a9ae2013-06-12 21:25:59 -04001648 unittest.main()
Tim Peters400cbc32006-02-28 18:44:41 +00001649
Guido van Rossumdcfcd142019-01-31 03:40:27 -08001650#### EVERYTHING BELOW IS GENERATED BY python Lib/test/test_ast.py -g #####
Tim Peters400cbc32006-02-28 18:44:41 +00001651exec_results = [
Guido van Rossum10f8ce62019-03-13 13:00:46 -07001652('Module', [('Expr', (1, 0), ('Constant', (1, 0), None, None))], []),
1653('Module', [('Expr', (1, 0), ('Constant', (1, 0), 'module docstring', None))], []),
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01001654('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [], [], None, [], [], None, []), [('Pass', (1, 9))], [], None, None)], []),
1655('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [], [], None, [], [], None, []), [('Expr', (1, 9), ('Constant', (1, 9), 'function docstring', None))], [], None, None)], []),
1656('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [('arg', (1, 6), 'a', None, None)], [], None, [], [], None, []), [('Pass', (1, 10))], [], None, None)], []),
1657('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [('arg', (1, 6), 'a', None, None)], [], None, [], [], None, [('Constant', (1, 8), 0, None)]), [('Pass', (1, 12))], [], None, None)], []),
1658('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [], [], ('arg', (1, 7), 'args', None, None), [], [], None, []), [('Pass', (1, 14))], [], None, None)], []),
1659('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [], [], None, [], [], ('arg', (1, 8), 'kwargs', None, None), []), [('Pass', (1, 17))], [], None, None)], []),
1660('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [('arg', (1, 6), 'a', None, None), ('arg', (1, 9), 'b', None, None), ('arg', (1, 14), 'c', None, None), ('arg', (1, 22), 'd', None, None), ('arg', (1, 28), 'e', None, None)], [], ('arg', (1, 35), 'args', None, None), [('arg', (1, 41), 'f', None, None)], [('Constant', (1, 43), 42, None)], ('arg', (1, 49), 'kwargs', None, None), [('Constant', (1, 11), 1, None), ('Constant', (1, 16), None, None), ('List', (1, 24), [], ('Load',)), ('Dict', (1, 30), [], [])]), [('Expr', (1, 58), ('Constant', (1, 58), 'doc for f()', None))], [], None, None)], []),
Guido van Rossumdcfcd142019-01-31 03:40:27 -08001661('Module', [('ClassDef', (1, 0), 'C', [], [], [('Pass', (1, 8))], [])], []),
Guido van Rossum10f8ce62019-03-13 13:00:46 -07001662('Module', [('ClassDef', (1, 0), 'C', [], [], [('Expr', (1, 9), ('Constant', (1, 9), 'docstring for class C', None))], [])], []),
Guido van Rossumdcfcd142019-01-31 03:40:27 -08001663('Module', [('ClassDef', (1, 0), 'C', [('Name', (1, 8), 'object', ('Load',))], [], [('Pass', (1, 17))], [])], []),
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01001664('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [], [], None, [], [], None, []), [('Return', (1, 8), ('Constant', (1, 15), 1, None))], [], None, None)], []),
Guido van Rossumdcfcd142019-01-31 03:40:27 -08001665('Module', [('Delete', (1, 0), [('Name', (1, 4), 'v', ('Del',))])], []),
Guido van Rossum10f8ce62019-03-13 13:00:46 -07001666('Module', [('Assign', (1, 0), [('Name', (1, 0), 'v', ('Store',))], ('Constant', (1, 4), 1, None), None)], []),
Guido van Rossumdcfcd142019-01-31 03:40:27 -08001667('Module', [('Assign', (1, 0), [('Tuple', (1, 0), [('Name', (1, 0), 'a', ('Store',)), ('Name', (1, 2), 'b', ('Store',))], ('Store',))], ('Name', (1, 6), 'c', ('Load',)), None)], []),
1668('Module', [('Assign', (1, 0), [('Tuple', (1, 0), [('Name', (1, 1), 'a', ('Store',)), ('Name', (1, 3), 'b', ('Store',))], ('Store',))], ('Name', (1, 8), 'c', ('Load',)), None)], []),
1669('Module', [('Assign', (1, 0), [('List', (1, 0), [('Name', (1, 1), 'a', ('Store',)), ('Name', (1, 3), 'b', ('Store',))], ('Store',))], ('Name', (1, 8), 'c', ('Load',)), None)], []),
Guido van Rossum10f8ce62019-03-13 13:00:46 -07001670('Module', [('AugAssign', (1, 0), ('Name', (1, 0), 'v', ('Store',)), ('Add',), ('Constant', (1, 5), 1, None))], []),
Guido van Rossumdcfcd142019-01-31 03:40:27 -08001671('Module', [('For', (1, 0), ('Name', (1, 4), 'v', ('Store',)), ('Name', (1, 9), 'v', ('Load',)), [('Pass', (1, 11))], [], None)], []),
1672('Module', [('While', (1, 0), ('Name', (1, 6), 'v', ('Load',)), [('Pass', (1, 8))], [])], []),
1673('Module', [('If', (1, 0), ('Name', (1, 3), 'v', ('Load',)), [('Pass', (1, 5))], [])], []),
1674('Module', [('With', (1, 0), [('withitem', ('Name', (1, 5), 'x', ('Load',)), ('Name', (1, 10), 'y', ('Store',)))], [('Pass', (1, 13))], None)], []),
1675('Module', [('With', (1, 0), [('withitem', ('Name', (1, 5), 'x', ('Load',)), ('Name', (1, 10), 'y', ('Store',))), ('withitem', ('Name', (1, 13), 'z', ('Load',)), ('Name', (1, 18), 'q', ('Store',)))], [('Pass', (1, 21))], None)], []),
Guido van Rossum10f8ce62019-03-13 13:00:46 -07001676('Module', [('Raise', (1, 0), ('Call', (1, 6), ('Name', (1, 6), 'Exception', ('Load',)), [('Constant', (1, 16), 'string', None)], []), None)], []),
Guido van Rossumdcfcd142019-01-31 03:40:27 -08001677('Module', [('Try', (1, 0), [('Pass', (2, 2))], [('ExceptHandler', (3, 0), ('Name', (3, 7), 'Exception', ('Load',)), None, [('Pass', (4, 2))])], [], [])], []),
1678('Module', [('Try', (1, 0), [('Pass', (2, 2))], [], [], [('Pass', (4, 2))])], []),
1679('Module', [('Assert', (1, 0), ('Name', (1, 7), 'v', ('Load',)), None)], []),
1680('Module', [('Import', (1, 0), [('alias', 'sys', None)])], []),
1681('Module', [('ImportFrom', (1, 0), 'sys', [('alias', 'v', None)], 0)], []),
1682('Module', [('Global', (1, 0), ['v'])], []),
Guido van Rossum10f8ce62019-03-13 13:00:46 -07001683('Module', [('Expr', (1, 0), ('Constant', (1, 0), 1, None))], []),
Guido van Rossumdcfcd142019-01-31 03:40:27 -08001684('Module', [('Pass', (1, 0))], []),
1685('Module', [('For', (1, 0), ('Name', (1, 4), 'v', ('Store',)), ('Name', (1, 9), 'v', ('Load',)), [('Break', (1, 11))], [], None)], []),
1686('Module', [('For', (1, 0), ('Name', (1, 4), 'v', ('Store',)), ('Name', (1, 9), 'v', ('Load',)), [('Continue', (1, 11))], [], None)], []),
1687('Module', [('For', (1, 0), ('Tuple', (1, 4), [('Name', (1, 4), 'a', ('Store',)), ('Name', (1, 6), 'b', ('Store',))], ('Store',)), ('Name', (1, 11), 'c', ('Load',)), [('Pass', (1, 14))], [], None)], []),
1688('Module', [('For', (1, 0), ('Tuple', (1, 4), [('Name', (1, 5), 'a', ('Store',)), ('Name', (1, 7), 'b', ('Store',))], ('Store',)), ('Name', (1, 13), 'c', ('Load',)), [('Pass', (1, 16))], [], None)], []),
1689('Module', [('For', (1, 0), ('List', (1, 4), [('Name', (1, 5), 'a', ('Store',)), ('Name', (1, 7), 'b', ('Store',))], ('Store',)), ('Name', (1, 13), 'c', ('Load',)), [('Pass', (1, 16))], [], None)], []),
1690('Module', [('Expr', (1, 0), ('GeneratorExp', (1, 0), ('Tuple', (2, 4), [('Name', (3, 4), 'Aa', ('Load',)), ('Name', (5, 7), 'Bb', ('Load',))], ('Load',)), [('comprehension', ('Tuple', (8, 4), [('Name', (8, 4), 'Aa', ('Store',)), ('Name', (10, 4), 'Bb', ('Store',))], ('Store',)), ('Name', (10, 10), 'Cc', ('Load',)), [], 0)]))], []),
1691('Module', [('Expr', (1, 0), ('DictComp', (1, 0), ('Name', (1, 1), 'a', ('Load',)), ('Name', (1, 5), 'b', ('Load',)), [('comprehension', ('Name', (1, 11), 'w', ('Store',)), ('Name', (1, 16), 'x', ('Load',)), [], 0), ('comprehension', ('Name', (1, 22), 'm', ('Store',)), ('Name', (1, 27), 'p', ('Load',)), [('Name', (1, 32), 'g', ('Load',))], 0)]))], []),
1692('Module', [('Expr', (1, 0), ('DictComp', (1, 0), ('Name', (1, 1), 'a', ('Load',)), ('Name', (1, 5), 'b', ('Load',)), [('comprehension', ('Tuple', (1, 11), [('Name', (1, 11), 'v', ('Store',)), ('Name', (1, 13), 'w', ('Store',))], ('Store',)), ('Name', (1, 18), 'x', ('Load',)), [], 0)]))], []),
1693('Module', [('Expr', (1, 0), ('SetComp', (1, 0), ('Name', (1, 1), 'r', ('Load',)), [('comprehension', ('Name', (1, 7), 'l', ('Store',)), ('Name', (1, 12), 'x', ('Load',)), [('Name', (1, 17), 'g', ('Load',))], 0)]))], []),
1694('Module', [('Expr', (1, 0), ('SetComp', (1, 0), ('Name', (1, 1), 'r', ('Load',)), [('comprehension', ('Tuple', (1, 7), [('Name', (1, 7), 'l', ('Store',)), ('Name', (1, 9), 'm', ('Store',))], ('Store',)), ('Name', (1, 14), 'x', ('Load',)), [], 0)]))], []),
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01001695('Module', [('AsyncFunctionDef', (1, 0), 'f', ('arguments', [], [], None, [], [], None, []), [('Expr', (2, 1), ('Constant', (2, 1), 'async function', None)), ('Expr', (3, 1), ('Await', (3, 1), ('Call', (3, 7), ('Name', (3, 7), 'something', ('Load',)), [], [])))], [], None, None)], []),
1696('Module', [('AsyncFunctionDef', (1, 0), 'f', ('arguments', [], [], None, [], [], None, []), [('AsyncFor', (2, 1), ('Name', (2, 11), 'e', ('Store',)), ('Name', (2, 16), 'i', ('Load',)), [('Expr', (2, 19), ('Constant', (2, 19), 1, None))], [('Expr', (3, 7), ('Constant', (3, 7), 2, None))], None)], [], None, None)], []),
1697('Module', [('AsyncFunctionDef', (1, 0), 'f', ('arguments', [], [], None, [], [], None, []), [('AsyncWith', (2, 1), [('withitem', ('Name', (2, 12), 'a', ('Load',)), ('Name', (2, 17), 'b', ('Store',)))], [('Expr', (2, 20), ('Constant', (2, 20), 1, None))], None)], [], None, None)], []),
Guido van Rossum10f8ce62019-03-13 13:00:46 -07001698('Module', [('Expr', (1, 0), ('Dict', (1, 0), [None, ('Constant', (1, 10), 2, None)], [('Dict', (1, 3), [('Constant', (1, 4), 1, None)], [('Constant', (1, 6), 2, None)]), ('Constant', (1, 12), 3, None)]))], []),
1699('Module', [('Expr', (1, 0), ('Set', (1, 0), [('Starred', (1, 1), ('Set', (1, 2), [('Constant', (1, 3), 1, None), ('Constant', (1, 6), 2, None)]), ('Load',)), ('Constant', (1, 10), 3, None)]))], []),
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01001700('Module', [('AsyncFunctionDef', (1, 0), 'f', ('arguments', [], [], None, [], [], None, []), [('Expr', (2, 1), ('ListComp', (2, 1), ('Name', (2, 2), 'i', ('Load',)), [('comprehension', ('Name', (2, 14), 'b', ('Store',)), ('Name', (2, 19), 'c', ('Load',)), [], 1)]))], [], None, None)], []),
1701('Module', [('FunctionDef', (3, 0), 'f', ('arguments', [], [], None, [], [], None, []), [('Pass', (3, 9))], [('Name', (1, 1), 'deco1', ('Load',)), ('Call', (2, 0), ('Name', (2, 1), 'deco2', ('Load',)), [], [])], None, None)], []),
1702('Module', [('AsyncFunctionDef', (3, 0), 'f', ('arguments', [], [], None, [], [], None, []), [('Pass', (3, 15))], [('Name', (1, 1), 'deco1', ('Load',)), ('Call', (2, 0), ('Name', (2, 1), 'deco2', ('Load',)), [], [])], None, None)], []),
Guido van Rossumdcfcd142019-01-31 03:40:27 -08001703('Module', [('ClassDef', (3, 0), 'C', [], [], [('Pass', (3, 9))], [('Name', (1, 1), 'deco1', ('Load',)), ('Call', (2, 0), ('Name', (2, 1), 'deco2', ('Load',)), [], [])])], []),
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01001704('Module', [('FunctionDef', (2, 0), 'f', ('arguments', [], [], None, [], [], None, []), [('Pass', (2, 9))], [('Call', (1, 1), ('Name', (1, 1), 'deco', ('Load',)), [('GeneratorExp', (1, 5), ('Name', (1, 6), 'a', ('Load',)), [('comprehension', ('Name', (1, 12), 'a', ('Store',)), ('Name', (1, 17), 'b', ('Load',)), [], 0)])], [])], None, None)], []),
Pablo Galindo0c9258a2019-03-18 13:51:53 +00001705('Module', [('Expr', (1, 0), ('NamedExpr', (1, 1), ('Name', (1, 1), 'a', ('Store',)), ('Constant', (1, 6), 1, None)))], []),
Pablo Galindo2f58a842019-05-31 14:09:49 +01001706('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [], [('arg', (1, 6), 'a', None, None)], None, [], [], None, []), [('Pass', (1, 14))], [], None, None)], []),
1707('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [('arg', (1, 12), 'c', None, None), ('arg', (1, 15), 'd', None, None), ('arg', (1, 18), 'e', None, None)], [('arg', (1, 6), 'a', None, None)], None, [], [], None, []), [('Pass', (1, 22))], [], None, None)], []),
1708('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [('arg', (1, 12), 'c', None, None)], [('arg', (1, 6), 'a', None, None)], None, [('arg', (1, 18), 'd', None, None), ('arg', (1, 21), 'e', None, None)], [None, None], None, []), [('Pass', (1, 25))], [], None, None)], []),
1709('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [('arg', (1, 12), 'c', None, None)], [('arg', (1, 6), 'a', None, None)], None, [('arg', (1, 18), 'd', None, None), ('arg', (1, 21), 'e', None, None)], [None, None], ('arg', (1, 26), 'kwargs', None, None), []), [('Pass', (1, 35))], [], None, None)], []),
1710('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [], [('arg', (1, 6), 'a', None, None)], None, [], [], None, [('Constant', (1, 8), 1, None)]), [('Pass', (1, 16))], [], None, None)], []),
1711('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [('arg', (1, 14), 'b', None, None), ('arg', (1, 19), 'c', None, None)], [('arg', (1, 6), 'a', None, None)], None, [], [], None, [('Constant', (1, 8), 1, None), ('Constant', (1, 16), 2, None), ('Constant', (1, 21), 4, None)]), [('Pass', (1, 25))], [], None, None)], []),
1712('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [('arg', (1, 14), 'b', None, None)], [('arg', (1, 6), 'a', None, None)], None, [('arg', (1, 22), 'c', None, None)], [('Constant', (1, 24), 4, None)], None, [('Constant', (1, 8), 1, None), ('Constant', (1, 16), 2, None)]), [('Pass', (1, 28))], [], None, None)], []),
1713('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [('arg', (1, 14), 'b', None, None)], [('arg', (1, 6), 'a', None, None)], None, [('arg', (1, 22), 'c', None, None)], [None], None, [('Constant', (1, 8), 1, None), ('Constant', (1, 16), 2, None)]), [('Pass', (1, 26))], [], None, None)], []),
1714('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [('arg', (1, 14), 'b', None, None)], [('arg', (1, 6), 'a', None, None)], None, [('arg', (1, 22), 'c', None, None)], [('Constant', (1, 24), 4, None)], ('arg', (1, 29), 'kwargs', None, None), [('Constant', (1, 8), 1, None), ('Constant', (1, 16), 2, None)]), [('Pass', (1, 38))], [], None, None)], []),
1715('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [('arg', (1, 14), 'b', None, None)], [('arg', (1, 6), 'a', None, None)], None, [('arg', (1, 22), 'c', None, None)], [None], ('arg', (1, 27), 'kwargs', None, None), [('Constant', (1, 8), 1, None), ('Constant', (1, 16), 2, None)]), [('Pass', (1, 36))], [], None, None)], []),
Tim Peters400cbc32006-02-28 18:44:41 +00001716]
1717single_results = [
Guido van Rossum10f8ce62019-03-13 13:00:46 -07001718('Interactive', [('Expr', (1, 0), ('BinOp', (1, 0), ('Constant', (1, 0), 1, None), ('Add',), ('Constant', (1, 2), 2, None)))]),
Tim Peters400cbc32006-02-28 18:44:41 +00001719]
1720eval_results = [
Guido van Rossum10f8ce62019-03-13 13:00:46 -07001721('Expression', ('Constant', (1, 0), None, None)),
Martin v. Löwis49c5da12006-03-01 22:49:05 +00001722('Expression', ('BoolOp', (1, 0), ('And',), [('Name', (1, 0), 'a', ('Load',)), ('Name', (1, 6), 'b', ('Load',))])),
1723('Expression', ('BinOp', (1, 0), ('Name', (1, 0), 'a', ('Load',)), ('Add',), ('Name', (1, 4), 'b', ('Load',)))),
1724('Expression', ('UnaryOp', (1, 0), ('Not',), ('Name', (1, 4), 'v', ('Load',)))),
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01001725('Expression', ('Lambda', (1, 0), ('arguments', [], [], None, [], [], None, []), ('Constant', (1, 7), None, None))),
Guido van Rossum10f8ce62019-03-13 13:00:46 -07001726('Expression', ('Dict', (1, 0), [('Constant', (1, 2), 1, None)], [('Constant', (1, 4), 2, None)])),
Benjamin Peterson6ccfe852011-06-27 17:46:06 -05001727('Expression', ('Dict', (1, 0), [], [])),
Guido van Rossum10f8ce62019-03-13 13:00:46 -07001728('Expression', ('Set', (1, 0), [('Constant', (1, 1), None, None)])),
1729('Expression', ('Dict', (1, 0), [('Constant', (2, 6), 1, None)], [('Constant', (4, 10), 2, None)])),
Serhiy Storchakab619b092018-11-27 09:40:29 +02001730('Expression', ('ListComp', (1, 0), ('Name', (1, 1), 'a', ('Load',)), [('comprehension', ('Name', (1, 7), 'b', ('Store',)), ('Name', (1, 12), 'c', ('Load',)), [('Name', (1, 17), 'd', ('Load',))], 0)])),
1731('Expression', ('GeneratorExp', (1, 0), ('Name', (1, 1), 'a', ('Load',)), [('comprehension', ('Name', (1, 7), 'b', ('Store',)), ('Name', (1, 12), 'c', ('Load',)), [('Name', (1, 17), 'd', ('Load',))], 0)])),
1732('Expression', ('ListComp', (1, 0), ('Tuple', (1, 1), [('Name', (1, 2), 'a', ('Load',)), ('Name', (1, 4), 'b', ('Load',))], ('Load',)), [('comprehension', ('Tuple', (1, 11), [('Name', (1, 11), 'a', ('Store',)), ('Name', (1, 13), 'b', ('Store',))], ('Store',)), ('Name', (1, 18), 'c', ('Load',)), [], 0)])),
1733('Expression', ('ListComp', (1, 0), ('Tuple', (1, 1), [('Name', (1, 2), 'a', ('Load',)), ('Name', (1, 4), 'b', ('Load',))], ('Load',)), [('comprehension', ('Tuple', (1, 11), [('Name', (1, 12), 'a', ('Store',)), ('Name', (1, 14), 'b', ('Store',))], ('Store',)), ('Name', (1, 20), 'c', ('Load',)), [], 0)])),
1734('Expression', ('ListComp', (1, 0), ('Tuple', (1, 1), [('Name', (1, 2), 'a', ('Load',)), ('Name', (1, 4), 'b', ('Load',))], ('Load',)), [('comprehension', ('List', (1, 11), [('Name', (1, 12), 'a', ('Store',)), ('Name', (1, 14), 'b', ('Store',))], ('Store',)), ('Name', (1, 20), 'c', ('Load',)), [], 0)])),
1735('Expression', ('SetComp', (1, 0), ('Tuple', (1, 1), [('Name', (1, 2), 'a', ('Load',)), ('Name', (1, 4), 'b', ('Load',))], ('Load',)), [('comprehension', ('Tuple', (1, 11), [('Name', (1, 11), 'a', ('Store',)), ('Name', (1, 13), 'b', ('Store',))], ('Store',)), ('Name', (1, 18), 'c', ('Load',)), [], 0)])),
1736('Expression', ('SetComp', (1, 0), ('Tuple', (1, 1), [('Name', (1, 2), 'a', ('Load',)), ('Name', (1, 4), 'b', ('Load',))], ('Load',)), [('comprehension', ('Tuple', (1, 11), [('Name', (1, 12), 'a', ('Store',)), ('Name', (1, 14), 'b', ('Store',))], ('Store',)), ('Name', (1, 20), 'c', ('Load',)), [], 0)])),
1737('Expression', ('SetComp', (1, 0), ('Tuple', (1, 1), [('Name', (1, 2), 'a', ('Load',)), ('Name', (1, 4), 'b', ('Load',))], ('Load',)), [('comprehension', ('List', (1, 11), [('Name', (1, 12), 'a', ('Store',)), ('Name', (1, 14), 'b', ('Store',))], ('Store',)), ('Name', (1, 20), 'c', ('Load',)), [], 0)])),
1738('Expression', ('GeneratorExp', (1, 0), ('Tuple', (1, 1), [('Name', (1, 2), 'a', ('Load',)), ('Name', (1, 4), 'b', ('Load',))], ('Load',)), [('comprehension', ('Tuple', (1, 11), [('Name', (1, 11), 'a', ('Store',)), ('Name', (1, 13), 'b', ('Store',))], ('Store',)), ('Name', (1, 18), 'c', ('Load',)), [], 0)])),
1739('Expression', ('GeneratorExp', (1, 0), ('Tuple', (1, 1), [('Name', (1, 2), 'a', ('Load',)), ('Name', (1, 4), 'b', ('Load',))], ('Load',)), [('comprehension', ('Tuple', (1, 11), [('Name', (1, 12), 'a', ('Store',)), ('Name', (1, 14), 'b', ('Store',))], ('Store',)), ('Name', (1, 20), 'c', ('Load',)), [], 0)])),
1740('Expression', ('GeneratorExp', (1, 0), ('Tuple', (1, 1), [('Name', (1, 2), 'a', ('Load',)), ('Name', (1, 4), 'b', ('Load',))], ('Load',)), [('comprehension', ('List', (1, 11), [('Name', (1, 12), 'a', ('Store',)), ('Name', (1, 14), 'b', ('Store',))], ('Store',)), ('Name', (1, 20), 'c', ('Load',)), [], 0)])),
Guido van Rossum10f8ce62019-03-13 13:00:46 -07001741('Expression', ('Compare', (1, 0), ('Constant', (1, 0), 1, None), [('Lt',), ('Lt',)], [('Constant', (1, 4), 2, None), ('Constant', (1, 8), 3, None)])),
1742('Expression', ('Call', (1, 0), ('Name', (1, 0), 'f', ('Load',)), [('Constant', (1, 2), 1, None), ('Constant', (1, 4), 2, None), ('Starred', (1, 10), ('Name', (1, 11), 'd', ('Load',)), ('Load',))], [('keyword', 'c', ('Constant', (1, 8), 3, None)), ('keyword', None, ('Name', (1, 15), 'e', ('Load',)))])),
Serhiy Storchakab619b092018-11-27 09:40:29 +02001743('Expression', ('Call', (1, 0), ('Name', (1, 0), 'f', ('Load',)), [('GeneratorExp', (1, 1), ('Name', (1, 2), 'a', ('Load',)), [('comprehension', ('Name', (1, 8), 'a', ('Store',)), ('Name', (1, 13), 'b', ('Load',)), [], 0)])], [])),
Guido van Rossum10f8ce62019-03-13 13:00:46 -07001744('Expression', ('Constant', (1, 0), 10, None)),
1745('Expression', ('Constant', (1, 0), 'string', None)),
Benjamin Peterson7a66fc22015-02-02 10:51:20 -05001746('Expression', ('Attribute', (1, 0), ('Name', (1, 0), 'a', ('Load',)), 'b', ('Load',))),
1747('Expression', ('Subscript', (1, 0), ('Name', (1, 0), 'a', ('Load',)), ('Slice', ('Name', (1, 2), 'b', ('Load',)), ('Name', (1, 4), 'c', ('Load',)), None), ('Load',))),
Martin v. Löwis49c5da12006-03-01 22:49:05 +00001748('Expression', ('Name', (1, 0), 'v', ('Load',))),
Guido van Rossum10f8ce62019-03-13 13:00:46 -07001749('Expression', ('List', (1, 0), [('Constant', (1, 1), 1, None), ('Constant', (1, 3), 2, None), ('Constant', (1, 5), 3, None)], ('Load',))),
Benjamin Peterson6ccfe852011-06-27 17:46:06 -05001750('Expression', ('List', (1, 0), [], ('Load',))),
Guido van Rossum10f8ce62019-03-13 13:00:46 -07001751('Expression', ('Tuple', (1, 0), [('Constant', (1, 0), 1, None), ('Constant', (1, 2), 2, None), ('Constant', (1, 4), 3, None)], ('Load',))),
1752('Expression', ('Tuple', (1, 0), [('Constant', (1, 1), 1, None), ('Constant', (1, 3), 2, None), ('Constant', (1, 5), 3, None)], ('Load',))),
Benjamin Peterson6ccfe852011-06-27 17:46:06 -05001753('Expression', ('Tuple', (1, 0), [], ('Load',))),
Guido van Rossum10f8ce62019-03-13 13:00:46 -07001754('Expression', ('Call', (1, 0), ('Attribute', (1, 0), ('Attribute', (1, 0), ('Attribute', (1, 0), ('Name', (1, 0), 'a', ('Load',)), 'b', ('Load',)), 'c', ('Load',)), 'd', ('Load',)), [('Subscript', (1, 8), ('Attribute', (1, 8), ('Name', (1, 8), 'a', ('Load',)), 'b', ('Load',)), ('Slice', ('Constant', (1, 12), 1, None), ('Constant', (1, 14), 2, None), None), ('Load',))], [])),
Tim Peters400cbc32006-02-28 18:44:41 +00001755]
Neal Norwitzee9b10a2008-03-31 05:29:39 +00001756main()