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

628 statements  

« prev     ^ index     » next       coverage.py v7.2.2, created at 2023-03-26 06:07 +0000

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 

46try: 

47 from collections.abc import Mapping 

48except ImportError: 

49 from collections import Mapping 

50from typing import Tuple 

51 

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

53from parso.python.prefix import split_prefix 

54from parso.utils import split_lines 

55 

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

57 'with_stmt', 'async_stmt', 'suite']) 

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

59 

60_FUNC_CONTAINERS = set( 

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

62) | _FLOW_CONTAINERS 

63 

64_GET_DEFINITION_TYPES = set([ 

65 'expr_stmt', 'sync_comp_for', 'with_stmt', 'for_stmt', 'import_name', 

66 'import_from', 'param', 'del_stmt', 'namedexpr_test', 

67]) 

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

69 

70 

71class DocstringMixin: 

72 __slots__ = () 

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 

105 def get_name_of_position(self, position): 

106 """ 

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

108 there is no name at that position. 

109 """ 

110 for c in self.children: 

111 if isinstance(c, Leaf): 

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

113 return c 

114 else: 

115 result = c.get_name_of_position(position) 

116 if result is not None: 

117 return result 

118 return None 

119 

120 

121class PythonLeaf(PythonMixin, Leaf): 

122 __slots__ = () 

123 

124 def _split_prefix(self): 

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

126 

127 def get_start_pos_of_prefix(self): 

128 """ 

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

130 """ 

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

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

133 previous_leaf = self.get_previous_leaf() 

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

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

136 previous_leaf = previous_leaf.get_previous_leaf() 

137 

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

139 lines = split_lines(self.prefix) 

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

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

142 return previous_leaf.end_pos 

143 

144 

145class _LeafWithoutNewlines(PythonLeaf): 

146 """ 

147 Simply here to optimize performance. 

148 """ 

149 __slots__ = () 

150 

151 @property 

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

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

154 

155 

156# Python base classes 

157class PythonBaseNode(PythonMixin, BaseNode): 

158 __slots__ = () 

159 

160 

161class PythonNode(PythonMixin, Node): 

162 __slots__ = () 

163 

164 

165class PythonErrorNode(PythonMixin, ErrorNode): 

166 __slots__ = () 

167 

168 

169class PythonErrorLeaf(ErrorLeaf, PythonLeaf): 

170 __slots__ = () 

171 

172 

173class EndMarker(_LeafWithoutNewlines): 

174 __slots__ = () 

175 type = 'endmarker' 

176 

177 def __repr__(self): 

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

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

180 ) 

181 

182 

183class Newline(PythonLeaf): 

184 """Contains NEWLINE and ENDMARKER tokens.""" 

185 __slots__ = () 

186 type = 'newline' 

187 

188 def __repr__(self): 

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

190 

191 

192class Name(_LeafWithoutNewlines): 

193 """ 

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

195 or not. 

196 """ 

197 type = 'name' 

198 __slots__ = () 

199 

200 def __repr__(self): 

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

202 self.line, self.column) 

203 

204 def is_definition(self, include_setitem=False): 

205 """ 

206 Returns True if the name is being defined. 

207 """ 

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

209 

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

211 """ 

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

213 

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

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

216 definition. 

217 """ 

218 node = self.parent 

219 type_ = node.type 

220 

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

222 if self == node.name: 

223 return node 

224 return None 

225 

226 if type_ == 'except_clause': 

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

228 return node.parent # The try_stmt. 

229 return None 

230 

231 while node is not None: 

232 if node.type == 'suite': 

233 return None 

234 if node.type in _GET_DEFINITION_TYPES: 

235 if self in node.get_defined_names(include_setitem): 

236 return node 

237 if import_name_always and node.type in _IMPORTS: 

238 return node 

239 return None 

240 node = node.parent 

241 return None 

242 

243 

244class Literal(PythonLeaf): 

245 __slots__ = () 

246 

247 

248class Number(Literal): 

249 type = 'number' 

250 __slots__ = () 

251 

252 

253class String(Literal): 

254 type = 'string' 

255 __slots__ = () 

256 

257 @property 

258 def string_prefix(self): 

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

260 

261 def _get_payload(self): 

262 match = re.search( 

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

264 self.value, 

265 flags=re.DOTALL 

266 ) 

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

268 

269 

270class FStringString(PythonLeaf): 

271 """ 

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

273 the string parts of f-strings. 

274 """ 

275 type = 'fstring_string' 

276 __slots__ = () 

277 

278 

279class FStringStart(PythonLeaf): 

280 """ 

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

282 the string parts of f-strings. 

283 """ 

284 type = 'fstring_start' 

285 __slots__ = () 

286 

287 

288class FStringEnd(PythonLeaf): 

289 """ 

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

291 the string parts of f-strings. 

292 """ 

293 type = 'fstring_end' 

294 __slots__ = () 

295 

296 

297class _StringComparisonMixin: 

298 def __eq__(self, other): 

299 """ 

300 Make comparisons with strings easy. 

301 Improves the readability of the parser. 

302 """ 

303 if isinstance(other, str): 

304 return self.value == other 

305 

306 return self is other 

307 

308 def __hash__(self): 

309 return hash(self.value) 

310 

311 

312class Operator(_LeafWithoutNewlines, _StringComparisonMixin): 

313 type = 'operator' 

314 __slots__ = () 

315 

316 

317class Keyword(_LeafWithoutNewlines, _StringComparisonMixin): 

318 type = 'keyword' 

319 __slots__ = () 

320 

321 

322class Scope(PythonBaseNode, DocstringMixin): 

323 """ 

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

325 text file. 

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

327 """ 

328 __slots__ = () 

329 

330 def __init__(self, children): 

331 super().__init__(children) 

332 

333 def iter_funcdefs(self): 

334 """ 

335 Returns a generator of `funcdef` nodes. 

336 """ 

337 return self._search_in_scope('funcdef') 

338 

339 def iter_classdefs(self): 

340 """ 

341 Returns a generator of `classdef` nodes. 

342 """ 

343 return self._search_in_scope('classdef') 

344 

345 def iter_imports(self): 

346 """ 

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

348 """ 

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

350 

351 def _search_in_scope(self, *names): 

352 def scan(children): 

353 for element in children: 

354 if element.type in names: 

355 yield element 

356 if element.type in _FUNC_CONTAINERS: 

357 yield from scan(element.children) 

358 

359 return scan(self.children) 

360 

361 def get_suite(self): 

362 """ 

363 Returns the part that is executed by the function. 

364 """ 

365 return self.children[-1] 

366 

367 def __repr__(self): 

368 try: 

369 name = self.name.value 

370 except AttributeError: 

371 name = '' 

372 

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

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

375 

376 

377class Module(Scope): 

378 """ 

379 The top scope, which is always a module. 

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

381 of a module. 

382 """ 

383 __slots__ = ('_used_names',) 

384 type = 'file_input' 

385 

386 def __init__(self, children): 

387 super().__init__(children) 

388 self._used_names = None 

389 

390 def _iter_future_import_names(self): 

391 """ 

392 :return: A list of future import names. 

393 :rtype: list of str 

394 """ 

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

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

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

398 # they should use the API. 

399 for imp in self.iter_imports(): 

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

401 for path in imp.get_paths(): 

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

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

404 yield names[1] 

405 

406 def get_used_names(self): 

407 """ 

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

409 includes both definitions and references of names. 

410 """ 

411 if self._used_names is None: 

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

413 dct = {} 

414 

415 def recurse(node): 

416 try: 

417 children = node.children 

418 except AttributeError: 

419 if node.type == 'name': 

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

421 arr.append(node) 

422 else: 

423 for child in children: 

424 recurse(child) 

425 

426 recurse(self) 

427 self._used_names = UsedNamesMapping(dct) 

428 return self._used_names 

429 

430 

431class Decorator(PythonBaseNode): 

432 type = 'decorator' 

433 __slots__ = () 

434 

435 

436class ClassOrFunc(Scope): 

437 __slots__ = () 

438 

439 @property 

440 def name(self): 

441 """ 

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

443 """ 

444 return self.children[1] 

445 

446 def get_decorators(self): 

447 """ 

448 :rtype: list of :class:`Decorator` 

449 """ 

450 decorated = self.parent 

451 if decorated.type == 'async_funcdef': 

452 decorated = decorated.parent 

453 

454 if decorated.type == 'decorated': 

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

456 return decorated.children[0].children 

457 else: 

458 return decorated.children[:1] 

459 else: 

460 return [] 

461 

462 

463class Class(ClassOrFunc): 

464 """ 

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

466 """ 

467 type = 'classdef' 

468 __slots__ = () 

469 

470 def __init__(self, children): 

471 super().__init__(children) 

472 

473 def get_super_arglist(self): 

474 """ 

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

476 None if there are no arguments. 

477 """ 

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

479 return None 

480 else: 

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

482 return None 

483 else: 

484 return self.children[3] 

485 

486 

487def _create_params(parent, argslist_list): 

488 """ 

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

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

491 at most one item). 

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

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

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

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

496 list of Param objects. 

497 """ 

498 try: 

499 first = argslist_list[0] 

500 except IndexError: 

501 return [] 

502 

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

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

505 elif first == '*': 

506 return [first] 

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

508 if first.type == 'tfpdef': 

509 children = [first] 

510 else: 

511 children = first.children 

512 new_children = [] 

513 start = 0 

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

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

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

517 param_children = children[start:end] 

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

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

520 and (len(param_children) == 1 

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

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

523 for p in param_children: 

524 p.parent = parent 

525 new_children += param_children 

526 else: 

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

528 start = end 

529 return new_children 

530 

531 

532class Function(ClassOrFunc): 

533 """ 

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

535 

536 Children:: 

537 

538 0. <Keyword: def> 

539 1. <Name> 

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

541 3. or 5. <Operator: :> 

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

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

544 4. annotation (if present) 

545 """ 

546 type = 'funcdef' 

547 

548 def __init__(self, children): 

549 super().__init__(children) 

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

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

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

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

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

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

556 

557 def _get_param_nodes(self): 

558 return self.children[2].children 

559 

560 def get_params(self): 

561 """ 

562 Returns a list of `Param()`. 

563 """ 

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

565 

566 @property 

567 def name(self): 

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

569 

570 def iter_yield_exprs(self): 

571 """ 

572 Returns a generator of `yield_expr`. 

573 """ 

574 def scan(children): 

575 for element in children: 

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

577 continue 

578 

579 try: 

580 nested_children = element.children 

581 except AttributeError: 

582 if element.value == 'yield': 

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

584 yield element.parent 

585 else: 

586 yield element 

587 else: 

588 yield from scan(nested_children) 

589 

590 return scan(self.children) 

591 

592 def iter_return_stmts(self): 

593 """ 

594 Returns a generator of `return_stmt`. 

595 """ 

596 def scan(children): 

597 for element in children: 

598 if element.type == 'return_stmt' \ 

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

600 yield element 

601 if element.type in _RETURN_STMT_CONTAINERS: 

602 yield from scan(element.children) 

603 

604 return scan(self.children) 

605 

606 def iter_raise_stmts(self): 

607 """ 

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

609 """ 

610 def scan(children): 

611 for element in children: 

612 if element.type == 'raise_stmt' \ 

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

614 yield element 

615 if element.type in _RETURN_STMT_CONTAINERS: 

616 yield from scan(element.children) 

617 

618 return scan(self.children) 

619 

620 def is_generator(self): 

621 """ 

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

623 """ 

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

625 

626 @property 

627 def annotation(self): 

628 """ 

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

630 """ 

631 try: 

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

633 return self.children[4] 

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

635 return None 

636 except IndexError: 

637 return None 

638 

639 

640class Lambda(Function): 

641 """ 

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

643 

644 Children:: 

645 

646 0. <Keyword: lambda> 

647 *. <Param x> for each argument x 

648 -2. <Operator: :> 

649 -1. Node() representing body 

650 """ 

651 type = 'lambdef' 

652 __slots__ = () 

653 

654 def __init__(self, children): 

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

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

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

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

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

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

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

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

663 

664 @property 

665 def name(self): 

666 """ 

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

668 """ 

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

670 

671 def _get_param_nodes(self): 

672 return self.children[1:-2] 

673 

674 @property 

675 def annotation(self): 

676 """ 

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

678 """ 

679 return None 

680 

681 def __repr__(self): 

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

683 

684 

685class Flow(PythonBaseNode): 

686 __slots__ = () 

687 

688 

689class IfStmt(Flow): 

690 type = 'if_stmt' 

691 __slots__ = () 

692 

693 def get_test_nodes(self): 

694 """ 

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

696 

697 if x: 

698 pass 

699 elif x: 

700 pass 

701 """ 

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

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

704 yield self.children[i + 1] 

705 

706 def get_corresponding_test_node(self, node): 

707 """ 

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

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

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

711 """ 

712 start_pos = node.start_pos 

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

714 if check_node.start_pos < start_pos: 

715 if start_pos < check_node.end_pos: 

716 return None 

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

718 # not in the suite 

719 else: 

720 return check_node 

721 

722 def is_node_after_else(self, node): 

723 """ 

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

725 """ 

726 for c in self.children: 

727 if c == 'else': 

728 if node.start_pos > c.start_pos: 

729 return True 

730 else: 

731 return False 

732 

733 

734class WhileStmt(Flow): 

735 type = 'while_stmt' 

736 __slots__ = () 

737 

738 

739class ForStmt(Flow): 

740 type = 'for_stmt' 

741 __slots__ = () 

742 

743 def get_testlist(self): 

744 """ 

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

746 """ 

747 return self.children[3] 

748 

749 def get_defined_names(self, include_setitem=False): 

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

751 

752 

753class TryStmt(Flow): 

754 type = 'try_stmt' 

755 __slots__ = () 

756 

757 def get_except_clause_tests(self): 

758 """ 

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

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

761 """ 

762 for node in self.children: 

763 if node.type == 'except_clause': 

764 yield node.children[1] 

765 elif node == 'except': 

766 yield None 

767 

768 

769class WithStmt(Flow): 

770 type = 'with_stmt' 

771 __slots__ = () 

772 

773 def get_defined_names(self, include_setitem=False): 

774 """ 

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

776 defined names are set after `as`. 

777 """ 

778 names = [] 

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

780 # Check with items for 'as' names. 

781 if with_item.type == 'with_item': 

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

783 return names 

784 

785 def get_test_node_from_name(self, name): 

786 node = name.search_ancestor("with_item") 

787 if node is None: 

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

789 return node.children[0] 

790 

791 

792class Import(PythonBaseNode): 

793 __slots__ = () 

794 

795 def get_path_for_name(self, name): 

796 """ 

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

798 

799 :return list of Name: 

800 """ 

801 try: 

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

803 name = self._aliases()[name] 

804 except KeyError: 

805 pass 

806 

807 for path in self.get_paths(): 

808 if name in path: 

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

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

811 

812 def is_nested(self): 

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

814 

815 def is_star_import(self): 

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

817 

818 

819class ImportFrom(Import): 

820 type = 'import_from' 

821 __slots__ = () 

822 

823 def get_defined_names(self, include_setitem=False): 

824 """ 

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

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

827 present that name is returned. 

828 """ 

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

830 

831 def _aliases(self): 

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

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

834 if alias is not None) 

835 

836 def get_from_names(self): 

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

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

839 break 

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

841 return n.children[::2] 

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

843 return [] 

844 else: # from x import 

845 return [n] 

846 

847 @property 

848 def level(self): 

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

850 level = 0 

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

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

853 level += len(n.value) 

854 else: 

855 break 

856 return level 

857 

858 def _as_name_tuples(self): 

859 last = self.children[-1] 

860 if last == ')': 

861 last = self.children[-2] 

862 elif last == '*': 

863 return # No names defined directly. 

864 

865 if last.type == 'import_as_names': 

866 as_names = last.children[::2] 

867 else: 

868 as_names = [last] 

869 for as_name in as_names: 

870 if as_name.type == 'name': 

871 yield as_name, None 

872 else: 

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

874 

875 def get_paths(self): 

876 """ 

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

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

879 

880 :return list of list of Name: 

881 """ 

882 dotted = self.get_from_names() 

883 

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

885 return [dotted] 

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

887 

888 

889class ImportName(Import): 

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

891 type = 'import_name' 

892 __slots__ = () 

893 

894 def get_defined_names(self, include_setitem=False): 

895 """ 

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

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

898 present that name is returned. 

899 """ 

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

901 

902 @property 

903 def level(self): 

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

905 return 0 # Obviously 0 for imports without from. 

906 

907 def get_paths(self): 

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

909 

910 def _dotted_as_names(self): 

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

912 dotted_as_names = self.children[1] 

913 if dotted_as_names.type == 'dotted_as_names': 

914 as_names = dotted_as_names.children[::2] 

915 else: 

916 as_names = [dotted_as_names] 

917 

918 for as_name in as_names: 

919 if as_name.type == 'dotted_as_name': 

920 alias = as_name.children[2] 

921 as_name = as_name.children[0] 

922 else: 

923 alias = None 

924 if as_name.type == 'name': 

925 yield [as_name], alias 

926 else: 

927 # dotted_names 

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

929 

930 def is_nested(self): 

931 """ 

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

933 from statement:: 

934 

935 import foo.bar 

936 """ 

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

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

939 

940 def _aliases(self): 

941 """ 

942 :return list of Name: Returns all the alias 

943 """ 

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

945 if alias is not None) 

946 

947 

948class KeywordStatement(PythonBaseNode): 

949 """ 

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

951 `raise`, `return`, `yield`. 

952 

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

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

955 """ 

956 __slots__ = () 

957 

958 @property 

959 def type(self): 

960 """ 

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

962 crosscheck this with the Python grammar. 

963 """ 

964 return '%s_stmt' % self.keyword 

965 

966 @property 

967 def keyword(self): 

968 return self.children[0].value 

969 

970 def get_defined_names(self, include_setitem=False): 

971 keyword = self.keyword 

972 if keyword == 'del': 

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

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

975 return self.children[1::2] 

976 return [] 

977 

978 

979class AssertStmt(KeywordStatement): 

980 __slots__ = () 

981 

982 @property 

983 def assertion(self): 

984 return self.children[1] 

985 

986 

987class GlobalStmt(KeywordStatement): 

988 __slots__ = () 

989 

990 def get_global_names(self): 

991 return self.children[1::2] 

992 

993 

994class ReturnStmt(KeywordStatement): 

995 __slots__ = () 

996 

997 

998class YieldExpr(PythonBaseNode): 

999 type = 'yield_expr' 

1000 __slots__ = () 

1001 

1002 

1003def _defined_names(current, include_setitem): 

1004 """ 

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

1006 list comprehensions. 

1007 """ 

1008 names = [] 

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

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

1011 names += _defined_names(child, include_setitem) 

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

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

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

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

1016 trailer = current.children[-1] 

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

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

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

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

1021 if node.type == 'trailer': 

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

1023 break 

1024 if node.type == 'name': 

1025 names.append(node) 

1026 break 

1027 else: 

1028 names.append(current) 

1029 return names 

1030 

1031 

1032class ExprStmt(PythonBaseNode, DocstringMixin): 

1033 type = 'expr_stmt' 

1034 __slots__ = () 

1035 

1036 def get_defined_names(self, include_setitem=False): 

1037 """ 

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

1039 """ 

1040 names = [] 

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

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

1043 return [ 

1044 name 

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

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

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

1048 ] + names 

1049 

1050 def get_rhs(self): 

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

1052 node = self.children[-1] 

1053 if node.type == 'annassign': 

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

1055 node = node.children[3] 

1056 else: 

1057 node = node.children[1] 

1058 return node 

1059 

1060 def yield_operators(self): 

1061 """ 

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

1063 """ 

1064 first = self.children[1] 

1065 if first.type == 'annassign': 

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

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

1068 

1069 first = first.children[2] 

1070 yield first 

1071 

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

1073 

1074 

1075class NamedExpr(PythonBaseNode): 

1076 type = 'namedexpr_test' 

1077 

1078 def get_defined_names(self, include_setitem=False): 

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

1080 

1081 

1082class Param(PythonBaseNode): 

1083 """ 

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

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

1086 that is not really suited to working with parameters. 

1087 """ 

1088 type = 'param' 

1089 

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

1091 super().__init__(children) 

1092 self.parent = parent 

1093 

1094 @property 

1095 def star_count(self): 

1096 """ 

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

1098 `**foo`. 

1099 """ 

1100 first = self.children[0] 

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

1102 return len(first.value) 

1103 return 0 

1104 

1105 @property 

1106 def default(self): 

1107 """ 

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

1109 case no default is present. 

1110 """ 

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

1112 try: 

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

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

1115 except IndexError: 

1116 return None 

1117 

1118 @property 

1119 def annotation(self): 

1120 """ 

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

1122 no annotation is present. 

1123 """ 

1124 tfpdef = self._tfpdef() 

1125 if tfpdef.type == 'tfpdef': 

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

1127 assert len(tfpdef.children) == 3 

1128 annotation = tfpdef.children[2] 

1129 return annotation 

1130 else: 

1131 return None 

1132 

1133 def _tfpdef(self): 

1134 """ 

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

1136 """ 

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

1138 return self.children[offset] 

1139 

1140 @property 

1141 def name(self): 

1142 """ 

1143 The `Name` leaf of the param. 

1144 """ 

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

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

1147 else: 

1148 return self._tfpdef() 

1149 

1150 def get_defined_names(self, include_setitem=False): 

1151 return [self.name] 

1152 

1153 @property 

1154 def position_index(self): 

1155 """ 

1156 Property for the positional index of a paramter. 

1157 """ 

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

1159 try: 

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

1161 if index > keyword_only_index: 

1162 # Skip the ` *, ` 

1163 index -= 2 

1164 except ValueError: 

1165 pass 

1166 try: 

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

1168 if index > keyword_only_index: 

1169 # Skip the ` /, ` 

1170 index -= 2 

1171 except ValueError: 

1172 pass 

1173 return index - 1 

1174 

1175 def get_parent_function(self): 

1176 """ 

1177 Returns the function/lambda of a parameter. 

1178 """ 

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

1180 

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

1182 """ 

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

1184 `include_comma`. 

1185 

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

1187 """ 

1188 if include_comma: 

1189 return super().get_code(include_prefix) 

1190 

1191 children = self.children 

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

1193 children = children[:-1] 

1194 return self._get_code_for_children( 

1195 children, 

1196 include_prefix=include_prefix 

1197 ) 

1198 

1199 def __repr__(self): 

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

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

1202 

1203 

1204class SyncCompFor(PythonBaseNode): 

1205 type = 'sync_comp_for' 

1206 __slots__ = () 

1207 

1208 def get_defined_names(self, include_setitem=False): 

1209 """ 

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

1211 """ 

1212 # allow async for 

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

1214 

1215 

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

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

1218CompFor = SyncCompFor 

1219 

1220 

1221class UsedNamesMapping(Mapping): 

1222 """ 

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

1224 """ 

1225 def __init__(self, dct): 

1226 self._dict = dct 

1227 

1228 def __getitem__(self, key): 

1229 return self._dict[key] 

1230 

1231 def __len__(self): 

1232 return len(self._dict) 

1233 

1234 def __iter__(self): 

1235 return iter(self._dict) 

1236 

1237 def __hash__(self): 

1238 return id(self) 

1239 

1240 def __eq__(self, other): 

1241 # Comparing these dicts does not make sense. 

1242 return self is other