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