]> crepu.dev Git - config.git/blame - djavu-asus/elpy/rpc-venv/lib/python3.11/site-packages/parso/python/tree.py
ActualizaciĆ³n de Readme
[config.git] / djavu-asus / elpy / rpc-venv / lib / python3.11 / site-packages / parso / python / tree.py
CommitLineData
53e6db90
DC
1"""
2This is the syntax tree for Python 3 syntaxes. The classes represent
3syntax elements like functions and imports.
4
5All of the nodes can be traced back to the `Python grammar file
6<https://docs.python.org/3/reference/grammar.html>`_. If you want to know how
7a tree is structured, just analyse that file (for each Python version it's a
8bit different).
9
10There's a lot of logic here that makes it easier for Jedi (and other libraries)
11to deal with a Python syntax tree.
12
13By using :py:meth:`parso.tree.NodeOrLeaf.get_code` on a module, you can get
14back the 1-to-1 representation of the input given to the parser. This is
15important if you want to refactor a parser tree.
16
17>>> from parso import parse
18>>> parser = parse('import os')
19>>> module = parser.get_root_node()
20>>> module
21<Module: @1-1>
22
23Any subclasses of :class:`Scope`, including :class:`Module` has an attribute
24:attr:`iter_imports <Scope.iter_imports>`:
25
26>>> list(module.iter_imports())
27[<ImportName: import os@1,0>]
28
29Changes to the Python Grammar
30-----------------------------
31
32A few things have changed when looking at Python grammar files:
33
34- :class:`Param` does not exist in Python grammar files. It is essentially a
35 part of a ``parameters`` node. |parso| splits it up to make it easier to
36 analyse parameters. However this just makes it easier to deal with the syntax
37 tree, it doesn't actually change the valid syntax.
38- A few nodes like `lambdef` and `lambdef_nocond` have been merged in the
39 syntax tree to make it easier to do deal with them.
40
41Parser Tree Classes
42-------------------
43"""
44
45import re
46try:
47 from collections.abc import Mapping
48except ImportError:
49 from collections import Mapping
50from typing import Tuple
51
52from parso.tree import Node, BaseNode, Leaf, ErrorNode, ErrorLeaf, search_ancestor # noqa
53from parso.python.prefix import split_prefix
54from parso.utils import split_lines
55
56_FLOW_CONTAINERS = set(['if_stmt', 'while_stmt', 'for_stmt', 'try_stmt',
57 'with_stmt', 'async_stmt', 'suite'])
58_RETURN_STMT_CONTAINERS = set(['suite', 'simple_stmt']) | _FLOW_CONTAINERS
59
60_FUNC_CONTAINERS = set(
61 ['suite', 'simple_stmt', 'decorated', 'async_funcdef']
62) | _FLOW_CONTAINERS
63
64_GET_DEFINITION_TYPES = set([
65 'expr_stmt', 'sync_comp_for', 'with_stmt', 'for_stmt', 'import_name',
66 'import_from', 'param', 'del_stmt', 'namedexpr_test',
67])
68_IMPORTS = set(['import_name', 'import_from'])
69
70
71class DocstringMixin:
72 __slots__ = ()
73
74 def get_doc_node(self):
75 """
76 Returns the string leaf of a docstring. e.g. ``r'''foo'''``.
77 """
78 if self.type == 'file_input':
79 node = self.children[0]
80 elif self.type in ('funcdef', 'classdef'):
81 node = self.children[self.children.index(':') + 1]
82 if node.type == 'suite': # Normally a suite
83 node = node.children[1] # -> NEWLINE stmt
84 else: # ExprStmt
85 simple_stmt = self.parent
86 c = simple_stmt.parent.children
87 index = c.index(simple_stmt)
88 if not index:
89 return None
90 node = c[index - 1]
91
92 if node.type == 'simple_stmt':
93 node = node.children[0]
94 if node.type == 'string':
95 return node
96 return None
97
98
99class PythonMixin:
100 """
101 Some Python specific utilities.
102 """
103 __slots__ = ()
104
105 def get_name_of_position(self, position):
106 """
107 Given a (line, column) tuple, returns a :py:class:`Name` or ``None`` if
108 there is no name at that position.
109 """
110 for c in self.children:
111 if isinstance(c, Leaf):
112 if c.type == 'name' and c.start_pos <= position <= c.end_pos:
113 return c
114 else:
115 result = c.get_name_of_position(position)
116 if result is not None:
117 return result
118 return None
119
120
121class PythonLeaf(PythonMixin, Leaf):
122 __slots__ = ()
123
124 def _split_prefix(self):
125 return split_prefix(self, self.get_start_pos_of_prefix())
126
127 def get_start_pos_of_prefix(self):
128 """
129 Basically calls :py:meth:`parso.tree.NodeOrLeaf.get_start_pos_of_prefix`.
130 """
131 # TODO it is really ugly that we have to override it. Maybe change
132 # indent error leafs somehow? No idea how, though.
133 previous_leaf = self.get_previous_leaf()
134 if previous_leaf is not None and previous_leaf.type == 'error_leaf' \
135 and previous_leaf.token_type in ('INDENT', 'DEDENT', 'ERROR_DEDENT'):
136 previous_leaf = previous_leaf.get_previous_leaf()
137
138 if previous_leaf is None: # It's the first leaf.
139 lines = split_lines(self.prefix)
140 # + 1 is needed because split_lines always returns at least [''].
141 return self.line - len(lines) + 1, 0 # It's the first leaf.
142 return previous_leaf.end_pos
143
144
145class _LeafWithoutNewlines(PythonLeaf):
146 """
147 Simply here to optimize performance.
148 """
149 __slots__ = ()
150
151 @property
152 def end_pos(self) -> Tuple[int, int]:
153 return self.line, self.column + len(self.value)
154
155
156# Python base classes
157class PythonBaseNode(PythonMixin, BaseNode):
158 __slots__ = ()
159
160
161class PythonNode(PythonMixin, Node):
162 __slots__ = ()
163
164
165class PythonErrorNode(PythonMixin, ErrorNode):
166 __slots__ = ()
167
168
169class PythonErrorLeaf(ErrorLeaf, PythonLeaf):
170 __slots__ = ()
171
172
173class EndMarker(_LeafWithoutNewlines):
174 __slots__ = ()
175 type = 'endmarker'
176
177 def __repr__(self):
178 return "<%s: prefix=%s end_pos=%s>" % (
179 type(self).__name__, repr(self.prefix), self.end_pos
180 )
181
182
183class Newline(PythonLeaf):
184 """Contains NEWLINE and ENDMARKER tokens."""
185 __slots__ = ()
186 type = 'newline'
187
188 def __repr__(self):
189 return "<%s: %s>" % (type(self).__name__, repr(self.value))
190
191
192class Name(_LeafWithoutNewlines):
193 """
194 A string. Sometimes it is important to know if the string belongs to a name
195 or not.
196 """
197 type = 'name'
198 __slots__ = ()
199
200 def __repr__(self):
201 return "<%s: %s@%s,%s>" % (type(self).__name__, self.value,
202 self.line, self.column)
203
204 def is_definition(self, include_setitem=False):
205 """
206 Returns True if the name is being defined.
207 """
208 return self.get_definition(include_setitem=include_setitem) is not None
209
210 def get_definition(self, import_name_always=False, include_setitem=False):
211 """
212 Returns None if there's no definition for a name.
213
214 :param import_name_always: Specifies if an import name is always a
215 definition. Normally foo in `from foo import bar` is not a
216 definition.
217 """
218 node = self.parent
219 type_ = node.type
220
221 if type_ in ('funcdef', 'classdef'):
222 if self == node.name:
223 return node
224 return None
225
226 if type_ == 'except_clause':
227 if self.get_previous_sibling() == 'as':
228 return node.parent # The try_stmt.
229 return None
230
231 while node is not None:
232 if node.type == 'suite':
233 return None
234 if node.type in _GET_DEFINITION_TYPES:
235 if self in node.get_defined_names(include_setitem):
236 return node
237 if import_name_always and node.type in _IMPORTS:
238 return node
239 return None
240 node = node.parent
241 return None
242
243
244class Literal(PythonLeaf):
245 __slots__ = ()
246
247
248class Number(Literal):
249 type = 'number'
250 __slots__ = ()
251
252
253class String(Literal):
254 type = 'string'
255 __slots__ = ()
256
257 @property
258 def string_prefix(self):
259 return re.match(r'\w*(?=[\'"])', self.value).group(0)
260
261 def _get_payload(self):
262 match = re.search(
263 r'''('{3}|"{3}|'|")(.*)$''',
264 self.value,
265 flags=re.DOTALL
266 )
267 return match.group(2)[:-len(match.group(1))]
268
269
270class FStringString(PythonLeaf):
271 """
272 f-strings contain f-string expressions and normal python strings. These are
273 the string parts of f-strings.
274 """
275 type = 'fstring_string'
276 __slots__ = ()
277
278
279class FStringStart(PythonLeaf):
280 """
281 f-strings contain f-string expressions and normal python strings. These are
282 the string parts of f-strings.
283 """
284 type = 'fstring_start'
285 __slots__ = ()
286
287
288class FStringEnd(PythonLeaf):
289 """
290 f-strings contain f-string expressions and normal python strings. These are
291 the string parts of f-strings.
292 """
293 type = 'fstring_end'
294 __slots__ = ()
295
296
297class _StringComparisonMixin:
298 def __eq__(self, other):
299 """
300 Make comparisons with strings easy.
301 Improves the readability of the parser.
302 """
303 if isinstance(other, str):
304 return self.value == other
305
306 return self is other
307
308 def __hash__(self):
309 return hash(self.value)
310
311
312class Operator(_LeafWithoutNewlines, _StringComparisonMixin):
313 type = 'operator'
314 __slots__ = ()
315
316
317class Keyword(_LeafWithoutNewlines, _StringComparisonMixin):
318 type = 'keyword'
319 __slots__ = ()
320
321
322class Scope(PythonBaseNode, DocstringMixin):
323 """
324 Super class for the parser tree, which represents the state of a python
325 text file.
326 A Scope is either a function, class or lambda.
327 """
328 __slots__ = ()
329
330 def __init__(self, children):
331 super().__init__(children)
332
333 def iter_funcdefs(self):
334 """
335 Returns a generator of `funcdef` nodes.
336 """
337 return self._search_in_scope('funcdef')
338
339 def iter_classdefs(self):
340 """
341 Returns a generator of `classdef` nodes.
342 """
343 return self._search_in_scope('classdef')
344
345 def iter_imports(self):
346 """
347 Returns a generator of `import_name` and `import_from` nodes.
348 """
349 return self._search_in_scope('import_name', 'import_from')
350
351 def _search_in_scope(self, *names):
352 def scan(children):
353 for element in children:
354 if element.type in names:
355 yield element
356 if element.type in _FUNC_CONTAINERS:
357 yield from scan(element.children)
358
359 return scan(self.children)
360
361 def get_suite(self):
362 """
363 Returns the part that is executed by the function.
364 """
365 return self.children[-1]
366
367 def __repr__(self):
368 try:
369 name = self.name.value
370 except AttributeError:
371 name = ''
372
373 return "<%s: %s@%s-%s>" % (type(self).__name__, name,
374 self.start_pos[0], self.end_pos[0])
375
376
377class Module(Scope):
378 """
379 The top scope, which is always a module.
380 Depending on the underlying parser this may be a full module or just a part
381 of a module.
382 """
383 __slots__ = ('_used_names',)
384 type = 'file_input'
385
386 def __init__(self, children):
387 super().__init__(children)
388 self._used_names = None
389
390 def _iter_future_import_names(self):
391 """
392 :return: A list of future import names.
393 :rtype: list of str
394 """
395 # In Python it's not allowed to use future imports after the first
396 # actual (non-future) statement. However this is not a linter here,
397 # just return all future imports. If people want to scan for issues
398 # they should use the API.
399 for imp in self.iter_imports():
400 if imp.type == 'import_from' and imp.level == 0:
401 for path in imp.get_paths():
402 names = [name.value for name in path]
403 if len(names) == 2 and names[0] == '__future__':
404 yield names[1]
405
406 def get_used_names(self):
407 """
408 Returns all the :class:`Name` leafs that exist in this module. This
409 includes both definitions and references of names.
410 """
411 if self._used_names is None:
412 # Don't directly use self._used_names to eliminate a lookup.
413 dct = {}
414
415 def recurse(node):
416 try:
417 children = node.children
418 except AttributeError:
419 if node.type == 'name':
420 arr = dct.setdefault(node.value, [])
421 arr.append(node)
422 else:
423 for child in children:
424 recurse(child)
425
426 recurse(self)
427 self._used_names = UsedNamesMapping(dct)
428 return self._used_names
429
430
431class Decorator(PythonBaseNode):
432 type = 'decorator'
433 __slots__ = ()
434
435
436class ClassOrFunc(Scope):
437 __slots__ = ()
438
439 @property
440 def name(self):
441 """
442 Returns the `Name` leaf that defines the function or class name.
443 """
444 return self.children[1]
445
446 def get_decorators(self):
447 """
448 :rtype: list of :class:`Decorator`
449 """
450 decorated = self.parent
451 if decorated.type == 'async_funcdef':
452 decorated = decorated.parent
453
454 if decorated.type == 'decorated':
455 if decorated.children[0].type == 'decorators':
456 return decorated.children[0].children
457 else:
458 return decorated.children[:1]
459 else:
460 return []
461
462
463class Class(ClassOrFunc):
464 """
465 Used to store the parsed contents of a python class.
466 """
467 type = 'classdef'
468 __slots__ = ()
469
470 def __init__(self, children):
471 super().__init__(children)
472
473 def get_super_arglist(self):
474 """
475 Returns the `arglist` node that defines the super classes. It returns
476 None if there are no arguments.
477 """
478 if self.children[2] != '(': # Has no parentheses
479 return None
480 else:
481 if self.children[3] == ')': # Empty parentheses
482 return None
483 else:
484 return self.children[3]
485
486
487def _create_params(parent, argslist_list):
488 """
489 `argslist_list` is a list that can contain an argslist as a first item, but
490 most not. It's basically the items between the parameter brackets (which is
491 at most one item).
492 This function modifies the parser structure. It generates `Param` objects
493 from the normal ast. Those param objects do not exist in a normal ast, but
494 make the evaluation of the ast tree so much easier.
495 You could also say that this function replaces the argslist node with a
496 list of Param objects.
497 """
498 try:
499 first = argslist_list[0]
500 except IndexError:
501 return []
502
503 if first.type in ('name', 'fpdef'):
504 return [Param([first], parent)]
505 elif first == '*':
506 return [first]
507 else: # argslist is a `typedargslist` or a `varargslist`.
508 if first.type == 'tfpdef':
509 children = [first]
510 else:
511 children = first.children
512 new_children = []
513 start = 0
514 # Start with offset 1, because the end is higher.
515 for end, child in enumerate(children + [None], 1):
516 if child is None or child == ',':
517 param_children = children[start:end]
518 if param_children: # Could as well be comma and then end.
519 if param_children[0] == '*' \
520 and (len(param_children) == 1
521 or param_children[1] == ',') \
522 or param_children[0] == '/':
523 for p in param_children:
524 p.parent = parent
525 new_children += param_children
526 else:
527 new_children.append(Param(param_children, parent))
528 start = end
529 return new_children
530
531
532class Function(ClassOrFunc):
533 """
534 Used to store the parsed contents of a python function.
535
536 Children::
537
538 0. <Keyword: def>
539 1. <Name>
540 2. parameter list (including open-paren and close-paren <Operator>s)
541 3. or 5. <Operator: :>
542 4. or 6. Node() representing function body
543 3. -> (if annotation is also present)
544 4. annotation (if present)
545 """
546 type = 'funcdef'
547
548 def __init__(self, children):
549 super().__init__(children)
550 parameters = self.children[2] # After `def foo`
551 parameters_children = parameters.children[1:-1]
552 # If input parameters list already has Param objects, keep it as is;
553 # otherwise, convert it to a list of Param objects.
554 if not any(isinstance(child, Param) for child in parameters_children):
555 parameters.children[1:-1] = _create_params(parameters, parameters_children)
556
557 def _get_param_nodes(self):
558 return self.children[2].children
559
560 def get_params(self):
561 """
562 Returns a list of `Param()`.
563 """
564 return [p for p in self._get_param_nodes() if p.type == 'param']
565
566 @property
567 def name(self):
568 return self.children[1] # First token after `def`
569
570 def iter_yield_exprs(self):
571 """
572 Returns a generator of `yield_expr`.
573 """
574 def scan(children):
575 for element in children:
576 if element.type in ('classdef', 'funcdef', 'lambdef'):
577 continue
578
579 try:
580 nested_children = element.children
581 except AttributeError:
582 if element.value == 'yield':
583 if element.parent.type == 'yield_expr':
584 yield element.parent
585 else:
586 yield element
587 else:
588 yield from scan(nested_children)
589
590 return scan(self.children)
591
592 def iter_return_stmts(self):
593 """
594 Returns a generator of `return_stmt`.
595 """
596 def scan(children):
597 for element in children:
598 if element.type == 'return_stmt' \
599 or element.type == 'keyword' and element.value == 'return':
600 yield element
601 if element.type in _RETURN_STMT_CONTAINERS:
602 yield from scan(element.children)
603
604 return scan(self.children)
605
606 def iter_raise_stmts(self):
607 """
608 Returns a generator of `raise_stmt`. Includes raise statements inside try-except blocks
609 """
610 def scan(children):
611 for element in children:
612 if element.type == 'raise_stmt' \
613 or element.type == 'keyword' and element.value == 'raise':
614 yield element
615 if element.type in _RETURN_STMT_CONTAINERS:
616 yield from scan(element.children)
617
618 return scan(self.children)
619
620 def is_generator(self):
621 """
622 :return bool: Checks if a function is a generator or not.
623 """
624 return next(self.iter_yield_exprs(), None) is not None
625
626 @property
627 def annotation(self):
628 """
629 Returns the test node after `->` or `None` if there is no annotation.
630 """
631 try:
632 if self.children[3] == "->":
633 return self.children[4]
634 assert self.children[3] == ":"
635 return None
636 except IndexError:
637 return None
638
639
640class Lambda(Function):
641 """
642 Lambdas are basically trimmed functions, so give it the same interface.
643
644 Children::
645
646 0. <Keyword: lambda>
647 *. <Param x> for each argument x
648 -2. <Operator: :>
649 -1. Node() representing body
650 """
651 type = 'lambdef'
652 __slots__ = ()
653
654 def __init__(self, children):
655 # We don't want to call the Function constructor, call its parent.
656 super(Function, self).__init__(children)
657 # Everything between `lambda` and the `:` operator is a parameter.
658 parameters_children = self.children[1:-2]
659 # If input children list already has Param objects, keep it as is;
660 # otherwise, convert it to a list of Param objects.
661 if not any(isinstance(child, Param) for child in parameters_children):
662 self.children[1:-2] = _create_params(self, parameters_children)
663
664 @property
665 def name(self):
666 """
667 Raises an AttributeError. Lambdas don't have a defined name.
668 """
669 raise AttributeError("lambda is not named.")
670
671 def _get_param_nodes(self):
672 return self.children[1:-2]
673
674 @property
675 def annotation(self):
676 """
677 Returns `None`, lambdas don't have annotations.
678 """
679 return None
680
681 def __repr__(self):
682 return "<%s@%s>" % (self.__class__.__name__, self.start_pos)
683
684
685class Flow(PythonBaseNode):
686 __slots__ = ()
687
688
689class IfStmt(Flow):
690 type = 'if_stmt'
691 __slots__ = ()
692
693 def get_test_nodes(self):
694 """
695 E.g. returns all the `test` nodes that are named as x, below:
696
697 if x:
698 pass
699 elif x:
700 pass
701 """
702 for i, c in enumerate(self.children):
703 if c in ('elif', 'if'):
704 yield self.children[i + 1]
705
706 def get_corresponding_test_node(self, node):
707 """
708 Searches for the branch in which the node is and returns the
709 corresponding test node (see function above). However if the node is in
710 the test node itself and not in the suite return None.
711 """
712 start_pos = node.start_pos
713 for check_node in reversed(list(self.get_test_nodes())):
714 if check_node.start_pos < start_pos:
715 if start_pos < check_node.end_pos:
716 return None
717 # In this case the node is within the check_node itself,
718 # not in the suite
719 else:
720 return check_node
721
722 def is_node_after_else(self, node):
723 """
724 Checks if a node is defined after `else`.
725 """
726 for c in self.children:
727 if c == 'else':
728 if node.start_pos > c.start_pos:
729 return True
730 else:
731 return False
732
733
734class WhileStmt(Flow):
735 type = 'while_stmt'
736 __slots__ = ()
737
738
739class ForStmt(Flow):
740 type = 'for_stmt'
741 __slots__ = ()
742
743 def get_testlist(self):
744 """
745 Returns the input node ``y`` from: ``for x in y:``.
746 """
747 return self.children[3]
748
749 def get_defined_names(self, include_setitem=False):
750 return _defined_names(self.children[1], include_setitem)
751
752
753class TryStmt(Flow):
754 type = 'try_stmt'
755 __slots__ = ()
756
757 def get_except_clause_tests(self):
758 """
759 Returns the ``test`` nodes found in ``except_clause`` nodes.
760 Returns ``[None]`` for except clauses without an exception given.
761 """
762 for node in self.children:
763 if node.type == 'except_clause':
764 yield node.children[1]
765 elif node == 'except':
766 yield None
767
768
769class WithStmt(Flow):
770 type = 'with_stmt'
771 __slots__ = ()
772
773 def get_defined_names(self, include_setitem=False):
774 """
775 Returns the a list of `Name` that the with statement defines. The
776 defined names are set after `as`.
777 """
778 names = []
779 for with_item in self.children[1:-2:2]:
780 # Check with items for 'as' names.
781 if with_item.type == 'with_item':
782 names += _defined_names(with_item.children[2], include_setitem)
783 return names
784
785 def get_test_node_from_name(self, name):
786 node = name.search_ancestor("with_item")
787 if node is None:
788 raise ValueError('The name is not actually part of a with statement.')
789 return node.children[0]
790
791
792class Import(PythonBaseNode):
793 __slots__ = ()
794
795 def get_path_for_name(self, name):
796 """
797 The path is the list of names that leads to the searched name.
798
799 :return list of Name:
800 """
801 try:
802 # The name may be an alias. If it is, just map it back to the name.
803 name = self._aliases()[name]
804 except KeyError:
805 pass
806
807 for path in self.get_paths():
808 if name in path:
809 return path[:path.index(name) + 1]
810 raise ValueError('Name should be defined in the import itself')
811
812 def is_nested(self):
813 return False # By default, sub classes may overwrite this behavior
814
815 def is_star_import(self):
816 return self.children[-1] == '*'
817
818
819class ImportFrom(Import):
820 type = 'import_from'
821 __slots__ = ()
822
823 def get_defined_names(self, include_setitem=False):
824 """
825 Returns the a list of `Name` that the import defines. The
826 defined names are set after `import` or in case an alias - `as` - is
827 present that name is returned.
828 """
829 return [alias or name for name, alias in self._as_name_tuples()]
830
831 def _aliases(self):
832 """Mapping from alias to its corresponding name."""
833 return dict((alias, name) for name, alias in self._as_name_tuples()
834 if alias is not None)
835
836 def get_from_names(self):
837 for n in self.children[1:]:
838 if n not in ('.', '...'):
839 break
840 if n.type == 'dotted_name': # from x.y import
841 return n.children[::2]
842 elif n == 'import': # from . import
843 return []
844 else: # from x import
845 return [n]
846
847 @property
848 def level(self):
849 """The level parameter of ``__import__``."""
850 level = 0
851 for n in self.children[1:]:
852 if n in ('.', '...'):
853 level += len(n.value)
854 else:
855 break
856 return level
857
858 def _as_name_tuples(self):
859 last = self.children[-1]
860 if last == ')':
861 last = self.children[-2]
862 elif last == '*':
863 return # No names defined directly.
864
865 if last.type == 'import_as_names':
866 as_names = last.children[::2]
867 else:
868 as_names = [last]
869 for as_name in as_names:
870 if as_name.type == 'name':
871 yield as_name, None
872 else:
873 yield as_name.children[::2] # yields x, y -> ``x as y``
874
875 def get_paths(self):
876 """
877 The import paths defined in an import statement. Typically an array
878 like this: ``[<Name: datetime>, <Name: date>]``.
879
880 :return list of list of Name:
881 """
882 dotted = self.get_from_names()
883
884 if self.children[-1] == '*':
885 return [dotted]
886 return [dotted + [name] for name, alias in self._as_name_tuples()]
887
888
889class ImportName(Import):
890 """For ``import_name`` nodes. Covers normal imports without ``from``."""
891 type = 'import_name'
892 __slots__ = ()
893
894 def get_defined_names(self, include_setitem=False):
895 """
896 Returns the a list of `Name` that the import defines. The defined names
897 is always the first name after `import` or in case an alias - `as` - is
898 present that name is returned.
899 """
900 return [alias or path[0] for path, alias in self._dotted_as_names()]
901
902 @property
903 def level(self):
904 """The level parameter of ``__import__``."""
905 return 0 # Obviously 0 for imports without from.
906
907 def get_paths(self):
908 return [path for path, alias in self._dotted_as_names()]
909
910 def _dotted_as_names(self):
911 """Generator of (list(path), alias) where alias may be None."""
912 dotted_as_names = self.children[1]
913 if dotted_as_names.type == 'dotted_as_names':
914 as_names = dotted_as_names.children[::2]
915 else:
916 as_names = [dotted_as_names]
917
918 for as_name in as_names:
919 if as_name.type == 'dotted_as_name':
920 alias = as_name.children[2]
921 as_name = as_name.children[0]
922 else:
923 alias = None
924 if as_name.type == 'name':
925 yield [as_name], alias
926 else:
927 # dotted_names
928 yield as_name.children[::2], alias
929
930 def is_nested(self):
931 """
932 This checks for the special case of nested imports, without aliases and
933 from statement::
934
935 import foo.bar
936 """
937 return bool([1 for path, alias in self._dotted_as_names()
938 if alias is None and len(path) > 1])
939
940 def _aliases(self):
941 """
942 :return list of Name: Returns all the alias
943 """
944 return dict((alias, path[-1]) for path, alias in self._dotted_as_names()
945 if alias is not None)
946
947
948class KeywordStatement(PythonBaseNode):
949 """
950 For the following statements: `assert`, `del`, `global`, `nonlocal`,
951 `raise`, `return`, `yield`.
952
953 `pass`, `continue` and `break` are not in there, because they are just
954 simple keywords and the parser reduces it to a keyword.
955 """
956 __slots__ = ()
957
958 @property
959 def type(self):
960 """
961 Keyword statements start with the keyword and end with `_stmt`. You can
962 crosscheck this with the Python grammar.
963 """
964 return '%s_stmt' % self.keyword
965
966 @property
967 def keyword(self):
968 return self.children[0].value
969
970 def get_defined_names(self, include_setitem=False):
971 keyword = self.keyword
972 if keyword == 'del':
973 return _defined_names(self.children[1], include_setitem)
974 if keyword in ('global', 'nonlocal'):
975 return self.children[1::2]
976 return []
977
978
979class AssertStmt(KeywordStatement):
980 __slots__ = ()
981
982 @property
983 def assertion(self):
984 return self.children[1]
985
986
987class GlobalStmt(KeywordStatement):
988 __slots__ = ()
989
990 def get_global_names(self):
991 return self.children[1::2]
992
993
994class ReturnStmt(KeywordStatement):
995 __slots__ = ()
996
997
998class YieldExpr(PythonBaseNode):
999 type = 'yield_expr'
1000 __slots__ = ()
1001
1002
1003def _defined_names(current, include_setitem):
1004 """
1005 A helper function to find the defined names in statements, for loops and
1006 list comprehensions.
1007 """
1008 names = []
1009 if current.type in ('testlist_star_expr', 'testlist_comp', 'exprlist', 'testlist'):
1010 for child in current.children[::2]:
1011 names += _defined_names(child, include_setitem)
1012 elif current.type in ('atom', 'star_expr'):
1013 names += _defined_names(current.children[1], include_setitem)
1014 elif current.type in ('power', 'atom_expr'):
1015 if current.children[-2] != '**': # Just if there's no operation
1016 trailer = current.children[-1]
1017 if trailer.children[0] == '.':
1018 names.append(trailer.children[1])
1019 elif trailer.children[0] == '[' and include_setitem:
1020 for node in current.children[-2::-1]:
1021 if node.type == 'trailer':
1022 names.append(node.children[1])
1023 break
1024 if node.type == 'name':
1025 names.append(node)
1026 break
1027 else:
1028 names.append(current)
1029 return names
1030
1031
1032class ExprStmt(PythonBaseNode, DocstringMixin):
1033 type = 'expr_stmt'
1034 __slots__ = ()
1035
1036 def get_defined_names(self, include_setitem=False):
1037 """
1038 Returns a list of `Name` defined before the `=` sign.
1039 """
1040 names = []
1041 if self.children[1].type == 'annassign':
1042 names = _defined_names(self.children[0], include_setitem)
1043 return [
1044 name
1045 for i in range(0, len(self.children) - 2, 2)
1046 if '=' in self.children[i + 1].value
1047 for name in _defined_names(self.children[i], include_setitem)
1048 ] + names
1049
1050 def get_rhs(self):
1051 """Returns the right-hand-side of the equals."""
1052 node = self.children[-1]
1053 if node.type == 'annassign':
1054 if len(node.children) == 4:
1055 node = node.children[3]
1056 else:
1057 node = node.children[1]
1058 return node
1059
1060 def yield_operators(self):
1061 """
1062 Returns a generator of `+=`, `=`, etc. or None if there is no operation.
1063 """
1064 first = self.children[1]
1065 if first.type == 'annassign':
1066 if len(first.children) <= 2:
1067 return # No operator is available, it's just PEP 484.
1068
1069 first = first.children[2]
1070 yield first
1071
1072 yield from self.children[3::2]
1073
1074
1075class NamedExpr(PythonBaseNode):
1076 type = 'namedexpr_test'
1077
1078 def get_defined_names(self, include_setitem=False):
1079 return _defined_names(self.children[0], include_setitem)
1080
1081
1082class Param(PythonBaseNode):
1083 """
1084 It's a helper class that makes business logic with params much easier. The
1085 Python grammar defines no ``param`` node. It defines it in a different way
1086 that is not really suited to working with parameters.
1087 """
1088 type = 'param'
1089
1090 def __init__(self, children, parent=None):
1091 super().__init__(children)
1092 self.parent = parent
1093
1094 @property
1095 def star_count(self):
1096 """
1097 Is `0` in case of `foo`, `1` in case of `*foo` or `2` in case of
1098 `**foo`.
1099 """
1100 first = self.children[0]
1101 if first in ('*', '**'):
1102 return len(first.value)
1103 return 0
1104
1105 @property
1106 def default(self):
1107 """
1108 The default is the test node that appears after the `=`. Is `None` in
1109 case no default is present.
1110 """
1111 has_comma = self.children[-1] == ','
1112 try:
1113 if self.children[-2 - int(has_comma)] == '=':
1114 return self.children[-1 - int(has_comma)]
1115 except IndexError:
1116 return None
1117
1118 @property
1119 def annotation(self):
1120 """
1121 The default is the test node that appears after `:`. Is `None` in case
1122 no annotation is present.
1123 """
1124 tfpdef = self._tfpdef()
1125 if tfpdef.type == 'tfpdef':
1126 assert tfpdef.children[1] == ":"
1127 assert len(tfpdef.children) == 3
1128 annotation = tfpdef.children[2]
1129 return annotation
1130 else:
1131 return None
1132
1133 def _tfpdef(self):
1134 """
1135 tfpdef: see e.g. grammar36.txt.
1136 """
1137 offset = int(self.children[0] in ('*', '**'))
1138 return self.children[offset]
1139
1140 @property
1141 def name(self):
1142 """
1143 The `Name` leaf of the param.
1144 """
1145 if self._tfpdef().type == 'tfpdef':
1146 return self._tfpdef().children[0]
1147 else:
1148 return self._tfpdef()
1149
1150 def get_defined_names(self, include_setitem=False):
1151 return [self.name]
1152
1153 @property
1154 def position_index(self):
1155 """
1156 Property for the positional index of a paramter.
1157 """
1158 index = self.parent.children.index(self)
1159 try:
1160 keyword_only_index = self.parent.children.index('*')
1161 if index > keyword_only_index:
1162 # Skip the ` *, `
1163 index -= 2
1164 except ValueError:
1165 pass
1166 try:
1167 keyword_only_index = self.parent.children.index('/')
1168 if index > keyword_only_index:
1169 # Skip the ` /, `
1170 index -= 2
1171 except ValueError:
1172 pass
1173 return index - 1
1174
1175 def get_parent_function(self):
1176 """
1177 Returns the function/lambda of a parameter.
1178 """
1179 return self.search_ancestor('funcdef', 'lambdef')
1180
1181 def get_code(self, include_prefix=True, include_comma=True):
1182 """
1183 Like all the other get_code functions, but includes the param
1184 `include_comma`.
1185
1186 :param include_comma bool: If enabled includes the comma in the string output.
1187 """
1188 if include_comma:
1189 return super().get_code(include_prefix)
1190
1191 children = self.children
1192 if children[-1] == ',':
1193 children = children[:-1]
1194 return self._get_code_for_children(
1195 children,
1196 include_prefix=include_prefix
1197 )
1198
1199 def __repr__(self):
1200 default = '' if self.default is None else '=%s' % self.default.get_code()
1201 return '<%s: %s>' % (type(self).__name__, str(self._tfpdef()) + default)
1202
1203
1204class SyncCompFor(PythonBaseNode):
1205 type = 'sync_comp_for'
1206 __slots__ = ()
1207
1208 def get_defined_names(self, include_setitem=False):
1209 """
1210 Returns the a list of `Name` that the comprehension defines.
1211 """
1212 # allow async for
1213 return _defined_names(self.children[1], include_setitem)
1214
1215
1216# This is simply here so an older Jedi version can work with this new parso
1217# version. Can be deleted in the next release.
1218CompFor = SyncCompFor
1219
1220
1221class UsedNamesMapping(Mapping):
1222 """
1223 This class exists for the sole purpose of creating an immutable dict.
1224 """
1225 def __init__(self, dct):
1226 self._dict = dct
1227
1228 def __getitem__(self, key):
1229 return self._dict[key]
1230
1231 def __len__(self):
1232 return len(self._dict)
1233
1234 def __iter__(self):
1235 return iter(self._dict)
1236
1237 def __hash__(self):
1238 return id(self)
1239
1240 def __eq__(self, other):
1241 # Comparing these dicts does not make sense.
1242 return self is other