Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/parso/python/tree.py: 39%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

637 statements  

1""" 

2This is the syntax tree for Python 3 syntaxes. The classes represent 

3syntax elements like functions and imports. 

4 

5All of the nodes can be traced back to the `Python grammar file 

6<https://docs.python.org/3/reference/grammar.html>`_. If you want to know how 

7a tree is structured, just analyse that file (for each Python version it's a 

8bit different). 

9 

10There's a lot of logic here that makes it easier for Jedi (and other libraries) 

11to deal with a Python syntax tree. 

12 

13By using :py:meth:`parso.tree.NodeOrLeaf.get_code` on a module, you can get 

14back the 1-to-1 representation of the input given to the parser. This is 

15important if you want to refactor a parser tree. 

16 

17>>> from parso import parse 

18>>> parser = parse('import os') 

19>>> module = parser.get_root_node() 

20>>> module 

21<Module: @1-1> 

22 

23Any subclasses of :class:`Scope`, including :class:`Module` has an attribute 

24:attr:`iter_imports <Scope.iter_imports>`: 

25 

26>>> list(module.iter_imports()) 

27[<ImportName: import os@1,0>] 

28 

29Changes to the Python Grammar 

30----------------------------- 

31 

32A few things have changed when looking at Python grammar files: 

33 

34- :class:`Param` does not exist in Python grammar files. It is essentially a 

35 part of a ``parameters`` node. |parso| splits it up to make it easier to 

36 analyse parameters. However this just makes it easier to deal with the syntax 

37 tree, it doesn't actually change the valid syntax. 

38- A few nodes like `lambdef` and `lambdef_nocond` have been merged in the 

39 syntax tree to make it easier to do deal with them. 

40 

41Parser Tree Classes 

42------------------- 

43""" 

44 

45import re 

46from collections.abc import Mapping 

47from typing import Tuple, Any 

48 

49from parso.tree import Node, BaseNode, Leaf, ErrorNode, ErrorLeaf, search_ancestor # noqa 

50from parso.python.prefix import split_prefix 

51from parso.utils import split_lines 

52 

53_FLOW_CONTAINERS = set(['if_stmt', 'while_stmt', 'for_stmt', 'try_stmt', 

54 'with_stmt', 'async_stmt', 'suite']) 

55_RETURN_STMT_CONTAINERS = set(['suite', 'simple_stmt']) | _FLOW_CONTAINERS 

56 

57_FUNC_CONTAINERS = set( 

58 ['suite', 'simple_stmt', 'decorated', 'async_funcdef'] 

59) | _FLOW_CONTAINERS 

60 

61_GET_DEFINITION_TYPES = set([ 

62 'expr_stmt', 'sync_comp_for', 'with_stmt', 'for_stmt', 'import_name', 

63 'import_from', 'param', 'del_stmt', 'namedexpr_test', 

64]) 

65_IMPORTS = set(['import_name', 'import_from']) 

66 

67 

68class DocstringMixin: 

69 __slots__ = () 

70 type: str 

71 children: "list[Any]" 

72 parent: Any 

73 

74 def get_doc_node(self): 

75 """ 

76 Returns the string leaf of a docstring. e.g. ``r'''foo'''``. 

77 """ 

78 if self.type == 'file_input': 

79 node = self.children[0] 

80 elif self.type in ('funcdef', 'classdef'): 

81 node = self.children[self.children.index(':') + 1] 

82 if node.type == 'suite': # Normally a suite 

83 node = node.children[1] # -> NEWLINE stmt 

84 else: # ExprStmt 

85 simple_stmt = self.parent 

86 c = simple_stmt.parent.children 

87 index = c.index(simple_stmt) 

88 if not index: 

89 return None 

90 node = c[index - 1] 

91 

92 if node.type == 'simple_stmt': 

93 node = node.children[0] 

94 if node.type == 'string': 

95 return node 

96 return None 

97 

98 

99class PythonMixin: 

100 """ 

101 Some Python specific utilities. 

102 """ 

103 __slots__ = () 

104 children: "list[Any]" 

105 

106 def get_name_of_position(self, position): 

107 """ 

108 Given a (line, column) tuple, returns a :py:class:`Name` or ``None`` if 

109 there is no name at that position. 

110 """ 

111 for c in self.children: 

112 if isinstance(c, Leaf): 

113 if c.type == 'name' and c.start_pos <= position <= c.end_pos: 

114 return c 

115 else: 

116 result = c.get_name_of_position(position) 

117 if result is not None: 

118 return result 

119 return None 

120 

121 

122class PythonLeaf(PythonMixin, Leaf): 

123 __slots__ = () 

124 

125 def _split_prefix(self): 

126 return split_prefix(self, self.get_start_pos_of_prefix()) 

127 

128 def get_start_pos_of_prefix(self): 

129 """ 

130 Basically calls :py:meth:`parso.tree.NodeOrLeaf.get_start_pos_of_prefix`. 

131 """ 

132 # TODO it is really ugly that we have to override it. Maybe change 

133 # indent error leafs somehow? No idea how, though. 

134 previous_leaf = self.get_previous_leaf() 

135 if previous_leaf is not None and previous_leaf.type == 'error_leaf' \ 

136 and previous_leaf.token_type in ('INDENT', 'DEDENT', 'ERROR_DEDENT'): 

137 previous_leaf = previous_leaf.get_previous_leaf() 

138 

139 if previous_leaf is None: # It's the first leaf. 

140 lines = split_lines(self.prefix) 

141 # + 1 is needed because split_lines always returns at least ['']. 

142 return self.line - len(lines) + 1, 0 # It's the first leaf. 

143 return previous_leaf.end_pos 

144 

145 

146class _LeafWithoutNewlines(PythonLeaf): 

147 """ 

148 Simply here to optimize performance. 

149 """ 

150 __slots__ = () 

151 

152 @property 

153 def end_pos(self) -> Tuple[int, int]: 

154 return self.line, self.column + len(self.value) 

155 

156 

157# Python base classes 

158class PythonBaseNode(PythonMixin, BaseNode): 

159 __slots__ = () 

160 

161 

162class PythonNode(PythonMixin, Node): 

163 __slots__ = () 

164 

165 

166class PythonErrorNode(PythonMixin, ErrorNode): 

167 __slots__ = () 

168 

169 

170class PythonErrorLeaf(ErrorLeaf, PythonLeaf): 

171 __slots__ = () 

172 

173 

174class EndMarker(_LeafWithoutNewlines): 

175 __slots__ = () 

176 type = 'endmarker' 

177 

178 def __repr__(self): 

179 return "<%s: prefix=%s end_pos=%s>" % ( 

180 type(self).__name__, repr(self.prefix), self.end_pos 

181 ) 

182 

183 

184class Newline(PythonLeaf): 

185 """Contains NEWLINE and ENDMARKER tokens.""" 

186 __slots__ = () 

187 type = 'newline' 

188 

189 def __repr__(self): 

190 return "<%s: %s>" % (type(self).__name__, repr(self.value)) 

191 

192 

193class Name(_LeafWithoutNewlines): 

194 """ 

195 A string. Sometimes it is important to know if the string belongs to a name 

196 or not. 

197 """ 

198 type = 'name' 

199 __slots__ = () 

200 

201 def __repr__(self): 

202 return "<%s: %s@%s,%s>" % (type(self).__name__, self.value, 

203 self.line, self.column) 

204 

205 def is_definition(self, include_setitem=False): 

206 """ 

207 Returns True if the name is being defined. 

208 """ 

209 return self.get_definition(include_setitem=include_setitem) is not None 

210 

211 def get_definition(self, import_name_always=False, include_setitem=False): 

212 """ 

213 Returns None if there's no definition for a name. 

214 

215 :param import_name_always: Specifies if an import name is always a 

216 definition. Normally foo in `from foo import bar` is not a 

217 definition. 

218 """ 

219 node = self.parent 

220 type_ = node.type 

221 

222 if type_ in ('funcdef', 'classdef'): 

223 if self == node.name: # type: ignore[union-attr] 

224 return node 

225 return None 

226 

227 if type_ == 'except_clause': 

228 if self.get_previous_sibling() == 'as': 

229 return node.parent # The try_stmt. 

230 return None 

231 

232 while node is not None: 

233 if node.type == 'suite': 

234 return None 

235 if node.type in _GET_DEFINITION_TYPES: 

236 if self in node.get_defined_names(include_setitem): # type: ignore[attr-defined] 

237 return node 

238 if import_name_always and node.type in _IMPORTS: 

239 return node 

240 return None 

241 node = node.parent 

242 return None 

243 

244 

245class Literal(PythonLeaf): 

246 __slots__ = () 

247 

248 

249class Number(Literal): 

250 type = 'number' 

251 __slots__ = () 

252 

253 

254class String(Literal): 

255 type = 'string' 

256 __slots__ = () 

257 

258 @property 

259 def string_prefix(self): 

260 return re.match(r'\w*(?=[\'"])', self.value).group(0) 

261 

262 def _get_payload(self): 

263 match = re.search( 

264 r'''('{3}|"{3}|'|")(.*)$''', 

265 self.value, 

266 flags=re.DOTALL 

267 ) 

268 return match.group(2)[:-len(match.group(1))] 

269 

270 

271class FStringString(PythonLeaf): 

272 """ 

273 f-strings contain f-string expressions and normal python strings. These are 

274 the string parts of f-strings. 

275 """ 

276 type = 'fstring_string' 

277 __slots__ = () 

278 

279 

280class FStringStart(PythonLeaf): 

281 """ 

282 f-strings contain f-string expressions and normal python strings. These are 

283 the string parts of f-strings. 

284 """ 

285 type = 'fstring_start' 

286 __slots__ = () 

287 

288 

289class FStringEnd(PythonLeaf): 

290 """ 

291 f-strings contain f-string expressions and normal python strings. These are 

292 the string parts of f-strings. 

293 """ 

294 type = 'fstring_end' 

295 __slots__ = () 

296 

297 

298class _StringComparisonMixin: 

299 __slots__ = () 

300 value: Any 

301 

302 def __eq__(self, other): 

303 """ 

304 Make comparisons with strings easy. 

305 Improves the readability of the parser. 

306 """ 

307 if isinstance(other, str): 

308 return self.value == other 

309 

310 return self is other 

311 

312 def __hash__(self): 

313 return hash(self.value) 

314 

315 

316class Operator(_LeafWithoutNewlines, _StringComparisonMixin): 

317 type = 'operator' 

318 __slots__ = () 

319 

320 

321class Keyword(_LeafWithoutNewlines, _StringComparisonMixin): 

322 type = 'keyword' 

323 __slots__ = () 

324 

325 

326class Scope(PythonBaseNode, DocstringMixin): 

327 """ 

328 Super class for the parser tree, which represents the state of a python 

329 text file. 

330 A Scope is either a function, class or lambda. 

331 """ 

332 __slots__ = () 

333 

334 def __init__(self, children): 

335 super().__init__(children) 

336 

337 def iter_funcdefs(self): 

338 """ 

339 Returns a generator of `funcdef` nodes. 

340 """ 

341 return self._search_in_scope('funcdef') 

342 

343 def iter_classdefs(self): 

344 """ 

345 Returns a generator of `classdef` nodes. 

346 """ 

347 return self._search_in_scope('classdef') 

348 

349 def iter_imports(self): 

350 """ 

351 Returns a generator of `import_name` and `import_from` nodes. 

352 """ 

353 return self._search_in_scope('import_name', 'import_from') 

354 

355 def _search_in_scope(self, *names): 

356 def scan(children): 

357 for element in children: 

358 if element.type in names: 

359 yield element 

360 if element.type in _FUNC_CONTAINERS: 

361 yield from scan(element.children) 

362 

363 return scan(self.children) 

364 

365 def get_suite(self): 

366 """ 

367 Returns the part that is executed by the function. 

368 """ 

369 return self.children[-1] 

370 

371 def __repr__(self): 

372 try: 

373 name = self.name.value # type: ignore[attr-defined] 

374 except AttributeError: 

375 name = '' 

376 

377 return "<%s: %s@%s-%s>" % (type(self).__name__, name, 

378 self.start_pos[0], self.end_pos[0]) 

379 

380 

381class Module(Scope): 

382 """ 

383 The top scope, which is always a module. 

384 Depending on the underlying parser this may be a full module or just a part 

385 of a module. 

386 """ 

387 __slots__ = ('_used_names',) 

388 type = 'file_input' 

389 

390 def __init__(self, children): 

391 super().__init__(children) 

392 self._used_names = None 

393 

394 def _iter_future_import_names(self): 

395 """ 

396 :return: A list of future import names. 

397 :rtype: list of str 

398 """ 

399 # In Python it's not allowed to use future imports after the first 

400 # actual (non-future) statement. However this is not a linter here, 

401 # just return all future imports. If people want to scan for issues 

402 # they should use the API. 

403 for imp in self.iter_imports(): 

404 if imp.type == 'import_from' and imp.level == 0: 

405 for path in imp.get_paths(): 

406 names = [name.value for name in path] 

407 if len(names) == 2 and names[0] == '__future__': 

408 yield names[1] 

409 

410 def get_used_names(self): 

411 """ 

412 Returns all the :class:`Name` leafs that exist in this module. This 

413 includes both definitions and references of names. 

414 """ 

415 if self._used_names is None: 

416 # Don't directly use self._used_names to eliminate a lookup. 

417 dct = {} 

418 

419 def recurse(node): 

420 try: 

421 children = node.children 

422 except AttributeError: 

423 if node.type == 'name': 

424 arr = dct.setdefault(node.value, []) 

425 arr.append(node) 

426 else: 

427 for child in children: 

428 recurse(child) 

429 

430 recurse(self) 

431 self._used_names = UsedNamesMapping(dct) 

432 return self._used_names 

433 

434 

435class Decorator(PythonBaseNode): 

436 type = 'decorator' 

437 __slots__ = () 

438 

439 

440class ClassOrFunc(Scope): 

441 __slots__ = () 

442 

443 @property 

444 def name(self): 

445 """ 

446 Returns the `Name` leaf that defines the function or class name. 

447 """ 

448 return self.children[1] 

449 

450 def get_decorators(self): 

451 """ 

452 :rtype: list of :class:`Decorator` 

453 """ 

454 decorated = self.parent 

455 if decorated.type == 'async_funcdef': 

456 decorated = decorated.parent 

457 

458 if decorated.type == 'decorated': 

459 if decorated.children[0].type == 'decorators': 

460 return decorated.children[0].children 

461 else: 

462 return decorated.children[:1] 

463 else: 

464 return [] 

465 

466 

467class Class(ClassOrFunc): 

468 """ 

469 Used to store the parsed contents of a python class. 

470 """ 

471 type = 'classdef' 

472 __slots__ = () 

473 

474 def __init__(self, children): 

475 super().__init__(children) 

476 

477 def get_super_arglist(self): 

478 """ 

479 Returns the `arglist` node that defines the super classes. It returns 

480 None if there are no arguments. 

481 """ 

482 if self.children[2] != '(': # Has no parentheses 

483 return None 

484 else: 

485 if self.children[3] == ')': # Empty parentheses 

486 return None 

487 else: 

488 return self.children[3] 

489 

490 

491def _create_params(parent, argslist_list): 

492 """ 

493 `argslist_list` is a list that can contain an argslist as a first item, but 

494 most not. It's basically the items between the parameter brackets (which is 

495 at most one item). 

496 This function modifies the parser structure. It generates `Param` objects 

497 from the normal ast. Those param objects do not exist in a normal ast, but 

498 make the evaluation of the ast tree so much easier. 

499 You could also say that this function replaces the argslist node with a 

500 list of Param objects. 

501 """ 

502 try: 

503 first = argslist_list[0] 

504 except IndexError: 

505 return [] 

506 

507 if first.type in ('name', 'fpdef'): 

508 return [Param([first], parent)] 

509 elif first == '*': 

510 return [first] 

511 else: # argslist is a `typedargslist` or a `varargslist`. 

512 if first.type == 'tfpdef': 

513 children = [first] 

514 else: 

515 children = first.children 

516 new_children = [] 

517 start = 0 

518 # Start with offset 1, because the end is higher. 

519 for end, child in enumerate(children + [None], 1): 

520 if child is None or child == ',': 

521 param_children = children[start:end] 

522 if param_children: # Could as well be comma and then end. 

523 if param_children[0] == '*' \ 

524 and (len(param_children) == 1 

525 or param_children[1] == ',') \ 

526 or param_children[0] == '/': 

527 for p in param_children: 

528 p.parent = parent 

529 new_children += param_children 

530 else: 

531 new_children.append(Param(param_children, parent)) 

532 start = end 

533 return new_children 

534 

535 

536class Function(ClassOrFunc): 

537 """ 

538 Used to store the parsed contents of a python function. 

539 

540 Children:: 

541 

542 0. <Keyword: def> 

543 1. <Name> 

544 2. parameter list (including open-paren and close-paren <Operator>s) 

545 3. or 5. <Operator: :> 

546 4. or 6. Node() representing function body 

547 3. -> (if annotation is also present) 

548 4. annotation (if present) 

549 """ 

550 type = 'funcdef' 

551 __slots__ = () 

552 

553 def __init__(self, children): 

554 super().__init__(children) 

555 parameters = self.children[2] # After `def foo` 

556 parameters_children = parameters.children[1:-1] 

557 # If input parameters list already has Param objects, keep it as is; 

558 # otherwise, convert it to a list of Param objects. 

559 if not any(isinstance(child, Param) for child in parameters_children): 

560 parameters.children[1:-1] = _create_params(parameters, parameters_children) 

561 

562 def _get_param_nodes(self): 

563 return self.children[2].children 

564 

565 def get_params(self): 

566 """ 

567 Returns a list of `Param()`. 

568 """ 

569 return [p for p in self._get_param_nodes() if p.type == 'param'] 

570 

571 @property 

572 def name(self): 

573 return self.children[1] # First token after `def` 

574 

575 def iter_yield_exprs(self): 

576 """ 

577 Returns a generator of `yield_expr`. 

578 """ 

579 def scan(children): 

580 for element in children: 

581 if element.type in ('classdef', 'funcdef', 'lambdef'): 

582 continue 

583 

584 try: 

585 nested_children = element.children 

586 except AttributeError: 

587 if element.value == 'yield': 

588 if element.parent.type == 'yield_expr': 

589 yield element.parent 

590 else: 

591 yield element 

592 else: 

593 yield from scan(nested_children) 

594 

595 return scan(self.children) 

596 

597 def iter_return_stmts(self): 

598 """ 

599 Returns a generator of `return_stmt`. 

600 """ 

601 def scan(children): 

602 for element in children: 

603 if element.type == 'return_stmt' \ 

604 or element.type == 'keyword' and element.value == 'return': 

605 yield element 

606 if element.type in _RETURN_STMT_CONTAINERS: 

607 yield from scan(element.children) 

608 

609 return scan(self.children) 

610 

611 def iter_raise_stmts(self): 

612 """ 

613 Returns a generator of `raise_stmt`. Includes raise statements inside try-except blocks 

614 """ 

615 def scan(children): 

616 for element in children: 

617 if element.type == 'raise_stmt' \ 

618 or element.type == 'keyword' and element.value == 'raise': 

619 yield element 

620 if element.type in _RETURN_STMT_CONTAINERS: 

621 yield from scan(element.children) 

622 

623 return scan(self.children) 

624 

625 def is_generator(self): 

626 """ 

627 :return bool: Checks if a function is a generator or not. 

628 """ 

629 return next(self.iter_yield_exprs(), None) is not None 

630 

631 @property 

632 def annotation(self): 

633 """ 

634 Returns the test node after `->` or `None` if there is no annotation. 

635 """ 

636 try: 

637 if self.children[3] == "->": 

638 return self.children[4] 

639 assert self.children[3] == ":" 

640 return None 

641 except IndexError: 

642 return None 

643 

644 

645class Lambda(Function): 

646 """ 

647 Lambdas are basically trimmed functions, so give it the same interface. 

648 

649 Children:: 

650 

651 0. <Keyword: lambda> 

652 *. <Param x> for each argument x 

653 -2. <Operator: :> 

654 -1. Node() representing body 

655 """ 

656 type = 'lambdef' 

657 __slots__ = () 

658 

659 def __init__(self, children): 

660 # We don't want to call the Function constructor, call its parent. 

661 super(Function, self).__init__(children) 

662 # Everything between `lambda` and the `:` operator is a parameter. 

663 parameters_children = self.children[1:-2] 

664 # If input children list already has Param objects, keep it as is; 

665 # otherwise, convert it to a list of Param objects. 

666 if not any(isinstance(child, Param) for child in parameters_children): 

667 self.children[1:-2] = _create_params(self, parameters_children) 

668 

669 @property 

670 def name(self): 

671 """ 

672 Raises an AttributeError. Lambdas don't have a defined name. 

673 """ 

674 raise AttributeError("lambda is not named.") 

675 

676 def _get_param_nodes(self): 

677 return self.children[1:-2] 

678 

679 @property 

680 def annotation(self): 

681 """ 

682 Returns `None`, lambdas don't have annotations. 

683 """ 

684 return None 

685 

686 def __repr__(self): 

687 return "<%s@%s>" % (self.__class__.__name__, self.start_pos) 

688 

689 

690class Flow(PythonBaseNode): 

691 __slots__ = () 

692 

693 

694class IfStmt(Flow): 

695 type = 'if_stmt' 

696 __slots__ = () 

697 

698 def get_test_nodes(self): 

699 """ 

700 E.g. returns all the `test` nodes that are named as x, below: 

701 

702 if x: 

703 pass 

704 elif x: 

705 pass 

706 """ 

707 for i, c in enumerate(self.children): 

708 if c in ('elif', 'if'): 

709 yield self.children[i + 1] 

710 

711 def get_corresponding_test_node(self, node): 

712 """ 

713 Searches for the branch in which the node is and returns the 

714 corresponding test node (see function above). However if the node is in 

715 the test node itself and not in the suite return None. 

716 """ 

717 start_pos = node.start_pos 

718 for check_node in reversed(list(self.get_test_nodes())): 

719 if check_node.start_pos < start_pos: 

720 if start_pos < check_node.end_pos: 

721 return None 

722 # In this case the node is within the check_node itself, 

723 # not in the suite 

724 else: 

725 return check_node 

726 

727 def is_node_after_else(self, node): 

728 """ 

729 Checks if a node is defined after `else`. 

730 """ 

731 for c in self.children: 

732 if c == 'else': 

733 if node.start_pos > c.start_pos: 

734 return True 

735 else: 

736 return False 

737 

738 

739class WhileStmt(Flow): 

740 type = 'while_stmt' 

741 __slots__ = () 

742 

743 

744class ForStmt(Flow): 

745 type = 'for_stmt' 

746 __slots__ = () 

747 

748 def get_testlist(self): 

749 """ 

750 Returns the input node ``y`` from: ``for x in y:``. 

751 """ 

752 return self.children[3] 

753 

754 def get_defined_names(self, include_setitem=False): 

755 return _defined_names(self.children[1], include_setitem) 

756 

757 

758class TryStmt(Flow): 

759 type = 'try_stmt' 

760 __slots__ = () 

761 

762 def get_except_clause_tests(self): 

763 """ 

764 Returns the ``test`` nodes found in ``except_clause`` nodes. 

765 Returns ``[None]`` for except clauses without an exception given. 

766 """ 

767 for node in self.children: 

768 if node.type == 'except_clause': 

769 yield node.children[1] 

770 elif node == 'except': 

771 yield None 

772 

773 

774class WithStmt(Flow): 

775 type = 'with_stmt' 

776 __slots__ = () 

777 

778 def get_defined_names(self, include_setitem=False): 

779 """ 

780 Returns the a list of `Name` that the with statement defines. The 

781 defined names are set after `as`. 

782 """ 

783 names = [] 

784 for with_item in self.children[1:-2:2]: 

785 # Check with items for 'as' names. 

786 if with_item.type == 'with_item': 

787 names += _defined_names(with_item.children[2], include_setitem) 

788 return names 

789 

790 def get_test_node_from_name(self, name): 

791 node = name.search_ancestor("with_item") 

792 if node is None: 

793 raise ValueError('The name is not actually part of a with statement.') 

794 return node.children[0] 

795 

796 

797class Import(PythonBaseNode): 

798 __slots__ = () 

799 get_paths: Any 

800 _aliases: Any 

801 

802 def get_path_for_name(self, name): 

803 """ 

804 The path is the list of names that leads to the searched name. 

805 

806 :return list of Name: 

807 """ 

808 try: 

809 # The name may be an alias. If it is, just map it back to the name. 

810 name = self._aliases()[name] 

811 except KeyError: 

812 pass 

813 

814 for path in self.get_paths(): 

815 if name in path: 

816 return path[:path.index(name) + 1] 

817 raise ValueError('Name should be defined in the import itself') 

818 

819 def is_nested(self): 

820 return False # By default, sub classes may overwrite this behavior 

821 

822 def is_star_import(self): 

823 return self.children[-1] == '*' 

824 

825 def get_defined_names(self): 

826 raise NotImplementedError("Use ImportFrom or ImportName") 

827 

828 

829class ImportFrom(Import): 

830 type = 'import_from' 

831 __slots__ = () 

832 

833 def get_defined_names(self, include_setitem=False): 

834 """ 

835 Returns the a list of `Name` that the import defines. The 

836 defined names are set after `import` or in case an alias - `as` - is 

837 present that name is returned. 

838 """ 

839 return [alias or name for name, alias in self._as_name_tuples()] 

840 

841 def _aliases(self): 

842 """Mapping from alias to its corresponding name.""" 

843 return dict((alias, name) for name, alias in self._as_name_tuples() 

844 if alias is not None) 

845 

846 def get_from_names(self): 

847 for n in self.children[1:]: 

848 if n not in ('.', '...'): 

849 break 

850 if n.type == 'dotted_name': # from x.y import 

851 return n.children[::2] 

852 elif n == 'import': # from . import 

853 return [] 

854 else: # from x import 

855 return [n] 

856 

857 @property 

858 def level(self): 

859 """The level parameter of ``__import__``.""" 

860 level = 0 

861 for n in self.children[1:]: 

862 if n in ('.', '...'): 

863 level += len(n.value) 

864 else: 

865 break 

866 return level 

867 

868 def _as_name_tuples(self): 

869 last = self.children[-1] 

870 if last == ')': 

871 last = self.children[-2] 

872 elif last == '*': 

873 return # No names defined directly. 

874 

875 if last.type == 'import_as_names': 

876 as_names = last.children[::2] 

877 else: 

878 as_names = [last] 

879 for as_name in as_names: 

880 if as_name.type == 'name': 

881 yield as_name, None 

882 else: 

883 yield as_name.children[::2] # yields x, y -> ``x as y`` 

884 

885 def get_paths(self): 

886 """ 

887 The import paths defined in an import statement. Typically an array 

888 like this: ``[<Name: datetime>, <Name: date>]``. 

889 

890 :return list of list of Name: 

891 """ 

892 dotted = self.get_from_names() 

893 

894 if self.children[-1] == '*': 

895 return [dotted] 

896 return [dotted + [name] for name, alias in self._as_name_tuples()] 

897 

898 

899class ImportName(Import): 

900 """For ``import_name`` nodes. Covers normal imports without ``from``.""" 

901 type = 'import_name' 

902 __slots__ = () 

903 

904 def get_defined_names(self, include_setitem=False): 

905 """ 

906 Returns the a list of `Name` that the import defines. The defined names 

907 is always the first name after `import` or in case an alias - `as` - is 

908 present that name is returned. 

909 """ 

910 return [alias or path[0] for path, alias in self._dotted_as_names()] 

911 

912 @property 

913 def level(self): 

914 """The level parameter of ``__import__``.""" 

915 return 0 # Obviously 0 for imports without from. 

916 

917 def get_paths(self): 

918 return [path for path, alias in self._dotted_as_names()] 

919 

920 def _dotted_as_names(self): 

921 """Generator of (list(path), alias) where alias may be None.""" 

922 dotted_as_names = self.children[1] 

923 if dotted_as_names.type == 'dotted_as_names': 

924 as_names = dotted_as_names.children[::2] 

925 else: 

926 as_names = [dotted_as_names] 

927 

928 for as_name in as_names: 

929 if as_name.type == 'dotted_as_name': 

930 alias = as_name.children[2] 

931 as_name = as_name.children[0] 

932 else: 

933 alias = None 

934 if as_name.type == 'name': 

935 yield [as_name], alias 

936 else: 

937 # dotted_names 

938 yield as_name.children[::2], alias 

939 

940 def is_nested(self): 

941 """ 

942 This checks for the special case of nested imports, without aliases and 

943 from statement:: 

944 

945 import foo.bar 

946 """ 

947 return bool([1 for path, alias in self._dotted_as_names() 

948 if alias is None and len(path) > 1]) 

949 

950 def _aliases(self): 

951 """ 

952 :return list of Name: Returns all the alias 

953 """ 

954 return dict((alias, path[-1]) for path, alias in self._dotted_as_names() 

955 if alias is not None) 

956 

957 

958class KeywordStatement(PythonBaseNode): 

959 """ 

960 For the following statements: `assert`, `del`, `global`, `nonlocal`, 

961 `raise`, `return`, `yield`. 

962 

963 `pass`, `continue` and `break` are not in there, because they are just 

964 simple keywords and the parser reduces it to a keyword. 

965 """ 

966 __slots__ = () 

967 

968 @property 

969 def type(self): 

970 """ 

971 Keyword statements start with the keyword and end with `_stmt`. You can 

972 crosscheck this with the Python grammar. 

973 """ 

974 return '%s_stmt' % self.keyword 

975 

976 @property 

977 def keyword(self): 

978 return self.children[0].value 

979 

980 def get_defined_names(self, include_setitem=False): 

981 keyword = self.keyword 

982 if keyword == 'del': 

983 return _defined_names(self.children[1], include_setitem) 

984 if keyword in ('global', 'nonlocal'): 

985 return self.children[1::2] 

986 return [] 

987 

988 

989class AssertStmt(KeywordStatement): 

990 __slots__ = () 

991 

992 @property 

993 def assertion(self): 

994 return self.children[1] 

995 

996 

997class GlobalStmt(KeywordStatement): 

998 __slots__ = () 

999 

1000 def get_global_names(self): 

1001 return self.children[1::2] 

1002 

1003 

1004class ReturnStmt(KeywordStatement): 

1005 __slots__ = () 

1006 

1007 

1008class YieldExpr(PythonBaseNode): 

1009 type = 'yield_expr' 

1010 __slots__ = () 

1011 

1012 

1013def _defined_names(current, include_setitem): 

1014 """ 

1015 A helper function to find the defined names in statements, for loops and 

1016 list comprehensions. 

1017 """ 

1018 names = [] 

1019 if current.type in ('testlist_star_expr', 'testlist_comp', 'exprlist', 'testlist'): 

1020 for child in current.children[::2]: 

1021 names += _defined_names(child, include_setitem) 

1022 elif current.type in ('atom', 'star_expr'): 

1023 names += _defined_names(current.children[1], include_setitem) 

1024 elif current.type in ('power', 'atom_expr'): 

1025 if current.children[-2] != '**': # Just if there's no operation 

1026 trailer = current.children[-1] 

1027 if trailer.children[0] == '.': 

1028 names.append(trailer.children[1]) 

1029 elif trailer.children[0] == '[' and include_setitem: 

1030 for node in current.children[-2::-1]: 

1031 if node.type == 'trailer': 

1032 names.append(node.children[1]) 

1033 break 

1034 if node.type == 'name': 

1035 names.append(node) 

1036 break 

1037 else: 

1038 names.append(current) 

1039 return names 

1040 

1041 

1042class ExprStmt(PythonBaseNode, DocstringMixin): 

1043 type = 'expr_stmt' 

1044 __slots__ = () 

1045 

1046 def get_defined_names(self, include_setitem=False): 

1047 """ 

1048 Returns a list of `Name` defined before the `=` sign. 

1049 """ 

1050 names = [] 

1051 if self.children[1].type == 'annassign': 

1052 names = _defined_names(self.children[0], include_setitem) 

1053 return [ 

1054 name 

1055 for i in range(0, len(self.children) - 2, 2) 

1056 if '=' in self.children[i + 1].value 

1057 for name in _defined_names(self.children[i], include_setitem) 

1058 ] + names 

1059 

1060 def get_rhs(self): 

1061 """Returns the right-hand-side of the equals.""" 

1062 node = self.children[-1] 

1063 if node.type == 'annassign': 

1064 if len(node.children) == 4: 

1065 node = node.children[3] 

1066 else: 

1067 node = node.children[1] 

1068 return node 

1069 

1070 def yield_operators(self): 

1071 """ 

1072 Returns a generator of `+=`, `=`, etc. or None if there is no operation. 

1073 """ 

1074 first = self.children[1] 

1075 if first.type == 'annassign': 

1076 if len(first.children) <= 2: 

1077 return # No operator is available, it's just PEP 484. 

1078 

1079 first = first.children[2] 

1080 yield first 

1081 

1082 yield from self.children[3::2] 

1083 

1084 

1085class NamedExpr(PythonBaseNode): 

1086 type = 'namedexpr_test' 

1087 

1088 def get_defined_names(self, include_setitem=False): 

1089 return _defined_names(self.children[0], include_setitem) 

1090 

1091 

1092class Param(PythonBaseNode): 

1093 """ 

1094 It's a helper class that makes business logic with params much easier. The 

1095 Python grammar defines no ``param`` node. It defines it in a different way 

1096 that is not really suited to working with parameters. 

1097 """ 

1098 type = 'param' 

1099 

1100 def __init__(self, children, parent=None): 

1101 super().__init__(children) 

1102 self.parent = parent 

1103 

1104 @property 

1105 def star_count(self): 

1106 """ 

1107 Is `0` in case of `foo`, `1` in case of `*foo` or `2` in case of 

1108 `**foo`. 

1109 """ 

1110 first = self.children[0] 

1111 if first in ('*', '**'): 

1112 return len(first.value) 

1113 return 0 

1114 

1115 @property 

1116 def default(self): 

1117 """ 

1118 The default is the test node that appears after the `=`. Is `None` in 

1119 case no default is present. 

1120 """ 

1121 has_comma = self.children[-1] == ',' 

1122 try: 

1123 if self.children[-2 - int(has_comma)] == '=': 

1124 return self.children[-1 - int(has_comma)] 

1125 except IndexError: 

1126 return None 

1127 

1128 @property 

1129 def annotation(self): 

1130 """ 

1131 The default is the test node that appears after `:`. Is `None` in case 

1132 no annotation is present. 

1133 """ 

1134 tfpdef = self._tfpdef() 

1135 if tfpdef.type == 'tfpdef': 

1136 assert tfpdef.children[1] == ":" 

1137 assert len(tfpdef.children) == 3 

1138 annotation = tfpdef.children[2] 

1139 return annotation 

1140 else: 

1141 return None 

1142 

1143 def _tfpdef(self): 

1144 """ 

1145 tfpdef: see e.g. grammar36.txt. 

1146 """ 

1147 offset = int(self.children[0] in ('*', '**')) 

1148 return self.children[offset] 

1149 

1150 @property 

1151 def name(self): 

1152 """ 

1153 The `Name` leaf of the param. 

1154 """ 

1155 if self._tfpdef().type == 'tfpdef': 

1156 return self._tfpdef().children[0] 

1157 else: 

1158 return self._tfpdef() 

1159 

1160 def get_defined_names(self, include_setitem=False): 

1161 return [self.name] 

1162 

1163 @property 

1164 def position_index(self): 

1165 """ 

1166 Property for the positional index of a paramter. 

1167 """ 

1168 index = self.parent.children.index(self) 

1169 try: 

1170 keyword_only_index = self.parent.children.index('*') 

1171 if index > keyword_only_index: 

1172 # Skip the ` *, ` 

1173 index -= 2 

1174 except ValueError: 

1175 pass 

1176 try: 

1177 keyword_only_index = self.parent.children.index('/') 

1178 if index > keyword_only_index: 

1179 # Skip the ` /, ` 

1180 index -= 2 

1181 except ValueError: 

1182 pass 

1183 return index - 1 

1184 

1185 def get_parent_function(self): 

1186 """ 

1187 Returns the function/lambda of a parameter. 

1188 """ 

1189 return self.search_ancestor('funcdef', 'lambdef') 

1190 

1191 def get_code(self, include_prefix=True, include_comma=True): 

1192 """ 

1193 Like all the other get_code functions, but includes the param 

1194 `include_comma`. 

1195 

1196 :param include_comma bool: If enabled includes the comma in the string output. 

1197 """ 

1198 if include_comma: 

1199 return super().get_code(include_prefix) 

1200 

1201 children = self.children 

1202 if children[-1] == ',': 

1203 children = children[:-1] 

1204 return self._get_code_for_children( 

1205 children, 

1206 include_prefix=include_prefix 

1207 ) 

1208 

1209 def __repr__(self): 

1210 default = '' if self.default is None else '=%s' % self.default.get_code() 

1211 return '<%s: %s>' % (type(self).__name__, str(self._tfpdef()) + default) 

1212 

1213 

1214class SyncCompFor(PythonBaseNode): 

1215 type = 'sync_comp_for' 

1216 __slots__ = () 

1217 

1218 def get_defined_names(self, include_setitem=False): 

1219 """ 

1220 Returns the a list of `Name` that the comprehension defines. 

1221 """ 

1222 # allow async for 

1223 return _defined_names(self.children[1], include_setitem) 

1224 

1225 

1226# This is simply here so an older Jedi version can work with this new parso 

1227# version. Can be deleted in the next release. 

1228CompFor = SyncCompFor 

1229 

1230 

1231class UsedNamesMapping(Mapping): 

1232 """ 

1233 This class exists for the sole purpose of creating an immutable dict. 

1234 """ 

1235 def __init__(self, dct): 

1236 self._dict = dct 

1237 

1238 def __getitem__(self, key): 

1239 return self._dict[key] 

1240 

1241 def __len__(self): 

1242 return len(self._dict) 

1243 

1244 def __iter__(self): 

1245 return iter(self._dict) 

1246 

1247 def __hash__(self): 

1248 return id(self) 

1249 

1250 def __eq__(self, other): 

1251 # Comparing these dicts does not make sense. 

1252 return self is other