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 __slots__ = ()
299
300 def __eq__(self, other):
301 """
302 Make comparisons with strings easy.
303 Improves the readability of the parser.
304 """
305 if isinstance(other, str):
306 return self.value == other
307
308 return self is other
309
310 def __hash__(self):
311 return hash(self.value)
312
313
314class Operator(_LeafWithoutNewlines, _StringComparisonMixin):
315 type = 'operator'
316 __slots__ = ()
317
318
319class Keyword(_LeafWithoutNewlines, _StringComparisonMixin):
320 type = 'keyword'
321 __slots__ = ()
322
323
324class Scope(PythonBaseNode, DocstringMixin):
325 """
326 Super class for the parser tree, which represents the state of a python
327 text file.
328 A Scope is either a function, class or lambda.
329 """
330 __slots__ = ()
331
332 def __init__(self, children):
333 super().__init__(children)
334
335 def iter_funcdefs(self):
336 """
337 Returns a generator of `funcdef` nodes.
338 """
339 return self._search_in_scope('funcdef')
340
341 def iter_classdefs(self):
342 """
343 Returns a generator of `classdef` nodes.
344 """
345 return self._search_in_scope('classdef')
346
347 def iter_imports(self):
348 """
349 Returns a generator of `import_name` and `import_from` nodes.
350 """
351 return self._search_in_scope('import_name', 'import_from')
352
353 def _search_in_scope(self, *names):
354 def scan(children):
355 for element in children:
356 if element.type in names:
357 yield element
358 if element.type in _FUNC_CONTAINERS:
359 yield from scan(element.children)
360
361 return scan(self.children)
362
363 def get_suite(self):
364 """
365 Returns the part that is executed by the function.
366 """
367 return self.children[-1]
368
369 def __repr__(self):
370 try:
371 name = self.name.value
372 except AttributeError:
373 name = ''
374
375 return "<%s: %s@%s-%s>" % (type(self).__name__, name,
376 self.start_pos[0], self.end_pos[0])
377
378
379class Module(Scope):
380 """
381 The top scope, which is always a module.
382 Depending on the underlying parser this may be a full module or just a part
383 of a module.
384 """
385 __slots__ = ('_used_names',)
386 type = 'file_input'
387
388 def __init__(self, children):
389 super().__init__(children)
390 self._used_names = None
391
392 def _iter_future_import_names(self):
393 """
394 :return: A list of future import names.
395 :rtype: list of str
396 """
397 # In Python it's not allowed to use future imports after the first
398 # actual (non-future) statement. However this is not a linter here,
399 # just return all future imports. If people want to scan for issues
400 # they should use the API.
401 for imp in self.iter_imports():
402 if imp.type == 'import_from' and imp.level == 0:
403 for path in imp.get_paths():
404 names = [name.value for name in path]
405 if len(names) == 2 and names[0] == '__future__':
406 yield names[1]
407
408 def get_used_names(self):
409 """
410 Returns all the :class:`Name` leafs that exist in this module. This
411 includes both definitions and references of names.
412 """
413 if self._used_names is None:
414 # Don't directly use self._used_names to eliminate a lookup.
415 dct = {}
416
417 def recurse(node):
418 try:
419 children = node.children
420 except AttributeError:
421 if node.type == 'name':
422 arr = dct.setdefault(node.value, [])
423 arr.append(node)
424 else:
425 for child in children:
426 recurse(child)
427
428 recurse(self)
429 self._used_names = UsedNamesMapping(dct)
430 return self._used_names
431
432
433class Decorator(PythonBaseNode):
434 type = 'decorator'
435 __slots__ = ()
436
437
438class ClassOrFunc(Scope):
439 __slots__ = ()
440
441 @property
442 def name(self):
443 """
444 Returns the `Name` leaf that defines the function or class name.
445 """
446 return self.children[1]
447
448 def get_decorators(self):
449 """
450 :rtype: list of :class:`Decorator`
451 """
452 decorated = self.parent
453 if decorated.type == 'async_funcdef':
454 decorated = decorated.parent
455
456 if decorated.type == 'decorated':
457 if decorated.children[0].type == 'decorators':
458 return decorated.children[0].children
459 else:
460 return decorated.children[:1]
461 else:
462 return []
463
464
465class Class(ClassOrFunc):
466 """
467 Used to store the parsed contents of a python class.
468 """
469 type = 'classdef'
470 __slots__ = ()
471
472 def __init__(self, children):
473 super().__init__(children)
474
475 def get_super_arglist(self):
476 """
477 Returns the `arglist` node that defines the super classes. It returns
478 None if there are no arguments.
479 """
480 if self.children[2] != '(': # Has no parentheses
481 return None
482 else:
483 if self.children[3] == ')': # Empty parentheses
484 return None
485 else:
486 return self.children[3]
487
488
489def _create_params(parent, argslist_list):
490 """
491 `argslist_list` is a list that can contain an argslist as a first item, but
492 most not. It's basically the items between the parameter brackets (which is
493 at most one item).
494 This function modifies the parser structure. It generates `Param` objects
495 from the normal ast. Those param objects do not exist in a normal ast, but
496 make the evaluation of the ast tree so much easier.
497 You could also say that this function replaces the argslist node with a
498 list of Param objects.
499 """
500 try:
501 first = argslist_list[0]
502 except IndexError:
503 return []
504
505 if first.type in ('name', 'fpdef'):
506 return [Param([first], parent)]
507 elif first == '*':
508 return [first]
509 else: # argslist is a `typedargslist` or a `varargslist`.
510 if first.type == 'tfpdef':
511 children = [first]
512 else:
513 children = first.children
514 new_children = []
515 start = 0
516 # Start with offset 1, because the end is higher.
517 for end, child in enumerate(children + [None], 1):
518 if child is None or child == ',':
519 param_children = children[start:end]
520 if param_children: # Could as well be comma and then end.
521 if param_children[0] == '*' \
522 and (len(param_children) == 1
523 or param_children[1] == ',') \
524 or param_children[0] == '/':
525 for p in param_children:
526 p.parent = parent
527 new_children += param_children
528 else:
529 new_children.append(Param(param_children, parent))
530 start = end
531 return new_children
532
533
534class Function(ClassOrFunc):
535 """
536 Used to store the parsed contents of a python function.
537
538 Children::
539
540 0. <Keyword: def>
541 1. <Name>
542 2. parameter list (including open-paren and close-paren <Operator>s)
543 3. or 5. <Operator: :>
544 4. or 6. Node() representing function body
545 3. -> (if annotation is also present)
546 4. annotation (if present)
547 """
548 type = 'funcdef'
549 __slots__ = ()
550
551 def __init__(self, children):
552 super().__init__(children)
553 parameters = self.children[2] # After `def foo`
554 parameters_children = parameters.children[1:-1]
555 # If input parameters list already has Param objects, keep it as is;
556 # otherwise, convert it to a list of Param objects.
557 if not any(isinstance(child, Param) for child in parameters_children):
558 parameters.children[1:-1] = _create_params(parameters, parameters_children)
559
560 def _get_param_nodes(self):
561 return self.children[2].children
562
563 def get_params(self):
564 """
565 Returns a list of `Param()`.
566 """
567 return [p for p in self._get_param_nodes() if p.type == 'param']
568
569 @property
570 def name(self):
571 return self.children[1] # First token after `def`
572
573 def iter_yield_exprs(self):
574 """
575 Returns a generator of `yield_expr`.
576 """
577 def scan(children):
578 for element in children:
579 if element.type in ('classdef', 'funcdef', 'lambdef'):
580 continue
581
582 try:
583 nested_children = element.children
584 except AttributeError:
585 if element.value == 'yield':
586 if element.parent.type == 'yield_expr':
587 yield element.parent
588 else:
589 yield element
590 else:
591 yield from scan(nested_children)
592
593 return scan(self.children)
594
595 def iter_return_stmts(self):
596 """
597 Returns a generator of `return_stmt`.
598 """
599 def scan(children):
600 for element in children:
601 if element.type == 'return_stmt' \
602 or element.type == 'keyword' and element.value == 'return':
603 yield element
604 if element.type in _RETURN_STMT_CONTAINERS:
605 yield from scan(element.children)
606
607 return scan(self.children)
608
609 def iter_raise_stmts(self):
610 """
611 Returns a generator of `raise_stmt`. Includes raise statements inside try-except blocks
612 """
613 def scan(children):
614 for element in children:
615 if element.type == 'raise_stmt' \
616 or element.type == 'keyword' and element.value == 'raise':
617 yield element
618 if element.type in _RETURN_STMT_CONTAINERS:
619 yield from scan(element.children)
620
621 return scan(self.children)
622
623 def is_generator(self):
624 """
625 :return bool: Checks if a function is a generator or not.
626 """
627 return next(self.iter_yield_exprs(), None) is not None
628
629 @property
630 def annotation(self):
631 """
632 Returns the test node after `->` or `None` if there is no annotation.
633 """
634 try:
635 if self.children[3] == "->":
636 return self.children[4]
637 assert self.children[3] == ":"
638 return None
639 except IndexError:
640 return None
641
642
643class Lambda(Function):
644 """
645 Lambdas are basically trimmed functions, so give it the same interface.
646
647 Children::
648
649 0. <Keyword: lambda>
650 *. <Param x> for each argument x
651 -2. <Operator: :>
652 -1. Node() representing body
653 """
654 type = 'lambdef'
655 __slots__ = ()
656
657 def __init__(self, children):
658 # We don't want to call the Function constructor, call its parent.
659 super(Function, self).__init__(children)
660 # Everything between `lambda` and the `:` operator is a parameter.
661 parameters_children = self.children[1:-2]
662 # If input children list already has Param objects, keep it as is;
663 # otherwise, convert it to a list of Param objects.
664 if not any(isinstance(child, Param) for child in parameters_children):
665 self.children[1:-2] = _create_params(self, parameters_children)
666
667 @property
668 def name(self):
669 """
670 Raises an AttributeError. Lambdas don't have a defined name.
671 """
672 raise AttributeError("lambda is not named.")
673
674 def _get_param_nodes(self):
675 return self.children[1:-2]
676
677 @property
678 def annotation(self):
679 """
680 Returns `None`, lambdas don't have annotations.
681 """
682 return None
683
684 def __repr__(self):
685 return "<%s@%s>" % (self.__class__.__name__, self.start_pos)
686
687
688class Flow(PythonBaseNode):
689 __slots__ = ()
690
691
692class IfStmt(Flow):
693 type = 'if_stmt'
694 __slots__ = ()
695
696 def get_test_nodes(self):
697 """
698 E.g. returns all the `test` nodes that are named as x, below:
699
700 if x:
701 pass
702 elif x:
703 pass
704 """
705 for i, c in enumerate(self.children):
706 if c in ('elif', 'if'):
707 yield self.children[i + 1]
708
709 def get_corresponding_test_node(self, node):
710 """
711 Searches for the branch in which the node is and returns the
712 corresponding test node (see function above). However if the node is in
713 the test node itself and not in the suite return None.
714 """
715 start_pos = node.start_pos
716 for check_node in reversed(list(self.get_test_nodes())):
717 if check_node.start_pos < start_pos:
718 if start_pos < check_node.end_pos:
719 return None
720 # In this case the node is within the check_node itself,
721 # not in the suite
722 else:
723 return check_node
724
725 def is_node_after_else(self, node):
726 """
727 Checks if a node is defined after `else`.
728 """
729 for c in self.children:
730 if c == 'else':
731 if node.start_pos > c.start_pos:
732 return True
733 else:
734 return False
735
736
737class WhileStmt(Flow):
738 type = 'while_stmt'
739 __slots__ = ()
740
741
742class ForStmt(Flow):
743 type = 'for_stmt'
744 __slots__ = ()
745
746 def get_testlist(self):
747 """
748 Returns the input node ``y`` from: ``for x in y:``.
749 """
750 return self.children[3]
751
752 def get_defined_names(self, include_setitem=False):
753 return _defined_names(self.children[1], include_setitem)
754
755
756class TryStmt(Flow):
757 type = 'try_stmt'
758 __slots__ = ()
759
760 def get_except_clause_tests(self):
761 """
762 Returns the ``test`` nodes found in ``except_clause`` nodes.
763 Returns ``[None]`` for except clauses without an exception given.
764 """
765 for node in self.children:
766 if node.type == 'except_clause':
767 yield node.children[1]
768 elif node == 'except':
769 yield None
770
771
772class WithStmt(Flow):
773 type = 'with_stmt'
774 __slots__ = ()
775
776 def get_defined_names(self, include_setitem=False):
777 """
778 Returns the a list of `Name` that the with statement defines. The
779 defined names are set after `as`.
780 """
781 names = []
782 for with_item in self.children[1:-2:2]:
783 # Check with items for 'as' names.
784 if with_item.type == 'with_item':
785 names += _defined_names(with_item.children[2], include_setitem)
786 return names
787
788 def get_test_node_from_name(self, name):
789 node = name.search_ancestor("with_item")
790 if node is None:
791 raise ValueError('The name is not actually part of a with statement.')
792 return node.children[0]
793
794
795class Import(PythonBaseNode):
796 __slots__ = ()
797
798 def get_path_for_name(self, name):
799 """
800 The path is the list of names that leads to the searched name.
801
802 :return list of Name:
803 """
804 try:
805 # The name may be an alias. If it is, just map it back to the name.
806 name = self._aliases()[name]
807 except KeyError:
808 pass
809
810 for path in self.get_paths():
811 if name in path:
812 return path[:path.index(name) + 1]
813 raise ValueError('Name should be defined in the import itself')
814
815 def is_nested(self):
816 return False # By default, sub classes may overwrite this behavior
817
818 def is_star_import(self):
819 return self.children[-1] == '*'
820
821
822class ImportFrom(Import):
823 type = 'import_from'
824 __slots__ = ()
825
826 def get_defined_names(self, include_setitem=False):
827 """
828 Returns the a list of `Name` that the import defines. The
829 defined names are set after `import` or in case an alias - `as` - is
830 present that name is returned.
831 """
832 return [alias or name for name, alias in self._as_name_tuples()]
833
834 def _aliases(self):
835 """Mapping from alias to its corresponding name."""
836 return dict((alias, name) for name, alias in self._as_name_tuples()
837 if alias is not None)
838
839 def get_from_names(self):
840 for n in self.children[1:]:
841 if n not in ('.', '...'):
842 break
843 if n.type == 'dotted_name': # from x.y import
844 return n.children[::2]
845 elif n == 'import': # from . import
846 return []
847 else: # from x import
848 return [n]
849
850 @property
851 def level(self):
852 """The level parameter of ``__import__``."""
853 level = 0
854 for n in self.children[1:]:
855 if n in ('.', '...'):
856 level += len(n.value)
857 else:
858 break
859 return level
860
861 def _as_name_tuples(self):
862 last = self.children[-1]
863 if last == ')':
864 last = self.children[-2]
865 elif last == '*':
866 return # No names defined directly.
867
868 if last.type == 'import_as_names':
869 as_names = last.children[::2]
870 else:
871 as_names = [last]
872 for as_name in as_names:
873 if as_name.type == 'name':
874 yield as_name, None
875 else:
876 yield as_name.children[::2] # yields x, y -> ``x as y``
877
878 def get_paths(self):
879 """
880 The import paths defined in an import statement. Typically an array
881 like this: ``[<Name: datetime>, <Name: date>]``.
882
883 :return list of list of Name:
884 """
885 dotted = self.get_from_names()
886
887 if self.children[-1] == '*':
888 return [dotted]
889 return [dotted + [name] for name, alias in self._as_name_tuples()]
890
891
892class ImportName(Import):
893 """For ``import_name`` nodes. Covers normal imports without ``from``."""
894 type = 'import_name'
895 __slots__ = ()
896
897 def get_defined_names(self, include_setitem=False):
898 """
899 Returns the a list of `Name` that the import defines. The defined names
900 is always the first name after `import` or in case an alias - `as` - is
901 present that name is returned.
902 """
903 return [alias or path[0] for path, alias in self._dotted_as_names()]
904
905 @property
906 def level(self):
907 """The level parameter of ``__import__``."""
908 return 0 # Obviously 0 for imports without from.
909
910 def get_paths(self):
911 return [path for path, alias in self._dotted_as_names()]
912
913 def _dotted_as_names(self):
914 """Generator of (list(path), alias) where alias may be None."""
915 dotted_as_names = self.children[1]
916 if dotted_as_names.type == 'dotted_as_names':
917 as_names = dotted_as_names.children[::2]
918 else:
919 as_names = [dotted_as_names]
920
921 for as_name in as_names:
922 if as_name.type == 'dotted_as_name':
923 alias = as_name.children[2]
924 as_name = as_name.children[0]
925 else:
926 alias = None
927 if as_name.type == 'name':
928 yield [as_name], alias
929 else:
930 # dotted_names
931 yield as_name.children[::2], alias
932
933 def is_nested(self):
934 """
935 This checks for the special case of nested imports, without aliases and
936 from statement::
937
938 import foo.bar
939 """
940 return bool([1 for path, alias in self._dotted_as_names()
941 if alias is None and len(path) > 1])
942
943 def _aliases(self):
944 """
945 :return list of Name: Returns all the alias
946 """
947 return dict((alias, path[-1]) for path, alias in self._dotted_as_names()
948 if alias is not None)
949
950
951class KeywordStatement(PythonBaseNode):
952 """
953 For the following statements: `assert`, `del`, `global`, `nonlocal`,
954 `raise`, `return`, `yield`.
955
956 `pass`, `continue` and `break` are not in there, because they are just
957 simple keywords and the parser reduces it to a keyword.
958 """
959 __slots__ = ()
960
961 @property
962 def type(self):
963 """
964 Keyword statements start with the keyword and end with `_stmt`. You can
965 crosscheck this with the Python grammar.
966 """
967 return '%s_stmt' % self.keyword
968
969 @property
970 def keyword(self):
971 return self.children[0].value
972
973 def get_defined_names(self, include_setitem=False):
974 keyword = self.keyword
975 if keyword == 'del':
976 return _defined_names(self.children[1], include_setitem)
977 if keyword in ('global', 'nonlocal'):
978 return self.children[1::2]
979 return []
980
981
982class AssertStmt(KeywordStatement):
983 __slots__ = ()
984
985 @property
986 def assertion(self):
987 return self.children[1]
988
989
990class GlobalStmt(KeywordStatement):
991 __slots__ = ()
992
993 def get_global_names(self):
994 return self.children[1::2]
995
996
997class ReturnStmt(KeywordStatement):
998 __slots__ = ()
999
1000
1001class YieldExpr(PythonBaseNode):
1002 type = 'yield_expr'
1003 __slots__ = ()
1004
1005
1006def _defined_names(current, include_setitem):
1007 """
1008 A helper function to find the defined names in statements, for loops and
1009 list comprehensions.
1010 """
1011 names = []
1012 if current.type in ('testlist_star_expr', 'testlist_comp', 'exprlist', 'testlist'):
1013 for child in current.children[::2]:
1014 names += _defined_names(child, include_setitem)
1015 elif current.type in ('atom', 'star_expr'):
1016 names += _defined_names(current.children[1], include_setitem)
1017 elif current.type in ('power', 'atom_expr'):
1018 if current.children[-2] != '**': # Just if there's no operation
1019 trailer = current.children[-1]
1020 if trailer.children[0] == '.':
1021 names.append(trailer.children[1])
1022 elif trailer.children[0] == '[' and include_setitem:
1023 for node in current.children[-2::-1]:
1024 if node.type == 'trailer':
1025 names.append(node.children[1])
1026 break
1027 if node.type == 'name':
1028 names.append(node)
1029 break
1030 else:
1031 names.append(current)
1032 return names
1033
1034
1035class ExprStmt(PythonBaseNode, DocstringMixin):
1036 type = 'expr_stmt'
1037 __slots__ = ()
1038
1039 def get_defined_names(self, include_setitem=False):
1040 """
1041 Returns a list of `Name` defined before the `=` sign.
1042 """
1043 names = []
1044 if self.children[1].type == 'annassign':
1045 names = _defined_names(self.children[0], include_setitem)
1046 return [
1047 name
1048 for i in range(0, len(self.children) - 2, 2)
1049 if '=' in self.children[i + 1].value
1050 for name in _defined_names(self.children[i], include_setitem)
1051 ] + names
1052
1053 def get_rhs(self):
1054 """Returns the right-hand-side of the equals."""
1055 node = self.children[-1]
1056 if node.type == 'annassign':
1057 if len(node.children) == 4:
1058 node = node.children[3]
1059 else:
1060 node = node.children[1]
1061 return node
1062
1063 def yield_operators(self):
1064 """
1065 Returns a generator of `+=`, `=`, etc. or None if there is no operation.
1066 """
1067 first = self.children[1]
1068 if first.type == 'annassign':
1069 if len(first.children) <= 2:
1070 return # No operator is available, it's just PEP 484.
1071
1072 first = first.children[2]
1073 yield first
1074
1075 yield from self.children[3::2]
1076
1077
1078class NamedExpr(PythonBaseNode):
1079 type = 'namedexpr_test'
1080
1081 def get_defined_names(self, include_setitem=False):
1082 return _defined_names(self.children[0], include_setitem)
1083
1084
1085class Param(PythonBaseNode):
1086 """
1087 It's a helper class that makes business logic with params much easier. The
1088 Python grammar defines no ``param`` node. It defines it in a different way
1089 that is not really suited to working with parameters.
1090 """
1091 type = 'param'
1092
1093 def __init__(self, children, parent=None):
1094 super().__init__(children)
1095 self.parent = parent
1096
1097 @property
1098 def star_count(self):
1099 """
1100 Is `0` in case of `foo`, `1` in case of `*foo` or `2` in case of
1101 `**foo`.
1102 """
1103 first = self.children[0]
1104 if first in ('*', '**'):
1105 return len(first.value)
1106 return 0
1107
1108 @property
1109 def default(self):
1110 """
1111 The default is the test node that appears after the `=`. Is `None` in
1112 case no default is present.
1113 """
1114 has_comma = self.children[-1] == ','
1115 try:
1116 if self.children[-2 - int(has_comma)] == '=':
1117 return self.children[-1 - int(has_comma)]
1118 except IndexError:
1119 return None
1120
1121 @property
1122 def annotation(self):
1123 """
1124 The default is the test node that appears after `:`. Is `None` in case
1125 no annotation is present.
1126 """
1127 tfpdef = self._tfpdef()
1128 if tfpdef.type == 'tfpdef':
1129 assert tfpdef.children[1] == ":"
1130 assert len(tfpdef.children) == 3
1131 annotation = tfpdef.children[2]
1132 return annotation
1133 else:
1134 return None
1135
1136 def _tfpdef(self):
1137 """
1138 tfpdef: see e.g. grammar36.txt.
1139 """
1140 offset = int(self.children[0] in ('*', '**'))
1141 return self.children[offset]
1142
1143 @property
1144 def name(self):
1145 """
1146 The `Name` leaf of the param.
1147 """
1148 if self._tfpdef().type == 'tfpdef':
1149 return self._tfpdef().children[0]
1150 else:
1151 return self._tfpdef()
1152
1153 def get_defined_names(self, include_setitem=False):
1154 return [self.name]
1155
1156 @property
1157 def position_index(self):
1158 """
1159 Property for the positional index of a paramter.
1160 """
1161 index = self.parent.children.index(self)
1162 try:
1163 keyword_only_index = self.parent.children.index('*')
1164 if index > keyword_only_index:
1165 # Skip the ` *, `
1166 index -= 2
1167 except ValueError:
1168 pass
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 return index - 1
1177
1178 def get_parent_function(self):
1179 """
1180 Returns the function/lambda of a parameter.
1181 """
1182 return self.search_ancestor('funcdef', 'lambdef')
1183
1184 def get_code(self, include_prefix=True, include_comma=True):
1185 """
1186 Like all the other get_code functions, but includes the param
1187 `include_comma`.
1188
1189 :param include_comma bool: If enabled includes the comma in the string output.
1190 """
1191 if include_comma:
1192 return super().get_code(include_prefix)
1193
1194 children = self.children
1195 if children[-1] == ',':
1196 children = children[:-1]
1197 return self._get_code_for_children(
1198 children,
1199 include_prefix=include_prefix
1200 )
1201
1202 def __repr__(self):
1203 default = '' if self.default is None else '=%s' % self.default.get_code()
1204 return '<%s: %s>' % (type(self).__name__, str(self._tfpdef()) + default)
1205
1206
1207class SyncCompFor(PythonBaseNode):
1208 type = 'sync_comp_for'
1209 __slots__ = ()
1210
1211 def get_defined_names(self, include_setitem=False):
1212 """
1213 Returns the a list of `Name` that the comprehension defines.
1214 """
1215 # allow async for
1216 return _defined_names(self.children[1], include_setitem)
1217
1218
1219# This is simply here so an older Jedi version can work with this new parso
1220# version. Can be deleted in the next release.
1221CompFor = SyncCompFor
1222
1223
1224class UsedNamesMapping(Mapping):
1225 """
1226 This class exists for the sole purpose of creating an immutable dict.
1227 """
1228 def __init__(self, dct):
1229 self._dict = dct
1230
1231 def __getitem__(self, key):
1232 return self._dict[key]
1233
1234 def __len__(self):
1235 return len(self._dict)
1236
1237 def __iter__(self):
1238 return iter(self._dict)
1239
1240 def __hash__(self):
1241 return id(self)
1242
1243 def __eq__(self, other):
1244 # Comparing these dicts does not make sense.
1245 return self is other