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