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