blob: 2ed4657822e54c45274a0e9768b4fc622f6bb75f [file] [log] [blame]
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001import ast
2import dis
Benjamin Peterson832bfe22011-08-09 16:15:04 -05003import os
4import sys
5import unittest
Serhiy Storchakac3ea41e2019-08-26 10:13:19 +03006import warnings
Benjamin Peterson9ed37432012-07-08 11:13:36 -07007import weakref
Ivan Levkivskyi9932a222019-01-22 11:18:22 +00008from textwrap import dedent
Benjamin Peterson9ed37432012-07-08 11:13:36 -07009
10from test import support
Tim Peters400cbc32006-02-28 18:44:41 +000011
12def to_tuple(t):
Guido van Rossum3172c5d2007-10-16 18:12:55 +000013 if t is None or isinstance(t, (str, int, complex)):
Tim Peters400cbc32006-02-28 18:44:41 +000014 return t
15 elif isinstance(t, list):
16 return [to_tuple(e) for e in t]
17 result = [t.__class__.__name__]
Martin v. Löwis49c5da12006-03-01 22:49:05 +000018 if hasattr(t, 'lineno') and hasattr(t, 'col_offset'):
19 result.append((t.lineno, t.col_offset))
Serhiy Storchaka850a8852020-01-10 10:12:55 +020020 if hasattr(t, 'end_lineno') and hasattr(t, 'end_col_offset'):
21 result[-1] += (t.end_lineno, t.end_col_offset)
Tim Peters400cbc32006-02-28 18:44:41 +000022 if t._fields is None:
23 return tuple(result)
24 for f in t._fields:
25 result.append(to_tuple(getattr(t, f)))
26 return tuple(result)
27
Neal Norwitzee9b10a2008-03-31 05:29:39 +000028
Tim Peters400cbc32006-02-28 18:44:41 +000029# These tests are compiled through "exec"
Ezio Melotti85a86292013-08-17 16:57:41 +030030# There should be at least one test per statement
Tim Peters400cbc32006-02-28 18:44:41 +000031exec_tests = [
Benjamin Peterson6ccfe852011-06-27 17:46:06 -050032 # None
33 "None",
INADA Naokicb41b272017-02-23 00:31:59 +090034 # Module docstring
35 "'module docstring'",
Tim Peters400cbc32006-02-28 18:44:41 +000036 # FunctionDef
37 "def f(): pass",
INADA Naokicb41b272017-02-23 00:31:59 +090038 # FunctionDef with docstring
39 "def f(): 'function docstring'",
Benjamin Peterson6ccfe852011-06-27 17:46:06 -050040 # FunctionDef with arg
41 "def f(a): pass",
42 # FunctionDef with arg and default value
43 "def f(a=0): pass",
44 # FunctionDef with varargs
45 "def f(*args): pass",
46 # FunctionDef with kwargs
47 "def f(**kwargs): pass",
INADA Naokicb41b272017-02-23 00:31:59 +090048 # FunctionDef with all kind of args and docstring
49 "def f(a, b=1, c=None, d=[], e={}, *args, f=42, **kwargs): 'doc for f()'",
Tim Peters400cbc32006-02-28 18:44:41 +000050 # ClassDef
51 "class C:pass",
INADA Naokicb41b272017-02-23 00:31:59 +090052 # ClassDef with docstring
53 "class C: 'docstring for class C'",
Benjamin Peterson6ccfe852011-06-27 17:46:06 -050054 # ClassDef, new style class
55 "class C(object): pass",
Tim Peters400cbc32006-02-28 18:44:41 +000056 # Return
57 "def f():return 1",
58 # Delete
59 "del v",
60 # Assign
61 "v = 1",
Serhiy Storchakab619b092018-11-27 09:40:29 +020062 "a,b = c",
63 "(a,b) = c",
64 "[a,b] = c",
Tim Peters400cbc32006-02-28 18:44:41 +000065 # AugAssign
66 "v += 1",
Tim Peters400cbc32006-02-28 18:44:41 +000067 # For
68 "for v in v:pass",
69 # While
70 "while v:pass",
71 # If
72 "if v:pass",
Lysandros Nikolaou025a6022019-12-12 22:40:21 +010073 # If-Elif
74 "if a:\n pass\nelif b:\n pass",
Lysandros Nikolaou5936a4c2019-12-14 11:24:57 +010075 # If-Elif-Else
76 "if a:\n pass\nelif b:\n pass\nelse:\n pass",
Benjamin Petersonaeabd5f2011-05-27 15:02:03 -050077 # With
78 "with x as y: pass",
79 "with x as y, z as q: pass",
Tim Peters400cbc32006-02-28 18:44:41 +000080 # Raise
Collin Winter828f04a2007-08-31 00:04:24 +000081 "raise Exception('string')",
Tim Peters400cbc32006-02-28 18:44:41 +000082 # TryExcept
83 "try:\n pass\nexcept Exception:\n pass",
84 # TryFinally
85 "try:\n pass\nfinally:\n pass",
86 # Assert
87 "assert v",
88 # Import
89 "import sys",
90 # ImportFrom
91 "from sys import v",
Tim Peters400cbc32006-02-28 18:44:41 +000092 # Global
93 "global v",
94 # Expr
95 "1",
96 # Pass,
97 "pass",
98 # Break
Yury Selivanovb3d53132015-09-01 16:10:49 -040099 "for v in v:break",
Tim Peters400cbc32006-02-28 18:44:41 +0000100 # Continue
Yury Selivanovb3d53132015-09-01 16:10:49 -0400101 "for v in v:continue",
Benjamin Peterson2e4b0e12009-09-11 22:36:20 +0000102 # for statements with naked tuples (see http://bugs.python.org/issue6704)
103 "for a,b in c: pass",
Serhiy Storchakab619b092018-11-27 09:40:29 +0200104 "for (a,b) in c: pass",
105 "for [a,b] in c: pass",
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500106 # Multiline generator expression (test for .lineno & .col_offset)
107 """(
108 (
109 Aa
110 ,
111 Bb
112 )
113 for
114 Aa
115 ,
116 Bb in Cc
117 )""",
118 # dictcomp
119 "{a : b for w in x for m in p if g}",
120 # dictcomp with naked tuple
121 "{a : b for v,w in x}",
122 # setcomp
123 "{r for l in x if g}",
124 # setcomp with naked tuple
125 "{r for l,m in x}",
Yury Selivanov75445082015-05-11 22:57:16 -0400126 # AsyncFunctionDef
INADA Naokicb41b272017-02-23 00:31:59 +0900127 "async def f():\n 'async function'\n await something()",
Yury Selivanov75445082015-05-11 22:57:16 -0400128 # AsyncFor
129 "async def f():\n async for e in i: 1\n else: 2",
130 # AsyncWith
131 "async def f():\n async with a as b: 1",
Yury Selivanovb3d53132015-09-01 16:10:49 -0400132 # PEP 448: Additional Unpacking Generalizations
133 "{**{1:2}, 2:3}",
134 "{*{1, 2}, 3}",
Yury Selivanov52c4e7c2016-09-09 10:36:01 -0700135 # Asynchronous comprehensions
136 "async def f():\n [i async for b in c]",
Serhiy Storchaka95b6acf2018-10-30 13:16:02 +0200137 # Decorated FunctionDef
Serhiy Storchaka26ae9f62019-10-26 16:46:05 +0300138 "@deco1\n@deco2()\n@deco3(1)\ndef f(): pass",
Serhiy Storchaka95b6acf2018-10-30 13:16:02 +0200139 # Decorated AsyncFunctionDef
Serhiy Storchaka26ae9f62019-10-26 16:46:05 +0300140 "@deco1\n@deco2()\n@deco3(1)\nasync def f(): pass",
Serhiy Storchaka95b6acf2018-10-30 13:16:02 +0200141 # Decorated ClassDef
Serhiy Storchaka26ae9f62019-10-26 16:46:05 +0300142 "@deco1\n@deco2()\n@deco3(1)\nclass C: pass",
Serhiy Storchakab619b092018-11-27 09:40:29 +0200143 # Decorator with generator argument
144 "@deco(a for a in b)\ndef f(): pass",
Lysandros Nikolaoud2e10982020-02-08 00:36:32 +0100145 # Decorator with attribute
146 "@a.b.c\ndef f(): pass",
Pablo Galindo0c9258a2019-03-18 13:51:53 +0000147 # Simple assignment expression
148 "(a := 1)",
Pablo Galindo2f58a842019-05-31 14:09:49 +0100149 # Positional-only arguments
150 "def f(a, /,): pass",
151 "def f(a, /, c, d, e): pass",
152 "def f(a, /, c, *, d, e): pass",
153 "def f(a, /, c, *, d, e, **kwargs): pass",
154 # Positional-only arguments with defaults
155 "def f(a=1, /,): pass",
156 "def f(a=1, /, b=2, c=4): pass",
157 "def f(a=1, /, b=2, *, c=4): pass",
158 "def f(a=1, /, b=2, *, c): pass",
159 "def f(a=1, /, b=2, *, c=4, **kwargs): pass",
160 "def f(a=1, /, b=2, *, c, **kwargs): pass",
Pablo Galindo0c9258a2019-03-18 13:51:53 +0000161
Tim Peters400cbc32006-02-28 18:44:41 +0000162]
163
164# These are compiled through "single"
165# because of overlap with "eval", it just tests what
166# can't be tested with "eval"
167single_tests = [
168 "1+2"
169]
170
171# These are compiled through "eval"
172# It should test all expressions
173eval_tests = [
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500174 # None
175 "None",
Tim Peters400cbc32006-02-28 18:44:41 +0000176 # BoolOp
177 "a and b",
178 # BinOp
179 "a + b",
180 # UnaryOp
181 "not v",
182 # Lambda
183 "lambda:None",
184 # Dict
185 "{ 1:2 }",
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500186 # Empty dict
187 "{}",
188 # Set
189 "{None,}",
190 # Multiline dict (test for .lineno & .col_offset)
191 """{
192 1
193 :
194 2
195 }""",
Tim Peters400cbc32006-02-28 18:44:41 +0000196 # ListComp
197 "[a for b in c if d]",
198 # GeneratorExp
199 "(a for b in c if d)",
Serhiy Storchakab619b092018-11-27 09:40:29 +0200200 # Comprehensions with multiple for targets
201 "[(a,b) for a,b in c]",
202 "[(a,b) for (a,b) in c]",
203 "[(a,b) for [a,b] in c]",
204 "{(a,b) for a,b in c}",
205 "{(a,b) for (a,b) in c}",
206 "{(a,b) for [a,b] in c}",
207 "((a,b) for a,b in c)",
208 "((a,b) for (a,b) in c)",
209 "((a,b) for [a,b] in c)",
Tim Peters400cbc32006-02-28 18:44:41 +0000210 # Yield - yield expressions can't work outside a function
211 #
212 # Compare
213 "1 < 2 < 3",
214 # Call
215 "f(1,2,c=3,*d,**e)",
Lysandros Nikolaou50d4f122019-12-18 01:20:55 +0100216 # Call with multi-character starred
217 "f(*[0, 1])",
Serhiy Storchakab619b092018-11-27 09:40:29 +0200218 # Call with a generator argument
219 "f(a for a in b)",
Tim Peters400cbc32006-02-28 18:44:41 +0000220 # Num
Guido van Rossume2a383d2007-01-15 16:59:06 +0000221 "10",
Tim Peters400cbc32006-02-28 18:44:41 +0000222 # Str
223 "'string'",
224 # Attribute
225 "a.b",
226 # Subscript
227 "a[b:c]",
228 # Name
229 "v",
230 # List
231 "[1,2,3]",
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500232 # Empty list
233 "[]",
Tim Peters400cbc32006-02-28 18:44:41 +0000234 # Tuple
Martin v. Löwis49c5da12006-03-01 22:49:05 +0000235 "1,2,3",
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500236 # Tuple
237 "(1,2,3)",
238 # Empty tuple
239 "()",
Martin v. Löwis49c5da12006-03-01 22:49:05 +0000240 # Combination
241 "a.b.c.d(a.b[1:2])",
242
Tim Peters400cbc32006-02-28 18:44:41 +0000243]
244
245# TODO: expr_context, slice, boolop, operator, unaryop, cmpop, comprehension
246# excepthandler, arguments, keywords, alias
247
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000248class AST_Tests(unittest.TestCase):
Tim Peters400cbc32006-02-28 18:44:41 +0000249
Benjamin Peterson7a66fc22015-02-02 10:51:20 -0500250 def _assertTrueorder(self, ast_node, parent_pos):
Georg Brandl0c77a822008-06-10 16:37:50 +0000251 if not isinstance(ast_node, ast.AST) or ast_node._fields is None:
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000252 return
Georg Brandl0c77a822008-06-10 16:37:50 +0000253 if isinstance(ast_node, (ast.expr, ast.stmt, ast.excepthandler)):
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000254 node_pos = (ast_node.lineno, ast_node.col_offset)
Serhiy Storchaka95b6acf2018-10-30 13:16:02 +0200255 self.assertGreaterEqual(node_pos, parent_pos)
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000256 parent_pos = (ast_node.lineno, ast_node.col_offset)
257 for name in ast_node._fields:
258 value = getattr(ast_node, name)
259 if isinstance(value, list):
Serhiy Storchaka95b6acf2018-10-30 13:16:02 +0200260 first_pos = parent_pos
261 if value and name == 'decorator_list':
262 first_pos = (value[0].lineno, value[0].col_offset)
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000263 for child in value:
Serhiy Storchaka95b6acf2018-10-30 13:16:02 +0200264 self._assertTrueorder(child, first_pos)
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000265 elif value is not None:
Benjamin Peterson7a66fc22015-02-02 10:51:20 -0500266 self._assertTrueorder(value, parent_pos)
Tim Peters5ddfe412006-03-01 23:02:57 +0000267
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500268 def test_AST_objects(self):
269 x = ast.AST()
270 self.assertEqual(x._fields, ())
Benjamin Peterson7e0dbfb2012-03-12 09:46:44 -0700271 x.foobar = 42
272 self.assertEqual(x.foobar, 42)
273 self.assertEqual(x.__dict__["foobar"], 42)
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500274
275 with self.assertRaises(AttributeError):
276 x.vararg
277
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500278 with self.assertRaises(TypeError):
279 # "_ast.AST constructor takes 0 positional arguments"
280 ast.AST(2)
281
Benjamin Peterson9ed37432012-07-08 11:13:36 -0700282 def test_AST_garbage_collection(self):
283 class X:
284 pass
285 a = ast.AST()
286 a.x = X()
287 a.x.a = a
288 ref = weakref.ref(a.x)
289 del a
290 support.gc_collect()
291 self.assertIsNone(ref())
292
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000293 def test_snippets(self):
294 for input, output, kind in ((exec_tests, exec_results, "exec"),
295 (single_tests, single_results, "single"),
296 (eval_tests, eval_results, "eval")):
297 for i, o in zip(input, output):
Yury Selivanovb3d53132015-09-01 16:10:49 -0400298 with self.subTest(action="parsing", input=i):
299 ast_tree = compile(i, "?", kind, ast.PyCF_ONLY_AST)
300 self.assertEqual(to_tuple(ast_tree), o)
301 self._assertTrueorder(ast_tree, (0, 0))
Victor Stinner15a30952016-02-08 22:45:06 +0100302 with self.subTest(action="compiling", input=i, kind=kind):
303 compile(ast_tree, "?", kind)
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000304
Pablo Galindo0c9258a2019-03-18 13:51:53 +0000305 def test_ast_validation(self):
306 # compile() is the only function that calls PyAST_Validate
307 snippets_to_validate = exec_tests + single_tests + eval_tests
308 for snippet in snippets_to_validate:
309 tree = ast.parse(snippet)
310 compile(tree, '<string>', 'exec')
311
Benjamin Peterson78565b22009-06-28 19:19:51 +0000312 def test_slice(self):
313 slc = ast.parse("x[::]").body[0].value.slice
314 self.assertIsNone(slc.upper)
315 self.assertIsNone(slc.lower)
316 self.assertIsNone(slc.step)
317
318 def test_from_import(self):
319 im = ast.parse("from . import y").body[0]
320 self.assertIsNone(im.module)
321
Benjamin Petersona4e4e352012-03-22 08:19:04 -0400322 def test_non_interned_future_from_ast(self):
323 mod = ast.parse("from __future__ import division")
324 self.assertIsInstance(mod.body[0], ast.ImportFrom)
325 mod.body[0].module = " __future__ ".strip()
326 compile(mod, "<test>", "exec")
327
Benjamin Petersona0dfa822009-11-13 02:25:08 +0000328 def test_base_classes(self):
329 self.assertTrue(issubclass(ast.For, ast.stmt))
330 self.assertTrue(issubclass(ast.Name, ast.expr))
331 self.assertTrue(issubclass(ast.stmt, ast.AST))
332 self.assertTrue(issubclass(ast.expr, ast.AST))
333 self.assertTrue(issubclass(ast.comprehension, ast.AST))
334 self.assertTrue(issubclass(ast.Gt, ast.AST))
335
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500336 def test_field_attr_existence(self):
337 for name, item in ast.__dict__.items():
338 if isinstance(item, type) and name != 'AST' and name[0].isupper():
339 x = item()
340 if isinstance(x, ast.AST):
341 self.assertEqual(type(x._fields), tuple)
342
343 def test_arguments(self):
344 x = ast.arguments()
Pablo Galindocd6e83b2019-07-15 01:32:18 +0200345 self.assertEqual(x._fields, ('posonlyargs', 'args', 'vararg', 'kwonlyargs',
346 'kw_defaults', 'kwarg', 'defaults'))
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500347
348 with self.assertRaises(AttributeError):
349 x.vararg
350
Pablo Galindo8c77b8c2019-04-29 13:36:57 +0100351 x = ast.arguments(*range(1, 8))
352 self.assertEqual(x.vararg, 3)
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500353
354 def test_field_attr_writable(self):
355 x = ast.Num()
356 # We can assign to _fields
357 x._fields = 666
358 self.assertEqual(x._fields, 666)
359
360 def test_classattrs(self):
361 x = ast.Num()
Guido van Rossum10f8ce62019-03-13 13:00:46 -0700362 self.assertEqual(x._fields, ('value', 'kind'))
Serhiy Storchaka3f228112018-09-27 17:42:37 +0300363
364 with self.assertRaises(AttributeError):
365 x.value
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500366
367 with self.assertRaises(AttributeError):
368 x.n
369
370 x = ast.Num(42)
Serhiy Storchaka3f228112018-09-27 17:42:37 +0300371 self.assertEqual(x.value, 42)
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500372 self.assertEqual(x.n, 42)
373
374 with self.assertRaises(AttributeError):
375 x.lineno
376
377 with self.assertRaises(AttributeError):
378 x.foobar
379
380 x = ast.Num(lineno=2)
381 self.assertEqual(x.lineno, 2)
382
383 x = ast.Num(42, lineno=0)
384 self.assertEqual(x.lineno, 0)
Guido van Rossum10f8ce62019-03-13 13:00:46 -0700385 self.assertEqual(x._fields, ('value', 'kind'))
Serhiy Storchaka3f228112018-09-27 17:42:37 +0300386 self.assertEqual(x.value, 42)
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500387 self.assertEqual(x.n, 42)
388
Guido van Rossum10f8ce62019-03-13 13:00:46 -0700389 self.assertRaises(TypeError, ast.Num, 1, None, 2)
390 self.assertRaises(TypeError, ast.Num, 1, None, 2, lineno=0)
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500391
Serhiy Storchaka3f228112018-09-27 17:42:37 +0300392 self.assertEqual(ast.Num(42).n, 42)
393 self.assertEqual(ast.Num(4.25).n, 4.25)
394 self.assertEqual(ast.Num(4.25j).n, 4.25j)
395 self.assertEqual(ast.Str('42').s, '42')
396 self.assertEqual(ast.Bytes(b'42').s, b'42')
397 self.assertIs(ast.NameConstant(True).value, True)
398 self.assertIs(ast.NameConstant(False).value, False)
399 self.assertIs(ast.NameConstant(None).value, None)
400
401 self.assertEqual(ast.Constant(42).value, 42)
402 self.assertEqual(ast.Constant(4.25).value, 4.25)
403 self.assertEqual(ast.Constant(4.25j).value, 4.25j)
404 self.assertEqual(ast.Constant('42').value, '42')
405 self.assertEqual(ast.Constant(b'42').value, b'42')
406 self.assertIs(ast.Constant(True).value, True)
407 self.assertIs(ast.Constant(False).value, False)
408 self.assertIs(ast.Constant(None).value, None)
409 self.assertIs(ast.Constant(...).value, ...)
410
411 def test_realtype(self):
412 self.assertEqual(type(ast.Num(42)), ast.Constant)
413 self.assertEqual(type(ast.Num(4.25)), ast.Constant)
414 self.assertEqual(type(ast.Num(4.25j)), ast.Constant)
415 self.assertEqual(type(ast.Str('42')), ast.Constant)
416 self.assertEqual(type(ast.Bytes(b'42')), ast.Constant)
417 self.assertEqual(type(ast.NameConstant(True)), ast.Constant)
418 self.assertEqual(type(ast.NameConstant(False)), ast.Constant)
419 self.assertEqual(type(ast.NameConstant(None)), ast.Constant)
420 self.assertEqual(type(ast.Ellipsis()), ast.Constant)
421
422 def test_isinstance(self):
423 self.assertTrue(isinstance(ast.Num(42), ast.Num))
424 self.assertTrue(isinstance(ast.Num(4.2), ast.Num))
425 self.assertTrue(isinstance(ast.Num(4.2j), ast.Num))
426 self.assertTrue(isinstance(ast.Str('42'), ast.Str))
427 self.assertTrue(isinstance(ast.Bytes(b'42'), ast.Bytes))
428 self.assertTrue(isinstance(ast.NameConstant(True), ast.NameConstant))
429 self.assertTrue(isinstance(ast.NameConstant(False), ast.NameConstant))
430 self.assertTrue(isinstance(ast.NameConstant(None), ast.NameConstant))
431 self.assertTrue(isinstance(ast.Ellipsis(), ast.Ellipsis))
432
433 self.assertTrue(isinstance(ast.Constant(42), ast.Num))
434 self.assertTrue(isinstance(ast.Constant(4.2), ast.Num))
435 self.assertTrue(isinstance(ast.Constant(4.2j), ast.Num))
436 self.assertTrue(isinstance(ast.Constant('42'), ast.Str))
437 self.assertTrue(isinstance(ast.Constant(b'42'), ast.Bytes))
438 self.assertTrue(isinstance(ast.Constant(True), ast.NameConstant))
439 self.assertTrue(isinstance(ast.Constant(False), ast.NameConstant))
440 self.assertTrue(isinstance(ast.Constant(None), ast.NameConstant))
441 self.assertTrue(isinstance(ast.Constant(...), ast.Ellipsis))
442
443 self.assertFalse(isinstance(ast.Str('42'), ast.Num))
444 self.assertFalse(isinstance(ast.Num(42), ast.Str))
445 self.assertFalse(isinstance(ast.Str('42'), ast.Bytes))
446 self.assertFalse(isinstance(ast.Num(42), ast.NameConstant))
447 self.assertFalse(isinstance(ast.Num(42), ast.Ellipsis))
Anthony Sottile74176222019-01-18 11:30:28 -0800448 self.assertFalse(isinstance(ast.NameConstant(True), ast.Num))
449 self.assertFalse(isinstance(ast.NameConstant(False), ast.Num))
Serhiy Storchaka3f228112018-09-27 17:42:37 +0300450
451 self.assertFalse(isinstance(ast.Constant('42'), ast.Num))
452 self.assertFalse(isinstance(ast.Constant(42), ast.Str))
453 self.assertFalse(isinstance(ast.Constant('42'), ast.Bytes))
454 self.assertFalse(isinstance(ast.Constant(42), ast.NameConstant))
455 self.assertFalse(isinstance(ast.Constant(42), ast.Ellipsis))
Anthony Sottile74176222019-01-18 11:30:28 -0800456 self.assertFalse(isinstance(ast.Constant(True), ast.Num))
457 self.assertFalse(isinstance(ast.Constant(False), ast.Num))
Serhiy Storchaka3f228112018-09-27 17:42:37 +0300458
459 self.assertFalse(isinstance(ast.Constant(), ast.Num))
460 self.assertFalse(isinstance(ast.Constant(), ast.Str))
461 self.assertFalse(isinstance(ast.Constant(), ast.Bytes))
462 self.assertFalse(isinstance(ast.Constant(), ast.NameConstant))
463 self.assertFalse(isinstance(ast.Constant(), ast.Ellipsis))
464
Serhiy Storchaka6015cc52018-10-28 13:43:03 +0200465 class S(str): pass
466 self.assertTrue(isinstance(ast.Constant(S('42')), ast.Str))
467 self.assertFalse(isinstance(ast.Constant(S('42')), ast.Num))
468
Serhiy Storchaka3f228112018-09-27 17:42:37 +0300469 def test_subclasses(self):
470 class N(ast.Num):
471 def __init__(self, *args, **kwargs):
472 super().__init__(*args, **kwargs)
473 self.z = 'spam'
474 class N2(ast.Num):
475 pass
476
477 n = N(42)
478 self.assertEqual(n.n, 42)
479 self.assertEqual(n.z, 'spam')
480 self.assertEqual(type(n), N)
481 self.assertTrue(isinstance(n, N))
482 self.assertTrue(isinstance(n, ast.Num))
483 self.assertFalse(isinstance(n, N2))
484 self.assertFalse(isinstance(ast.Num(42), N))
485 n = N(n=42)
486 self.assertEqual(n.n, 42)
487 self.assertEqual(type(n), N)
488
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500489 def test_module(self):
490 body = [ast.Num(42)]
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800491 x = ast.Module(body, [])
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500492 self.assertEqual(x.body, body)
493
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000494 def test_nodeclasses(self):
Florent Xicluna992d9e02011-11-11 19:35:42 +0100495 # Zero arguments constructor explicitly allowed
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500496 x = ast.BinOp()
497 self.assertEqual(x._fields, ('left', 'op', 'right'))
498
499 # Random attribute allowed too
500 x.foobarbaz = 5
501 self.assertEqual(x.foobarbaz, 5)
502
503 n1 = ast.Num(1)
504 n3 = ast.Num(3)
505 addop = ast.Add()
506 x = ast.BinOp(n1, addop, n3)
507 self.assertEqual(x.left, n1)
508 self.assertEqual(x.op, addop)
509 self.assertEqual(x.right, n3)
Benjamin Peterson68b543a2011-06-27 17:51:18 -0500510
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500511 x = ast.BinOp(1, 2, 3)
512 self.assertEqual(x.left, 1)
513 self.assertEqual(x.op, 2)
514 self.assertEqual(x.right, 3)
515
Georg Brandl0c77a822008-06-10 16:37:50 +0000516 x = ast.BinOp(1, 2, 3, lineno=0)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000517 self.assertEqual(x.left, 1)
518 self.assertEqual(x.op, 2)
519 self.assertEqual(x.right, 3)
520 self.assertEqual(x.lineno, 0)
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000521
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500522 # node raises exception when given too many arguments
523 self.assertRaises(TypeError, ast.BinOp, 1, 2, 3, 4)
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500524 # node raises exception when given too many arguments
525 self.assertRaises(TypeError, ast.BinOp, 1, 2, 3, 4, lineno=0)
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000526
527 # can set attributes through kwargs too
Georg Brandl0c77a822008-06-10 16:37:50 +0000528 x = ast.BinOp(left=1, op=2, right=3, lineno=0)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000529 self.assertEqual(x.left, 1)
530 self.assertEqual(x.op, 2)
531 self.assertEqual(x.right, 3)
532 self.assertEqual(x.lineno, 0)
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000533
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500534 # Random kwargs also allowed
535 x = ast.BinOp(1, 2, 3, foobarbaz=42)
536 self.assertEqual(x.foobarbaz, 42)
537
538 def test_no_fields(self):
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000539 # this used to fail because Sub._fields was None
Georg Brandl0c77a822008-06-10 16:37:50 +0000540 x = ast.Sub()
Benjamin Peterson6ccfe852011-06-27 17:46:06 -0500541 self.assertEqual(x._fields, ())
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000542
543 def test_pickling(self):
544 import pickle
545 mods = [pickle]
546 try:
547 import cPickle
548 mods.append(cPickle)
549 except ImportError:
550 pass
551 protocols = [0, 1, 2]
552 for mod in mods:
553 for protocol in protocols:
554 for ast in (compile(i, "?", "exec", 0x400) for i in exec_tests):
555 ast2 = mod.loads(mod.dumps(ast, protocol))
Ezio Melottib3aedd42010-11-20 19:04:17 +0000556 self.assertEqual(to_tuple(ast2), to_tuple(ast))
Neal Norwitzee9b10a2008-03-31 05:29:39 +0000557
Benjamin Peterson5b066812010-11-20 01:38:49 +0000558 def test_invalid_sum(self):
559 pos = dict(lineno=2, col_offset=3)
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800560 m = ast.Module([ast.Expr(ast.expr(**pos), **pos)], [])
Benjamin Peterson5b066812010-11-20 01:38:49 +0000561 with self.assertRaises(TypeError) as cm:
562 compile(m, "<test>", "exec")
563 self.assertIn("but got <_ast.expr", str(cm.exception))
564
Min ho Kimc4cacc82019-07-31 08:16:13 +1000565 def test_invalid_identifier(self):
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800566 m = ast.Module([ast.Expr(ast.Name(42, ast.Load()))], [])
Benjamin Peterson2193d2b2011-07-22 10:50:23 -0500567 ast.fix_missing_locations(m)
568 with self.assertRaises(TypeError) as cm:
569 compile(m, "<test>", "exec")
570 self.assertIn("identifier must be of type str", str(cm.exception))
571
Mark Dickinsonded35ae2012-11-25 14:36:26 +0000572 def test_empty_yield_from(self):
573 # Issue 16546: yield from value is not optional.
574 empty_yield_from = ast.parse("def f():\n yield from g()")
575 empty_yield_from.body[0].body[0].value.value = None
576 with self.assertRaises(ValueError) as cm:
577 compile(empty_yield_from, "<test>", "exec")
578 self.assertIn("field value is required", str(cm.exception))
579
Oren Milman7dc46d82017-09-30 20:16:24 +0300580 @support.cpython_only
581 def test_issue31592(self):
582 # There shouldn't be an assertion failure in case of a bad
583 # unicodedata.normalize().
584 import unicodedata
585 def bad_normalize(*args):
586 return None
587 with support.swap_attr(unicodedata, 'normalize', bad_normalize):
588 self.assertRaises(TypeError, ast.parse, '\u03D5')
589
Carl Friedrich Bolz-Tereick110a47c2019-07-08 23:17:56 +0200590 def test_issue18374_binop_col_offset(self):
591 tree = ast.parse('4+5+6+7')
592 parent_binop = tree.body[0].value
593 child_binop = parent_binop.left
594 grandchild_binop = child_binop.left
595 self.assertEqual(parent_binop.col_offset, 0)
596 self.assertEqual(parent_binop.end_col_offset, 7)
597 self.assertEqual(child_binop.col_offset, 0)
598 self.assertEqual(child_binop.end_col_offset, 5)
599 self.assertEqual(grandchild_binop.col_offset, 0)
600 self.assertEqual(grandchild_binop.end_col_offset, 3)
601
602 tree = ast.parse('4+5-\\\n 6-7')
603 parent_binop = tree.body[0].value
604 child_binop = parent_binop.left
605 grandchild_binop = child_binop.left
606 self.assertEqual(parent_binop.col_offset, 0)
607 self.assertEqual(parent_binop.lineno, 1)
608 self.assertEqual(parent_binop.end_col_offset, 4)
609 self.assertEqual(parent_binop.end_lineno, 2)
610
611 self.assertEqual(child_binop.col_offset, 0)
Carl Friedrich Bolz-Tereick430a9f42019-07-09 14:20:01 +0200612 self.assertEqual(child_binop.lineno, 1)
Carl Friedrich Bolz-Tereick110a47c2019-07-08 23:17:56 +0200613 self.assertEqual(child_binop.end_col_offset, 2)
Carl Friedrich Bolz-Tereick430a9f42019-07-09 14:20:01 +0200614 self.assertEqual(child_binop.end_lineno, 2)
Carl Friedrich Bolz-Tereick110a47c2019-07-08 23:17:56 +0200615
616 self.assertEqual(grandchild_binop.col_offset, 0)
Carl Friedrich Bolz-Tereick430a9f42019-07-09 14:20:01 +0200617 self.assertEqual(grandchild_binop.lineno, 1)
Carl Friedrich Bolz-Tereick110a47c2019-07-08 23:17:56 +0200618 self.assertEqual(grandchild_binop.end_col_offset, 3)
Carl Friedrich Bolz-Tereick430a9f42019-07-09 14:20:01 +0200619 self.assertEqual(grandchild_binop.end_lineno, 1)
Georg Brandl0c77a822008-06-10 16:37:50 +0000620
Lysandros Nikolaoud2e10982020-02-08 00:36:32 +0100621 def test_issue39579_dotted_name_end_col_offset(self):
622 tree = ast.parse('@a.b.c\ndef f(): pass')
623 attr_b = tree.body[0].decorator_list[0].value
624 self.assertEqual(attr_b.end_col_offset, 4)
625
Georg Brandl0c77a822008-06-10 16:37:50 +0000626class ASTHelpers_Test(unittest.TestCase):
Guido van Rossum10f8ce62019-03-13 13:00:46 -0700627 maxDiff = None
Georg Brandl0c77a822008-06-10 16:37:50 +0000628
629 def test_parse(self):
630 a = ast.parse('foo(1 + 1)')
631 b = compile('foo(1 + 1)', '<unknown>', 'exec', ast.PyCF_ONLY_AST)
632 self.assertEqual(ast.dump(a), ast.dump(b))
633
Benjamin Peterson2e2c9032012-09-02 14:23:15 -0400634 def test_parse_in_error(self):
635 try:
636 1/0
637 except Exception:
Benjamin Petersonbd0df502012-09-02 15:04:51 -0400638 with self.assertRaises(SyntaxError) as e:
639 ast.literal_eval(r"'\U'")
640 self.assertIsNotNone(e.exception.__context__)
Benjamin Peterson2e2c9032012-09-02 14:23:15 -0400641
Georg Brandl0c77a822008-06-10 16:37:50 +0000642 def test_dump(self):
643 node = ast.parse('spam(eggs, "and cheese")')
644 self.assertEqual(ast.dump(node),
645 "Module(body=[Expr(value=Call(func=Name(id='spam', ctx=Load()), "
Guido van Rossum10f8ce62019-03-13 13:00:46 -0700646 "args=[Name(id='eggs', ctx=Load()), Constant(value='and cheese', kind=None)], "
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800647 "keywords=[]))], type_ignores=[])"
Georg Brandl0c77a822008-06-10 16:37:50 +0000648 )
649 self.assertEqual(ast.dump(node, annotate_fields=False),
650 "Module([Expr(Call(Name('spam', Load()), [Name('eggs', Load()), "
Guido van Rossum10f8ce62019-03-13 13:00:46 -0700651 "Constant('and cheese', None)], []))], [])"
Georg Brandl0c77a822008-06-10 16:37:50 +0000652 )
653 self.assertEqual(ast.dump(node, include_attributes=True),
654 "Module(body=[Expr(value=Call(func=Name(id='spam', ctx=Load(), "
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000655 "lineno=1, col_offset=0, end_lineno=1, end_col_offset=4), "
656 "args=[Name(id='eggs', ctx=Load(), lineno=1, col_offset=5, "
Guido van Rossum10f8ce62019-03-13 13:00:46 -0700657 "end_lineno=1, end_col_offset=9), Constant(value='and cheese', kind=None, "
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000658 "lineno=1, col_offset=11, end_lineno=1, end_col_offset=23)], keywords=[], "
659 "lineno=1, col_offset=0, end_lineno=1, end_col_offset=24), "
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800660 "lineno=1, col_offset=0, end_lineno=1, end_col_offset=24)], type_ignores=[])"
Georg Brandl0c77a822008-06-10 16:37:50 +0000661 )
662
Serhiy Storchaka850573b2019-09-09 19:33:13 +0300663 def test_dump_indent(self):
664 node = ast.parse('spam(eggs, "and cheese")')
665 self.assertEqual(ast.dump(node, indent=3), """\
666Module(
667 body=[
668 Expr(
669 value=Call(
670 func=Name(id='spam', ctx=Load()),
671 args=[
672 Name(id='eggs', ctx=Load()),
673 Constant(value='and cheese', kind=None)],
674 keywords=[]))],
675 type_ignores=[])""")
676 self.assertEqual(ast.dump(node, annotate_fields=False, indent='\t'), """\
677Module(
678\t[
679\t\tExpr(
680\t\t\tCall(
681\t\t\t\tName('spam', Load()),
682\t\t\t\t[
683\t\t\t\t\tName('eggs', Load()),
684\t\t\t\t\tConstant('and cheese', None)],
685\t\t\t\t[]))],
686\t[])""")
687 self.assertEqual(ast.dump(node, include_attributes=True, indent=3), """\
688Module(
689 body=[
690 Expr(
691 value=Call(
692 func=Name(
693 id='spam',
694 ctx=Load(),
695 lineno=1,
696 col_offset=0,
697 end_lineno=1,
698 end_col_offset=4),
699 args=[
700 Name(
701 id='eggs',
702 ctx=Load(),
703 lineno=1,
704 col_offset=5,
705 end_lineno=1,
706 end_col_offset=9),
707 Constant(
708 value='and cheese',
709 kind=None,
710 lineno=1,
711 col_offset=11,
712 end_lineno=1,
713 end_col_offset=23)],
714 keywords=[],
715 lineno=1,
716 col_offset=0,
717 end_lineno=1,
718 end_col_offset=24),
719 lineno=1,
720 col_offset=0,
721 end_lineno=1,
722 end_col_offset=24)],
723 type_ignores=[])""")
724
Serhiy Storchakae64f9482019-08-29 09:30:23 +0300725 def test_dump_incomplete(self):
726 node = ast.Raise(lineno=3, col_offset=4)
727 self.assertEqual(ast.dump(node),
728 "Raise()"
729 )
730 self.assertEqual(ast.dump(node, include_attributes=True),
731 "Raise(lineno=3, col_offset=4)"
732 )
733 node = ast.Raise(exc=ast.Name(id='e', ctx=ast.Load()), lineno=3, col_offset=4)
734 self.assertEqual(ast.dump(node),
735 "Raise(exc=Name(id='e', ctx=Load()))"
736 )
737 self.assertEqual(ast.dump(node, annotate_fields=False),
738 "Raise(Name('e', Load()))"
739 )
740 self.assertEqual(ast.dump(node, include_attributes=True),
741 "Raise(exc=Name(id='e', ctx=Load()), lineno=3, col_offset=4)"
742 )
743 self.assertEqual(ast.dump(node, annotate_fields=False, include_attributes=True),
744 "Raise(Name('e', Load()), lineno=3, col_offset=4)"
745 )
746 node = ast.Raise(cause=ast.Name(id='e', ctx=ast.Load()))
747 self.assertEqual(ast.dump(node),
748 "Raise(cause=Name(id='e', ctx=Load()))"
749 )
750 self.assertEqual(ast.dump(node, annotate_fields=False),
751 "Raise(cause=Name('e', Load()))"
752 )
753
Georg Brandl0c77a822008-06-10 16:37:50 +0000754 def test_copy_location(self):
755 src = ast.parse('1 + 1', mode='eval')
756 src.body.right = ast.copy_location(ast.Num(2), src.body.right)
757 self.assertEqual(ast.dump(src, include_attributes=True),
Guido van Rossum10f8ce62019-03-13 13:00:46 -0700758 'Expression(body=BinOp(left=Constant(value=1, kind=None, lineno=1, col_offset=0, '
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000759 'end_lineno=1, end_col_offset=1), op=Add(), right=Constant(value=2, '
760 'lineno=1, col_offset=4, end_lineno=1, end_col_offset=5), lineno=1, '
761 'col_offset=0, end_lineno=1, end_col_offset=5))'
Georg Brandl0c77a822008-06-10 16:37:50 +0000762 )
763
764 def test_fix_missing_locations(self):
765 src = ast.parse('write("spam")')
766 src.body.append(ast.Expr(ast.Call(ast.Name('spam', ast.Load()),
Benjamin Peterson025e9eb2015-05-05 20:16:41 -0400767 [ast.Str('eggs')], [])))
Georg Brandl0c77a822008-06-10 16:37:50 +0000768 self.assertEqual(src, ast.fix_missing_locations(src))
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000769 self.maxDiff = None
Georg Brandl0c77a822008-06-10 16:37:50 +0000770 self.assertEqual(ast.dump(src, include_attributes=True),
771 "Module(body=[Expr(value=Call(func=Name(id='write', ctx=Load(), "
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000772 "lineno=1, col_offset=0, end_lineno=1, end_col_offset=5), "
Guido van Rossum10f8ce62019-03-13 13:00:46 -0700773 "args=[Constant(value='spam', kind=None, lineno=1, col_offset=6, end_lineno=1, "
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000774 "end_col_offset=12)], keywords=[], lineno=1, col_offset=0, end_lineno=1, "
775 "end_col_offset=13), lineno=1, col_offset=0, end_lineno=1, "
776 "end_col_offset=13), Expr(value=Call(func=Name(id='spam', ctx=Load(), "
777 "lineno=1, col_offset=0, end_lineno=1, end_col_offset=0), "
778 "args=[Constant(value='eggs', lineno=1, col_offset=0, end_lineno=1, "
779 "end_col_offset=0)], keywords=[], lineno=1, col_offset=0, end_lineno=1, "
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800780 "end_col_offset=0), lineno=1, col_offset=0, end_lineno=1, end_col_offset=0)], "
781 "type_ignores=[])"
Georg Brandl0c77a822008-06-10 16:37:50 +0000782 )
783
784 def test_increment_lineno(self):
785 src = ast.parse('1 + 1', mode='eval')
786 self.assertEqual(ast.increment_lineno(src, n=3), src)
787 self.assertEqual(ast.dump(src, include_attributes=True),
Guido van Rossum10f8ce62019-03-13 13:00:46 -0700788 'Expression(body=BinOp(left=Constant(value=1, kind=None, lineno=4, col_offset=0, '
789 'end_lineno=4, end_col_offset=1), op=Add(), right=Constant(value=1, kind=None, '
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000790 'lineno=4, col_offset=4, end_lineno=4, end_col_offset=5), lineno=4, '
791 'col_offset=0, end_lineno=4, end_col_offset=5))'
Georg Brandl0c77a822008-06-10 16:37:50 +0000792 )
Georg Brandl619e7ba2011-01-09 07:38:51 +0000793 # issue10869: do not increment lineno of root twice
Georg Brandlefb69022011-01-09 07:50:48 +0000794 src = ast.parse('1 + 1', mode='eval')
Georg Brandl619e7ba2011-01-09 07:38:51 +0000795 self.assertEqual(ast.increment_lineno(src.body, n=3), src.body)
796 self.assertEqual(ast.dump(src, include_attributes=True),
Guido van Rossum10f8ce62019-03-13 13:00:46 -0700797 'Expression(body=BinOp(left=Constant(value=1, kind=None, lineno=4, col_offset=0, '
798 'end_lineno=4, end_col_offset=1), op=Add(), right=Constant(value=1, kind=None, '
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000799 'lineno=4, col_offset=4, end_lineno=4, end_col_offset=5), lineno=4, '
800 'col_offset=0, end_lineno=4, end_col_offset=5))'
Georg Brandl619e7ba2011-01-09 07:38:51 +0000801 )
Georg Brandl0c77a822008-06-10 16:37:50 +0000802
803 def test_iter_fields(self):
804 node = ast.parse('foo()', mode='eval')
805 d = dict(ast.iter_fields(node.body))
806 self.assertEqual(d.pop('func').id, 'foo')
Benjamin Peterson025e9eb2015-05-05 20:16:41 -0400807 self.assertEqual(d, {'keywords': [], 'args': []})
Georg Brandl0c77a822008-06-10 16:37:50 +0000808
809 def test_iter_child_nodes(self):
810 node = ast.parse("spam(23, 42, eggs='leek')", mode='eval')
811 self.assertEqual(len(list(ast.iter_child_nodes(node.body))), 4)
812 iterator = ast.iter_child_nodes(node.body)
813 self.assertEqual(next(iterator).id, 'spam')
Serhiy Storchaka3f228112018-09-27 17:42:37 +0300814 self.assertEqual(next(iterator).value, 23)
815 self.assertEqual(next(iterator).value, 42)
Georg Brandl0c77a822008-06-10 16:37:50 +0000816 self.assertEqual(ast.dump(next(iterator)),
Guido van Rossum10f8ce62019-03-13 13:00:46 -0700817 "keyword(arg='eggs', value=Constant(value='leek', kind=None))"
Georg Brandl0c77a822008-06-10 16:37:50 +0000818 )
819
820 def test_get_docstring(self):
Serhiy Storchaka08f127a2018-06-15 11:05:15 +0300821 node = ast.parse('"""line one\n line two"""')
822 self.assertEqual(ast.get_docstring(node),
823 'line one\nline two')
824
825 node = ast.parse('class foo:\n """line one\n line two"""')
826 self.assertEqual(ast.get_docstring(node.body[0]),
827 'line one\nline two')
828
Georg Brandl0c77a822008-06-10 16:37:50 +0000829 node = ast.parse('def foo():\n """line one\n line two"""')
830 self.assertEqual(ast.get_docstring(node.body[0]),
831 'line one\nline two')
832
Yury Selivanov2f07a662015-07-23 08:54:35 +0300833 node = ast.parse('async def foo():\n """spam\n ham"""')
834 self.assertEqual(ast.get_docstring(node.body[0]), 'spam\nham')
Serhiy Storchaka08f127a2018-06-15 11:05:15 +0300835
836 def test_get_docstring_none(self):
Matthias Bussonnier41cea702017-02-23 22:44:19 -0800837 self.assertIsNone(ast.get_docstring(ast.parse('')))
Serhiy Storchaka08f127a2018-06-15 11:05:15 +0300838 node = ast.parse('x = "not docstring"')
839 self.assertIsNone(ast.get_docstring(node))
840 node = ast.parse('def foo():\n pass')
841 self.assertIsNone(ast.get_docstring(node))
842
843 node = ast.parse('class foo:\n pass')
844 self.assertIsNone(ast.get_docstring(node.body[0]))
845 node = ast.parse('class foo:\n x = "not docstring"')
846 self.assertIsNone(ast.get_docstring(node.body[0]))
847 node = ast.parse('class foo:\n def bar(self): pass')
848 self.assertIsNone(ast.get_docstring(node.body[0]))
849
850 node = ast.parse('def foo():\n pass')
851 self.assertIsNone(ast.get_docstring(node.body[0]))
852 node = ast.parse('def foo():\n x = "not docstring"')
853 self.assertIsNone(ast.get_docstring(node.body[0]))
854
855 node = ast.parse('async def foo():\n pass')
856 self.assertIsNone(ast.get_docstring(node.body[0]))
857 node = ast.parse('async def foo():\n x = "not docstring"')
858 self.assertIsNone(ast.get_docstring(node.body[0]))
Yury Selivanov2f07a662015-07-23 08:54:35 +0300859
Anthony Sottile995d9b92019-01-12 20:05:13 -0800860 def test_multi_line_docstring_col_offset_and_lineno_issue16806(self):
861 node = ast.parse(
862 '"""line one\nline two"""\n\n'
863 'def foo():\n """line one\n line two"""\n\n'
864 ' def bar():\n """line one\n line two"""\n'
865 ' """line one\n line two"""\n'
866 '"""line one\nline two"""\n\n'
867 )
868 self.assertEqual(node.body[0].col_offset, 0)
869 self.assertEqual(node.body[0].lineno, 1)
870 self.assertEqual(node.body[1].body[0].col_offset, 2)
871 self.assertEqual(node.body[1].body[0].lineno, 5)
872 self.assertEqual(node.body[1].body[1].body[0].col_offset, 4)
873 self.assertEqual(node.body[1].body[1].body[0].lineno, 9)
874 self.assertEqual(node.body[1].body[2].col_offset, 2)
875 self.assertEqual(node.body[1].body[2].lineno, 11)
876 self.assertEqual(node.body[2].col_offset, 0)
877 self.assertEqual(node.body[2].lineno, 13)
878
Lysandros Nikolaou025a6022019-12-12 22:40:21 +0100879 def test_elif_stmt_start_position(self):
880 node = ast.parse('if a:\n pass\nelif b:\n pass\n')
881 elif_stmt = node.body[0].orelse[0]
882 self.assertEqual(elif_stmt.lineno, 3)
883 self.assertEqual(elif_stmt.col_offset, 0)
884
Lysandros Nikolaou5936a4c2019-12-14 11:24:57 +0100885 def test_elif_stmt_start_position_with_else(self):
886 node = ast.parse('if a:\n pass\nelif b:\n pass\nelse:\n pass\n')
887 elif_stmt = node.body[0].orelse[0]
888 self.assertEqual(elif_stmt.lineno, 3)
889 self.assertEqual(elif_stmt.col_offset, 0)
890
Lysandros Nikolaou50d4f122019-12-18 01:20:55 +0100891 def test_starred_expr_end_position_within_call(self):
892 node = ast.parse('f(*[0, 1])')
893 starred_expr = node.body[0].value.args[0]
894 self.assertEqual(starred_expr.end_lineno, 1)
895 self.assertEqual(starred_expr.end_col_offset, 9)
896
Georg Brandl0c77a822008-06-10 16:37:50 +0000897 def test_literal_eval(self):
898 self.assertEqual(ast.literal_eval('[1, 2, 3]'), [1, 2, 3])
899 self.assertEqual(ast.literal_eval('{"foo": 42}'), {"foo": 42})
900 self.assertEqual(ast.literal_eval('(True, False, None)'), (True, False, None))
Benjamin Peterson3e742892010-07-11 12:59:24 +0000901 self.assertEqual(ast.literal_eval('{1, 2, 3}'), {1, 2, 3})
Benjamin Peterson5ef96e52010-07-11 23:06:06 +0000902 self.assertEqual(ast.literal_eval('b"hi"'), b"hi")
Raymond Hettinger4fcf5c12020-01-02 22:21:18 -0700903 self.assertEqual(ast.literal_eval('set()'), set())
Georg Brandl0c77a822008-06-10 16:37:50 +0000904 self.assertRaises(ValueError, ast.literal_eval, 'foo()')
Serhiy Storchakad8ac4d12018-01-04 11:15:39 +0200905 self.assertEqual(ast.literal_eval('6'), 6)
906 self.assertEqual(ast.literal_eval('+6'), 6)
Raymond Hettingerbc959732010-10-08 00:47:45 +0000907 self.assertEqual(ast.literal_eval('-6'), -6)
Raymond Hettingerbc959732010-10-08 00:47:45 +0000908 self.assertEqual(ast.literal_eval('3.25'), 3.25)
Serhiy Storchakad8ac4d12018-01-04 11:15:39 +0200909 self.assertEqual(ast.literal_eval('+3.25'), 3.25)
910 self.assertEqual(ast.literal_eval('-3.25'), -3.25)
911 self.assertEqual(repr(ast.literal_eval('-0.0')), '-0.0')
912 self.assertRaises(ValueError, ast.literal_eval, '++6')
913 self.assertRaises(ValueError, ast.literal_eval, '+True')
914 self.assertRaises(ValueError, ast.literal_eval, '2+3')
Georg Brandl0c77a822008-06-10 16:37:50 +0000915
Serhiy Storchakad8ac4d12018-01-04 11:15:39 +0200916 def test_literal_eval_complex(self):
917 # Issue #4907
918 self.assertEqual(ast.literal_eval('6j'), 6j)
919 self.assertEqual(ast.literal_eval('-6j'), -6j)
920 self.assertEqual(ast.literal_eval('6.75j'), 6.75j)
921 self.assertEqual(ast.literal_eval('-6.75j'), -6.75j)
922 self.assertEqual(ast.literal_eval('3+6j'), 3+6j)
923 self.assertEqual(ast.literal_eval('-3+6j'), -3+6j)
924 self.assertEqual(ast.literal_eval('3-6j'), 3-6j)
925 self.assertEqual(ast.literal_eval('-3-6j'), -3-6j)
926 self.assertEqual(ast.literal_eval('3.25+6.75j'), 3.25+6.75j)
927 self.assertEqual(ast.literal_eval('-3.25+6.75j'), -3.25+6.75j)
928 self.assertEqual(ast.literal_eval('3.25-6.75j'), 3.25-6.75j)
929 self.assertEqual(ast.literal_eval('-3.25-6.75j'), -3.25-6.75j)
930 self.assertEqual(ast.literal_eval('(3+6j)'), 3+6j)
931 self.assertRaises(ValueError, ast.literal_eval, '-6j+3')
932 self.assertRaises(ValueError, ast.literal_eval, '-6j+3j')
933 self.assertRaises(ValueError, ast.literal_eval, '3+-6j')
934 self.assertRaises(ValueError, ast.literal_eval, '3+(0+6j)')
935 self.assertRaises(ValueError, ast.literal_eval, '-(3+6j)')
Benjamin Peterson058e31e2009-01-16 03:54:08 +0000936
Amaury Forgeot d'Arc58e87612011-11-22 21:51:55 +0100937 def test_bad_integer(self):
938 # issue13436: Bad error message with invalid numeric values
939 body = [ast.ImportFrom(module='time',
940 names=[ast.alias(name='sleep')],
941 level=None,
942 lineno=None, col_offset=None)]
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800943 mod = ast.Module(body, [])
Amaury Forgeot d'Arc58e87612011-11-22 21:51:55 +0100944 with self.assertRaises(ValueError) as cm:
945 compile(mod, 'test', 'exec')
946 self.assertIn("invalid integer value: None", str(cm.exception))
947
Berker Peksag0a5bd512016-04-29 19:50:02 +0300948 def test_level_as_none(self):
949 body = [ast.ImportFrom(module='time',
950 names=[ast.alias(name='sleep')],
951 level=None,
952 lineno=0, col_offset=0)]
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800953 mod = ast.Module(body, [])
Berker Peksag0a5bd512016-04-29 19:50:02 +0300954 code = compile(mod, 'test', 'exec')
955 ns = {}
956 exec(code, ns)
957 self.assertIn('sleep', ns)
958
Georg Brandl0c77a822008-06-10 16:37:50 +0000959
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500960class ASTValidatorTests(unittest.TestCase):
961
962 def mod(self, mod, msg=None, mode="exec", *, exc=ValueError):
963 mod.lineno = mod.col_offset = 0
964 ast.fix_missing_locations(mod)
Serhiy Storchaka3f228112018-09-27 17:42:37 +0300965 if msg is None:
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500966 compile(mod, "<test>", mode)
Serhiy Storchaka3f228112018-09-27 17:42:37 +0300967 else:
968 with self.assertRaises(exc) as cm:
969 compile(mod, "<test>", mode)
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500970 self.assertIn(msg, str(cm.exception))
971
972 def expr(self, node, msg=None, *, exc=ValueError):
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800973 mod = ast.Module([ast.Expr(node)], [])
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500974 self.mod(mod, msg, exc=exc)
975
976 def stmt(self, stmt, msg=None):
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800977 mod = ast.Module([stmt], [])
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500978 self.mod(mod, msg)
979
980 def test_module(self):
981 m = ast.Interactive([ast.Expr(ast.Name("x", ast.Store()))])
982 self.mod(m, "must have Load context", "single")
983 m = ast.Expression(ast.Name("x", ast.Store()))
984 self.mod(m, "must have Load context", "eval")
985
986 def _check_arguments(self, fac, check):
Pablo Galindo8c77b8c2019-04-29 13:36:57 +0100987 def arguments(args=None, posonlyargs=None, vararg=None,
Benjamin Petersoncda75be2013-03-18 10:48:58 -0700988 kwonlyargs=None, kwarg=None,
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500989 defaults=None, kw_defaults=None):
990 if args is None:
991 args = []
Pablo Galindo8c77b8c2019-04-29 13:36:57 +0100992 if posonlyargs is None:
993 posonlyargs = []
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500994 if kwonlyargs is None:
995 kwonlyargs = []
996 if defaults is None:
997 defaults = []
998 if kw_defaults is None:
999 kw_defaults = []
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01001000 args = ast.arguments(args, posonlyargs, vararg, kwonlyargs,
1001 kw_defaults, kwarg, defaults)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001002 return fac(args)
1003 args = [ast.arg("x", ast.Name("x", ast.Store()))]
1004 check(arguments(args=args), "must have Load context")
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01001005 check(arguments(posonlyargs=args), "must have Load context")
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001006 check(arguments(kwonlyargs=args), "must have Load context")
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001007 check(arguments(defaults=[ast.Num(3)]),
1008 "more positional defaults than args")
1009 check(arguments(kw_defaults=[ast.Num(4)]),
1010 "length of kwonlyargs is not the same as kw_defaults")
1011 args = [ast.arg("x", ast.Name("x", ast.Load()))]
1012 check(arguments(args=args, defaults=[ast.Name("x", ast.Store())]),
1013 "must have Load context")
1014 args = [ast.arg("a", ast.Name("x", ast.Load())),
1015 ast.arg("b", ast.Name("y", ast.Load()))]
1016 check(arguments(kwonlyargs=args,
1017 kw_defaults=[None, ast.Name("x", ast.Store())]),
1018 "must have Load context")
1019
1020 def test_funcdef(self):
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01001021 a = ast.arguments([], [], None, [], [], None, [])
Serhiy Storchaka73cbe7a2018-05-29 12:04:55 +03001022 f = ast.FunctionDef("x", a, [], [], None)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001023 self.stmt(f, "empty body on FunctionDef")
1024 f = ast.FunctionDef("x", a, [ast.Pass()], [ast.Name("x", ast.Store())],
Serhiy Storchaka73cbe7a2018-05-29 12:04:55 +03001025 None)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001026 self.stmt(f, "must have Load context")
1027 f = ast.FunctionDef("x", a, [ast.Pass()], [],
Serhiy Storchaka73cbe7a2018-05-29 12:04:55 +03001028 ast.Name("x", ast.Store()))
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001029 self.stmt(f, "must have Load context")
1030 def fac(args):
Serhiy Storchaka73cbe7a2018-05-29 12:04:55 +03001031 return ast.FunctionDef("x", args, [ast.Pass()], [], None)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001032 self._check_arguments(fac, self.stmt)
1033
1034 def test_classdef(self):
Benjamin Peterson025e9eb2015-05-05 20:16:41 -04001035 def cls(bases=None, keywords=None, body=None, decorator_list=None):
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001036 if bases is None:
1037 bases = []
1038 if keywords is None:
1039 keywords = []
1040 if body is None:
1041 body = [ast.Pass()]
1042 if decorator_list is None:
1043 decorator_list = []
Benjamin Peterson025e9eb2015-05-05 20:16:41 -04001044 return ast.ClassDef("myclass", bases, keywords,
Serhiy Storchaka73cbe7a2018-05-29 12:04:55 +03001045 body, decorator_list)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001046 self.stmt(cls(bases=[ast.Name("x", ast.Store())]),
1047 "must have Load context")
1048 self.stmt(cls(keywords=[ast.keyword("x", ast.Name("x", ast.Store()))]),
1049 "must have Load context")
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001050 self.stmt(cls(body=[]), "empty body on ClassDef")
1051 self.stmt(cls(body=[None]), "None disallowed")
1052 self.stmt(cls(decorator_list=[ast.Name("x", ast.Store())]),
1053 "must have Load context")
1054
1055 def test_delete(self):
1056 self.stmt(ast.Delete([]), "empty targets on Delete")
1057 self.stmt(ast.Delete([None]), "None disallowed")
1058 self.stmt(ast.Delete([ast.Name("x", ast.Load())]),
1059 "must have Del context")
1060
1061 def test_assign(self):
1062 self.stmt(ast.Assign([], ast.Num(3)), "empty targets on Assign")
1063 self.stmt(ast.Assign([None], ast.Num(3)), "None disallowed")
1064 self.stmt(ast.Assign([ast.Name("x", ast.Load())], ast.Num(3)),
1065 "must have Store context")
1066 self.stmt(ast.Assign([ast.Name("x", ast.Store())],
1067 ast.Name("y", ast.Store())),
1068 "must have Load context")
1069
1070 def test_augassign(self):
1071 aug = ast.AugAssign(ast.Name("x", ast.Load()), ast.Add(),
1072 ast.Name("y", ast.Load()))
1073 self.stmt(aug, "must have Store context")
1074 aug = ast.AugAssign(ast.Name("x", ast.Store()), ast.Add(),
1075 ast.Name("y", ast.Store()))
1076 self.stmt(aug, "must have Load context")
1077
1078 def test_for(self):
1079 x = ast.Name("x", ast.Store())
1080 y = ast.Name("y", ast.Load())
1081 p = ast.Pass()
1082 self.stmt(ast.For(x, y, [], []), "empty body on For")
1083 self.stmt(ast.For(ast.Name("x", ast.Load()), y, [p], []),
1084 "must have Store context")
1085 self.stmt(ast.For(x, ast.Name("y", ast.Store()), [p], []),
1086 "must have Load context")
1087 e = ast.Expr(ast.Name("x", ast.Store()))
1088 self.stmt(ast.For(x, y, [e], []), "must have Load context")
1089 self.stmt(ast.For(x, y, [p], [e]), "must have Load context")
1090
1091 def test_while(self):
1092 self.stmt(ast.While(ast.Num(3), [], []), "empty body on While")
1093 self.stmt(ast.While(ast.Name("x", ast.Store()), [ast.Pass()], []),
1094 "must have Load context")
1095 self.stmt(ast.While(ast.Num(3), [ast.Pass()],
1096 [ast.Expr(ast.Name("x", ast.Store()))]),
1097 "must have Load context")
1098
1099 def test_if(self):
1100 self.stmt(ast.If(ast.Num(3), [], []), "empty body on If")
1101 i = ast.If(ast.Name("x", ast.Store()), [ast.Pass()], [])
1102 self.stmt(i, "must have Load context")
1103 i = ast.If(ast.Num(3), [ast.Expr(ast.Name("x", ast.Store()))], [])
1104 self.stmt(i, "must have Load context")
1105 i = ast.If(ast.Num(3), [ast.Pass()],
1106 [ast.Expr(ast.Name("x", ast.Store()))])
1107 self.stmt(i, "must have Load context")
1108
1109 def test_with(self):
1110 p = ast.Pass()
1111 self.stmt(ast.With([], [p]), "empty items on With")
1112 i = ast.withitem(ast.Num(3), None)
1113 self.stmt(ast.With([i], []), "empty body on With")
1114 i = ast.withitem(ast.Name("x", ast.Store()), None)
1115 self.stmt(ast.With([i], [p]), "must have Load context")
1116 i = ast.withitem(ast.Num(3), ast.Name("x", ast.Load()))
1117 self.stmt(ast.With([i], [p]), "must have Store context")
1118
1119 def test_raise(self):
1120 r = ast.Raise(None, ast.Num(3))
1121 self.stmt(r, "Raise with cause but no exception")
1122 r = ast.Raise(ast.Name("x", ast.Store()), None)
1123 self.stmt(r, "must have Load context")
1124 r = ast.Raise(ast.Num(4), ast.Name("x", ast.Store()))
1125 self.stmt(r, "must have Load context")
1126
1127 def test_try(self):
1128 p = ast.Pass()
1129 t = ast.Try([], [], [], [p])
1130 self.stmt(t, "empty body on Try")
1131 t = ast.Try([ast.Expr(ast.Name("x", ast.Store()))], [], [], [p])
1132 self.stmt(t, "must have Load context")
1133 t = ast.Try([p], [], [], [])
1134 self.stmt(t, "Try has neither except handlers nor finalbody")
1135 t = ast.Try([p], [], [p], [p])
1136 self.stmt(t, "Try has orelse but no except handlers")
1137 t = ast.Try([p], [ast.ExceptHandler(None, "x", [])], [], [])
1138 self.stmt(t, "empty body on ExceptHandler")
1139 e = [ast.ExceptHandler(ast.Name("x", ast.Store()), "y", [p])]
1140 self.stmt(ast.Try([p], e, [], []), "must have Load context")
1141 e = [ast.ExceptHandler(None, "x", [p])]
1142 t = ast.Try([p], e, [ast.Expr(ast.Name("x", ast.Store()))], [p])
1143 self.stmt(t, "must have Load context")
1144 t = ast.Try([p], e, [p], [ast.Expr(ast.Name("x", ast.Store()))])
1145 self.stmt(t, "must have Load context")
1146
1147 def test_assert(self):
1148 self.stmt(ast.Assert(ast.Name("x", ast.Store()), None),
1149 "must have Load context")
1150 assrt = ast.Assert(ast.Name("x", ast.Load()),
1151 ast.Name("y", ast.Store()))
1152 self.stmt(assrt, "must have Load context")
1153
1154 def test_import(self):
1155 self.stmt(ast.Import([]), "empty names on Import")
1156
1157 def test_importfrom(self):
1158 imp = ast.ImportFrom(None, [ast.alias("x", None)], -42)
Serhiy Storchaka7de28402016-06-27 23:40:43 +03001159 self.stmt(imp, "Negative ImportFrom level")
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001160 self.stmt(ast.ImportFrom(None, [], 0), "empty names on ImportFrom")
1161
1162 def test_global(self):
1163 self.stmt(ast.Global([]), "empty names on Global")
1164
1165 def test_nonlocal(self):
1166 self.stmt(ast.Nonlocal([]), "empty names on Nonlocal")
1167
1168 def test_expr(self):
1169 e = ast.Expr(ast.Name("x", ast.Store()))
1170 self.stmt(e, "must have Load context")
1171
1172 def test_boolop(self):
1173 b = ast.BoolOp(ast.And(), [])
1174 self.expr(b, "less than 2 values")
1175 b = ast.BoolOp(ast.And(), [ast.Num(3)])
1176 self.expr(b, "less than 2 values")
1177 b = ast.BoolOp(ast.And(), [ast.Num(4), None])
1178 self.expr(b, "None disallowed")
1179 b = ast.BoolOp(ast.And(), [ast.Num(4), ast.Name("x", ast.Store())])
1180 self.expr(b, "must have Load context")
1181
1182 def test_unaryop(self):
1183 u = ast.UnaryOp(ast.Not(), ast.Name("x", ast.Store()))
1184 self.expr(u, "must have Load context")
1185
1186 def test_lambda(self):
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01001187 a = ast.arguments([], [], None, [], [], None, [])
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001188 self.expr(ast.Lambda(a, ast.Name("x", ast.Store())),
1189 "must have Load context")
1190 def fac(args):
1191 return ast.Lambda(args, ast.Name("x", ast.Load()))
1192 self._check_arguments(fac, self.expr)
1193
1194 def test_ifexp(self):
1195 l = ast.Name("x", ast.Load())
1196 s = ast.Name("y", ast.Store())
1197 for args in (s, l, l), (l, s, l), (l, l, s):
Benjamin Peterson71ce8972011-08-09 16:17:12 -05001198 self.expr(ast.IfExp(*args), "must have Load context")
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001199
1200 def test_dict(self):
1201 d = ast.Dict([], [ast.Name("x", ast.Load())])
1202 self.expr(d, "same number of keys as values")
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001203 d = ast.Dict([ast.Name("x", ast.Load())], [None])
1204 self.expr(d, "None disallowed")
1205
1206 def test_set(self):
1207 self.expr(ast.Set([None]), "None disallowed")
1208 s = ast.Set([ast.Name("x", ast.Store())])
1209 self.expr(s, "must have Load context")
1210
1211 def _check_comprehension(self, fac):
1212 self.expr(fac([]), "comprehension with no generators")
1213 g = ast.comprehension(ast.Name("x", ast.Load()),
Yury Selivanov52c4e7c2016-09-09 10:36:01 -07001214 ast.Name("x", ast.Load()), [], 0)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001215 self.expr(fac([g]), "must have Store context")
1216 g = ast.comprehension(ast.Name("x", ast.Store()),
Yury Selivanov52c4e7c2016-09-09 10:36:01 -07001217 ast.Name("x", ast.Store()), [], 0)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001218 self.expr(fac([g]), "must have Load context")
1219 x = ast.Name("x", ast.Store())
1220 y = ast.Name("y", ast.Load())
Yury Selivanov52c4e7c2016-09-09 10:36:01 -07001221 g = ast.comprehension(x, y, [None], 0)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001222 self.expr(fac([g]), "None disallowed")
Yury Selivanov52c4e7c2016-09-09 10:36:01 -07001223 g = ast.comprehension(x, y, [ast.Name("x", ast.Store())], 0)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001224 self.expr(fac([g]), "must have Load context")
1225
1226 def _simple_comp(self, fac):
1227 g = ast.comprehension(ast.Name("x", ast.Store()),
Yury Selivanov52c4e7c2016-09-09 10:36:01 -07001228 ast.Name("x", ast.Load()), [], 0)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001229 self.expr(fac(ast.Name("x", ast.Store()), [g]),
1230 "must have Load context")
1231 def wrap(gens):
1232 return fac(ast.Name("x", ast.Store()), gens)
1233 self._check_comprehension(wrap)
1234
1235 def test_listcomp(self):
1236 self._simple_comp(ast.ListComp)
1237
1238 def test_setcomp(self):
1239 self._simple_comp(ast.SetComp)
1240
1241 def test_generatorexp(self):
1242 self._simple_comp(ast.GeneratorExp)
1243
1244 def test_dictcomp(self):
1245 g = ast.comprehension(ast.Name("y", ast.Store()),
Yury Selivanov52c4e7c2016-09-09 10:36:01 -07001246 ast.Name("p", ast.Load()), [], 0)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001247 c = ast.DictComp(ast.Name("x", ast.Store()),
1248 ast.Name("y", ast.Load()), [g])
1249 self.expr(c, "must have Load context")
1250 c = ast.DictComp(ast.Name("x", ast.Load()),
1251 ast.Name("y", ast.Store()), [g])
1252 self.expr(c, "must have Load context")
1253 def factory(comps):
1254 k = ast.Name("x", ast.Load())
1255 v = ast.Name("y", ast.Load())
1256 return ast.DictComp(k, v, comps)
1257 self._check_comprehension(factory)
1258
1259 def test_yield(self):
Benjamin Peterson527c6222012-01-14 08:58:23 -05001260 self.expr(ast.Yield(ast.Name("x", ast.Store())), "must have Load")
1261 self.expr(ast.YieldFrom(ast.Name("x", ast.Store())), "must have Load")
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001262
1263 def test_compare(self):
1264 left = ast.Name("x", ast.Load())
1265 comp = ast.Compare(left, [ast.In()], [])
1266 self.expr(comp, "no comparators")
1267 comp = ast.Compare(left, [ast.In()], [ast.Num(4), ast.Num(5)])
1268 self.expr(comp, "different number of comparators and operands")
1269 comp = ast.Compare(ast.Num("blah"), [ast.In()], [left])
Serhiy Storchaka3f228112018-09-27 17:42:37 +03001270 self.expr(comp)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001271 comp = ast.Compare(left, [ast.In()], [ast.Num("blah")])
Serhiy Storchaka3f228112018-09-27 17:42:37 +03001272 self.expr(comp)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001273
1274 def test_call(self):
1275 func = ast.Name("x", ast.Load())
1276 args = [ast.Name("y", ast.Load())]
1277 keywords = [ast.keyword("w", ast.Name("z", ast.Load()))]
Benjamin Peterson025e9eb2015-05-05 20:16:41 -04001278 call = ast.Call(ast.Name("x", ast.Store()), args, keywords)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001279 self.expr(call, "must have Load context")
Benjamin Peterson025e9eb2015-05-05 20:16:41 -04001280 call = ast.Call(func, [None], keywords)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001281 self.expr(call, "None disallowed")
1282 bad_keywords = [ast.keyword("w", ast.Name("z", ast.Store()))]
Benjamin Peterson025e9eb2015-05-05 20:16:41 -04001283 call = ast.Call(func, args, bad_keywords)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001284 self.expr(call, "must have Load context")
1285
1286 def test_num(self):
1287 class subint(int):
1288 pass
1289 class subfloat(float):
1290 pass
1291 class subcomplex(complex):
1292 pass
Serhiy Storchaka3f228112018-09-27 17:42:37 +03001293 for obj in "0", "hello":
1294 self.expr(ast.Num(obj))
1295 for obj in subint(), subfloat(), subcomplex():
1296 self.expr(ast.Num(obj), "invalid type", exc=TypeError)
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001297
1298 def test_attribute(self):
1299 attr = ast.Attribute(ast.Name("x", ast.Store()), "y", ast.Load())
1300 self.expr(attr, "must have Load context")
1301
1302 def test_subscript(self):
1303 sub = ast.Subscript(ast.Name("x", ast.Store()), ast.Index(ast.Num(3)),
1304 ast.Load())
1305 self.expr(sub, "must have Load context")
1306 x = ast.Name("x", ast.Load())
1307 sub = ast.Subscript(x, ast.Index(ast.Name("y", ast.Store())),
1308 ast.Load())
1309 self.expr(sub, "must have Load context")
1310 s = ast.Name("x", ast.Store())
1311 for args in (s, None, None), (None, s, None), (None, None, s):
1312 sl = ast.Slice(*args)
1313 self.expr(ast.Subscript(x, sl, ast.Load()),
1314 "must have Load context")
1315 sl = ast.ExtSlice([])
1316 self.expr(ast.Subscript(x, sl, ast.Load()), "empty dims on ExtSlice")
1317 sl = ast.ExtSlice([ast.Index(s)])
1318 self.expr(ast.Subscript(x, sl, ast.Load()), "must have Load context")
1319
1320 def test_starred(self):
1321 left = ast.List([ast.Starred(ast.Name("x", ast.Load()), ast.Store())],
1322 ast.Store())
1323 assign = ast.Assign([left], ast.Num(4))
1324 self.stmt(assign, "must have Store context")
1325
1326 def _sequence(self, fac):
1327 self.expr(fac([None], ast.Load()), "None disallowed")
1328 self.expr(fac([ast.Name("x", ast.Store())], ast.Load()),
1329 "must have Load context")
1330
1331 def test_list(self):
1332 self._sequence(ast.List)
1333
1334 def test_tuple(self):
1335 self._sequence(ast.Tuple)
1336
Benjamin Peterson442f2092012-12-06 17:41:04 -05001337 def test_nameconstant(self):
Serhiy Storchaka3f228112018-09-27 17:42:37 +03001338 self.expr(ast.NameConstant(4))
Benjamin Peterson442f2092012-12-06 17:41:04 -05001339
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001340 def test_stdlib_validates(self):
1341 stdlib = os.path.dirname(ast.__file__)
1342 tests = [fn for fn in os.listdir(stdlib) if fn.endswith(".py")]
1343 tests.extend(["test/test_grammar.py", "test/test_unpack_ex.py"])
1344 for module in tests:
Serhiy Storchaka3bcbedc2019-01-18 07:47:48 +02001345 with self.subTest(module):
1346 fn = os.path.join(stdlib, module)
1347 with open(fn, "r", encoding="utf-8") as fp:
1348 source = fp.read()
1349 mod = ast.parse(source, fn)
1350 compile(mod, fn, "exec")
Benjamin Peterson832bfe22011-08-09 16:15:04 -05001351
1352
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001353class ConstantTests(unittest.TestCase):
1354 """Tests on the ast.Constant node type."""
1355
1356 def compile_constant(self, value):
1357 tree = ast.parse("x = 123")
1358
1359 node = tree.body[0].value
1360 new_node = ast.Constant(value=value)
1361 ast.copy_location(new_node, node)
1362 tree.body[0].value = new_node
1363
1364 code = compile(tree, "<string>", "exec")
1365
1366 ns = {}
1367 exec(code, ns)
1368 return ns['x']
1369
Victor Stinnerbe59d142016-01-27 00:39:12 +01001370 def test_validation(self):
1371 with self.assertRaises(TypeError) as cm:
1372 self.compile_constant([1, 2, 3])
1373 self.assertEqual(str(cm.exception),
1374 "got an invalid type in Constant: list")
1375
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001376 def test_singletons(self):
1377 for const in (None, False, True, Ellipsis, b'', frozenset()):
1378 with self.subTest(const=const):
1379 value = self.compile_constant(const)
1380 self.assertIs(value, const)
1381
1382 def test_values(self):
1383 nested_tuple = (1,)
1384 nested_frozenset = frozenset({1})
1385 for level in range(3):
1386 nested_tuple = (nested_tuple, 2)
1387 nested_frozenset = frozenset({nested_frozenset, 2})
1388 values = (123, 123.0, 123j,
1389 "unicode", b'bytes',
1390 tuple("tuple"), frozenset("frozenset"),
1391 nested_tuple, nested_frozenset)
1392 for value in values:
1393 with self.subTest(value=value):
1394 result = self.compile_constant(value)
1395 self.assertEqual(result, value)
1396
1397 def test_assign_to_constant(self):
1398 tree = ast.parse("x = 1")
1399
1400 target = tree.body[0].targets[0]
1401 new_target = ast.Constant(value=1)
1402 ast.copy_location(new_target, target)
1403 tree.body[0].targets[0] = new_target
1404
1405 with self.assertRaises(ValueError) as cm:
1406 compile(tree, "string", "exec")
1407 self.assertEqual(str(cm.exception),
1408 "expression which can't be assigned "
1409 "to in Store context")
1410
1411 def test_get_docstring(self):
1412 tree = ast.parse("'docstring'\nx = 1")
1413 self.assertEqual(ast.get_docstring(tree), 'docstring')
1414
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001415 def get_load_const(self, tree):
1416 # Compile to bytecode, disassemble and get parameter of LOAD_CONST
1417 # instructions
1418 co = compile(tree, '<string>', 'exec')
1419 consts = []
1420 for instr in dis.get_instructions(co):
1421 if instr.opname == 'LOAD_CONST':
1422 consts.append(instr.argval)
1423 return consts
1424
1425 @support.cpython_only
1426 def test_load_const(self):
1427 consts = [None,
1428 True, False,
1429 124,
1430 2.0,
1431 3j,
1432 "unicode",
1433 b'bytes',
1434 (1, 2, 3)]
1435
Victor Stinnera2724092016-02-08 18:17:58 +01001436 code = '\n'.join(['x={!r}'.format(const) for const in consts])
1437 code += '\nx = ...'
1438 consts.extend((Ellipsis, None))
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001439
1440 tree = ast.parse(code)
Victor Stinnera2724092016-02-08 18:17:58 +01001441 self.assertEqual(self.get_load_const(tree),
1442 consts)
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001443
1444 # Replace expression nodes with constants
Victor Stinnera2724092016-02-08 18:17:58 +01001445 for assign, const in zip(tree.body, consts):
1446 assert isinstance(assign, ast.Assign), ast.dump(assign)
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001447 new_node = ast.Constant(value=const)
Victor Stinnera2724092016-02-08 18:17:58 +01001448 ast.copy_location(new_node, assign.value)
1449 assign.value = new_node
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001450
Victor Stinnera2724092016-02-08 18:17:58 +01001451 self.assertEqual(self.get_load_const(tree),
1452 consts)
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001453
1454 def test_literal_eval(self):
1455 tree = ast.parse("1 + 2")
1456 binop = tree.body[0].value
1457
1458 new_left = ast.Constant(value=10)
1459 ast.copy_location(new_left, binop.left)
1460 binop.left = new_left
1461
Serhiy Storchakad8ac4d12018-01-04 11:15:39 +02001462 new_right = ast.Constant(value=20j)
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001463 ast.copy_location(new_right, binop.right)
1464 binop.right = new_right
1465
Serhiy Storchakad8ac4d12018-01-04 11:15:39 +02001466 self.assertEqual(ast.literal_eval(binop), 10+20j)
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001467
Guido van Rossum10f8ce62019-03-13 13:00:46 -07001468 def test_string_kind(self):
1469 c = ast.parse('"x"', mode='eval').body
1470 self.assertEqual(c.value, "x")
1471 self.assertEqual(c.kind, None)
1472
1473 c = ast.parse('u"x"', mode='eval').body
1474 self.assertEqual(c.value, "x")
1475 self.assertEqual(c.kind, "u")
1476
1477 c = ast.parse('r"x"', mode='eval').body
1478 self.assertEqual(c.value, "x")
1479 self.assertEqual(c.kind, None)
1480
1481 c = ast.parse('b"x"', mode='eval').body
1482 self.assertEqual(c.value, b"x")
1483 self.assertEqual(c.kind, None)
1484
Victor Stinnerf2c1aa12016-01-26 00:40:57 +01001485
Ivan Levkivskyi9932a222019-01-22 11:18:22 +00001486class EndPositionTests(unittest.TestCase):
1487 """Tests for end position of AST nodes.
1488
1489 Testing end positions of nodes requires a bit of extra care
1490 because of how LL parsers work.
1491 """
1492 def _check_end_pos(self, ast_node, end_lineno, end_col_offset):
1493 self.assertEqual(ast_node.end_lineno, end_lineno)
1494 self.assertEqual(ast_node.end_col_offset, end_col_offset)
1495
1496 def _check_content(self, source, ast_node, content):
1497 self.assertEqual(ast.get_source_segment(source, ast_node), content)
1498
1499 def _parse_value(self, s):
1500 # Use duck-typing to support both single expression
1501 # and a right hand side of an assignment statement.
1502 return ast.parse(s).body[0].value
1503
1504 def test_lambda(self):
1505 s = 'lambda x, *y: None'
1506 lam = self._parse_value(s)
1507 self._check_content(s, lam.body, 'None')
1508 self._check_content(s, lam.args.args[0], 'x')
1509 self._check_content(s, lam.args.vararg, 'y')
1510
1511 def test_func_def(self):
1512 s = dedent('''
1513 def func(x: int,
1514 *args: str,
1515 z: float = 0,
1516 **kwargs: Any) -> bool:
1517 return True
1518 ''').strip()
1519 fdef = ast.parse(s).body[0]
1520 self._check_end_pos(fdef, 5, 15)
1521 self._check_content(s, fdef.body[0], 'return True')
1522 self._check_content(s, fdef.args.args[0], 'x: int')
1523 self._check_content(s, fdef.args.args[0].annotation, 'int')
1524 self._check_content(s, fdef.args.kwarg, 'kwargs: Any')
1525 self._check_content(s, fdef.args.kwarg.annotation, 'Any')
1526
1527 def test_call(self):
1528 s = 'func(x, y=2, **kw)'
1529 call = self._parse_value(s)
1530 self._check_content(s, call.func, 'func')
1531 self._check_content(s, call.keywords[0].value, '2')
1532 self._check_content(s, call.keywords[1].value, 'kw')
1533
1534 def test_call_noargs(self):
1535 s = 'x[0]()'
1536 call = self._parse_value(s)
1537 self._check_content(s, call.func, 'x[0]')
1538 self._check_end_pos(call, 1, 6)
1539
1540 def test_class_def(self):
1541 s = dedent('''
1542 class C(A, B):
1543 x: int = 0
1544 ''').strip()
1545 cdef = ast.parse(s).body[0]
1546 self._check_end_pos(cdef, 2, 14)
1547 self._check_content(s, cdef.bases[1], 'B')
1548 self._check_content(s, cdef.body[0], 'x: int = 0')
1549
1550 def test_class_kw(self):
1551 s = 'class S(metaclass=abc.ABCMeta): pass'
1552 cdef = ast.parse(s).body[0]
1553 self._check_content(s, cdef.keywords[0].value, 'abc.ABCMeta')
1554
1555 def test_multi_line_str(self):
1556 s = dedent('''
1557 x = """Some multi-line text.
1558
1559 It goes on starting from same indent."""
1560 ''').strip()
1561 assign = ast.parse(s).body[0]
1562 self._check_end_pos(assign, 3, 40)
1563 self._check_end_pos(assign.value, 3, 40)
1564
1565 def test_continued_str(self):
1566 s = dedent('''
1567 x = "first part" \\
1568 "second part"
1569 ''').strip()
1570 assign = ast.parse(s).body[0]
1571 self._check_end_pos(assign, 2, 13)
1572 self._check_end_pos(assign.value, 2, 13)
1573
1574 def test_suites(self):
1575 # We intentionally put these into the same string to check
1576 # that empty lines are not part of the suite.
1577 s = dedent('''
1578 while True:
1579 pass
1580
1581 if one():
1582 x = None
1583 elif other():
1584 y = None
1585 else:
1586 z = None
1587
1588 for x, y in stuff:
1589 assert True
1590
1591 try:
1592 raise RuntimeError
1593 except TypeError as e:
1594 pass
1595
1596 pass
1597 ''').strip()
1598 mod = ast.parse(s)
1599 while_loop = mod.body[0]
1600 if_stmt = mod.body[1]
1601 for_loop = mod.body[2]
1602 try_stmt = mod.body[3]
1603 pass_stmt = mod.body[4]
1604
1605 self._check_end_pos(while_loop, 2, 8)
1606 self._check_end_pos(if_stmt, 9, 12)
1607 self._check_end_pos(for_loop, 12, 15)
1608 self._check_end_pos(try_stmt, 17, 8)
1609 self._check_end_pos(pass_stmt, 19, 4)
1610
1611 self._check_content(s, while_loop.test, 'True')
1612 self._check_content(s, if_stmt.body[0], 'x = None')
1613 self._check_content(s, if_stmt.orelse[0].test, 'other()')
1614 self._check_content(s, for_loop.target, 'x, y')
1615 self._check_content(s, try_stmt.body[0], 'raise RuntimeError')
1616 self._check_content(s, try_stmt.handlers[0].type, 'TypeError')
1617
1618 def test_fstring(self):
1619 s = 'x = f"abc {x + y} abc"'
1620 fstr = self._parse_value(s)
1621 binop = fstr.values[1].value
1622 self._check_content(s, binop, 'x + y')
1623
1624 def test_fstring_multi_line(self):
1625 s = dedent('''
1626 f"""Some multi-line text.
1627 {
1628 arg_one
1629 +
1630 arg_two
1631 }
1632 It goes on..."""
1633 ''').strip()
1634 fstr = self._parse_value(s)
1635 binop = fstr.values[1].value
1636 self._check_end_pos(binop, 5, 7)
1637 self._check_content(s, binop.left, 'arg_one')
1638 self._check_content(s, binop.right, 'arg_two')
1639
1640 def test_import_from_multi_line(self):
1641 s = dedent('''
1642 from x.y.z import (
1643 a, b, c as c
1644 )
1645 ''').strip()
1646 imp = ast.parse(s).body[0]
1647 self._check_end_pos(imp, 3, 1)
1648
1649 def test_slices(self):
1650 s1 = 'f()[1, 2] [0]'
1651 s2 = 'x[ a.b: c.d]'
1652 sm = dedent('''
1653 x[ a.b: f () ,
1654 g () : c.d
1655 ]
1656 ''').strip()
1657 i1, i2, im = map(self._parse_value, (s1, s2, sm))
1658 self._check_content(s1, i1.value, 'f()[1, 2]')
1659 self._check_content(s1, i1.value.slice.value, '1, 2')
1660 self._check_content(s2, i2.slice.lower, 'a.b')
1661 self._check_content(s2, i2.slice.upper, 'c.d')
1662 self._check_content(sm, im.slice.dims[0].upper, 'f ()')
1663 self._check_content(sm, im.slice.dims[1].lower, 'g ()')
1664 self._check_end_pos(im, 3, 3)
1665
1666 def test_binop(self):
1667 s = dedent('''
1668 (1 * 2 + (3 ) +
1669 4
1670 )
1671 ''').strip()
1672 binop = self._parse_value(s)
1673 self._check_end_pos(binop, 2, 6)
1674 self._check_content(s, binop.right, '4')
1675 self._check_content(s, binop.left, '1 * 2 + (3 )')
1676 self._check_content(s, binop.left.right, '3')
1677
1678 def test_boolop(self):
1679 s = dedent('''
1680 if (one_condition and
1681 (other_condition or yet_another_one)):
1682 pass
1683 ''').strip()
1684 bop = ast.parse(s).body[0].test
1685 self._check_end_pos(bop, 2, 44)
1686 self._check_content(s, bop.values[1],
1687 'other_condition or yet_another_one')
1688
1689 def test_tuples(self):
1690 s1 = 'x = () ;'
1691 s2 = 'x = 1 , ;'
1692 s3 = 'x = (1 , 2 ) ;'
1693 sm = dedent('''
1694 x = (
1695 a, b,
1696 )
1697 ''').strip()
1698 t1, t2, t3, tm = map(self._parse_value, (s1, s2, s3, sm))
1699 self._check_content(s1, t1, '()')
1700 self._check_content(s2, t2, '1 ,')
1701 self._check_content(s3, t3, '(1 , 2 )')
1702 self._check_end_pos(tm, 3, 1)
1703
1704 def test_attribute_spaces(self):
1705 s = 'func(x. y .z)'
1706 call = self._parse_value(s)
1707 self._check_content(s, call, s)
1708 self._check_content(s, call.args[0], 'x. y .z')
1709
Serhiy Storchaka6e619c42020-02-12 22:37:49 +02001710 def test_redundant_parenthesis(self):
1711 s = '( ( ( a + b ) ) )'
1712 v = ast.parse(s).body[0].value
1713 self.assertEqual(type(v).__name__, 'BinOp')
1714 self._check_content(s, v, 'a + b')
1715 s2 = 'await ' + s
1716 v = ast.parse(s2).body[0].value.value
1717 self.assertEqual(type(v).__name__, 'BinOp')
1718 self._check_content(s2, v, 'a + b')
1719
1720 def test_trailers_with_redundant_parenthesis(self):
1721 tests = (
1722 ('( ( ( a ) ) ) ( )', 'Call'),
1723 ('( ( ( a ) ) ) ( b )', 'Call'),
1724 ('( ( ( a ) ) ) [ b ]', 'Subscript'),
1725 ('( ( ( a ) ) ) . b', 'Attribute'),
1726 )
1727 for s, t in tests:
1728 with self.subTest(s):
1729 v = ast.parse(s).body[0].value
1730 self.assertEqual(type(v).__name__, t)
1731 self._check_content(s, v, s)
1732 s2 = 'await ' + s
1733 v = ast.parse(s2).body[0].value.value
1734 self.assertEqual(type(v).__name__, t)
1735 self._check_content(s2, v, s)
1736
Ivan Levkivskyi9932a222019-01-22 11:18:22 +00001737 def test_displays(self):
1738 s1 = '[{}, {1, }, {1, 2,} ]'
1739 s2 = '{a: b, f (): g () ,}'
1740 c1 = self._parse_value(s1)
1741 c2 = self._parse_value(s2)
1742 self._check_content(s1, c1.elts[0], '{}')
1743 self._check_content(s1, c1.elts[1], '{1, }')
1744 self._check_content(s1, c1.elts[2], '{1, 2,}')
1745 self._check_content(s2, c2.keys[1], 'f ()')
1746 self._check_content(s2, c2.values[1], 'g ()')
1747
1748 def test_comprehensions(self):
1749 s = dedent('''
1750 x = [{x for x, y in stuff
1751 if cond.x} for stuff in things]
1752 ''').strip()
1753 cmp = self._parse_value(s)
1754 self._check_end_pos(cmp, 2, 37)
1755 self._check_content(s, cmp.generators[0].iter, 'things')
1756 self._check_content(s, cmp.elt.generators[0].iter, 'stuff')
1757 self._check_content(s, cmp.elt.generators[0].ifs[0], 'cond.x')
1758 self._check_content(s, cmp.elt.generators[0].target, 'x, y')
1759
1760 def test_yield_await(self):
1761 s = dedent('''
1762 async def f():
1763 yield x
1764 await y
1765 ''').strip()
1766 fdef = ast.parse(s).body[0]
1767 self._check_content(s, fdef.body[0].value, 'yield x')
1768 self._check_content(s, fdef.body[1].value, 'await y')
1769
1770 def test_source_segment_multi(self):
1771 s_orig = dedent('''
1772 x = (
1773 a, b,
1774 ) + ()
1775 ''').strip()
1776 s_tuple = dedent('''
1777 (
1778 a, b,
1779 )
1780 ''').strip()
1781 binop = self._parse_value(s_orig)
1782 self.assertEqual(ast.get_source_segment(s_orig, binop.left), s_tuple)
1783
1784 def test_source_segment_padded(self):
1785 s_orig = dedent('''
1786 class C:
1787 def fun(self) -> None:
1788 "Đ–Đ–Đ–Đ–Đ–"
1789 ''').strip()
1790 s_method = ' def fun(self) -> None:\n' \
1791 ' "Đ–Đ–Đ–Đ–Đ–"'
1792 cdef = ast.parse(s_orig).body[0]
1793 self.assertEqual(ast.get_source_segment(s_orig, cdef.body[0], padded=True),
1794 s_method)
1795
1796 def test_source_segment_endings(self):
1797 s = 'v = 1\r\nw = 1\nx = 1\n\ry = 1\rz = 1\r\n'
1798 v, w, x, y, z = ast.parse(s).body
1799 self._check_content(s, v, 'v = 1')
1800 self._check_content(s, w, 'w = 1')
1801 self._check_content(s, x, 'x = 1')
1802 self._check_content(s, y, 'y = 1')
1803 self._check_content(s, z, 'z = 1')
1804
1805 def test_source_segment_tabs(self):
1806 s = dedent('''
1807 class C:
1808 \t\f def fun(self) -> None:
1809 \t\f pass
1810 ''').strip()
1811 s_method = ' \t\f def fun(self) -> None:\n' \
1812 ' \t\f pass'
1813
1814 cdef = ast.parse(s).body[0]
1815 self.assertEqual(ast.get_source_segment(s, cdef.body[0], padded=True), s_method)
1816
1817
Serhiy Storchakac3ea41e2019-08-26 10:13:19 +03001818class NodeVisitorTests(unittest.TestCase):
1819 def test_old_constant_nodes(self):
1820 class Visitor(ast.NodeVisitor):
1821 def visit_Num(self, node):
1822 log.append((node.lineno, 'Num', node.n))
1823 def visit_Str(self, node):
1824 log.append((node.lineno, 'Str', node.s))
1825 def visit_Bytes(self, node):
1826 log.append((node.lineno, 'Bytes', node.s))
1827 def visit_NameConstant(self, node):
1828 log.append((node.lineno, 'NameConstant', node.value))
1829 def visit_Ellipsis(self, node):
1830 log.append((node.lineno, 'Ellipsis', ...))
1831 mod = ast.parse(dedent('''\
1832 i = 42
1833 f = 4.25
1834 c = 4.25j
1835 s = 'string'
1836 b = b'bytes'
1837 t = True
1838 n = None
1839 e = ...
1840 '''))
1841 visitor = Visitor()
1842 log = []
1843 with warnings.catch_warnings(record=True) as wlog:
1844 warnings.filterwarnings('always', '', DeprecationWarning)
1845 visitor.visit(mod)
1846 self.assertEqual(log, [
1847 (1, 'Num', 42),
1848 (2, 'Num', 4.25),
1849 (3, 'Num', 4.25j),
1850 (4, 'Str', 'string'),
1851 (5, 'Bytes', b'bytes'),
1852 (6, 'NameConstant', True),
1853 (7, 'NameConstant', None),
1854 (8, 'Ellipsis', ...),
1855 ])
1856 self.assertEqual([str(w.message) for w in wlog], [
1857 'visit_Num is deprecated; add visit_Constant',
1858 'visit_Num is deprecated; add visit_Constant',
1859 'visit_Num is deprecated; add visit_Constant',
1860 'visit_Str is deprecated; add visit_Constant',
1861 'visit_Bytes is deprecated; add visit_Constant',
1862 'visit_NameConstant is deprecated; add visit_Constant',
1863 'visit_NameConstant is deprecated; add visit_Constant',
1864 'visit_Ellipsis is deprecated; add visit_Constant',
1865 ])
1866
1867
Neal Norwitzee9b10a2008-03-31 05:29:39 +00001868def main():
1869 if __name__ != '__main__':
Martin v. Löwis49c5da12006-03-01 22:49:05 +00001870 return
Neal Norwitzee9b10a2008-03-31 05:29:39 +00001871 if sys.argv[1:] == ['-g']:
1872 for statements, kind in ((exec_tests, "exec"), (single_tests, "single"),
1873 (eval_tests, "eval")):
1874 print(kind+"_results = [")
Victor Stinnerf0891962016-02-08 17:15:21 +01001875 for statement in statements:
1876 tree = ast.parse(statement, "?", kind)
1877 print("%r," % (to_tuple(tree),))
Neal Norwitzee9b10a2008-03-31 05:29:39 +00001878 print("]")
1879 print("main()")
1880 raise SystemExit
Brett Cannon3e9a9ae2013-06-12 21:25:59 -04001881 unittest.main()
Tim Peters400cbc32006-02-28 18:44:41 +00001882
Guido van Rossumdcfcd142019-01-31 03:40:27 -08001883#### EVERYTHING BELOW IS GENERATED BY python Lib/test/test_ast.py -g #####
Tim Peters400cbc32006-02-28 18:44:41 +00001884exec_results = [
Serhiy Storchaka850a8852020-01-10 10:12:55 +02001885('Module', [('Expr', (1, 0, 1, 4), ('Constant', (1, 0, 1, 4), None, None))], []),
1886('Module', [('Expr', (1, 0, 1, 18), ('Constant', (1, 0, 1, 18), 'module docstring', None))], []),
1887('Module', [('FunctionDef', (1, 0, 1, 13), 'f', ('arguments', [], [], None, [], [], None, []), [('Pass', (1, 9, 1, 13))], [], None, None)], []),
1888('Module', [('FunctionDef', (1, 0, 1, 29), 'f', ('arguments', [], [], None, [], [], None, []), [('Expr', (1, 9, 1, 29), ('Constant', (1, 9, 1, 29), 'function docstring', None))], [], None, None)], []),
1889('Module', [('FunctionDef', (1, 0, 1, 14), 'f', ('arguments', [], [('arg', (1, 6, 1, 7), 'a', None, None)], None, [], [], None, []), [('Pass', (1, 10, 1, 14))], [], None, None)], []),
1890('Module', [('FunctionDef', (1, 0, 1, 16), 'f', ('arguments', [], [('arg', (1, 6, 1, 7), 'a', None, None)], None, [], [], None, [('Constant', (1, 8, 1, 9), 0, None)]), [('Pass', (1, 12, 1, 16))], [], None, None)], []),
1891('Module', [('FunctionDef', (1, 0, 1, 18), 'f', ('arguments', [], [], ('arg', (1, 7, 1, 11), 'args', None, None), [], [], None, []), [('Pass', (1, 14, 1, 18))], [], None, None)], []),
1892('Module', [('FunctionDef', (1, 0, 1, 21), 'f', ('arguments', [], [], None, [], [], ('arg', (1, 8, 1, 14), 'kwargs', None, None), []), [('Pass', (1, 17, 1, 21))], [], None, None)], []),
1893('Module', [('FunctionDef', (1, 0, 1, 71), 'f', ('arguments', [], [('arg', (1, 6, 1, 7), 'a', None, None), ('arg', (1, 9, 1, 10), 'b', None, None), ('arg', (1, 14, 1, 15), 'c', None, None), ('arg', (1, 22, 1, 23), 'd', None, None), ('arg', (1, 28, 1, 29), 'e', None, None)], ('arg', (1, 35, 1, 39), 'args', None, None), [('arg', (1, 41, 1, 42), 'f', None, None)], [('Constant', (1, 43, 1, 45), 42, None)], ('arg', (1, 49, 1, 55), 'kwargs', None, None), [('Constant', (1, 11, 1, 12), 1, None), ('Constant', (1, 16, 1, 20), None, None), ('List', (1, 24, 1, 26), [], ('Load',)), ('Dict', (1, 30, 1, 32), [], [])]), [('Expr', (1, 58, 1, 71), ('Constant', (1, 58, 1, 71), 'doc for f()', None))], [], None, None)], []),
1894('Module', [('ClassDef', (1, 0, 1, 12), 'C', [], [], [('Pass', (1, 8, 1, 12))], [])], []),
1895('Module', [('ClassDef', (1, 0, 1, 32), 'C', [], [], [('Expr', (1, 9, 1, 32), ('Constant', (1, 9, 1, 32), 'docstring for class C', None))], [])], []),
1896('Module', [('ClassDef', (1, 0, 1, 21), 'C', [('Name', (1, 8, 1, 14), 'object', ('Load',))], [], [('Pass', (1, 17, 1, 21))], [])], []),
1897('Module', [('FunctionDef', (1, 0, 1, 16), 'f', ('arguments', [], [], None, [], [], None, []), [('Return', (1, 8, 1, 16), ('Constant', (1, 15, 1, 16), 1, None))], [], None, None)], []),
1898('Module', [('Delete', (1, 0, 1, 5), [('Name', (1, 4, 1, 5), 'v', ('Del',))])], []),
1899('Module', [('Assign', (1, 0, 1, 5), [('Name', (1, 0, 1, 1), 'v', ('Store',))], ('Constant', (1, 4, 1, 5), 1, None), None)], []),
1900('Module', [('Assign', (1, 0, 1, 7), [('Tuple', (1, 0, 1, 3), [('Name', (1, 0, 1, 1), 'a', ('Store',)), ('Name', (1, 2, 1, 3), 'b', ('Store',))], ('Store',))], ('Name', (1, 6, 1, 7), 'c', ('Load',)), None)], []),
1901('Module', [('Assign', (1, 0, 1, 9), [('Tuple', (1, 0, 1, 5), [('Name', (1, 1, 1, 2), 'a', ('Store',)), ('Name', (1, 3, 1, 4), 'b', ('Store',))], ('Store',))], ('Name', (1, 8, 1, 9), 'c', ('Load',)), None)], []),
1902('Module', [('Assign', (1, 0, 1, 9), [('List', (1, 0, 1, 5), [('Name', (1, 1, 1, 2), 'a', ('Store',)), ('Name', (1, 3, 1, 4), 'b', ('Store',))], ('Store',))], ('Name', (1, 8, 1, 9), 'c', ('Load',)), None)], []),
1903('Module', [('AugAssign', (1, 0, 1, 6), ('Name', (1, 0, 1, 1), 'v', ('Store',)), ('Add',), ('Constant', (1, 5, 1, 6), 1, None))], []),
1904('Module', [('For', (1, 0, 1, 15), ('Name', (1, 4, 1, 5), 'v', ('Store',)), ('Name', (1, 9, 1, 10), 'v', ('Load',)), [('Pass', (1, 11, 1, 15))], [], None)], []),
1905('Module', [('While', (1, 0, 1, 12), ('Name', (1, 6, 1, 7), 'v', ('Load',)), [('Pass', (1, 8, 1, 12))], [])], []),
1906('Module', [('If', (1, 0, 1, 9), ('Name', (1, 3, 1, 4), 'v', ('Load',)), [('Pass', (1, 5, 1, 9))], [])], []),
1907('Module', [('If', (1, 0, 4, 6), ('Name', (1, 3, 1, 4), 'a', ('Load',)), [('Pass', (2, 2, 2, 6))], [('If', (3, 0, 4, 6), ('Name', (3, 5, 3, 6), 'b', ('Load',)), [('Pass', (4, 2, 4, 6))], [])])], []),
1908('Module', [('If', (1, 0, 6, 6), ('Name', (1, 3, 1, 4), 'a', ('Load',)), [('Pass', (2, 2, 2, 6))], [('If', (3, 0, 6, 6), ('Name', (3, 5, 3, 6), 'b', ('Load',)), [('Pass', (4, 2, 4, 6))], [('Pass', (6, 2, 6, 6))])])], []),
1909('Module', [('With', (1, 0, 1, 17), [('withitem', ('Name', (1, 5, 1, 6), 'x', ('Load',)), ('Name', (1, 10, 1, 11), 'y', ('Store',)))], [('Pass', (1, 13, 1, 17))], None)], []),
1910('Module', [('With', (1, 0, 1, 25), [('withitem', ('Name', (1, 5, 1, 6), 'x', ('Load',)), ('Name', (1, 10, 1, 11), 'y', ('Store',))), ('withitem', ('Name', (1, 13, 1, 14), 'z', ('Load',)), ('Name', (1, 18, 1, 19), 'q', ('Store',)))], [('Pass', (1, 21, 1, 25))], None)], []),
1911('Module', [('Raise', (1, 0, 1, 25), ('Call', (1, 6, 1, 25), ('Name', (1, 6, 1, 15), 'Exception', ('Load',)), [('Constant', (1, 16, 1, 24), 'string', None)], []), None)], []),
1912('Module', [('Try', (1, 0, 4, 6), [('Pass', (2, 2, 2, 6))], [('ExceptHandler', (3, 0, 4, 6), ('Name', (3, 7, 3, 16), 'Exception', ('Load',)), None, [('Pass', (4, 2, 4, 6))])], [], [])], []),
1913('Module', [('Try', (1, 0, 4, 6), [('Pass', (2, 2, 2, 6))], [], [], [('Pass', (4, 2, 4, 6))])], []),
1914('Module', [('Assert', (1, 0, 1, 8), ('Name', (1, 7, 1, 8), 'v', ('Load',)), None)], []),
1915('Module', [('Import', (1, 0, 1, 10), [('alias', 'sys', None)])], []),
1916('Module', [('ImportFrom', (1, 0, 1, 17), 'sys', [('alias', 'v', None)], 0)], []),
1917('Module', [('Global', (1, 0, 1, 8), ['v'])], []),
1918('Module', [('Expr', (1, 0, 1, 1), ('Constant', (1, 0, 1, 1), 1, None))], []),
1919('Module', [('Pass', (1, 0, 1, 4))], []),
1920('Module', [('For', (1, 0, 1, 16), ('Name', (1, 4, 1, 5), 'v', ('Store',)), ('Name', (1, 9, 1, 10), 'v', ('Load',)), [('Break', (1, 11, 1, 16))], [], None)], []),
1921('Module', [('For', (1, 0, 1, 19), ('Name', (1, 4, 1, 5), 'v', ('Store',)), ('Name', (1, 9, 1, 10), 'v', ('Load',)), [('Continue', (1, 11, 1, 19))], [], None)], []),
1922('Module', [('For', (1, 0, 1, 18), ('Tuple', (1, 4, 1, 7), [('Name', (1, 4, 1, 5), 'a', ('Store',)), ('Name', (1, 6, 1, 7), 'b', ('Store',))], ('Store',)), ('Name', (1, 11, 1, 12), 'c', ('Load',)), [('Pass', (1, 14, 1, 18))], [], None)], []),
1923('Module', [('For', (1, 0, 1, 20), ('Tuple', (1, 4, 1, 9), [('Name', (1, 5, 1, 6), 'a', ('Store',)), ('Name', (1, 7, 1, 8), 'b', ('Store',))], ('Store',)), ('Name', (1, 13, 1, 14), 'c', ('Load',)), [('Pass', (1, 16, 1, 20))], [], None)], []),
1924('Module', [('For', (1, 0, 1, 20), ('List', (1, 4, 1, 9), [('Name', (1, 5, 1, 6), 'a', ('Store',)), ('Name', (1, 7, 1, 8), 'b', ('Store',))], ('Store',)), ('Name', (1, 13, 1, 14), 'c', ('Load',)), [('Pass', (1, 16, 1, 20))], [], None)], []),
1925('Module', [('Expr', (1, 0, 11, 5), ('GeneratorExp', (1, 0, 11, 5), ('Tuple', (2, 4, 6, 5), [('Name', (3, 4, 3, 6), 'Aa', ('Load',)), ('Name', (5, 7, 5, 9), 'Bb', ('Load',))], ('Load',)), [('comprehension', ('Tuple', (8, 4, 10, 6), [('Name', (8, 4, 8, 6), 'Aa', ('Store',)), ('Name', (10, 4, 10, 6), 'Bb', ('Store',))], ('Store',)), ('Name', (10, 10, 10, 12), 'Cc', ('Load',)), [], 0)]))], []),
1926('Module', [('Expr', (1, 0, 1, 34), ('DictComp', (1, 0, 1, 34), ('Name', (1, 1, 1, 2), 'a', ('Load',)), ('Name', (1, 5, 1, 6), 'b', ('Load',)), [('comprehension', ('Name', (1, 11, 1, 12), 'w', ('Store',)), ('Name', (1, 16, 1, 17), 'x', ('Load',)), [], 0), ('comprehension', ('Name', (1, 22, 1, 23), 'm', ('Store',)), ('Name', (1, 27, 1, 28), 'p', ('Load',)), [('Name', (1, 32, 1, 33), 'g', ('Load',))], 0)]))], []),
1927('Module', [('Expr', (1, 0, 1, 20), ('DictComp', (1, 0, 1, 20), ('Name', (1, 1, 1, 2), 'a', ('Load',)), ('Name', (1, 5, 1, 6), 'b', ('Load',)), [('comprehension', ('Tuple', (1, 11, 1, 14), [('Name', (1, 11, 1, 12), 'v', ('Store',)), ('Name', (1, 13, 1, 14), 'w', ('Store',))], ('Store',)), ('Name', (1, 18, 1, 19), 'x', ('Load',)), [], 0)]))], []),
1928('Module', [('Expr', (1, 0, 1, 19), ('SetComp', (1, 0, 1, 19), ('Name', (1, 1, 1, 2), 'r', ('Load',)), [('comprehension', ('Name', (1, 7, 1, 8), 'l', ('Store',)), ('Name', (1, 12, 1, 13), 'x', ('Load',)), [('Name', (1, 17, 1, 18), 'g', ('Load',))], 0)]))], []),
1929('Module', [('Expr', (1, 0, 1, 16), ('SetComp', (1, 0, 1, 16), ('Name', (1, 1, 1, 2), 'r', ('Load',)), [('comprehension', ('Tuple', (1, 7, 1, 10), [('Name', (1, 7, 1, 8), 'l', ('Store',)), ('Name', (1, 9, 1, 10), 'm', ('Store',))], ('Store',)), ('Name', (1, 14, 1, 15), 'x', ('Load',)), [], 0)]))], []),
1930('Module', [('AsyncFunctionDef', (1, 0, 3, 18), 'f', ('arguments', [], [], None, [], [], None, []), [('Expr', (2, 1, 2, 17), ('Constant', (2, 1, 2, 17), 'async function', None)), ('Expr', (3, 1, 3, 18), ('Await', (3, 1, 3, 18), ('Call', (3, 7, 3, 18), ('Name', (3, 7, 3, 16), 'something', ('Load',)), [], [])))], [], None, None)], []),
1931('Module', [('AsyncFunctionDef', (1, 0, 3, 8), 'f', ('arguments', [], [], None, [], [], None, []), [('AsyncFor', (2, 1, 3, 8), ('Name', (2, 11, 2, 12), 'e', ('Store',)), ('Name', (2, 16, 2, 17), 'i', ('Load',)), [('Expr', (2, 19, 2, 20), ('Constant', (2, 19, 2, 20), 1, None))], [('Expr', (3, 7, 3, 8), ('Constant', (3, 7, 3, 8), 2, None))], None)], [], None, None)], []),
1932('Module', [('AsyncFunctionDef', (1, 0, 2, 21), 'f', ('arguments', [], [], None, [], [], None, []), [('AsyncWith', (2, 1, 2, 21), [('withitem', ('Name', (2, 12, 2, 13), 'a', ('Load',)), ('Name', (2, 17, 2, 18), 'b', ('Store',)))], [('Expr', (2, 20, 2, 21), ('Constant', (2, 20, 2, 21), 1, None))], None)], [], None, None)], []),
1933('Module', [('Expr', (1, 0, 1, 14), ('Dict', (1, 0, 1, 14), [None, ('Constant', (1, 10, 1, 11), 2, None)], [('Dict', (1, 3, 1, 8), [('Constant', (1, 4, 1, 5), 1, None)], [('Constant', (1, 6, 1, 7), 2, None)]), ('Constant', (1, 12, 1, 13), 3, None)]))], []),
1934('Module', [('Expr', (1, 0, 1, 12), ('Set', (1, 0, 1, 12), [('Starred', (1, 1, 1, 8), ('Set', (1, 2, 1, 8), [('Constant', (1, 3, 1, 4), 1, None), ('Constant', (1, 6, 1, 7), 2, None)]), ('Load',)), ('Constant', (1, 10, 1, 11), 3, None)]))], []),
1935('Module', [('AsyncFunctionDef', (1, 0, 2, 21), 'f', ('arguments', [], [], None, [], [], None, []), [('Expr', (2, 1, 2, 21), ('ListComp', (2, 1, 2, 21), ('Name', (2, 2, 2, 3), 'i', ('Load',)), [('comprehension', ('Name', (2, 14, 2, 15), 'b', ('Store',)), ('Name', (2, 19, 2, 20), 'c', ('Load',)), [], 1)]))], [], None, None)], []),
1936('Module', [('FunctionDef', (4, 0, 4, 13), 'f', ('arguments', [], [], None, [], [], None, []), [('Pass', (4, 9, 4, 13))], [('Name', (1, 1, 1, 6), 'deco1', ('Load',)), ('Call', (2, 1, 2, 8), ('Name', (2, 1, 2, 6), 'deco2', ('Load',)), [], []), ('Call', (3, 1, 3, 9), ('Name', (3, 1, 3, 6), 'deco3', ('Load',)), [('Constant', (3, 7, 3, 8), 1, None)], [])], None, None)], []),
1937('Module', [('AsyncFunctionDef', (4, 0, 4, 19), 'f', ('arguments', [], [], None, [], [], None, []), [('Pass', (4, 15, 4, 19))], [('Name', (1, 1, 1, 6), 'deco1', ('Load',)), ('Call', (2, 1, 2, 8), ('Name', (2, 1, 2, 6), 'deco2', ('Load',)), [], []), ('Call', (3, 1, 3, 9), ('Name', (3, 1, 3, 6), 'deco3', ('Load',)), [('Constant', (3, 7, 3, 8), 1, None)], [])], None, None)], []),
1938('Module', [('ClassDef', (4, 0, 4, 13), 'C', [], [], [('Pass', (4, 9, 4, 13))], [('Name', (1, 1, 1, 6), 'deco1', ('Load',)), ('Call', (2, 1, 2, 8), ('Name', (2, 1, 2, 6), 'deco2', ('Load',)), [], []), ('Call', (3, 1, 3, 9), ('Name', (3, 1, 3, 6), 'deco3', ('Load',)), [('Constant', (3, 7, 3, 8), 1, None)], [])])], []),
1939('Module', [('FunctionDef', (2, 0, 2, 13), 'f', ('arguments', [], [], None, [], [], None, []), [('Pass', (2, 9, 2, 13))], [('Call', (1, 1, 1, 19), ('Name', (1, 1, 1, 5), 'deco', ('Load',)), [('GeneratorExp', (1, 5, 1, 19), ('Name', (1, 6, 1, 7), 'a', ('Load',)), [('comprehension', ('Name', (1, 12, 1, 13), 'a', ('Store',)), ('Name', (1, 17, 1, 18), 'b', ('Load',)), [], 0)])], [])], None, None)], []),
Lysandros Nikolaoud2e10982020-02-08 00:36:32 +01001940('Module', [('FunctionDef', (2, 0, 2, 13), 'f', ('arguments', [], [], None, [], [], None, []), [('Pass', (2, 9, 2, 13))], [('Attribute', (1, 1, 1, 6), ('Attribute', (1, 1, 1, 4), ('Name', (1, 1, 1, 2), 'a', ('Load',)), 'b', ('Load',)), 'c', ('Load',))], None, None)], []),
Serhiy Storchaka850a8852020-01-10 10:12:55 +02001941('Module', [('Expr', (1, 0, 1, 8), ('NamedExpr', (1, 1, 1, 7), ('Name', (1, 1, 1, 2), 'a', ('Store',)), ('Constant', (1, 6, 1, 7), 1, None)))], []),
1942('Module', [('FunctionDef', (1, 0, 1, 18), 'f', ('arguments', [('arg', (1, 6, 1, 7), 'a', None, None)], [], None, [], [], None, []), [('Pass', (1, 14, 1, 18))], [], None, None)], []),
1943('Module', [('FunctionDef', (1, 0, 1, 26), 'f', ('arguments', [('arg', (1, 6, 1, 7), 'a', None, None)], [('arg', (1, 12, 1, 13), 'c', None, None), ('arg', (1, 15, 1, 16), 'd', None, None), ('arg', (1, 18, 1, 19), 'e', None, None)], None, [], [], None, []), [('Pass', (1, 22, 1, 26))], [], None, None)], []),
1944('Module', [('FunctionDef', (1, 0, 1, 29), 'f', ('arguments', [('arg', (1, 6, 1, 7), 'a', None, None)], [('arg', (1, 12, 1, 13), 'c', None, None)], None, [('arg', (1, 18, 1, 19), 'd', None, None), ('arg', (1, 21, 1, 22), 'e', None, None)], [None, None], None, []), [('Pass', (1, 25, 1, 29))], [], None, None)], []),
1945('Module', [('FunctionDef', (1, 0, 1, 39), 'f', ('arguments', [('arg', (1, 6, 1, 7), 'a', None, None)], [('arg', (1, 12, 1, 13), 'c', None, None)], None, [('arg', (1, 18, 1, 19), 'd', None, None), ('arg', (1, 21, 1, 22), 'e', None, None)], [None, None], ('arg', (1, 26, 1, 32), 'kwargs', None, None), []), [('Pass', (1, 35, 1, 39))], [], None, None)], []),
1946('Module', [('FunctionDef', (1, 0, 1, 20), 'f', ('arguments', [('arg', (1, 6, 1, 7), 'a', None, None)], [], None, [], [], None, [('Constant', (1, 8, 1, 9), 1, None)]), [('Pass', (1, 16, 1, 20))], [], None, None)], []),
1947('Module', [('FunctionDef', (1, 0, 1, 29), 'f', ('arguments', [('arg', (1, 6, 1, 7), 'a', None, None)], [('arg', (1, 14, 1, 15), 'b', None, None), ('arg', (1, 19, 1, 20), 'c', None, None)], None, [], [], None, [('Constant', (1, 8, 1, 9), 1, None), ('Constant', (1, 16, 1, 17), 2, None), ('Constant', (1, 21, 1, 22), 4, None)]), [('Pass', (1, 25, 1, 29))], [], None, None)], []),
1948('Module', [('FunctionDef', (1, 0, 1, 32), 'f', ('arguments', [('arg', (1, 6, 1, 7), 'a', None, None)], [('arg', (1, 14, 1, 15), 'b', None, None)], None, [('arg', (1, 22, 1, 23), 'c', None, None)], [('Constant', (1, 24, 1, 25), 4, None)], None, [('Constant', (1, 8, 1, 9), 1, None), ('Constant', (1, 16, 1, 17), 2, None)]), [('Pass', (1, 28, 1, 32))], [], None, None)], []),
1949('Module', [('FunctionDef', (1, 0, 1, 30), 'f', ('arguments', [('arg', (1, 6, 1, 7), 'a', None, None)], [('arg', (1, 14, 1, 15), 'b', None, None)], None, [('arg', (1, 22, 1, 23), 'c', None, None)], [None], None, [('Constant', (1, 8, 1, 9), 1, None), ('Constant', (1, 16, 1, 17), 2, None)]), [('Pass', (1, 26, 1, 30))], [], None, None)], []),
1950('Module', [('FunctionDef', (1, 0, 1, 42), 'f', ('arguments', [('arg', (1, 6, 1, 7), 'a', None, None)], [('arg', (1, 14, 1, 15), 'b', None, None)], None, [('arg', (1, 22, 1, 23), 'c', None, None)], [('Constant', (1, 24, 1, 25), 4, None)], ('arg', (1, 29, 1, 35), 'kwargs', None, None), [('Constant', (1, 8, 1, 9), 1, None), ('Constant', (1, 16, 1, 17), 2, None)]), [('Pass', (1, 38, 1, 42))], [], None, None)], []),
1951('Module', [('FunctionDef', (1, 0, 1, 40), 'f', ('arguments', [('arg', (1, 6, 1, 7), 'a', None, None)], [('arg', (1, 14, 1, 15), 'b', None, None)], None, [('arg', (1, 22, 1, 23), 'c', None, None)], [None], ('arg', (1, 27, 1, 33), 'kwargs', None, None), [('Constant', (1, 8, 1, 9), 1, None), ('Constant', (1, 16, 1, 17), 2, None)]), [('Pass', (1, 36, 1, 40))], [], None, None)], []),
Tim Peters400cbc32006-02-28 18:44:41 +00001952]
1953single_results = [
Serhiy Storchaka850a8852020-01-10 10:12:55 +02001954('Interactive', [('Expr', (1, 0, 1, 3), ('BinOp', (1, 0, 1, 3), ('Constant', (1, 0, 1, 1), 1, None), ('Add',), ('Constant', (1, 2, 1, 3), 2, None)))]),
Tim Peters400cbc32006-02-28 18:44:41 +00001955]
1956eval_results = [
Serhiy Storchaka850a8852020-01-10 10:12:55 +02001957('Expression', ('Constant', (1, 0, 1, 4), None, None)),
1958('Expression', ('BoolOp', (1, 0, 1, 7), ('And',), [('Name', (1, 0, 1, 1), 'a', ('Load',)), ('Name', (1, 6, 1, 7), 'b', ('Load',))])),
1959('Expression', ('BinOp', (1, 0, 1, 5), ('Name', (1, 0, 1, 1), 'a', ('Load',)), ('Add',), ('Name', (1, 4, 1, 5), 'b', ('Load',)))),
1960('Expression', ('UnaryOp', (1, 0, 1, 5), ('Not',), ('Name', (1, 4, 1, 5), 'v', ('Load',)))),
1961('Expression', ('Lambda', (1, 0, 1, 11), ('arguments', [], [], None, [], [], None, []), ('Constant', (1, 7, 1, 11), None, None))),
1962('Expression', ('Dict', (1, 0, 1, 7), [('Constant', (1, 2, 1, 3), 1, None)], [('Constant', (1, 4, 1, 5), 2, None)])),
1963('Expression', ('Dict', (1, 0, 1, 2), [], [])),
1964('Expression', ('Set', (1, 0, 1, 7), [('Constant', (1, 1, 1, 5), None, None)])),
1965('Expression', ('Dict', (1, 0, 5, 6), [('Constant', (2, 6, 2, 7), 1, None)], [('Constant', (4, 10, 4, 11), 2, None)])),
1966('Expression', ('ListComp', (1, 0, 1, 19), ('Name', (1, 1, 1, 2), 'a', ('Load',)), [('comprehension', ('Name', (1, 7, 1, 8), 'b', ('Store',)), ('Name', (1, 12, 1, 13), 'c', ('Load',)), [('Name', (1, 17, 1, 18), 'd', ('Load',))], 0)])),
1967('Expression', ('GeneratorExp', (1, 0, 1, 19), ('Name', (1, 1, 1, 2), 'a', ('Load',)), [('comprehension', ('Name', (1, 7, 1, 8), 'b', ('Store',)), ('Name', (1, 12, 1, 13), 'c', ('Load',)), [('Name', (1, 17, 1, 18), 'd', ('Load',))], 0)])),
1968('Expression', ('ListComp', (1, 0, 1, 20), ('Tuple', (1, 1, 1, 6), [('Name', (1, 2, 1, 3), 'a', ('Load',)), ('Name', (1, 4, 1, 5), 'b', ('Load',))], ('Load',)), [('comprehension', ('Tuple', (1, 11, 1, 14), [('Name', (1, 11, 1, 12), 'a', ('Store',)), ('Name', (1, 13, 1, 14), 'b', ('Store',))], ('Store',)), ('Name', (1, 18, 1, 19), 'c', ('Load',)), [], 0)])),
1969('Expression', ('ListComp', (1, 0, 1, 22), ('Tuple', (1, 1, 1, 6), [('Name', (1, 2, 1, 3), 'a', ('Load',)), ('Name', (1, 4, 1, 5), 'b', ('Load',))], ('Load',)), [('comprehension', ('Tuple', (1, 11, 1, 16), [('Name', (1, 12, 1, 13), 'a', ('Store',)), ('Name', (1, 14, 1, 15), 'b', ('Store',))], ('Store',)), ('Name', (1, 20, 1, 21), 'c', ('Load',)), [], 0)])),
1970('Expression', ('ListComp', (1, 0, 1, 22), ('Tuple', (1, 1, 1, 6), [('Name', (1, 2, 1, 3), 'a', ('Load',)), ('Name', (1, 4, 1, 5), 'b', ('Load',))], ('Load',)), [('comprehension', ('List', (1, 11, 1, 16), [('Name', (1, 12, 1, 13), 'a', ('Store',)), ('Name', (1, 14, 1, 15), 'b', ('Store',))], ('Store',)), ('Name', (1, 20, 1, 21), 'c', ('Load',)), [], 0)])),
1971('Expression', ('SetComp', (1, 0, 1, 20), ('Tuple', (1, 1, 1, 6), [('Name', (1, 2, 1, 3), 'a', ('Load',)), ('Name', (1, 4, 1, 5), 'b', ('Load',))], ('Load',)), [('comprehension', ('Tuple', (1, 11, 1, 14), [('Name', (1, 11, 1, 12), 'a', ('Store',)), ('Name', (1, 13, 1, 14), 'b', ('Store',))], ('Store',)), ('Name', (1, 18, 1, 19), 'c', ('Load',)), [], 0)])),
1972('Expression', ('SetComp', (1, 0, 1, 22), ('Tuple', (1, 1, 1, 6), [('Name', (1, 2, 1, 3), 'a', ('Load',)), ('Name', (1, 4, 1, 5), 'b', ('Load',))], ('Load',)), [('comprehension', ('Tuple', (1, 11, 1, 16), [('Name', (1, 12, 1, 13), 'a', ('Store',)), ('Name', (1, 14, 1, 15), 'b', ('Store',))], ('Store',)), ('Name', (1, 20, 1, 21), 'c', ('Load',)), [], 0)])),
1973('Expression', ('SetComp', (1, 0, 1, 22), ('Tuple', (1, 1, 1, 6), [('Name', (1, 2, 1, 3), 'a', ('Load',)), ('Name', (1, 4, 1, 5), 'b', ('Load',))], ('Load',)), [('comprehension', ('List', (1, 11, 1, 16), [('Name', (1, 12, 1, 13), 'a', ('Store',)), ('Name', (1, 14, 1, 15), 'b', ('Store',))], ('Store',)), ('Name', (1, 20, 1, 21), 'c', ('Load',)), [], 0)])),
1974('Expression', ('GeneratorExp', (1, 0, 1, 20), ('Tuple', (1, 1, 1, 6), [('Name', (1, 2, 1, 3), 'a', ('Load',)), ('Name', (1, 4, 1, 5), 'b', ('Load',))], ('Load',)), [('comprehension', ('Tuple', (1, 11, 1, 14), [('Name', (1, 11, 1, 12), 'a', ('Store',)), ('Name', (1, 13, 1, 14), 'b', ('Store',))], ('Store',)), ('Name', (1, 18, 1, 19), 'c', ('Load',)), [], 0)])),
1975('Expression', ('GeneratorExp', (1, 0, 1, 22), ('Tuple', (1, 1, 1, 6), [('Name', (1, 2, 1, 3), 'a', ('Load',)), ('Name', (1, 4, 1, 5), 'b', ('Load',))], ('Load',)), [('comprehension', ('Tuple', (1, 11, 1, 16), [('Name', (1, 12, 1, 13), 'a', ('Store',)), ('Name', (1, 14, 1, 15), 'b', ('Store',))], ('Store',)), ('Name', (1, 20, 1, 21), 'c', ('Load',)), [], 0)])),
1976('Expression', ('GeneratorExp', (1, 0, 1, 22), ('Tuple', (1, 1, 1, 6), [('Name', (1, 2, 1, 3), 'a', ('Load',)), ('Name', (1, 4, 1, 5), 'b', ('Load',))], ('Load',)), [('comprehension', ('List', (1, 11, 1, 16), [('Name', (1, 12, 1, 13), 'a', ('Store',)), ('Name', (1, 14, 1, 15), 'b', ('Store',))], ('Store',)), ('Name', (1, 20, 1, 21), 'c', ('Load',)), [], 0)])),
1977('Expression', ('Compare', (1, 0, 1, 9), ('Constant', (1, 0, 1, 1), 1, None), [('Lt',), ('Lt',)], [('Constant', (1, 4, 1, 5), 2, None), ('Constant', (1, 8, 1, 9), 3, None)])),
1978('Expression', ('Call', (1, 0, 1, 17), ('Name', (1, 0, 1, 1), 'f', ('Load',)), [('Constant', (1, 2, 1, 3), 1, None), ('Constant', (1, 4, 1, 5), 2, None), ('Starred', (1, 10, 1, 12), ('Name', (1, 11, 1, 12), 'd', ('Load',)), ('Load',))], [('keyword', 'c', ('Constant', (1, 8, 1, 9), 3, None)), ('keyword', None, ('Name', (1, 15, 1, 16), 'e', ('Load',)))])),
1979('Expression', ('Call', (1, 0, 1, 10), ('Name', (1, 0, 1, 1), 'f', ('Load',)), [('Starred', (1, 2, 1, 9), ('List', (1, 3, 1, 9), [('Constant', (1, 4, 1, 5), 0, None), ('Constant', (1, 7, 1, 8), 1, None)], ('Load',)), ('Load',))], [])),
1980('Expression', ('Call', (1, 0, 1, 15), ('Name', (1, 0, 1, 1), 'f', ('Load',)), [('GeneratorExp', (1, 1, 1, 15), ('Name', (1, 2, 1, 3), 'a', ('Load',)), [('comprehension', ('Name', (1, 8, 1, 9), 'a', ('Store',)), ('Name', (1, 13, 1, 14), 'b', ('Load',)), [], 0)])], [])),
1981('Expression', ('Constant', (1, 0, 1, 2), 10, None)),
1982('Expression', ('Constant', (1, 0, 1, 8), 'string', None)),
1983('Expression', ('Attribute', (1, 0, 1, 3), ('Name', (1, 0, 1, 1), 'a', ('Load',)), 'b', ('Load',))),
1984('Expression', ('Subscript', (1, 0, 1, 6), ('Name', (1, 0, 1, 1), 'a', ('Load',)), ('Slice', ('Name', (1, 2, 1, 3), 'b', ('Load',)), ('Name', (1, 4, 1, 5), 'c', ('Load',)), None), ('Load',))),
1985('Expression', ('Name', (1, 0, 1, 1), 'v', ('Load',))),
1986('Expression', ('List', (1, 0, 1, 7), [('Constant', (1, 1, 1, 2), 1, None), ('Constant', (1, 3, 1, 4), 2, None), ('Constant', (1, 5, 1, 6), 3, None)], ('Load',))),
1987('Expression', ('List', (1, 0, 1, 2), [], ('Load',))),
1988('Expression', ('Tuple', (1, 0, 1, 5), [('Constant', (1, 0, 1, 1), 1, None), ('Constant', (1, 2, 1, 3), 2, None), ('Constant', (1, 4, 1, 5), 3, None)], ('Load',))),
1989('Expression', ('Tuple', (1, 0, 1, 7), [('Constant', (1, 1, 1, 2), 1, None), ('Constant', (1, 3, 1, 4), 2, None), ('Constant', (1, 5, 1, 6), 3, None)], ('Load',))),
1990('Expression', ('Tuple', (1, 0, 1, 2), [], ('Load',))),
1991('Expression', ('Call', (1, 0, 1, 17), ('Attribute', (1, 0, 1, 7), ('Attribute', (1, 0, 1, 5), ('Attribute', (1, 0, 1, 3), ('Name', (1, 0, 1, 1), 'a', ('Load',)), 'b', ('Load',)), 'c', ('Load',)), 'd', ('Load',)), [('Subscript', (1, 8, 1, 16), ('Attribute', (1, 8, 1, 11), ('Name', (1, 8, 1, 9), 'a', ('Load',)), 'b', ('Load',)), ('Slice', ('Constant', (1, 12, 1, 13), 1, None), ('Constant', (1, 14, 1, 15), 2, None), None), ('Load',))], [])),
Tim Peters400cbc32006-02-28 18:44:41 +00001992]
Neal Norwitzee9b10a2008-03-31 05:29:39 +00001993main()