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