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