Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/parso/python/tree.py: 38%
630 statements
« prev ^ index » next coverage.py v7.4.4, created at 2024-04-20 06:09 +0000
« prev ^ index » next coverage.py v7.4.4, created at 2024-04-20 06:09 +0000
1"""
2This is the syntax tree for Python 3 syntaxes. The classes represent
3syntax elements like functions and imports.
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).
10There's a lot of logic here that makes it easier for Jedi (and other libraries)
11to deal with a Python syntax tree.
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.
17>>> from parso import parse
18>>> parser = parse('import os')
19>>> module = parser.get_root_node()
20>>> module
21<Module: @1-1>
23Any subclasses of :class:`Scope`, including :class:`Module` has an attribute
24:attr:`iter_imports <Scope.iter_imports>`:
26>>> list(module.iter_imports())
27[<ImportName: import os@1,0>]
29Changes to the Python Grammar
30-----------------------------
32A few things have changed when looking at Python grammar files:
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.
41Parser Tree Classes
42-------------------
43"""
45import re
46try:
47 from collections.abc import Mapping
48except ImportError:
49 from collections import Mapping
50from typing import Tuple
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
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
60_FUNC_CONTAINERS = set(
61 ['suite', 'simple_stmt', 'decorated', 'async_funcdef']
62) | _FLOW_CONTAINERS
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'])
71class DocstringMixin:
72 __slots__ = ()
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]
92 if node.type == 'simple_stmt':
93 node = node.children[0]
94 if node.type == 'string':
95 return node
96 return None
99class PythonMixin:
100 """
101 Some Python specific utilities.
102 """
103 __slots__ = ()
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
121class PythonLeaf(PythonMixin, Leaf):
122 __slots__ = ()
124 def _split_prefix(self):
125 return split_prefix(self, self.get_start_pos_of_prefix())
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()
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
145class _LeafWithoutNewlines(PythonLeaf):
146 """
147 Simply here to optimize performance.
148 """
149 __slots__ = ()
151 @property
152 def end_pos(self) -> Tuple[int, int]:
153 return self.line, self.column + len(self.value)
156# Python base classes
157class PythonBaseNode(PythonMixin, BaseNode):
158 __slots__ = ()
161class PythonNode(PythonMixin, Node):
162 __slots__ = ()
165class PythonErrorNode(PythonMixin, ErrorNode):
166 __slots__ = ()
169class PythonErrorLeaf(ErrorLeaf, PythonLeaf):
170 __slots__ = ()
173class EndMarker(_LeafWithoutNewlines):
174 __slots__ = ()
175 type = 'endmarker'
177 def __repr__(self):
178 return "<%s: prefix=%s end_pos=%s>" % (
179 type(self).__name__, repr(self.prefix), self.end_pos
180 )
183class Newline(PythonLeaf):
184 """Contains NEWLINE and ENDMARKER tokens."""
185 __slots__ = ()
186 type = 'newline'
188 def __repr__(self):
189 return "<%s: %s>" % (type(self).__name__, repr(self.value))
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__ = ()
200 def __repr__(self):
201 return "<%s: %s@%s,%s>" % (type(self).__name__, self.value,
202 self.line, self.column)
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
210 def get_definition(self, import_name_always=False, include_setitem=False):
211 """
212 Returns None if there's no definition for a name.
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
221 if type_ in ('funcdef', 'classdef'):
222 if self == node.name:
223 return node
224 return None
226 if type_ == 'except_clause':
227 if self.get_previous_sibling() == 'as':
228 return node.parent # The try_stmt.
229 return None
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
244class Literal(PythonLeaf):
245 __slots__ = ()
248class Number(Literal):
249 type = 'number'
250 __slots__ = ()
253class String(Literal):
254 type = 'string'
255 __slots__ = ()
257 @property
258 def string_prefix(self):
259 return re.match(r'\w*(?=[\'"])', self.value).group(0)
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))]
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__ = ()
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__ = ()
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__ = ()
297class _StringComparisonMixin:
298 __slots__ = ()
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
308 return self is other
310 def __hash__(self):
311 return hash(self.value)
314class Operator(_LeafWithoutNewlines, _StringComparisonMixin):
315 type = 'operator'
316 __slots__ = ()
319class Keyword(_LeafWithoutNewlines, _StringComparisonMixin):
320 type = 'keyword'
321 __slots__ = ()
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__ = ()
332 def __init__(self, children):
333 super().__init__(children)
335 def iter_funcdefs(self):
336 """
337 Returns a generator of `funcdef` nodes.
338 """
339 return self._search_in_scope('funcdef')
341 def iter_classdefs(self):
342 """
343 Returns a generator of `classdef` nodes.
344 """
345 return self._search_in_scope('classdef')
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')
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)
361 return scan(self.children)
363 def get_suite(self):
364 """
365 Returns the part that is executed by the function.
366 """
367 return self.children[-1]
369 def __repr__(self):
370 try:
371 name = self.name.value
372 except AttributeError:
373 name = ''
375 return "<%s: %s@%s-%s>" % (type(self).__name__, name,
376 self.start_pos[0], self.end_pos[0])
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'
388 def __init__(self, children):
389 super().__init__(children)
390 self._used_names = None
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]
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 = {}
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)
428 recurse(self)
429 self._used_names = UsedNamesMapping(dct)
430 return self._used_names
433class Decorator(PythonBaseNode):
434 type = 'decorator'
435 __slots__ = ()
438class ClassOrFunc(Scope):
439 __slots__ = ()
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]
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
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 []
465class Class(ClassOrFunc):
466 """
467 Used to store the parsed contents of a python class.
468 """
469 type = 'classdef'
470 __slots__ = ()
472 def __init__(self, children):
473 super().__init__(children)
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]
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 []
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
534class Function(ClassOrFunc):
535 """
536 Used to store the parsed contents of a python function.
538 Children::
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__ = ()
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)
560 def _get_param_nodes(self):
561 return self.children[2].children
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']
569 @property
570 def name(self):
571 return self.children[1] # First token after `def`
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
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)
593 return scan(self.children)
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)
607 return scan(self.children)
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)
621 return scan(self.children)
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
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
643class Lambda(Function):
644 """
645 Lambdas are basically trimmed functions, so give it the same interface.
647 Children::
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__ = ()
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)
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.")
674 def _get_param_nodes(self):
675 return self.children[1:-2]
677 @property
678 def annotation(self):
679 """
680 Returns `None`, lambdas don't have annotations.
681 """
682 return None
684 def __repr__(self):
685 return "<%s@%s>" % (self.__class__.__name__, self.start_pos)
688class Flow(PythonBaseNode):
689 __slots__ = ()
692class IfStmt(Flow):
693 type = 'if_stmt'
694 __slots__ = ()
696 def get_test_nodes(self):
697 """
698 E.g. returns all the `test` nodes that are named as x, below:
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]
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
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
737class WhileStmt(Flow):
738 type = 'while_stmt'
739 __slots__ = ()
742class ForStmt(Flow):
743 type = 'for_stmt'
744 __slots__ = ()
746 def get_testlist(self):
747 """
748 Returns the input node ``y`` from: ``for x in y:``.
749 """
750 return self.children[3]
752 def get_defined_names(self, include_setitem=False):
753 return _defined_names(self.children[1], include_setitem)
756class TryStmt(Flow):
757 type = 'try_stmt'
758 __slots__ = ()
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
772class WithStmt(Flow):
773 type = 'with_stmt'
774 __slots__ = ()
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
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]
795class Import(PythonBaseNode):
796 __slots__ = ()
798 def get_path_for_name(self, name):
799 """
800 The path is the list of names that leads to the searched name.
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
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')
815 def is_nested(self):
816 return False # By default, sub classes may overwrite this behavior
818 def is_star_import(self):
819 return self.children[-1] == '*'
822class ImportFrom(Import):
823 type = 'import_from'
824 __slots__ = ()
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()]
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)
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]
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
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.
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``
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>]``.
883 :return list of list of Name:
884 """
885 dotted = self.get_from_names()
887 if self.children[-1] == '*':
888 return [dotted]
889 return [dotted + [name] for name, alias in self._as_name_tuples()]
892class ImportName(Import):
893 """For ``import_name`` nodes. Covers normal imports without ``from``."""
894 type = 'import_name'
895 __slots__ = ()
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()]
905 @property
906 def level(self):
907 """The level parameter of ``__import__``."""
908 return 0 # Obviously 0 for imports without from.
910 def get_paths(self):
911 return [path for path, alias in self._dotted_as_names()]
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]
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
933 def is_nested(self):
934 """
935 This checks for the special case of nested imports, without aliases and
936 from statement::
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])
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)
951class KeywordStatement(PythonBaseNode):
952 """
953 For the following statements: `assert`, `del`, `global`, `nonlocal`,
954 `raise`, `return`, `yield`.
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__ = ()
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
969 @property
970 def keyword(self):
971 return self.children[0].value
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 []
982class AssertStmt(KeywordStatement):
983 __slots__ = ()
985 @property
986 def assertion(self):
987 return self.children[1]
990class GlobalStmt(KeywordStatement):
991 __slots__ = ()
993 def get_global_names(self):
994 return self.children[1::2]
997class ReturnStmt(KeywordStatement):
998 __slots__ = ()
1001class YieldExpr(PythonBaseNode):
1002 type = 'yield_expr'
1003 __slots__ = ()
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
1035class ExprStmt(PythonBaseNode, DocstringMixin):
1036 type = 'expr_stmt'
1037 __slots__ = ()
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
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
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.
1072 first = first.children[2]
1073 yield first
1075 yield from self.children[3::2]
1078class NamedExpr(PythonBaseNode):
1079 type = 'namedexpr_test'
1081 def get_defined_names(self, include_setitem=False):
1082 return _defined_names(self.children[0], include_setitem)
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'
1093 def __init__(self, children, parent=None):
1094 super().__init__(children)
1095 self.parent = parent
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
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
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
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]
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()
1153 def get_defined_names(self, include_setitem=False):
1154 return [self.name]
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
1178 def get_parent_function(self):
1179 """
1180 Returns the function/lambda of a parameter.
1181 """
1182 return self.search_ancestor('funcdef', 'lambdef')
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`.
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)
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 )
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)
1207class SyncCompFor(PythonBaseNode):
1208 type = 'sync_comp_for'
1209 __slots__ = ()
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)
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
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
1231 def __getitem__(self, key):
1232 return self._dict[key]
1234 def __len__(self):
1235 return len(self._dict)
1237 def __iter__(self):
1238 return iter(self._dict)
1240 def __hash__(self):
1241 return id(self)
1243 def __eq__(self, other):
1244 # Comparing these dicts does not make sense.
1245 return self is other