• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1import ast
2import builtins
3import dis
4import os
5import sys
6import types
7import unittest
8import warnings
9import weakref
10from textwrap import dedent
11
12from test import support
13
14def to_tuple(t):
15    if t is None or isinstance(t, (str, int, complex)):
16        return t
17    elif isinstance(t, list):
18        return [to_tuple(e) for e in t]
19    result = [t.__class__.__name__]
20    if hasattr(t, 'lineno') and hasattr(t, 'col_offset'):
21        result.append((t.lineno, t.col_offset))
22        if hasattr(t, 'end_lineno') and hasattr(t, 'end_col_offset'):
23            result[-1] += (t.end_lineno, t.end_col_offset)
24    if t._fields is None:
25        return tuple(result)
26    for f in t._fields:
27        result.append(to_tuple(getattr(t, f)))
28    return tuple(result)
29
30
31# These tests are compiled through "exec"
32# There should be at least one test per statement
33exec_tests = [
34    # None
35    "None",
36    # Module docstring
37    "'module docstring'",
38    # FunctionDef
39    "def f(): pass",
40    # FunctionDef with docstring
41    "def f(): 'function docstring'",
42    # FunctionDef with arg
43    "def f(a): pass",
44    # FunctionDef with arg and default value
45    "def f(a=0): pass",
46    # FunctionDef with varargs
47    "def f(*args): pass",
48    # FunctionDef with kwargs
49    "def f(**kwargs): pass",
50    # FunctionDef with all kind of args and docstring
51    "def f(a, b=1, c=None, d=[], e={}, *args, f=42, **kwargs): 'doc for f()'",
52    # ClassDef
53    "class C:pass",
54    # ClassDef with docstring
55    "class C: 'docstring for class C'",
56    # ClassDef, new style class
57    "class C(object): pass",
58    # Return
59    "def f():return 1",
60    # Delete
61    "del v",
62    # Assign
63    "v = 1",
64    "a,b = c",
65    "(a,b) = c",
66    "[a,b] = c",
67    # AugAssign
68    "v += 1",
69    # For
70    "for v in v:pass",
71    # While
72    "while v:pass",
73    # If
74    "if v:pass",
75    # If-Elif
76    "if a:\n  pass\nelif b:\n  pass",
77    # If-Elif-Else
78    "if a:\n  pass\nelif b:\n  pass\nelse:\n  pass",
79    # With
80    "with x as y: pass",
81    "with x as y, z as q: pass",
82    # Raise
83    "raise Exception('string')",
84    # TryExcept
85    "try:\n  pass\nexcept Exception:\n  pass",
86    # TryFinally
87    "try:\n  pass\nfinally:\n  pass",
88    # Assert
89    "assert v",
90    # Import
91    "import sys",
92    # ImportFrom
93    "from sys import v",
94    # Global
95    "global v",
96    # Expr
97    "1",
98    # Pass,
99    "pass",
100    # Break
101    "for v in v:break",
102    # Continue
103    "for v in v:continue",
104    # for statements with naked tuples (see http://bugs.python.org/issue6704)
105    "for a,b in c: pass",
106    "for (a,b) in c: pass",
107    "for [a,b] in c: pass",
108    # Multiline generator expression (test for .lineno & .col_offset)
109    """(
110    (
111    Aa
112    ,
113       Bb
114    )
115    for
116    Aa
117    ,
118    Bb in Cc
119    )""",
120    # dictcomp
121    "{a : b for w in x for m in p if g}",
122    # dictcomp with naked tuple
123    "{a : b for v,w in x}",
124    # setcomp
125    "{r for l in x if g}",
126    # setcomp with naked tuple
127    "{r for l,m in x}",
128    # AsyncFunctionDef
129    "async def f():\n 'async function'\n await something()",
130    # AsyncFor
131    "async def f():\n async for e in i: 1\n else: 2",
132    # AsyncWith
133    "async def f():\n async with a as b: 1",
134    # PEP 448: Additional Unpacking Generalizations
135    "{**{1:2}, 2:3}",
136    "{*{1, 2}, 3}",
137    # Asynchronous comprehensions
138    "async def f():\n [i async for b in c]",
139    # Decorated FunctionDef
140    "@deco1\n@deco2()\n@deco3(1)\ndef f(): pass",
141    # Decorated AsyncFunctionDef
142    "@deco1\n@deco2()\n@deco3(1)\nasync def f(): pass",
143    # Decorated ClassDef
144    "@deco1\n@deco2()\n@deco3(1)\nclass C: pass",
145    # Decorator with generator argument
146    "@deco(a for a in b)\ndef f(): pass",
147    # Decorator with attribute
148    "@a.b.c\ndef f(): pass",
149    # Simple assignment expression
150    "(a := 1)",
151    # Positional-only arguments
152    "def f(a, /,): pass",
153    "def f(a, /, c, d, e): pass",
154    "def f(a, /, c, *, d, e): pass",
155    "def f(a, /, c, *, d, e, **kwargs): pass",
156    # Positional-only arguments with defaults
157    "def f(a=1, /,): pass",
158    "def f(a=1, /, b=2, c=4): pass",
159    "def f(a=1, /, b=2, *, c=4): pass",
160    "def f(a=1, /, b=2, *, c): pass",
161    "def f(a=1, /, b=2, *, c=4, **kwargs): pass",
162    "def f(a=1, /, b=2, *, c, **kwargs): pass",
163
164]
165
166# These are compiled through "single"
167# because of overlap with "eval", it just tests what
168# can't be tested with "eval"
169single_tests = [
170    "1+2"
171]
172
173# These are compiled through "eval"
174# It should test all expressions
175eval_tests = [
176  # None
177  "None",
178  # BoolOp
179  "a and b",
180  # BinOp
181  "a + b",
182  # UnaryOp
183  "not v",
184  # Lambda
185  "lambda:None",
186  # Dict
187  "{ 1:2 }",
188  # Empty dict
189  "{}",
190  # Set
191  "{None,}",
192  # Multiline dict (test for .lineno & .col_offset)
193  """{
194      1
195        :
196          2
197     }""",
198  # ListComp
199  "[a for b in c if d]",
200  # GeneratorExp
201  "(a for b in c if d)",
202  # Comprehensions with multiple for targets
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)",
210  "((a,b) for (a,b) in c)",
211  "((a,b) for [a,b] in c)",
212  # Yield - yield expressions can't work outside a function
213  #
214  # Compare
215  "1 < 2 < 3",
216  # Call
217  "f(1,2,c=3,*d,**e)",
218  # Call with multi-character starred
219  "f(*[0, 1])",
220  # Call with a generator argument
221  "f(a for a in b)",
222  # Num
223  "10",
224  # Str
225  "'string'",
226  # Attribute
227  "a.b",
228  # Subscript
229  "a[b:c]",
230  # Name
231  "v",
232  # List
233  "[1,2,3]",
234  # Empty list
235  "[]",
236  # Tuple
237  "1,2,3",
238  # Tuple
239  "(1,2,3)",
240  # Empty tuple
241  "()",
242  # Combination
243  "a.b.c.d(a.b[1:2])",
244
245]
246
247# TODO: expr_context, slice, boolop, operator, unaryop, cmpop, comprehension
248# excepthandler, arguments, keywords, alias
249
250class AST_Tests(unittest.TestCase):
251
252    def _is_ast_node(self, name, node):
253        if not isinstance(node, type):
254            return False
255        if "ast" not in node.__module__:
256            return False
257        return name != 'AST' and name[0].isupper()
258
259    def _assertTrueorder(self, ast_node, parent_pos):
260        if not isinstance(ast_node, ast.AST) or ast_node._fields is None:
261            return
262        if isinstance(ast_node, (ast.expr, ast.stmt, ast.excepthandler)):
263            node_pos = (ast_node.lineno, ast_node.col_offset)
264            self.assertGreaterEqual(node_pos, parent_pos)
265            parent_pos = (ast_node.lineno, ast_node.col_offset)
266        for name in ast_node._fields:
267            value = getattr(ast_node, name)
268            if isinstance(value, list):
269                first_pos = parent_pos
270                if value and name == 'decorator_list':
271                    first_pos = (value[0].lineno, value[0].col_offset)
272                for child in value:
273                    self._assertTrueorder(child, first_pos)
274            elif value is not None:
275                self._assertTrueorder(value, parent_pos)
276        self.assertEqual(ast_node._fields, ast_node.__match_args__)
277
278    def test_AST_objects(self):
279        x = ast.AST()
280        self.assertEqual(x._fields, ())
281        x.foobar = 42
282        self.assertEqual(x.foobar, 42)
283        self.assertEqual(x.__dict__["foobar"], 42)
284
285        with self.assertRaises(AttributeError):
286            x.vararg
287
288        with self.assertRaises(TypeError):
289            # "ast.AST constructor takes 0 positional arguments"
290            ast.AST(2)
291
292    def test_AST_garbage_collection(self):
293        class X:
294            pass
295        a = ast.AST()
296        a.x = X()
297        a.x.a = a
298        ref = weakref.ref(a.x)
299        del a
300        support.gc_collect()
301        self.assertIsNone(ref())
302
303    def test_snippets(self):
304        for input, output, kind in ((exec_tests, exec_results, "exec"),
305                                    (single_tests, single_results, "single"),
306                                    (eval_tests, eval_results, "eval")):
307            for i, o in zip(input, output):
308                with self.subTest(action="parsing", input=i):
309                    ast_tree = compile(i, "?", kind, ast.PyCF_ONLY_AST)
310                    self.assertEqual(to_tuple(ast_tree), o)
311                    self._assertTrueorder(ast_tree, (0, 0))
312                with self.subTest(action="compiling", input=i, kind=kind):
313                    compile(ast_tree, "?", kind)
314
315    def test_ast_validation(self):
316        # compile() is the only function that calls PyAST_Validate
317        snippets_to_validate = exec_tests + single_tests + eval_tests
318        for snippet in snippets_to_validate:
319            tree = ast.parse(snippet)
320            compile(tree, '<string>', 'exec')
321
322    def test_slice(self):
323        slc = ast.parse("x[::]").body[0].value.slice
324        self.assertIsNone(slc.upper)
325        self.assertIsNone(slc.lower)
326        self.assertIsNone(slc.step)
327
328    def test_from_import(self):
329        im = ast.parse("from . import y").body[0]
330        self.assertIsNone(im.module)
331
332    def test_non_interned_future_from_ast(self):
333        mod = ast.parse("from __future__ import division")
334        self.assertIsInstance(mod.body[0], ast.ImportFrom)
335        mod.body[0].module = " __future__ ".strip()
336        compile(mod, "<test>", "exec")
337
338    def test_alias(self):
339        im = ast.parse("from bar import y").body[0]
340        self.assertEqual(len(im.names), 1)
341        alias = im.names[0]
342        self.assertEqual(alias.name, 'y')
343        self.assertIsNone(alias.asname)
344        self.assertEqual(alias.lineno, 1)
345        self.assertEqual(alias.end_lineno, 1)
346        self.assertEqual(alias.col_offset, 16)
347        self.assertEqual(alias.end_col_offset, 17)
348
349        im = ast.parse("from bar import *").body[0]
350        alias = im.names[0]
351        self.assertEqual(alias.name, '*')
352        self.assertIsNone(alias.asname)
353        self.assertEqual(alias.lineno, 1)
354        self.assertEqual(alias.end_lineno, 1)
355        self.assertEqual(alias.col_offset, 16)
356        self.assertEqual(alias.end_col_offset, 17)
357
358    def test_base_classes(self):
359        self.assertTrue(issubclass(ast.For, ast.stmt))
360        self.assertTrue(issubclass(ast.Name, ast.expr))
361        self.assertTrue(issubclass(ast.stmt, ast.AST))
362        self.assertTrue(issubclass(ast.expr, ast.AST))
363        self.assertTrue(issubclass(ast.comprehension, ast.AST))
364        self.assertTrue(issubclass(ast.Gt, ast.AST))
365
366    def test_field_attr_existence(self):
367        for name, item in ast.__dict__.items():
368            if self._is_ast_node(name, item):
369                if name == 'Index':
370                    # Index(value) just returns value now.
371                    # The argument is required.
372                    continue
373                x = item()
374                if isinstance(x, ast.AST):
375                    self.assertEqual(type(x._fields), tuple)
376
377    def test_arguments(self):
378        x = ast.arguments()
379        self.assertEqual(x._fields, ('posonlyargs', 'args', 'vararg', 'kwonlyargs',
380                                     'kw_defaults', 'kwarg', 'defaults'))
381
382        with self.assertRaises(AttributeError):
383            x.args
384        self.assertIsNone(x.vararg)
385
386        x = ast.arguments(*range(1, 8))
387        self.assertEqual(x.args, 2)
388        self.assertEqual(x.vararg, 3)
389
390    def test_field_attr_writable(self):
391        x = ast.Num()
392        # We can assign to _fields
393        x._fields = 666
394        self.assertEqual(x._fields, 666)
395
396    def test_classattrs(self):
397        x = ast.Num()
398        self.assertEqual(x._fields, ('value', 'kind'))
399
400        with self.assertRaises(AttributeError):
401            x.value
402
403        with self.assertRaises(AttributeError):
404            x.n
405
406        x = ast.Num(42)
407        self.assertEqual(x.value, 42)
408        self.assertEqual(x.n, 42)
409
410        with self.assertRaises(AttributeError):
411            x.lineno
412
413        with self.assertRaises(AttributeError):
414            x.foobar
415
416        x = ast.Num(lineno=2)
417        self.assertEqual(x.lineno, 2)
418
419        x = ast.Num(42, lineno=0)
420        self.assertEqual(x.lineno, 0)
421        self.assertEqual(x._fields, ('value', 'kind'))
422        self.assertEqual(x.value, 42)
423        self.assertEqual(x.n, 42)
424
425        self.assertRaises(TypeError, ast.Num, 1, None, 2)
426        self.assertRaises(TypeError, ast.Num, 1, None, 2, lineno=0)
427
428        # Arbitrary keyword arguments are supported
429        self.assertEqual(ast.Constant(1, foo='bar').foo, 'bar')
430        self.assertEqual(ast.Num(1, foo='bar').foo, 'bar')
431
432        with self.assertRaisesRegex(TypeError, "Num got multiple values for argument 'n'"):
433            ast.Num(1, n=2)
434        with self.assertRaisesRegex(TypeError, "Constant got multiple values for argument 'value'"):
435            ast.Constant(1, value=2)
436
437        self.assertEqual(ast.Num(42).n, 42)
438        self.assertEqual(ast.Num(4.25).n, 4.25)
439        self.assertEqual(ast.Num(4.25j).n, 4.25j)
440        self.assertEqual(ast.Str('42').s, '42')
441        self.assertEqual(ast.Bytes(b'42').s, b'42')
442        self.assertIs(ast.NameConstant(True).value, True)
443        self.assertIs(ast.NameConstant(False).value, False)
444        self.assertIs(ast.NameConstant(None).value, None)
445
446        self.assertEqual(ast.Constant(42).value, 42)
447        self.assertEqual(ast.Constant(4.25).value, 4.25)
448        self.assertEqual(ast.Constant(4.25j).value, 4.25j)
449        self.assertEqual(ast.Constant('42').value, '42')
450        self.assertEqual(ast.Constant(b'42').value, b'42')
451        self.assertIs(ast.Constant(True).value, True)
452        self.assertIs(ast.Constant(False).value, False)
453        self.assertIs(ast.Constant(None).value, None)
454        self.assertIs(ast.Constant(...).value, ...)
455
456    def test_realtype(self):
457        self.assertEqual(type(ast.Num(42)), ast.Constant)
458        self.assertEqual(type(ast.Num(4.25)), ast.Constant)
459        self.assertEqual(type(ast.Num(4.25j)), ast.Constant)
460        self.assertEqual(type(ast.Str('42')), ast.Constant)
461        self.assertEqual(type(ast.Bytes(b'42')), ast.Constant)
462        self.assertEqual(type(ast.NameConstant(True)), ast.Constant)
463        self.assertEqual(type(ast.NameConstant(False)), ast.Constant)
464        self.assertEqual(type(ast.NameConstant(None)), ast.Constant)
465        self.assertEqual(type(ast.Ellipsis()), ast.Constant)
466
467    def test_isinstance(self):
468        self.assertTrue(isinstance(ast.Num(42), ast.Num))
469        self.assertTrue(isinstance(ast.Num(4.2), ast.Num))
470        self.assertTrue(isinstance(ast.Num(4.2j), ast.Num))
471        self.assertTrue(isinstance(ast.Str('42'), ast.Str))
472        self.assertTrue(isinstance(ast.Bytes(b'42'), ast.Bytes))
473        self.assertTrue(isinstance(ast.NameConstant(True), ast.NameConstant))
474        self.assertTrue(isinstance(ast.NameConstant(False), ast.NameConstant))
475        self.assertTrue(isinstance(ast.NameConstant(None), ast.NameConstant))
476        self.assertTrue(isinstance(ast.Ellipsis(), ast.Ellipsis))
477
478        self.assertTrue(isinstance(ast.Constant(42), ast.Num))
479        self.assertTrue(isinstance(ast.Constant(4.2), ast.Num))
480        self.assertTrue(isinstance(ast.Constant(4.2j), ast.Num))
481        self.assertTrue(isinstance(ast.Constant('42'), ast.Str))
482        self.assertTrue(isinstance(ast.Constant(b'42'), ast.Bytes))
483        self.assertTrue(isinstance(ast.Constant(True), ast.NameConstant))
484        self.assertTrue(isinstance(ast.Constant(False), ast.NameConstant))
485        self.assertTrue(isinstance(ast.Constant(None), ast.NameConstant))
486        self.assertTrue(isinstance(ast.Constant(...), ast.Ellipsis))
487
488        self.assertFalse(isinstance(ast.Str('42'), ast.Num))
489        self.assertFalse(isinstance(ast.Num(42), ast.Str))
490        self.assertFalse(isinstance(ast.Str('42'), ast.Bytes))
491        self.assertFalse(isinstance(ast.Num(42), ast.NameConstant))
492        self.assertFalse(isinstance(ast.Num(42), ast.Ellipsis))
493        self.assertFalse(isinstance(ast.NameConstant(True), ast.Num))
494        self.assertFalse(isinstance(ast.NameConstant(False), ast.Num))
495
496        self.assertFalse(isinstance(ast.Constant('42'), ast.Num))
497        self.assertFalse(isinstance(ast.Constant(42), ast.Str))
498        self.assertFalse(isinstance(ast.Constant('42'), ast.Bytes))
499        self.assertFalse(isinstance(ast.Constant(42), ast.NameConstant))
500        self.assertFalse(isinstance(ast.Constant(42), ast.Ellipsis))
501        self.assertFalse(isinstance(ast.Constant(True), ast.Num))
502        self.assertFalse(isinstance(ast.Constant(False), ast.Num))
503
504        self.assertFalse(isinstance(ast.Constant(), ast.Num))
505        self.assertFalse(isinstance(ast.Constant(), ast.Str))
506        self.assertFalse(isinstance(ast.Constant(), ast.Bytes))
507        self.assertFalse(isinstance(ast.Constant(), ast.NameConstant))
508        self.assertFalse(isinstance(ast.Constant(), ast.Ellipsis))
509
510        class S(str): pass
511        self.assertTrue(isinstance(ast.Constant(S('42')), ast.Str))
512        self.assertFalse(isinstance(ast.Constant(S('42')), ast.Num))
513
514    def test_subclasses(self):
515        class N(ast.Num):
516            def __init__(self, *args, **kwargs):
517                super().__init__(*args, **kwargs)
518                self.z = 'spam'
519        class N2(ast.Num):
520            pass
521
522        n = N(42)
523        self.assertEqual(n.n, 42)
524        self.assertEqual(n.z, 'spam')
525        self.assertEqual(type(n), N)
526        self.assertTrue(isinstance(n, N))
527        self.assertTrue(isinstance(n, ast.Num))
528        self.assertFalse(isinstance(n, N2))
529        self.assertFalse(isinstance(ast.Num(42), N))
530        n = N(n=42)
531        self.assertEqual(n.n, 42)
532        self.assertEqual(type(n), N)
533
534    def test_module(self):
535        body = [ast.Num(42)]
536        x = ast.Module(body, [])
537        self.assertEqual(x.body, body)
538
539    def test_nodeclasses(self):
540        # Zero arguments constructor explicitly allowed
541        x = ast.BinOp()
542        self.assertEqual(x._fields, ('left', 'op', 'right'))
543
544        # Random attribute allowed too
545        x.foobarbaz = 5
546        self.assertEqual(x.foobarbaz, 5)
547
548        n1 = ast.Num(1)
549        n3 = ast.Num(3)
550        addop = ast.Add()
551        x = ast.BinOp(n1, addop, n3)
552        self.assertEqual(x.left, n1)
553        self.assertEqual(x.op, addop)
554        self.assertEqual(x.right, n3)
555
556        x = ast.BinOp(1, 2, 3)
557        self.assertEqual(x.left, 1)
558        self.assertEqual(x.op, 2)
559        self.assertEqual(x.right, 3)
560
561        x = ast.BinOp(1, 2, 3, lineno=0)
562        self.assertEqual(x.left, 1)
563        self.assertEqual(x.op, 2)
564        self.assertEqual(x.right, 3)
565        self.assertEqual(x.lineno, 0)
566
567        # node raises exception when given too many arguments
568        self.assertRaises(TypeError, ast.BinOp, 1, 2, 3, 4)
569        # node raises exception when given too many arguments
570        self.assertRaises(TypeError, ast.BinOp, 1, 2, 3, 4, lineno=0)
571
572        # can set attributes through kwargs too
573        x = ast.BinOp(left=1, op=2, right=3, lineno=0)
574        self.assertEqual(x.left, 1)
575        self.assertEqual(x.op, 2)
576        self.assertEqual(x.right, 3)
577        self.assertEqual(x.lineno, 0)
578
579        # Random kwargs also allowed
580        x = ast.BinOp(1, 2, 3, foobarbaz=42)
581        self.assertEqual(x.foobarbaz, 42)
582
583    def test_no_fields(self):
584        # this used to fail because Sub._fields was None
585        x = ast.Sub()
586        self.assertEqual(x._fields, ())
587
588    def test_pickling(self):
589        import pickle
590        mods = [pickle]
591        try:
592            import cPickle
593            mods.append(cPickle)
594        except ImportError:
595            pass
596        protocols = [0, 1, 2]
597        for mod in mods:
598            for protocol in protocols:
599                for ast in (compile(i, "?", "exec", 0x400) for i in exec_tests):
600                    ast2 = mod.loads(mod.dumps(ast, protocol))
601                    self.assertEqual(to_tuple(ast2), to_tuple(ast))
602
603    def test_invalid_sum(self):
604        pos = dict(lineno=2, col_offset=3)
605        m = ast.Module([ast.Expr(ast.expr(**pos), **pos)], [])
606        with self.assertRaises(TypeError) as cm:
607            compile(m, "<test>", "exec")
608        self.assertIn("but got <ast.expr", str(cm.exception))
609
610    def test_invalid_identifier(self):
611        m = ast.Module([ast.Expr(ast.Name(42, ast.Load()))], [])
612        ast.fix_missing_locations(m)
613        with self.assertRaises(TypeError) as cm:
614            compile(m, "<test>", "exec")
615        self.assertIn("identifier must be of type str", str(cm.exception))
616
617    def test_invalid_constant(self):
618        for invalid_constant in int, (1, 2, int), frozenset((1, 2, int)):
619            e = ast.Expression(body=ast.Constant(invalid_constant))
620            ast.fix_missing_locations(e)
621            with self.assertRaisesRegex(
622                TypeError, "invalid type in Constant: type"
623            ):
624                compile(e, "<test>", "eval")
625
626    def test_empty_yield_from(self):
627        # Issue 16546: yield from value is not optional.
628        empty_yield_from = ast.parse("def f():\n yield from g()")
629        empty_yield_from.body[0].body[0].value.value = None
630        with self.assertRaises(ValueError) as cm:
631            compile(empty_yield_from, "<test>", "exec")
632        self.assertIn("field 'value' is required", str(cm.exception))
633
634    @support.cpython_only
635    def test_issue31592(self):
636        # There shouldn't be an assertion failure in case of a bad
637        # unicodedata.normalize().
638        import unicodedata
639        def bad_normalize(*args):
640            return None
641        with support.swap_attr(unicodedata, 'normalize', bad_normalize):
642            self.assertRaises(TypeError, ast.parse, '\u03D5')
643
644    def test_issue18374_binop_col_offset(self):
645        tree = ast.parse('4+5+6+7')
646        parent_binop = tree.body[0].value
647        child_binop = parent_binop.left
648        grandchild_binop = child_binop.left
649        self.assertEqual(parent_binop.col_offset, 0)
650        self.assertEqual(parent_binop.end_col_offset, 7)
651        self.assertEqual(child_binop.col_offset, 0)
652        self.assertEqual(child_binop.end_col_offset, 5)
653        self.assertEqual(grandchild_binop.col_offset, 0)
654        self.assertEqual(grandchild_binop.end_col_offset, 3)
655
656        tree = ast.parse('4+5-\\\n 6-7')
657        parent_binop = tree.body[0].value
658        child_binop = parent_binop.left
659        grandchild_binop = child_binop.left
660        self.assertEqual(parent_binop.col_offset, 0)
661        self.assertEqual(parent_binop.lineno, 1)
662        self.assertEqual(parent_binop.end_col_offset, 4)
663        self.assertEqual(parent_binop.end_lineno, 2)
664
665        self.assertEqual(child_binop.col_offset, 0)
666        self.assertEqual(child_binop.lineno, 1)
667        self.assertEqual(child_binop.end_col_offset, 2)
668        self.assertEqual(child_binop.end_lineno, 2)
669
670        self.assertEqual(grandchild_binop.col_offset, 0)
671        self.assertEqual(grandchild_binop.lineno, 1)
672        self.assertEqual(grandchild_binop.end_col_offset, 3)
673        self.assertEqual(grandchild_binop.end_lineno, 1)
674
675    def test_issue39579_dotted_name_end_col_offset(self):
676        tree = ast.parse('@a.b.c\ndef f(): pass')
677        attr_b = tree.body[0].decorator_list[0].value
678        self.assertEqual(attr_b.end_col_offset, 4)
679
680    def test_ast_asdl_signature(self):
681        self.assertEqual(ast.withitem.__doc__, "withitem(expr context_expr, expr? optional_vars)")
682        self.assertEqual(ast.GtE.__doc__, "GtE")
683        self.assertEqual(ast.Name.__doc__, "Name(identifier id, expr_context ctx)")
684        self.assertEqual(ast.cmpop.__doc__, "cmpop = Eq | NotEq | Lt | LtE | Gt | GtE | Is | IsNot | In | NotIn")
685        expressions = [f"     | {node.__doc__}" for node in ast.expr.__subclasses__()]
686        expressions[0] = f"expr = {ast.expr.__subclasses__()[0].__doc__}"
687        self.assertCountEqual(ast.expr.__doc__.split("\n"), expressions)
688
689    def test_issue40614_feature_version(self):
690        ast.parse('f"{x=}"', feature_version=(3, 8))
691        with self.assertRaises(SyntaxError):
692            ast.parse('f"{x=}"', feature_version=(3, 7))
693
694    def test_constant_as_name(self):
695        for constant in "True", "False", "None":
696            expr = ast.Expression(ast.Name(constant, ast.Load()))
697            ast.fix_missing_locations(expr)
698            with self.assertRaisesRegex(ValueError, f"identifier field can't represent '{constant}' constant"):
699                compile(expr, "<test>", "eval")
700
701
702class ASTHelpers_Test(unittest.TestCase):
703    maxDiff = None
704
705    def test_parse(self):
706        a = ast.parse('foo(1 + 1)')
707        b = compile('foo(1 + 1)', '<unknown>', 'exec', ast.PyCF_ONLY_AST)
708        self.assertEqual(ast.dump(a), ast.dump(b))
709
710    def test_parse_in_error(self):
711        try:
712            1/0
713        except Exception:
714            with self.assertRaises(SyntaxError) as e:
715                ast.literal_eval(r"'\U'")
716            self.assertIsNotNone(e.exception.__context__)
717
718    def test_dump(self):
719        node = ast.parse('spam(eggs, "and cheese")')
720        self.assertEqual(ast.dump(node),
721            "Module(body=[Expr(value=Call(func=Name(id='spam', ctx=Load()), "
722            "args=[Name(id='eggs', ctx=Load()), Constant(value='and cheese')], "
723            "keywords=[]))], type_ignores=[])"
724        )
725        self.assertEqual(ast.dump(node, annotate_fields=False),
726            "Module([Expr(Call(Name('spam', Load()), [Name('eggs', Load()), "
727            "Constant('and cheese')], []))], [])"
728        )
729        self.assertEqual(ast.dump(node, include_attributes=True),
730            "Module(body=[Expr(value=Call(func=Name(id='spam', ctx=Load(), "
731            "lineno=1, col_offset=0, end_lineno=1, end_col_offset=4), "
732            "args=[Name(id='eggs', ctx=Load(), lineno=1, col_offset=5, "
733            "end_lineno=1, end_col_offset=9), Constant(value='and cheese', "
734            "lineno=1, col_offset=11, end_lineno=1, end_col_offset=23)], keywords=[], "
735            "lineno=1, col_offset=0, end_lineno=1, end_col_offset=24), "
736            "lineno=1, col_offset=0, end_lineno=1, end_col_offset=24)], type_ignores=[])"
737        )
738
739    def test_dump_indent(self):
740        node = ast.parse('spam(eggs, "and cheese")')
741        self.assertEqual(ast.dump(node, indent=3), """\
742Module(
743   body=[
744      Expr(
745         value=Call(
746            func=Name(id='spam', ctx=Load()),
747            args=[
748               Name(id='eggs', ctx=Load()),
749               Constant(value='and cheese')],
750            keywords=[]))],
751   type_ignores=[])""")
752        self.assertEqual(ast.dump(node, annotate_fields=False, indent='\t'), """\
753Module(
754\t[
755\t\tExpr(
756\t\t\tCall(
757\t\t\t\tName('spam', Load()),
758\t\t\t\t[
759\t\t\t\t\tName('eggs', Load()),
760\t\t\t\t\tConstant('and cheese')],
761\t\t\t\t[]))],
762\t[])""")
763        self.assertEqual(ast.dump(node, include_attributes=True, indent=3), """\
764Module(
765   body=[
766      Expr(
767         value=Call(
768            func=Name(
769               id='spam',
770               ctx=Load(),
771               lineno=1,
772               col_offset=0,
773               end_lineno=1,
774               end_col_offset=4),
775            args=[
776               Name(
777                  id='eggs',
778                  ctx=Load(),
779                  lineno=1,
780                  col_offset=5,
781                  end_lineno=1,
782                  end_col_offset=9),
783               Constant(
784                  value='and cheese',
785                  lineno=1,
786                  col_offset=11,
787                  end_lineno=1,
788                  end_col_offset=23)],
789            keywords=[],
790            lineno=1,
791            col_offset=0,
792            end_lineno=1,
793            end_col_offset=24),
794         lineno=1,
795         col_offset=0,
796         end_lineno=1,
797         end_col_offset=24)],
798   type_ignores=[])""")
799
800    def test_dump_incomplete(self):
801        node = ast.Raise(lineno=3, col_offset=4)
802        self.assertEqual(ast.dump(node),
803            "Raise()"
804        )
805        self.assertEqual(ast.dump(node, include_attributes=True),
806            "Raise(lineno=3, col_offset=4)"
807        )
808        node = ast.Raise(exc=ast.Name(id='e', ctx=ast.Load()), lineno=3, col_offset=4)
809        self.assertEqual(ast.dump(node),
810            "Raise(exc=Name(id='e', ctx=Load()))"
811        )
812        self.assertEqual(ast.dump(node, annotate_fields=False),
813            "Raise(Name('e', Load()))"
814        )
815        self.assertEqual(ast.dump(node, include_attributes=True),
816            "Raise(exc=Name(id='e', ctx=Load()), lineno=3, col_offset=4)"
817        )
818        self.assertEqual(ast.dump(node, annotate_fields=False, include_attributes=True),
819            "Raise(Name('e', Load()), lineno=3, col_offset=4)"
820        )
821        node = ast.Raise(cause=ast.Name(id='e', ctx=ast.Load()))
822        self.assertEqual(ast.dump(node),
823            "Raise(cause=Name(id='e', ctx=Load()))"
824        )
825        self.assertEqual(ast.dump(node, annotate_fields=False),
826            "Raise(cause=Name('e', Load()))"
827        )
828
829    def test_copy_location(self):
830        src = ast.parse('1 + 1', mode='eval')
831        src.body.right = ast.copy_location(ast.Num(2), src.body.right)
832        self.assertEqual(ast.dump(src, include_attributes=True),
833            'Expression(body=BinOp(left=Constant(value=1, lineno=1, col_offset=0, '
834            'end_lineno=1, end_col_offset=1), op=Add(), right=Constant(value=2, '
835            'lineno=1, col_offset=4, end_lineno=1, end_col_offset=5), lineno=1, '
836            'col_offset=0, end_lineno=1, end_col_offset=5))'
837        )
838        src = ast.Call(col_offset=1, lineno=1, end_lineno=1, end_col_offset=1)
839        new = ast.copy_location(src, ast.Call(col_offset=None, lineno=None))
840        self.assertIsNone(new.end_lineno)
841        self.assertIsNone(new.end_col_offset)
842        self.assertEqual(new.lineno, 1)
843        self.assertEqual(new.col_offset, 1)
844
845    def test_fix_missing_locations(self):
846        src = ast.parse('write("spam")')
847        src.body.append(ast.Expr(ast.Call(ast.Name('spam', ast.Load()),
848                                          [ast.Str('eggs')], [])))
849        self.assertEqual(src, ast.fix_missing_locations(src))
850        self.maxDiff = None
851        self.assertEqual(ast.dump(src, include_attributes=True),
852            "Module(body=[Expr(value=Call(func=Name(id='write', ctx=Load(), "
853            "lineno=1, col_offset=0, end_lineno=1, end_col_offset=5), "
854            "args=[Constant(value='spam', lineno=1, col_offset=6, end_lineno=1, "
855            "end_col_offset=12)], keywords=[], lineno=1, col_offset=0, end_lineno=1, "
856            "end_col_offset=13), lineno=1, col_offset=0, end_lineno=1, "
857            "end_col_offset=13), Expr(value=Call(func=Name(id='spam', ctx=Load(), "
858            "lineno=1, col_offset=0, end_lineno=1, end_col_offset=0), "
859            "args=[Constant(value='eggs', lineno=1, col_offset=0, end_lineno=1, "
860            "end_col_offset=0)], keywords=[], lineno=1, col_offset=0, end_lineno=1, "
861            "end_col_offset=0), lineno=1, col_offset=0, end_lineno=1, end_col_offset=0)], "
862            "type_ignores=[])"
863        )
864
865    def test_increment_lineno(self):
866        src = ast.parse('1 + 1', mode='eval')
867        self.assertEqual(ast.increment_lineno(src, n=3), src)
868        self.assertEqual(ast.dump(src, include_attributes=True),
869            'Expression(body=BinOp(left=Constant(value=1, lineno=4, col_offset=0, '
870            'end_lineno=4, end_col_offset=1), op=Add(), right=Constant(value=1, '
871            'lineno=4, col_offset=4, end_lineno=4, end_col_offset=5), lineno=4, '
872            'col_offset=0, end_lineno=4, end_col_offset=5))'
873        )
874        # issue10869: do not increment lineno of root twice
875        src = ast.parse('1 + 1', mode='eval')
876        self.assertEqual(ast.increment_lineno(src.body, n=3), src.body)
877        self.assertEqual(ast.dump(src, include_attributes=True),
878            'Expression(body=BinOp(left=Constant(value=1, lineno=4, col_offset=0, '
879            'end_lineno=4, end_col_offset=1), op=Add(), right=Constant(value=1, '
880            'lineno=4, col_offset=4, end_lineno=4, end_col_offset=5), lineno=4, '
881            'col_offset=0, end_lineno=4, end_col_offset=5))'
882        )
883        src = ast.Call(
884            func=ast.Name("test", ast.Load()), args=[], keywords=[], lineno=1
885        )
886        self.assertEqual(ast.increment_lineno(src).lineno, 2)
887        self.assertIsNone(ast.increment_lineno(src).end_lineno)
888
889    def test_iter_fields(self):
890        node = ast.parse('foo()', mode='eval')
891        d = dict(ast.iter_fields(node.body))
892        self.assertEqual(d.pop('func').id, 'foo')
893        self.assertEqual(d, {'keywords': [], 'args': []})
894
895    def test_iter_child_nodes(self):
896        node = ast.parse("spam(23, 42, eggs='leek')", mode='eval')
897        self.assertEqual(len(list(ast.iter_child_nodes(node.body))), 4)
898        iterator = ast.iter_child_nodes(node.body)
899        self.assertEqual(next(iterator).id, 'spam')
900        self.assertEqual(next(iterator).value, 23)
901        self.assertEqual(next(iterator).value, 42)
902        self.assertEqual(ast.dump(next(iterator)),
903            "keyword(arg='eggs', value=Constant(value='leek'))"
904        )
905
906    def test_get_docstring(self):
907        node = ast.parse('"""line one\n  line two"""')
908        self.assertEqual(ast.get_docstring(node),
909                         'line one\nline two')
910
911        node = ast.parse('class foo:\n  """line one\n  line two"""')
912        self.assertEqual(ast.get_docstring(node.body[0]),
913                         'line one\nline two')
914
915        node = ast.parse('def foo():\n  """line one\n  line two"""')
916        self.assertEqual(ast.get_docstring(node.body[0]),
917                         'line one\nline two')
918
919        node = ast.parse('async def foo():\n  """spam\n  ham"""')
920        self.assertEqual(ast.get_docstring(node.body[0]), 'spam\nham')
921
922    def test_get_docstring_none(self):
923        self.assertIsNone(ast.get_docstring(ast.parse('')))
924        node = ast.parse('x = "not docstring"')
925        self.assertIsNone(ast.get_docstring(node))
926        node = ast.parse('def foo():\n  pass')
927        self.assertIsNone(ast.get_docstring(node))
928
929        node = ast.parse('class foo:\n  pass')
930        self.assertIsNone(ast.get_docstring(node.body[0]))
931        node = ast.parse('class foo:\n  x = "not docstring"')
932        self.assertIsNone(ast.get_docstring(node.body[0]))
933        node = ast.parse('class foo:\n  def bar(self): pass')
934        self.assertIsNone(ast.get_docstring(node.body[0]))
935
936        node = ast.parse('def foo():\n  pass')
937        self.assertIsNone(ast.get_docstring(node.body[0]))
938        node = ast.parse('def foo():\n  x = "not docstring"')
939        self.assertIsNone(ast.get_docstring(node.body[0]))
940
941        node = ast.parse('async def foo():\n  pass')
942        self.assertIsNone(ast.get_docstring(node.body[0]))
943        node = ast.parse('async def foo():\n  x = "not docstring"')
944        self.assertIsNone(ast.get_docstring(node.body[0]))
945
946    def test_multi_line_docstring_col_offset_and_lineno_issue16806(self):
947        node = ast.parse(
948            '"""line one\nline two"""\n\n'
949            'def foo():\n  """line one\n  line two"""\n\n'
950            '  def bar():\n    """line one\n    line two"""\n'
951            '  """line one\n  line two"""\n'
952            '"""line one\nline two"""\n\n'
953        )
954        self.assertEqual(node.body[0].col_offset, 0)
955        self.assertEqual(node.body[0].lineno, 1)
956        self.assertEqual(node.body[1].body[0].col_offset, 2)
957        self.assertEqual(node.body[1].body[0].lineno, 5)
958        self.assertEqual(node.body[1].body[1].body[0].col_offset, 4)
959        self.assertEqual(node.body[1].body[1].body[0].lineno, 9)
960        self.assertEqual(node.body[1].body[2].col_offset, 2)
961        self.assertEqual(node.body[1].body[2].lineno, 11)
962        self.assertEqual(node.body[2].col_offset, 0)
963        self.assertEqual(node.body[2].lineno, 13)
964
965    def test_elif_stmt_start_position(self):
966        node = ast.parse('if a:\n    pass\nelif b:\n    pass\n')
967        elif_stmt = node.body[0].orelse[0]
968        self.assertEqual(elif_stmt.lineno, 3)
969        self.assertEqual(elif_stmt.col_offset, 0)
970
971    def test_elif_stmt_start_position_with_else(self):
972        node = ast.parse('if a:\n    pass\nelif b:\n    pass\nelse:\n    pass\n')
973        elif_stmt = node.body[0].orelse[0]
974        self.assertEqual(elif_stmt.lineno, 3)
975        self.assertEqual(elif_stmt.col_offset, 0)
976
977    def test_starred_expr_end_position_within_call(self):
978        node = ast.parse('f(*[0, 1])')
979        starred_expr = node.body[0].value.args[0]
980        self.assertEqual(starred_expr.end_lineno, 1)
981        self.assertEqual(starred_expr.end_col_offset, 9)
982
983    def test_literal_eval(self):
984        self.assertEqual(ast.literal_eval('[1, 2, 3]'), [1, 2, 3])
985        self.assertEqual(ast.literal_eval('{"foo": 42}'), {"foo": 42})
986        self.assertEqual(ast.literal_eval('(True, False, None)'), (True, False, None))
987        self.assertEqual(ast.literal_eval('{1, 2, 3}'), {1, 2, 3})
988        self.assertEqual(ast.literal_eval('b"hi"'), b"hi")
989        self.assertEqual(ast.literal_eval('set()'), set())
990        self.assertRaises(ValueError, ast.literal_eval, 'foo()')
991        self.assertEqual(ast.literal_eval('6'), 6)
992        self.assertEqual(ast.literal_eval('+6'), 6)
993        self.assertEqual(ast.literal_eval('-6'), -6)
994        self.assertEqual(ast.literal_eval('3.25'), 3.25)
995        self.assertEqual(ast.literal_eval('+3.25'), 3.25)
996        self.assertEqual(ast.literal_eval('-3.25'), -3.25)
997        self.assertEqual(repr(ast.literal_eval('-0.0')), '-0.0')
998        self.assertRaises(ValueError, ast.literal_eval, '++6')
999        self.assertRaises(ValueError, ast.literal_eval, '+True')
1000        self.assertRaises(ValueError, ast.literal_eval, '2+3')
1001
1002    def test_literal_eval_complex(self):
1003        # Issue #4907
1004        self.assertEqual(ast.literal_eval('6j'), 6j)
1005        self.assertEqual(ast.literal_eval('-6j'), -6j)
1006        self.assertEqual(ast.literal_eval('6.75j'), 6.75j)
1007        self.assertEqual(ast.literal_eval('-6.75j'), -6.75j)
1008        self.assertEqual(ast.literal_eval('3+6j'), 3+6j)
1009        self.assertEqual(ast.literal_eval('-3+6j'), -3+6j)
1010        self.assertEqual(ast.literal_eval('3-6j'), 3-6j)
1011        self.assertEqual(ast.literal_eval('-3-6j'), -3-6j)
1012        self.assertEqual(ast.literal_eval('3.25+6.75j'), 3.25+6.75j)
1013        self.assertEqual(ast.literal_eval('-3.25+6.75j'), -3.25+6.75j)
1014        self.assertEqual(ast.literal_eval('3.25-6.75j'), 3.25-6.75j)
1015        self.assertEqual(ast.literal_eval('-3.25-6.75j'), -3.25-6.75j)
1016        self.assertEqual(ast.literal_eval('(3+6j)'), 3+6j)
1017        self.assertRaises(ValueError, ast.literal_eval, '-6j+3')
1018        self.assertRaises(ValueError, ast.literal_eval, '-6j+3j')
1019        self.assertRaises(ValueError, ast.literal_eval, '3+-6j')
1020        self.assertRaises(ValueError, ast.literal_eval, '3+(0+6j)')
1021        self.assertRaises(ValueError, ast.literal_eval, '-(3+6j)')
1022
1023    def test_literal_eval_malformed_dict_nodes(self):
1024        malformed = ast.Dict(keys=[ast.Constant(1), ast.Constant(2)], values=[ast.Constant(3)])
1025        self.assertRaises(ValueError, ast.literal_eval, malformed)
1026        malformed = ast.Dict(keys=[ast.Constant(1)], values=[ast.Constant(2), ast.Constant(3)])
1027        self.assertRaises(ValueError, ast.literal_eval, malformed)
1028
1029    def test_literal_eval_trailing_ws(self):
1030        self.assertEqual(ast.literal_eval("    -1"), -1)
1031        self.assertEqual(ast.literal_eval("\t\t-1"), -1)
1032        self.assertEqual(ast.literal_eval(" \t -1"), -1)
1033        self.assertRaises(IndentationError, ast.literal_eval, "\n -1")
1034
1035    def test_literal_eval_malformed_lineno(self):
1036        msg = r'malformed node or string on line 3:'
1037        with self.assertRaisesRegex(ValueError, msg):
1038            ast.literal_eval("{'a': 1,\n'b':2,\n'c':++3,\n'd':4}")
1039
1040        node = ast.UnaryOp(
1041            ast.UAdd(), ast.UnaryOp(ast.UAdd(), ast.Constant(6)))
1042        self.assertIsNone(getattr(node, 'lineno', None))
1043        msg = r'malformed node or string:'
1044        with self.assertRaisesRegex(ValueError, msg):
1045            ast.literal_eval(node)
1046
1047    def test_literal_eval_syntax_errors(self):
1048        msg = "unexpected character after line continuation character"
1049        with self.assertRaisesRegex(SyntaxError, msg):
1050            ast.literal_eval(r'''
1051                \
1052                (\
1053            \ ''')
1054
1055    def test_bad_integer(self):
1056        # issue13436: Bad error message with invalid numeric values
1057        body = [ast.ImportFrom(module='time',
1058                               names=[ast.alias(name='sleep')],
1059                               level=None,
1060                               lineno=None, col_offset=None)]
1061        mod = ast.Module(body, [])
1062        with self.assertRaises(ValueError) as cm:
1063            compile(mod, 'test', 'exec')
1064        self.assertIn("invalid integer value: None", str(cm.exception))
1065
1066    def test_level_as_none(self):
1067        body = [ast.ImportFrom(module='time',
1068                               names=[ast.alias(name='sleep',
1069                                                lineno=0, col_offset=0)],
1070                               level=None,
1071                               lineno=0, col_offset=0)]
1072        mod = ast.Module(body, [])
1073        code = compile(mod, 'test', 'exec')
1074        ns = {}
1075        exec(code, ns)
1076        self.assertIn('sleep', ns)
1077
1078    def test_recursion_direct(self):
1079        e = ast.UnaryOp(op=ast.Not(), lineno=0, col_offset=0)
1080        e.operand = e
1081        with self.assertRaises(RecursionError):
1082            with support.infinite_recursion():
1083                compile(ast.Expression(e), "<test>", "eval")
1084
1085    def test_recursion_indirect(self):
1086        e = ast.UnaryOp(op=ast.Not(), lineno=0, col_offset=0)
1087        f = ast.UnaryOp(op=ast.Not(), lineno=0, col_offset=0)
1088        e.operand = f
1089        f.operand = e
1090        with self.assertRaises(RecursionError):
1091            with support.infinite_recursion():
1092                compile(ast.Expression(e), "<test>", "eval")
1093
1094
1095class ASTValidatorTests(unittest.TestCase):
1096
1097    def mod(self, mod, msg=None, mode="exec", *, exc=ValueError):
1098        mod.lineno = mod.col_offset = 0
1099        ast.fix_missing_locations(mod)
1100        if msg is None:
1101            compile(mod, "<test>", mode)
1102        else:
1103            with self.assertRaises(exc) as cm:
1104                compile(mod, "<test>", mode)
1105            self.assertIn(msg, str(cm.exception))
1106
1107    def expr(self, node, msg=None, *, exc=ValueError):
1108        mod = ast.Module([ast.Expr(node)], [])
1109        self.mod(mod, msg, exc=exc)
1110
1111    def stmt(self, stmt, msg=None):
1112        mod = ast.Module([stmt], [])
1113        self.mod(mod, msg)
1114
1115    def test_module(self):
1116        m = ast.Interactive([ast.Expr(ast.Name("x", ast.Store()))])
1117        self.mod(m, "must have Load context", "single")
1118        m = ast.Expression(ast.Name("x", ast.Store()))
1119        self.mod(m, "must have Load context", "eval")
1120
1121    def _check_arguments(self, fac, check):
1122        def arguments(args=None, posonlyargs=None, vararg=None,
1123                      kwonlyargs=None, kwarg=None,
1124                      defaults=None, kw_defaults=None):
1125            if args is None:
1126                args = []
1127            if posonlyargs is None:
1128                posonlyargs = []
1129            if kwonlyargs is None:
1130                kwonlyargs = []
1131            if defaults is None:
1132                defaults = []
1133            if kw_defaults is None:
1134                kw_defaults = []
1135            args = ast.arguments(args, posonlyargs, vararg, kwonlyargs,
1136                                 kw_defaults, kwarg, defaults)
1137            return fac(args)
1138        args = [ast.arg("x", ast.Name("x", ast.Store()))]
1139        check(arguments(args=args), "must have Load context")
1140        check(arguments(posonlyargs=args), "must have Load context")
1141        check(arguments(kwonlyargs=args), "must have Load context")
1142        check(arguments(defaults=[ast.Num(3)]),
1143                       "more positional defaults than args")
1144        check(arguments(kw_defaults=[ast.Num(4)]),
1145                       "length of kwonlyargs is not the same as kw_defaults")
1146        args = [ast.arg("x", ast.Name("x", ast.Load()))]
1147        check(arguments(args=args, defaults=[ast.Name("x", ast.Store())]),
1148                       "must have Load context")
1149        args = [ast.arg("a", ast.Name("x", ast.Load())),
1150                ast.arg("b", ast.Name("y", ast.Load()))]
1151        check(arguments(kwonlyargs=args,
1152                          kw_defaults=[None, ast.Name("x", ast.Store())]),
1153                          "must have Load context")
1154
1155    def test_funcdef(self):
1156        a = ast.arguments([], [], None, [], [], None, [])
1157        f = ast.FunctionDef("x", a, [], [], None)
1158        self.stmt(f, "empty body on FunctionDef")
1159        f = ast.FunctionDef("x", a, [ast.Pass()], [ast.Name("x", ast.Store())],
1160                            None)
1161        self.stmt(f, "must have Load context")
1162        f = ast.FunctionDef("x", a, [ast.Pass()], [],
1163                            ast.Name("x", ast.Store()))
1164        self.stmt(f, "must have Load context")
1165        def fac(args):
1166            return ast.FunctionDef("x", args, [ast.Pass()], [], None)
1167        self._check_arguments(fac, self.stmt)
1168
1169    def test_classdef(self):
1170        def cls(bases=None, keywords=None, body=None, decorator_list=None):
1171            if bases is None:
1172                bases = []
1173            if keywords is None:
1174                keywords = []
1175            if body is None:
1176                body = [ast.Pass()]
1177            if decorator_list is None:
1178                decorator_list = []
1179            return ast.ClassDef("myclass", bases, keywords,
1180                                body, decorator_list)
1181        self.stmt(cls(bases=[ast.Name("x", ast.Store())]),
1182                  "must have Load context")
1183        self.stmt(cls(keywords=[ast.keyword("x", ast.Name("x", ast.Store()))]),
1184                  "must have Load context")
1185        self.stmt(cls(body=[]), "empty body on ClassDef")
1186        self.stmt(cls(body=[None]), "None disallowed")
1187        self.stmt(cls(decorator_list=[ast.Name("x", ast.Store())]),
1188                  "must have Load context")
1189
1190    def test_delete(self):
1191        self.stmt(ast.Delete([]), "empty targets on Delete")
1192        self.stmt(ast.Delete([None]), "None disallowed")
1193        self.stmt(ast.Delete([ast.Name("x", ast.Load())]),
1194                  "must have Del context")
1195
1196    def test_assign(self):
1197        self.stmt(ast.Assign([], ast.Num(3)), "empty targets on Assign")
1198        self.stmt(ast.Assign([None], ast.Num(3)), "None disallowed")
1199        self.stmt(ast.Assign([ast.Name("x", ast.Load())], ast.Num(3)),
1200                  "must have Store context")
1201        self.stmt(ast.Assign([ast.Name("x", ast.Store())],
1202                                ast.Name("y", ast.Store())),
1203                  "must have Load context")
1204
1205    def test_augassign(self):
1206        aug = ast.AugAssign(ast.Name("x", ast.Load()), ast.Add(),
1207                            ast.Name("y", ast.Load()))
1208        self.stmt(aug, "must have Store context")
1209        aug = ast.AugAssign(ast.Name("x", ast.Store()), ast.Add(),
1210                            ast.Name("y", ast.Store()))
1211        self.stmt(aug, "must have Load context")
1212
1213    def test_for(self):
1214        x = ast.Name("x", ast.Store())
1215        y = ast.Name("y", ast.Load())
1216        p = ast.Pass()
1217        self.stmt(ast.For(x, y, [], []), "empty body on For")
1218        self.stmt(ast.For(ast.Name("x", ast.Load()), y, [p], []),
1219                  "must have Store context")
1220        self.stmt(ast.For(x, ast.Name("y", ast.Store()), [p], []),
1221                  "must have Load context")
1222        e = ast.Expr(ast.Name("x", ast.Store()))
1223        self.stmt(ast.For(x, y, [e], []), "must have Load context")
1224        self.stmt(ast.For(x, y, [p], [e]), "must have Load context")
1225
1226    def test_while(self):
1227        self.stmt(ast.While(ast.Num(3), [], []), "empty body on While")
1228        self.stmt(ast.While(ast.Name("x", ast.Store()), [ast.Pass()], []),
1229                  "must have Load context")
1230        self.stmt(ast.While(ast.Num(3), [ast.Pass()],
1231                             [ast.Expr(ast.Name("x", ast.Store()))]),
1232                             "must have Load context")
1233
1234    def test_if(self):
1235        self.stmt(ast.If(ast.Num(3), [], []), "empty body on If")
1236        i = ast.If(ast.Name("x", ast.Store()), [ast.Pass()], [])
1237        self.stmt(i, "must have Load context")
1238        i = ast.If(ast.Num(3), [ast.Expr(ast.Name("x", ast.Store()))], [])
1239        self.stmt(i, "must have Load context")
1240        i = ast.If(ast.Num(3), [ast.Pass()],
1241                   [ast.Expr(ast.Name("x", ast.Store()))])
1242        self.stmt(i, "must have Load context")
1243
1244    def test_with(self):
1245        p = ast.Pass()
1246        self.stmt(ast.With([], [p]), "empty items on With")
1247        i = ast.withitem(ast.Num(3), None)
1248        self.stmt(ast.With([i], []), "empty body on With")
1249        i = ast.withitem(ast.Name("x", ast.Store()), None)
1250        self.stmt(ast.With([i], [p]), "must have Load context")
1251        i = ast.withitem(ast.Num(3), ast.Name("x", ast.Load()))
1252        self.stmt(ast.With([i], [p]), "must have Store context")
1253
1254    def test_raise(self):
1255        r = ast.Raise(None, ast.Num(3))
1256        self.stmt(r, "Raise with cause but no exception")
1257        r = ast.Raise(ast.Name("x", ast.Store()), None)
1258        self.stmt(r, "must have Load context")
1259        r = ast.Raise(ast.Num(4), ast.Name("x", ast.Store()))
1260        self.stmt(r, "must have Load context")
1261
1262    def test_try(self):
1263        p = ast.Pass()
1264        t = ast.Try([], [], [], [p])
1265        self.stmt(t, "empty body on Try")
1266        t = ast.Try([ast.Expr(ast.Name("x", ast.Store()))], [], [], [p])
1267        self.stmt(t, "must have Load context")
1268        t = ast.Try([p], [], [], [])
1269        self.stmt(t, "Try has neither except handlers nor finalbody")
1270        t = ast.Try([p], [], [p], [p])
1271        self.stmt(t, "Try has orelse but no except handlers")
1272        t = ast.Try([p], [ast.ExceptHandler(None, "x", [])], [], [])
1273        self.stmt(t, "empty body on ExceptHandler")
1274        e = [ast.ExceptHandler(ast.Name("x", ast.Store()), "y", [p])]
1275        self.stmt(ast.Try([p], e, [], []), "must have Load context")
1276        e = [ast.ExceptHandler(None, "x", [p])]
1277        t = ast.Try([p], e, [ast.Expr(ast.Name("x", ast.Store()))], [p])
1278        self.stmt(t, "must have Load context")
1279        t = ast.Try([p], e, [p], [ast.Expr(ast.Name("x", ast.Store()))])
1280        self.stmt(t, "must have Load context")
1281
1282    def test_assert(self):
1283        self.stmt(ast.Assert(ast.Name("x", ast.Store()), None),
1284                  "must have Load context")
1285        assrt = ast.Assert(ast.Name("x", ast.Load()),
1286                           ast.Name("y", ast.Store()))
1287        self.stmt(assrt, "must have Load context")
1288
1289    def test_import(self):
1290        self.stmt(ast.Import([]), "empty names on Import")
1291
1292    def test_importfrom(self):
1293        imp = ast.ImportFrom(None, [ast.alias("x", None)], -42)
1294        self.stmt(imp, "Negative ImportFrom level")
1295        self.stmt(ast.ImportFrom(None, [], 0), "empty names on ImportFrom")
1296
1297    def test_global(self):
1298        self.stmt(ast.Global([]), "empty names on Global")
1299
1300    def test_nonlocal(self):
1301        self.stmt(ast.Nonlocal([]), "empty names on Nonlocal")
1302
1303    def test_expr(self):
1304        e = ast.Expr(ast.Name("x", ast.Store()))
1305        self.stmt(e, "must have Load context")
1306
1307    def test_boolop(self):
1308        b = ast.BoolOp(ast.And(), [])
1309        self.expr(b, "less than 2 values")
1310        b = ast.BoolOp(ast.And(), [ast.Num(3)])
1311        self.expr(b, "less than 2 values")
1312        b = ast.BoolOp(ast.And(), [ast.Num(4), None])
1313        self.expr(b, "None disallowed")
1314        b = ast.BoolOp(ast.And(), [ast.Num(4), ast.Name("x", ast.Store())])
1315        self.expr(b, "must have Load context")
1316
1317    def test_unaryop(self):
1318        u = ast.UnaryOp(ast.Not(), ast.Name("x", ast.Store()))
1319        self.expr(u, "must have Load context")
1320
1321    def test_lambda(self):
1322        a = ast.arguments([], [], None, [], [], None, [])
1323        self.expr(ast.Lambda(a, ast.Name("x", ast.Store())),
1324                  "must have Load context")
1325        def fac(args):
1326            return ast.Lambda(args, ast.Name("x", ast.Load()))
1327        self._check_arguments(fac, self.expr)
1328
1329    def test_ifexp(self):
1330        l = ast.Name("x", ast.Load())
1331        s = ast.Name("y", ast.Store())
1332        for args in (s, l, l), (l, s, l), (l, l, s):
1333            self.expr(ast.IfExp(*args), "must have Load context")
1334
1335    def test_dict(self):
1336        d = ast.Dict([], [ast.Name("x", ast.Load())])
1337        self.expr(d, "same number of keys as values")
1338        d = ast.Dict([ast.Name("x", ast.Load())], [None])
1339        self.expr(d, "None disallowed")
1340
1341    def test_set(self):
1342        self.expr(ast.Set([None]), "None disallowed")
1343        s = ast.Set([ast.Name("x", ast.Store())])
1344        self.expr(s, "must have Load context")
1345
1346    def _check_comprehension(self, fac):
1347        self.expr(fac([]), "comprehension with no generators")
1348        g = ast.comprehension(ast.Name("x", ast.Load()),
1349                              ast.Name("x", ast.Load()), [], 0)
1350        self.expr(fac([g]), "must have Store context")
1351        g = ast.comprehension(ast.Name("x", ast.Store()),
1352                              ast.Name("x", ast.Store()), [], 0)
1353        self.expr(fac([g]), "must have Load context")
1354        x = ast.Name("x", ast.Store())
1355        y = ast.Name("y", ast.Load())
1356        g = ast.comprehension(x, y, [None], 0)
1357        self.expr(fac([g]), "None disallowed")
1358        g = ast.comprehension(x, y, [ast.Name("x", ast.Store())], 0)
1359        self.expr(fac([g]), "must have Load context")
1360
1361    def _simple_comp(self, fac):
1362        g = ast.comprehension(ast.Name("x", ast.Store()),
1363                              ast.Name("x", ast.Load()), [], 0)
1364        self.expr(fac(ast.Name("x", ast.Store()), [g]),
1365                  "must have Load context")
1366        def wrap(gens):
1367            return fac(ast.Name("x", ast.Store()), gens)
1368        self._check_comprehension(wrap)
1369
1370    def test_listcomp(self):
1371        self._simple_comp(ast.ListComp)
1372
1373    def test_setcomp(self):
1374        self._simple_comp(ast.SetComp)
1375
1376    def test_generatorexp(self):
1377        self._simple_comp(ast.GeneratorExp)
1378
1379    def test_dictcomp(self):
1380        g = ast.comprehension(ast.Name("y", ast.Store()),
1381                              ast.Name("p", ast.Load()), [], 0)
1382        c = ast.DictComp(ast.Name("x", ast.Store()),
1383                         ast.Name("y", ast.Load()), [g])
1384        self.expr(c, "must have Load context")
1385        c = ast.DictComp(ast.Name("x", ast.Load()),
1386                         ast.Name("y", ast.Store()), [g])
1387        self.expr(c, "must have Load context")
1388        def factory(comps):
1389            k = ast.Name("x", ast.Load())
1390            v = ast.Name("y", ast.Load())
1391            return ast.DictComp(k, v, comps)
1392        self._check_comprehension(factory)
1393
1394    def test_yield(self):
1395        self.expr(ast.Yield(ast.Name("x", ast.Store())), "must have Load")
1396        self.expr(ast.YieldFrom(ast.Name("x", ast.Store())), "must have Load")
1397
1398    def test_compare(self):
1399        left = ast.Name("x", ast.Load())
1400        comp = ast.Compare(left, [ast.In()], [])
1401        self.expr(comp, "no comparators")
1402        comp = ast.Compare(left, [ast.In()], [ast.Num(4), ast.Num(5)])
1403        self.expr(comp, "different number of comparators and operands")
1404        comp = ast.Compare(ast.Num("blah"), [ast.In()], [left])
1405        self.expr(comp)
1406        comp = ast.Compare(left, [ast.In()], [ast.Num("blah")])
1407        self.expr(comp)
1408
1409    def test_call(self):
1410        func = ast.Name("x", ast.Load())
1411        args = [ast.Name("y", ast.Load())]
1412        keywords = [ast.keyword("w", ast.Name("z", ast.Load()))]
1413        call = ast.Call(ast.Name("x", ast.Store()), args, keywords)
1414        self.expr(call, "must have Load context")
1415        call = ast.Call(func, [None], keywords)
1416        self.expr(call, "None disallowed")
1417        bad_keywords = [ast.keyword("w", ast.Name("z", ast.Store()))]
1418        call = ast.Call(func, args, bad_keywords)
1419        self.expr(call, "must have Load context")
1420
1421    def test_num(self):
1422        class subint(int):
1423            pass
1424        class subfloat(float):
1425            pass
1426        class subcomplex(complex):
1427            pass
1428        for obj in "0", "hello":
1429            self.expr(ast.Num(obj))
1430        for obj in subint(), subfloat(), subcomplex():
1431            self.expr(ast.Num(obj), "invalid type", exc=TypeError)
1432
1433    def test_attribute(self):
1434        attr = ast.Attribute(ast.Name("x", ast.Store()), "y", ast.Load())
1435        self.expr(attr, "must have Load context")
1436
1437    def test_subscript(self):
1438        sub = ast.Subscript(ast.Name("x", ast.Store()), ast.Num(3),
1439                            ast.Load())
1440        self.expr(sub, "must have Load context")
1441        x = ast.Name("x", ast.Load())
1442        sub = ast.Subscript(x, ast.Name("y", ast.Store()),
1443                            ast.Load())
1444        self.expr(sub, "must have Load context")
1445        s = ast.Name("x", ast.Store())
1446        for args in (s, None, None), (None, s, None), (None, None, s):
1447            sl = ast.Slice(*args)
1448            self.expr(ast.Subscript(x, sl, ast.Load()),
1449                      "must have Load context")
1450        sl = ast.Tuple([], ast.Load())
1451        self.expr(ast.Subscript(x, sl, ast.Load()))
1452        sl = ast.Tuple([s], ast.Load())
1453        self.expr(ast.Subscript(x, sl, ast.Load()), "must have Load context")
1454
1455    def test_starred(self):
1456        left = ast.List([ast.Starred(ast.Name("x", ast.Load()), ast.Store())],
1457                        ast.Store())
1458        assign = ast.Assign([left], ast.Num(4))
1459        self.stmt(assign, "must have Store context")
1460
1461    def _sequence(self, fac):
1462        self.expr(fac([None], ast.Load()), "None disallowed")
1463        self.expr(fac([ast.Name("x", ast.Store())], ast.Load()),
1464                  "must have Load context")
1465
1466    def test_list(self):
1467        self._sequence(ast.List)
1468
1469    def test_tuple(self):
1470        self._sequence(ast.Tuple)
1471
1472    def test_nameconstant(self):
1473        self.expr(ast.NameConstant(4))
1474
1475    def test_stdlib_validates(self):
1476        stdlib = os.path.dirname(ast.__file__)
1477        tests = [fn for fn in os.listdir(stdlib) if fn.endswith(".py")]
1478        tests.extend(["test/test_grammar.py", "test/test_unpack_ex.py"])
1479        for module in tests:
1480            with self.subTest(module):
1481                fn = os.path.join(stdlib, module)
1482                with open(fn, "r", encoding="utf-8") as fp:
1483                    source = fp.read()
1484                mod = ast.parse(source, fn)
1485                compile(mod, fn, "exec")
1486
1487    constant_1 = ast.Constant(1)
1488    pattern_1 = ast.MatchValue(constant_1)
1489
1490    constant_x = ast.Constant('x')
1491    pattern_x = ast.MatchValue(constant_x)
1492
1493    constant_true = ast.Constant(True)
1494    pattern_true = ast.MatchSingleton(True)
1495
1496    name_carter = ast.Name('carter', ast.Load())
1497
1498    _MATCH_PATTERNS = [
1499        ast.MatchValue(
1500            ast.Attribute(
1501                ast.Attribute(
1502                    ast.Name('x', ast.Store()),
1503                    'y', ast.Load()
1504                ),
1505                'z', ast.Load()
1506            )
1507        ),
1508        ast.MatchValue(
1509            ast.Attribute(
1510                ast.Attribute(
1511                    ast.Name('x', ast.Load()),
1512                    'y', ast.Store()
1513                ),
1514                'z', ast.Load()
1515            )
1516        ),
1517        ast.MatchValue(
1518            ast.Constant(...)
1519        ),
1520        ast.MatchValue(
1521            ast.Constant(True)
1522        ),
1523        ast.MatchValue(
1524            ast.Constant((1,2,3))
1525        ),
1526        ast.MatchSingleton('string'),
1527        ast.MatchSequence([
1528          ast.MatchSingleton('string')
1529        ]),
1530        ast.MatchSequence(
1531            [
1532                ast.MatchSequence(
1533                    [
1534                        ast.MatchSingleton('string')
1535                    ]
1536                )
1537            ]
1538        ),
1539        ast.MatchMapping(
1540            [constant_1, constant_true],
1541            [pattern_x]
1542        ),
1543        ast.MatchMapping(
1544            [constant_true, constant_1],
1545            [pattern_x, pattern_1],
1546            rest='True'
1547        ),
1548        ast.MatchMapping(
1549            [constant_true, ast.Starred(ast.Name('lol', ast.Load()), ast.Load())],
1550            [pattern_x, pattern_1],
1551            rest='legit'
1552        ),
1553        ast.MatchClass(
1554            ast.Attribute(
1555                ast.Attribute(
1556                    constant_x,
1557                    'y', ast.Load()),
1558                'z', ast.Load()),
1559            patterns=[], kwd_attrs=[], kwd_patterns=[]
1560        ),
1561        ast.MatchClass(
1562            name_carter,
1563            patterns=[],
1564            kwd_attrs=['True'],
1565            kwd_patterns=[pattern_1]
1566        ),
1567        ast.MatchClass(
1568            name_carter,
1569            patterns=[],
1570            kwd_attrs=[],
1571            kwd_patterns=[pattern_1]
1572        ),
1573        ast.MatchClass(
1574            name_carter,
1575            patterns=[ast.MatchSingleton('string')],
1576            kwd_attrs=[],
1577            kwd_patterns=[]
1578        ),
1579        ast.MatchClass(
1580            name_carter,
1581            patterns=[ast.MatchStar()],
1582            kwd_attrs=[],
1583            kwd_patterns=[]
1584        ),
1585        ast.MatchClass(
1586            name_carter,
1587            patterns=[],
1588            kwd_attrs=[],
1589            kwd_patterns=[ast.MatchStar()]
1590        ),
1591        ast.MatchSequence(
1592            [
1593                ast.MatchStar("True")
1594            ]
1595        ),
1596        ast.MatchAs(
1597            name='False'
1598        ),
1599        ast.MatchOr(
1600            []
1601        ),
1602        ast.MatchOr(
1603            [pattern_1]
1604        ),
1605        ast.MatchOr(
1606            [pattern_1, pattern_x, ast.MatchSingleton('xxx')]
1607        ),
1608        ast.MatchAs(name="_"),
1609        ast.MatchStar(name="x"),
1610        ast.MatchSequence([ast.MatchStar("_")]),
1611        ast.MatchMapping([], [], rest="_"),
1612    ]
1613
1614    def test_match_validation_pattern(self):
1615        name_x = ast.Name('x', ast.Load())
1616        for pattern in self._MATCH_PATTERNS:
1617            with self.subTest(ast.dump(pattern, indent=4)):
1618                node = ast.Match(
1619                    subject=name_x,
1620                    cases = [
1621                        ast.match_case(
1622                            pattern=pattern,
1623                            body = [ast.Pass()]
1624                        )
1625                    ]
1626                )
1627                node = ast.fix_missing_locations(node)
1628                module = ast.Module([node], [])
1629                with self.assertRaises(ValueError):
1630                    compile(module, "<test>", "exec")
1631
1632
1633class ConstantTests(unittest.TestCase):
1634    """Tests on the ast.Constant node type."""
1635
1636    def compile_constant(self, value):
1637        tree = ast.parse("x = 123")
1638
1639        node = tree.body[0].value
1640        new_node = ast.Constant(value=value)
1641        ast.copy_location(new_node, node)
1642        tree.body[0].value = new_node
1643
1644        code = compile(tree, "<string>", "exec")
1645
1646        ns = {}
1647        exec(code, ns)
1648        return ns['x']
1649
1650    def test_validation(self):
1651        with self.assertRaises(TypeError) as cm:
1652            self.compile_constant([1, 2, 3])
1653        self.assertEqual(str(cm.exception),
1654                         "got an invalid type in Constant: list")
1655
1656    def test_singletons(self):
1657        for const in (None, False, True, Ellipsis, b'', frozenset()):
1658            with self.subTest(const=const):
1659                value = self.compile_constant(const)
1660                self.assertIs(value, const)
1661
1662    def test_values(self):
1663        nested_tuple = (1,)
1664        nested_frozenset = frozenset({1})
1665        for level in range(3):
1666            nested_tuple = (nested_tuple, 2)
1667            nested_frozenset = frozenset({nested_frozenset, 2})
1668        values = (123, 123.0, 123j,
1669                  "unicode", b'bytes',
1670                  tuple("tuple"), frozenset("frozenset"),
1671                  nested_tuple, nested_frozenset)
1672        for value in values:
1673            with self.subTest(value=value):
1674                result = self.compile_constant(value)
1675                self.assertEqual(result, value)
1676
1677    def test_assign_to_constant(self):
1678        tree = ast.parse("x = 1")
1679
1680        target = tree.body[0].targets[0]
1681        new_target = ast.Constant(value=1)
1682        ast.copy_location(new_target, target)
1683        tree.body[0].targets[0] = new_target
1684
1685        with self.assertRaises(ValueError) as cm:
1686            compile(tree, "string", "exec")
1687        self.assertEqual(str(cm.exception),
1688                         "expression which can't be assigned "
1689                         "to in Store context")
1690
1691    def test_get_docstring(self):
1692        tree = ast.parse("'docstring'\nx = 1")
1693        self.assertEqual(ast.get_docstring(tree), 'docstring')
1694
1695    def get_load_const(self, tree):
1696        # Compile to bytecode, disassemble and get parameter of LOAD_CONST
1697        # instructions
1698        co = compile(tree, '<string>', 'exec')
1699        consts = []
1700        for instr in dis.get_instructions(co):
1701            if instr.opname == 'LOAD_CONST':
1702                consts.append(instr.argval)
1703        return consts
1704
1705    @support.cpython_only
1706    def test_load_const(self):
1707        consts = [None,
1708                  True, False,
1709                  124,
1710                  2.0,
1711                  3j,
1712                  "unicode",
1713                  b'bytes',
1714                  (1, 2, 3)]
1715
1716        code = '\n'.join(['x={!r}'.format(const) for const in consts])
1717        code += '\nx = ...'
1718        consts.extend((Ellipsis, None))
1719
1720        tree = ast.parse(code)
1721        self.assertEqual(self.get_load_const(tree),
1722                         consts)
1723
1724        # Replace expression nodes with constants
1725        for assign, const in zip(tree.body, consts):
1726            assert isinstance(assign, ast.Assign), ast.dump(assign)
1727            new_node = ast.Constant(value=const)
1728            ast.copy_location(new_node, assign.value)
1729            assign.value = new_node
1730
1731        self.assertEqual(self.get_load_const(tree),
1732                         consts)
1733
1734    def test_literal_eval(self):
1735        tree = ast.parse("1 + 2")
1736        binop = tree.body[0].value
1737
1738        new_left = ast.Constant(value=10)
1739        ast.copy_location(new_left, binop.left)
1740        binop.left = new_left
1741
1742        new_right = ast.Constant(value=20j)
1743        ast.copy_location(new_right, binop.right)
1744        binop.right = new_right
1745
1746        self.assertEqual(ast.literal_eval(binop), 10+20j)
1747
1748    def test_string_kind(self):
1749        c = ast.parse('"x"', mode='eval').body
1750        self.assertEqual(c.value, "x")
1751        self.assertEqual(c.kind, None)
1752
1753        c = ast.parse('u"x"', mode='eval').body
1754        self.assertEqual(c.value, "x")
1755        self.assertEqual(c.kind, "u")
1756
1757        c = ast.parse('r"x"', mode='eval').body
1758        self.assertEqual(c.value, "x")
1759        self.assertEqual(c.kind, None)
1760
1761        c = ast.parse('b"x"', mode='eval').body
1762        self.assertEqual(c.value, b"x")
1763        self.assertEqual(c.kind, None)
1764
1765
1766class EndPositionTests(unittest.TestCase):
1767    """Tests for end position of AST nodes.
1768
1769    Testing end positions of nodes requires a bit of extra care
1770    because of how LL parsers work.
1771    """
1772    def _check_end_pos(self, ast_node, end_lineno, end_col_offset):
1773        self.assertEqual(ast_node.end_lineno, end_lineno)
1774        self.assertEqual(ast_node.end_col_offset, end_col_offset)
1775
1776    def _check_content(self, source, ast_node, content):
1777        self.assertEqual(ast.get_source_segment(source, ast_node), content)
1778
1779    def _parse_value(self, s):
1780        # Use duck-typing to support both single expression
1781        # and a right hand side of an assignment statement.
1782        return ast.parse(s).body[0].value
1783
1784    def test_lambda(self):
1785        s = 'lambda x, *y: None'
1786        lam = self._parse_value(s)
1787        self._check_content(s, lam.body, 'None')
1788        self._check_content(s, lam.args.args[0], 'x')
1789        self._check_content(s, lam.args.vararg, 'y')
1790
1791    def test_func_def(self):
1792        s = dedent('''
1793            def func(x: int,
1794                     *args: str,
1795                     z: float = 0,
1796                     **kwargs: Any) -> bool:
1797                return True
1798            ''').strip()
1799        fdef = ast.parse(s).body[0]
1800        self._check_end_pos(fdef, 5, 15)
1801        self._check_content(s, fdef.body[0], 'return True')
1802        self._check_content(s, fdef.args.args[0], 'x: int')
1803        self._check_content(s, fdef.args.args[0].annotation, 'int')
1804        self._check_content(s, fdef.args.kwarg, 'kwargs: Any')
1805        self._check_content(s, fdef.args.kwarg.annotation, 'Any')
1806
1807    def test_call(self):
1808        s = 'func(x, y=2, **kw)'
1809        call = self._parse_value(s)
1810        self._check_content(s, call.func, 'func')
1811        self._check_content(s, call.keywords[0].value, '2')
1812        self._check_content(s, call.keywords[1].value, 'kw')
1813
1814    def test_call_noargs(self):
1815        s = 'x[0]()'
1816        call = self._parse_value(s)
1817        self._check_content(s, call.func, 'x[0]')
1818        self._check_end_pos(call, 1, 6)
1819
1820    def test_class_def(self):
1821        s = dedent('''
1822            class C(A, B):
1823                x: int = 0
1824        ''').strip()
1825        cdef = ast.parse(s).body[0]
1826        self._check_end_pos(cdef, 2, 14)
1827        self._check_content(s, cdef.bases[1], 'B')
1828        self._check_content(s, cdef.body[0], 'x: int = 0')
1829
1830    def test_class_kw(self):
1831        s = 'class S(metaclass=abc.ABCMeta): pass'
1832        cdef = ast.parse(s).body[0]
1833        self._check_content(s, cdef.keywords[0].value, 'abc.ABCMeta')
1834
1835    def test_multi_line_str(self):
1836        s = dedent('''
1837            x = """Some multi-line text.
1838
1839            It goes on starting from same indent."""
1840        ''').strip()
1841        assign = ast.parse(s).body[0]
1842        self._check_end_pos(assign, 3, 40)
1843        self._check_end_pos(assign.value, 3, 40)
1844
1845    def test_continued_str(self):
1846        s = dedent('''
1847            x = "first part" \\
1848            "second part"
1849        ''').strip()
1850        assign = ast.parse(s).body[0]
1851        self._check_end_pos(assign, 2, 13)
1852        self._check_end_pos(assign.value, 2, 13)
1853
1854    def test_suites(self):
1855        # We intentionally put these into the same string to check
1856        # that empty lines are not part of the suite.
1857        s = dedent('''
1858            while True:
1859                pass
1860
1861            if one():
1862                x = None
1863            elif other():
1864                y = None
1865            else:
1866                z = None
1867
1868            for x, y in stuff:
1869                assert True
1870
1871            try:
1872                raise RuntimeError
1873            except TypeError as e:
1874                pass
1875
1876            pass
1877        ''').strip()
1878        mod = ast.parse(s)
1879        while_loop = mod.body[0]
1880        if_stmt = mod.body[1]
1881        for_loop = mod.body[2]
1882        try_stmt = mod.body[3]
1883        pass_stmt = mod.body[4]
1884
1885        self._check_end_pos(while_loop, 2, 8)
1886        self._check_end_pos(if_stmt, 9, 12)
1887        self._check_end_pos(for_loop, 12, 15)
1888        self._check_end_pos(try_stmt, 17, 8)
1889        self._check_end_pos(pass_stmt, 19, 4)
1890
1891        self._check_content(s, while_loop.test, 'True')
1892        self._check_content(s, if_stmt.body[0], 'x = None')
1893        self._check_content(s, if_stmt.orelse[0].test, 'other()')
1894        self._check_content(s, for_loop.target, 'x, y')
1895        self._check_content(s, try_stmt.body[0], 'raise RuntimeError')
1896        self._check_content(s, try_stmt.handlers[0].type, 'TypeError')
1897
1898    def test_fstring(self):
1899        s = 'x = f"abc {x + y} abc"'
1900        fstr = self._parse_value(s)
1901        binop = fstr.values[1].value
1902        self._check_content(s, binop, 'x + y')
1903
1904    def test_fstring_multi_line(self):
1905        s = dedent('''
1906            f"""Some multi-line text.
1907            {
1908            arg_one
1909            +
1910            arg_two
1911            }
1912            It goes on..."""
1913        ''').strip()
1914        fstr = self._parse_value(s)
1915        binop = fstr.values[1].value
1916        self._check_end_pos(binop, 5, 7)
1917        self._check_content(s, binop.left, 'arg_one')
1918        self._check_content(s, binop.right, 'arg_two')
1919
1920    def test_import_from_multi_line(self):
1921        s = dedent('''
1922            from x.y.z import (
1923                a, b, c as c
1924            )
1925        ''').strip()
1926        imp = ast.parse(s).body[0]
1927        self._check_end_pos(imp, 3, 1)
1928        self._check_end_pos(imp.names[2], 2, 16)
1929
1930    def test_slices(self):
1931        s1 = 'f()[1, 2] [0]'
1932        s2 = 'x[ a.b: c.d]'
1933        sm = dedent('''
1934            x[ a.b: f () ,
1935               g () : c.d
1936              ]
1937        ''').strip()
1938        i1, i2, im = map(self._parse_value, (s1, s2, sm))
1939        self._check_content(s1, i1.value, 'f()[1, 2]')
1940        self._check_content(s1, i1.value.slice, '1, 2')
1941        self._check_content(s2, i2.slice.lower, 'a.b')
1942        self._check_content(s2, i2.slice.upper, 'c.d')
1943        self._check_content(sm, im.slice.elts[0].upper, 'f ()')
1944        self._check_content(sm, im.slice.elts[1].lower, 'g ()')
1945        self._check_end_pos(im, 3, 3)
1946
1947    def test_binop(self):
1948        s = dedent('''
1949            (1 * 2 + (3 ) +
1950                 4
1951            )
1952        ''').strip()
1953        binop = self._parse_value(s)
1954        self._check_end_pos(binop, 2, 6)
1955        self._check_content(s, binop.right, '4')
1956        self._check_content(s, binop.left, '1 * 2 + (3 )')
1957        self._check_content(s, binop.left.right, '3')
1958
1959    def test_boolop(self):
1960        s = dedent('''
1961            if (one_condition and
1962                    (other_condition or yet_another_one)):
1963                pass
1964        ''').strip()
1965        bop = ast.parse(s).body[0].test
1966        self._check_end_pos(bop, 2, 44)
1967        self._check_content(s, bop.values[1],
1968                            'other_condition or yet_another_one')
1969
1970    def test_tuples(self):
1971        s1 = 'x = () ;'
1972        s2 = 'x = 1 , ;'
1973        s3 = 'x = (1 , 2 ) ;'
1974        sm = dedent('''
1975            x = (
1976                a, b,
1977            )
1978        ''').strip()
1979        t1, t2, t3, tm = map(self._parse_value, (s1, s2, s3, sm))
1980        self._check_content(s1, t1, '()')
1981        self._check_content(s2, t2, '1 ,')
1982        self._check_content(s3, t3, '(1 , 2 )')
1983        self._check_end_pos(tm, 3, 1)
1984
1985    def test_attribute_spaces(self):
1986        s = 'func(x. y .z)'
1987        call = self._parse_value(s)
1988        self._check_content(s, call, s)
1989        self._check_content(s, call.args[0], 'x. y .z')
1990
1991    def test_redundant_parenthesis(self):
1992        s = '( ( ( a + b ) ) )'
1993        v = ast.parse(s).body[0].value
1994        self.assertEqual(type(v).__name__, 'BinOp')
1995        self._check_content(s, v, 'a + b')
1996        s2 = 'await ' + s
1997        v = ast.parse(s2).body[0].value.value
1998        self.assertEqual(type(v).__name__, 'BinOp')
1999        self._check_content(s2, v, 'a + b')
2000
2001    def test_trailers_with_redundant_parenthesis(self):
2002        tests = (
2003            ('( ( ( a ) ) ) ( )', 'Call'),
2004            ('( ( ( a ) ) ) ( b )', 'Call'),
2005            ('( ( ( a ) ) ) [ b ]', 'Subscript'),
2006            ('( ( ( a ) ) ) . b', 'Attribute'),
2007        )
2008        for s, t in tests:
2009            with self.subTest(s):
2010                v = ast.parse(s).body[0].value
2011                self.assertEqual(type(v).__name__, t)
2012                self._check_content(s, v, s)
2013                s2 = 'await ' + s
2014                v = ast.parse(s2).body[0].value.value
2015                self.assertEqual(type(v).__name__, t)
2016                self._check_content(s2, v, s)
2017
2018    def test_displays(self):
2019        s1 = '[{}, {1, }, {1, 2,} ]'
2020        s2 = '{a: b, f (): g () ,}'
2021        c1 = self._parse_value(s1)
2022        c2 = self._parse_value(s2)
2023        self._check_content(s1, c1.elts[0], '{}')
2024        self._check_content(s1, c1.elts[1], '{1, }')
2025        self._check_content(s1, c1.elts[2], '{1, 2,}')
2026        self._check_content(s2, c2.keys[1], 'f ()')
2027        self._check_content(s2, c2.values[1], 'g ()')
2028
2029    def test_comprehensions(self):
2030        s = dedent('''
2031            x = [{x for x, y in stuff
2032                  if cond.x} for stuff in things]
2033        ''').strip()
2034        cmp = self._parse_value(s)
2035        self._check_end_pos(cmp, 2, 37)
2036        self._check_content(s, cmp.generators[0].iter, 'things')
2037        self._check_content(s, cmp.elt.generators[0].iter, 'stuff')
2038        self._check_content(s, cmp.elt.generators[0].ifs[0], 'cond.x')
2039        self._check_content(s, cmp.elt.generators[0].target, 'x, y')
2040
2041    def test_yield_await(self):
2042        s = dedent('''
2043            async def f():
2044                yield x
2045                await y
2046        ''').strip()
2047        fdef = ast.parse(s).body[0]
2048        self._check_content(s, fdef.body[0].value, 'yield x')
2049        self._check_content(s, fdef.body[1].value, 'await y')
2050
2051    def test_source_segment_multi(self):
2052        s_orig = dedent('''
2053            x = (
2054                a, b,
2055            ) + ()
2056        ''').strip()
2057        s_tuple = dedent('''
2058            (
2059                a, b,
2060            )
2061        ''').strip()
2062        binop = self._parse_value(s_orig)
2063        self.assertEqual(ast.get_source_segment(s_orig, binop.left), s_tuple)
2064
2065    def test_source_segment_padded(self):
2066        s_orig = dedent('''
2067            class C:
2068                def fun(self) -> None:
2069                    "ЖЖЖЖЖ"
2070        ''').strip()
2071        s_method = '    def fun(self) -> None:\n' \
2072                   '        "ЖЖЖЖЖ"'
2073        cdef = ast.parse(s_orig).body[0]
2074        self.assertEqual(ast.get_source_segment(s_orig, cdef.body[0], padded=True),
2075                         s_method)
2076
2077    def test_source_segment_endings(self):
2078        s = 'v = 1\r\nw = 1\nx = 1\n\ry = 1\rz = 1\r\n'
2079        v, w, x, y, z = ast.parse(s).body
2080        self._check_content(s, v, 'v = 1')
2081        self._check_content(s, w, 'w = 1')
2082        self._check_content(s, x, 'x = 1')
2083        self._check_content(s, y, 'y = 1')
2084        self._check_content(s, z, 'z = 1')
2085
2086    def test_source_segment_tabs(self):
2087        s = dedent('''
2088            class C:
2089              \t\f  def fun(self) -> None:
2090              \t\f      pass
2091        ''').strip()
2092        s_method = '  \t\f  def fun(self) -> None:\n' \
2093                   '  \t\f      pass'
2094
2095        cdef = ast.parse(s).body[0]
2096        self.assertEqual(ast.get_source_segment(s, cdef.body[0], padded=True), s_method)
2097
2098    def test_source_segment_missing_info(self):
2099        s = 'v = 1\r\nw = 1\nx = 1\n\ry = 1\r\n'
2100        v, w, x, y = ast.parse(s).body
2101        del v.lineno
2102        del w.end_lineno
2103        del x.col_offset
2104        del y.end_col_offset
2105        self.assertIsNone(ast.get_source_segment(s, v))
2106        self.assertIsNone(ast.get_source_segment(s, w))
2107        self.assertIsNone(ast.get_source_segment(s, x))
2108        self.assertIsNone(ast.get_source_segment(s, y))
2109
2110class NodeVisitorTests(unittest.TestCase):
2111    def test_old_constant_nodes(self):
2112        class Visitor(ast.NodeVisitor):
2113            def visit_Num(self, node):
2114                log.append((node.lineno, 'Num', node.n))
2115            def visit_Str(self, node):
2116                log.append((node.lineno, 'Str', node.s))
2117            def visit_Bytes(self, node):
2118                log.append((node.lineno, 'Bytes', node.s))
2119            def visit_NameConstant(self, node):
2120                log.append((node.lineno, 'NameConstant', node.value))
2121            def visit_Ellipsis(self, node):
2122                log.append((node.lineno, 'Ellipsis', ...))
2123        mod = ast.parse(dedent('''\
2124            i = 42
2125            f = 4.25
2126            c = 4.25j
2127            s = 'string'
2128            b = b'bytes'
2129            t = True
2130            n = None
2131            e = ...
2132            '''))
2133        visitor = Visitor()
2134        log = []
2135        with warnings.catch_warnings(record=True) as wlog:
2136            warnings.filterwarnings('always', '', DeprecationWarning)
2137            visitor.visit(mod)
2138        self.assertEqual(log, [
2139            (1, 'Num', 42),
2140            (2, 'Num', 4.25),
2141            (3, 'Num', 4.25j),
2142            (4, 'Str', 'string'),
2143            (5, 'Bytes', b'bytes'),
2144            (6, 'NameConstant', True),
2145            (7, 'NameConstant', None),
2146            (8, 'Ellipsis', ...),
2147        ])
2148        self.assertEqual([str(w.message) for w in wlog], [
2149            'visit_Num is deprecated; add visit_Constant',
2150            'visit_Num is deprecated; add visit_Constant',
2151            'visit_Num is deprecated; add visit_Constant',
2152            'visit_Str is deprecated; add visit_Constant',
2153            'visit_Bytes is deprecated; add visit_Constant',
2154            'visit_NameConstant is deprecated; add visit_Constant',
2155            'visit_NameConstant is deprecated; add visit_Constant',
2156            'visit_Ellipsis is deprecated; add visit_Constant',
2157        ])
2158
2159
2160@support.cpython_only
2161class ModuleStateTests(unittest.TestCase):
2162    # bpo-41194, bpo-41261, bpo-41631: The _ast module uses a global state.
2163
2164    def check_ast_module(self):
2165        # Check that the _ast module still works as expected
2166        code = 'x + 1'
2167        filename = '<string>'
2168        mode = 'eval'
2169
2170        # Create _ast.AST subclasses instances
2171        ast_tree = compile(code, filename, mode, flags=ast.PyCF_ONLY_AST)
2172
2173        # Call PyAST_Check()
2174        code = compile(ast_tree, filename, mode)
2175        self.assertIsInstance(code, types.CodeType)
2176
2177    def test_reload_module(self):
2178        # bpo-41194: Importing the _ast module twice must not crash.
2179        with support.swap_item(sys.modules, '_ast', None):
2180            del sys.modules['_ast']
2181            import _ast as ast1
2182
2183            del sys.modules['_ast']
2184            import _ast as ast2
2185
2186            self.check_ast_module()
2187
2188        # Unloading the two _ast module instances must not crash.
2189        del ast1
2190        del ast2
2191        support.gc_collect()
2192
2193        self.check_ast_module()
2194
2195    def test_sys_modules(self):
2196        # bpo-41631: Test reproducing a Mercurial crash when PyAST_Check()
2197        # imported the _ast module internally.
2198        lazy_mod = object()
2199
2200        def my_import(name, *args, **kw):
2201            sys.modules[name] = lazy_mod
2202            return lazy_mod
2203
2204        with support.swap_item(sys.modules, '_ast', None):
2205            del sys.modules['_ast']
2206
2207            with support.swap_attr(builtins, '__import__', my_import):
2208                # Test that compile() does not import the _ast module
2209                self.check_ast_module()
2210                self.assertNotIn('_ast', sys.modules)
2211
2212                # Sanity check of the test itself
2213                import _ast
2214                self.assertIs(_ast, lazy_mod)
2215
2216    def test_subinterpreter(self):
2217        # bpo-41631: Importing and using the _ast module in a subinterpreter
2218        # must not crash.
2219        code = dedent('''
2220            import _ast
2221            import ast
2222            import gc
2223            import sys
2224            import types
2225
2226            # Create _ast.AST subclasses instances and call PyAST_Check()
2227            ast_tree = compile('x+1', '<string>', 'eval',
2228                               flags=ast.PyCF_ONLY_AST)
2229            code = compile(ast_tree, 'string', 'eval')
2230            if not isinstance(code, types.CodeType):
2231                raise AssertionError
2232
2233            # Unloading the _ast module must not crash.
2234            del ast, _ast
2235            del sys.modules['ast'], sys.modules['_ast']
2236            gc.collect()
2237        ''')
2238        res = support.run_in_subinterp(code)
2239        self.assertEqual(res, 0)
2240
2241
2242def main():
2243    if __name__ != '__main__':
2244        return
2245    if sys.argv[1:] == ['-g']:
2246        for statements, kind in ((exec_tests, "exec"), (single_tests, "single"),
2247                                 (eval_tests, "eval")):
2248            print(kind+"_results = [")
2249            for statement in statements:
2250                tree = ast.parse(statement, "?", kind)
2251                print("%r," % (to_tuple(tree),))
2252            print("]")
2253        print("main()")
2254        raise SystemExit
2255    unittest.main()
2256
2257#### EVERYTHING BELOW IS GENERATED BY python Lib/test/test_ast.py -g  #####
2258exec_results = [
2259('Module', [('Expr', (1, 0, 1, 4), ('Constant', (1, 0, 1, 4), None, None))], []),
2260('Module', [('Expr', (1, 0, 1, 18), ('Constant', (1, 0, 1, 18), 'module docstring', None))], []),
2261('Module', [('FunctionDef', (1, 0, 1, 13), 'f', ('arguments', [], [], None, [], [], None, []), [('Pass', (1, 9, 1, 13))], [], None, None)], []),
2262('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)], []),
2263('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)], []),
2264('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)], []),
2265('Module', [('FunctionDef', (1, 0, 1, 18), 'f', ('arguments', [], [], ('arg', (1, 7, 1, 11), 'args', None, None), [], [], None, []), [('Pass', (1, 14, 1, 18))], [], None, None)], []),
2266('Module', [('FunctionDef', (1, 0, 1, 21), 'f', ('arguments', [], [], None, [], [], ('arg', (1, 8, 1, 14), 'kwargs', None, None), []), [('Pass', (1, 17, 1, 21))], [], None, None)], []),
2267('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)], []),
2268('Module', [('ClassDef', (1, 0, 1, 12), 'C', [], [], [('Pass', (1, 8, 1, 12))], [])], []),
2269('Module', [('ClassDef', (1, 0, 1, 32), 'C', [], [], [('Expr', (1, 9, 1, 32), ('Constant', (1, 9, 1, 32), 'docstring for class C', None))], [])], []),
2270('Module', [('ClassDef', (1, 0, 1, 21), 'C', [('Name', (1, 8, 1, 14), 'object', ('Load',))], [], [('Pass', (1, 17, 1, 21))], [])], []),
2271('Module', [('FunctionDef', (1, 0, 1, 16), 'f', ('arguments', [], [], None, [], [], None, []), [('Return', (1, 8, 1, 16), ('Constant', (1, 15, 1, 16), 1, None))], [], None, None)], []),
2272('Module', [('Delete', (1, 0, 1, 5), [('Name', (1, 4, 1, 5), 'v', ('Del',))])], []),
2273('Module', [('Assign', (1, 0, 1, 5), [('Name', (1, 0, 1, 1), 'v', ('Store',))], ('Constant', (1, 4, 1, 5), 1, None), None)], []),
2274('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)], []),
2275('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)], []),
2276('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)], []),
2277('Module', [('AugAssign', (1, 0, 1, 6), ('Name', (1, 0, 1, 1), 'v', ('Store',)), ('Add',), ('Constant', (1, 5, 1, 6), 1, None))], []),
2278('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)], []),
2279('Module', [('While', (1, 0, 1, 12), ('Name', (1, 6, 1, 7), 'v', ('Load',)), [('Pass', (1, 8, 1, 12))], [])], []),
2280('Module', [('If', (1, 0, 1, 9), ('Name', (1, 3, 1, 4), 'v', ('Load',)), [('Pass', (1, 5, 1, 9))], [])], []),
2281('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))], [])])], []),
2282('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))])])], []),
2283('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)], []),
2284('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)], []),
2285('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)], []),
2286('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))])], [], [])], []),
2287('Module', [('Try', (1, 0, 4, 6), [('Pass', (2, 2, 2, 6))], [], [], [('Pass', (4, 2, 4, 6))])], []),
2288('Module', [('Assert', (1, 0, 1, 8), ('Name', (1, 7, 1, 8), 'v', ('Load',)), None)], []),
2289('Module', [('Import', (1, 0, 1, 10), [('alias', (1, 7, 1, 10), 'sys', None)])], []),
2290('Module', [('ImportFrom', (1, 0, 1, 17), 'sys', [('alias', (1, 16, 1, 17), 'v', None)], 0)], []),
2291('Module', [('Global', (1, 0, 1, 8), ['v'])], []),
2292('Module', [('Expr', (1, 0, 1, 1), ('Constant', (1, 0, 1, 1), 1, None))], []),
2293('Module', [('Pass', (1, 0, 1, 4))], []),
2294('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)], []),
2295('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)], []),
2296('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)], []),
2297('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)], []),
2298('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)], []),
2299('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)]))], []),
2300('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)]))], []),
2301('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)]))], []),
2302('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)]))], []),
2303('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)]))], []),
2304('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)], []),
2305('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)], []),
2306('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)], []),
2307('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)]))], []),
2308('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)]))], []),
2309('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)], []),
2310('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)], []),
2311('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)], []),
2312('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)], [])])], []),
2313('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)], []),
2314('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)], []),
2315('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)))], []),
2316('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)], []),
2317('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)], []),
2318('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)], []),
2319('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)], []),
2320('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)], []),
2321('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)], []),
2322('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)], []),
2323('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)], []),
2324('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)], []),
2325('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)], []),
2326]
2327single_results = [
2328('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)))]),
2329]
2330eval_results = [
2331('Expression', ('Constant', (1, 0, 1, 4), None, None)),
2332('Expression', ('BoolOp', (1, 0, 1, 7), ('And',), [('Name', (1, 0, 1, 1), 'a', ('Load',)), ('Name', (1, 6, 1, 7), 'b', ('Load',))])),
2333('Expression', ('BinOp', (1, 0, 1, 5), ('Name', (1, 0, 1, 1), 'a', ('Load',)), ('Add',), ('Name', (1, 4, 1, 5), 'b', ('Load',)))),
2334('Expression', ('UnaryOp', (1, 0, 1, 5), ('Not',), ('Name', (1, 4, 1, 5), 'v', ('Load',)))),
2335('Expression', ('Lambda', (1, 0, 1, 11), ('arguments', [], [], None, [], [], None, []), ('Constant', (1, 7, 1, 11), None, None))),
2336('Expression', ('Dict', (1, 0, 1, 7), [('Constant', (1, 2, 1, 3), 1, None)], [('Constant', (1, 4, 1, 5), 2, None)])),
2337('Expression', ('Dict', (1, 0, 1, 2), [], [])),
2338('Expression', ('Set', (1, 0, 1, 7), [('Constant', (1, 1, 1, 5), None, None)])),
2339('Expression', ('Dict', (1, 0, 5, 6), [('Constant', (2, 6, 2, 7), 1, None)], [('Constant', (4, 10, 4, 11), 2, None)])),
2340('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)])),
2341('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)])),
2342('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)])),
2343('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)])),
2344('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)])),
2345('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)])),
2346('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)])),
2347('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)])),
2348('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)])),
2349('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)])),
2350('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)])),
2351('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)])),
2352('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', (1, 6, 1, 9), 'c', ('Constant', (1, 8, 1, 9), 3, None)), ('keyword', (1, 13, 1, 16), None, ('Name', (1, 15, 1, 16), 'e', ('Load',)))])),
2353('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',))], [])),
2354('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)])], [])),
2355('Expression', ('Constant', (1, 0, 1, 2), 10, None)),
2356('Expression', ('Constant', (1, 0, 1, 8), 'string', None)),
2357('Expression', ('Attribute', (1, 0, 1, 3), ('Name', (1, 0, 1, 1), 'a', ('Load',)), 'b', ('Load',))),
2358('Expression', ('Subscript', (1, 0, 1, 6), ('Name', (1, 0, 1, 1), 'a', ('Load',)), ('Slice', (1, 2, 1, 5), ('Name', (1, 2, 1, 3), 'b', ('Load',)), ('Name', (1, 4, 1, 5), 'c', ('Load',)), None), ('Load',))),
2359('Expression', ('Name', (1, 0, 1, 1), 'v', ('Load',))),
2360('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',))),
2361('Expression', ('List', (1, 0, 1, 2), [], ('Load',))),
2362('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',))),
2363('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',))),
2364('Expression', ('Tuple', (1, 0, 1, 2), [], ('Load',))),
2365('Expression', ('Call', (1, 0, 1, 17), ('Attribute', (1, 0, 1, 7), ('Attribute', (1, 0, 1, 5), ('Attribute', (1, 0, 1, 3), ('Name', (1, 0, 1, 1), 'a', ('Load',)), 'b', ('Load',)), 'c', ('Load',)), 'd', ('Load',)), [('Subscript', (1, 8, 1, 16), ('Attribute', (1, 8, 1, 11), ('Name', (1, 8, 1, 9), 'a', ('Load',)), 'b', ('Load',)), ('Slice', (1, 12, 1, 15), ('Constant', (1, 12, 1, 13), 1, None), ('Constant', (1, 14, 1, 15), 2, None), None), ('Load',))], [])),
2366]
2367main()
2368