1 from abc
import abstractmethod
2 from inspect
import Parameter
3 from typing
import Optional
, Tuple
5 from parso
.tree
import search_ancestor
7 from jedi
.parser_utils
import find_statement_documentation
, clean_scope_docstring
8 from jedi
.inference
.utils
import unite
9 from jedi
.inference
.base_value
import ValueSet
, NO_VALUES
10 from jedi
.inference
.cache
import inference_state_method_cache
11 from jedi
.inference
import docstrings
12 from jedi
.cache
import memoize_method
13 from jedi
.inference
.helpers
import deep_ast_copy
, infer_call_of_leaf
14 from jedi
.plugins
import plugin_manager
17 def _merge_name_docs(names
):
21 # In case we have multiple values, just return all of them
22 # separated by a few dashes.
23 doc
+= '\n' + '-' * 30 + '\n'
24 doc
+= name
.py__doc__()
28 class AbstractNameDefinition
:
29 start_pos
: Optional
[Tuple
[int, int]] = None
35 Used for the Jedi API to know if it's a keyword or an actual name.
40 raise NotImplementedError
44 # Typically names are already definitions and therefore a goto on that
45 # name will always result on itself.
48 def get_qualified_names(self
, include_module_names
=False):
49 qualified_names
= self
._get
_qualified
_names
()
50 if qualified_names
is None or not include_module_names
:
51 return qualified_names
53 module_names
= self
.get_root_context().string_names
54 if module_names
is None:
56 return module_names
+ qualified_names
58 def _get_qualified_names(self
):
59 # By default, a name has no qualified names.
62 def get_root_context(self
):
63 return self
.parent_context
.get_root_context()
65 def get_public_name(self
):
66 return self
.string_name
69 if self
.start_pos
is None:
70 return '<%s: string_name=%s>' % (self
.__class
__.__name
__, self
.string_name
)
71 return '<%s: string_name=%s start_pos=%s>' % (self
.__class
__.__name
__,
72 self
.string_name
, self
.start_pos
)
82 return self
.parent_context
.api_type
84 def get_defining_qualified_value(self
):
86 Returns either None or the value that is public and qualified. Won't
87 return a function, because a name in a function is never public.
92 class AbstractArbitraryName(AbstractNameDefinition
):
94 When you e.g. want to complete dicts keys, you probably want to complete
95 string literals, which is not really a name, but for Jedi we use this
96 concept of Name for completions as well.
100 def __init__(self
, inference_state
, string
):
101 self
.inference_state
= inference_state
102 self
.string_name
= string
103 self
.parent_context
= inference_state
.builtins_module
109 class AbstractTreeName(AbstractNameDefinition
):
110 def __init__(self
, parent_context
, tree_name
):
111 self
.parent_context
= parent_context
112 self
.tree_name
= tree_name
114 def get_qualified_names(self
, include_module_names
=False):
115 import_node
= search_ancestor(self
.tree_name
, 'import_name', 'import_from')
116 # For import nodes we cannot just have names, because it's very unclear
117 # how they would look like. For now we just ignore them in most cases.
118 # In case of level == 1, it works always, because it's like a submodule
120 if import_node
is not None and not (import_node
.level
== 1
121 and self
.get_root_context().get_value().is_package()):
122 # TODO improve the situation for when level is present.
123 if include_module_names
and not import_node
.level
:
124 return tuple(n
.value
for n
in import_node
.get_path_for_name(self
.tree_name
))
128 return super().get_qualified_names(include_module_names
)
130 def _get_qualified_names(self
):
131 parent_names
= self
.parent_context
.get_qualified_names()
132 if parent_names
is None:
134 return parent_names
+ (self
.tree_name
.value
,)
136 def get_defining_qualified_value(self
):
138 raise NotImplementedError("Shouldn't really happen, please report")
139 elif self
.parent_context
:
140 return self
.parent_context
.get_value() # Might be None
144 context
= self
.parent_context
145 name
= self
.tree_name
146 definition
= name
.get_definition(import_name_always
=True)
147 if definition
is not None:
148 type_
= definition
.type
149 if type_
== 'expr_stmt':
150 # Only take the parent, because if it's more complicated than just
151 # a name it's something you can "goto" again.
152 is_simple_name
= name
.parent
.type not in ('power', 'trailer')
155 elif type_
in ('import_from', 'import_name'):
156 from jedi
.inference
.imports
import goto_import
157 module_names
= goto_import(context
, name
)
162 from jedi
.inference
.imports
import follow_error_node_imports_if_possible
163 values
= follow_error_node_imports_if_possible(context
, name
)
164 if values
is not None:
165 return [value
.name
for value
in values
]
169 if node_type
== 'argument' and par
.children
[1] == '=' and par
.children
[0] == name
:
172 if trailer
.type == 'arglist':
173 trailer
= trailer
.parent
174 if trailer
.type != 'classdef':
175 if trailer
.type == 'decorator':
176 value_set
= context
.infer_node(trailer
.children
[1])
178 i
= trailer
.parent
.children
.index(trailer
)
179 to_infer
= trailer
.parent
.children
[:i
]
180 if to_infer
[0] == 'await':
182 value_set
= context
.infer_node(to_infer
[0])
183 from jedi
.inference
.syntax_tree
import infer_trailer
184 for trailer
in to_infer
[1:]:
185 value_set
= infer_trailer(context
, value_set
, trailer
)
187 for value
in value_set
:
188 for signature
in value
.get_signatures():
189 for param_name
in signature
.get_param_names():
190 if param_name
.string_name
== name
.value
:
191 param_names
.append(param_name
)
193 elif node_type
== 'dotted_name': # Is a decorator.
194 index
= par
.children
.index(name
)
196 new_dotted
= deep_ast_copy(par
)
197 new_dotted
.children
[index
- 1:] = []
198 values
= context
.infer_node(new_dotted
)
200 value
.goto(name
, name_context
=context
)
204 if node_type
== 'trailer' and par
.children
[0] == '.':
205 values
= infer_call_of_leaf(context
, name
, cut_own_trailer
=True)
206 return values
.goto(name
, name_context
=context
)
208 stmt
= search_ancestor(
209 name
, 'expr_stmt', 'lambdef'
211 if stmt
.type == 'lambdef':
213 return context
.goto(name
, position
=stmt
.start_pos
)
216 imp
= search_ancestor(self
.tree_name
, 'import_from', 'import_name')
217 return imp
is not None
220 def string_name(self
):
221 return self
.tree_name
.value
225 return self
.tree_name
.start_pos
228 class ValueNameMixin
:
230 return ValueSet([self
._value
])
233 doc
= self
._value
.py__doc__()
234 if not doc
and self
._value
.is_stub():
235 from jedi
.inference
.gradual
.conversion
import convert_names
236 names
= convert_names([self
], prefer_stub_to_compiled
=False)
237 if self
not in names
:
238 return _merge_name_docs(names
)
241 def _get_qualified_names(self
):
242 return self
._value
.get_qualified_names()
244 def get_root_context(self
):
245 if self
.parent_context
is None: # A module
246 return self
._value
.as_context()
247 return super().get_root_context()
249 def get_defining_qualified_value(self
):
250 context
= self
.parent_context
251 if context
is not None and (context
.is_module() or context
.is_class()):
252 return self
.parent_context
.get_value() # Might be None
257 return self
._value
.api_type
260 class ValueName(ValueNameMixin
, AbstractTreeName
):
261 def __init__(self
, value
, tree_name
):
262 super().__init
__(value
.parent_context
, tree_name
)
266 return ValueSet([self
._value
.name
])
269 class TreeNameDefinition(AbstractTreeName
):
271 import_name
='module',
272 import_from
='module',
279 # Refactor this, should probably be here.
280 from jedi
.inference
.syntax_tree
import tree_name_to_values
281 return tree_name_to_values(
282 self
.parent_context
.inference_state
,
289 definition
= self
.tree_name
.get_definition(import_name_always
=True)
290 if definition
is None:
292 return self
._API
_TYPES
.get(definition
.type, 'statement')
294 def assignment_indexes(self
):
296 Returns an array of tuple(int, node) of the indexes that are used in
299 For example if the name is ``y`` in the following code::
303 would result in ``[(1, xyz_node), (0, yz_node)]``.
305 When searching for b in the case ``a, *b, c = [...]`` it will return::
307 [(slice(1, -1), abc_node)]
311 node
= self
.tree_name
.parent
312 compare
= self
.tree_name
313 while node
is not None:
314 if node
.type in ('testlist', 'testlist_comp', 'testlist_star_expr', 'exprlist'):
315 for i
, child
in enumerate(node
.children
):
319 from_end
= int((len(node
.children
) - i
) / 2)
320 index
= slice(index
, -from_end
)
321 indexes
.insert(0, (index
, node
))
324 raise LookupError("Couldn't find the assignment.")
326 elif node
.type == 'star_expr':
328 elif node
.type in ('expr_stmt', 'sync_comp_for'):
336 def inference_state(self
):
337 # Used by the cache function below
338 return self
.parent_context
.inference_state
340 @inference_state_method_cache(default
='')
342 api_type
= self
.api_type
343 if api_type
in ('function', 'class', 'property'):
344 if self
.parent_context
.get_root_context().is_stub():
345 from jedi
.inference
.gradual
.conversion
import convert_names
346 names
= convert_names([self
], prefer_stub_to_compiled
=False)
347 if self
not in names
:
348 return _merge_name_docs(names
)
350 # Make sure the names are not TreeNameDefinitions anymore.
351 return clean_scope_docstring(self
.tree_name
.get_definition())
353 if api_type
== 'module':
355 if self
not in names
:
356 return _merge_name_docs(names
)
358 if api_type
== 'statement' and self
.tree_name
.is_definition():
359 return find_statement_documentation(self
.tree_name
.get_definition())
364 def maybe_positional_argument(self
, include_star
=True):
365 options
= [Parameter
.POSITIONAL_ONLY
, Parameter
.POSITIONAL_OR_KEYWORD
]
367 options
.append(Parameter
.VAR_POSITIONAL
)
368 return self
.get_kind() in options
370 def maybe_keyword_argument(self
, include_stars
=True):
371 options
= [Parameter
.KEYWORD_ONLY
, Parameter
.POSITIONAL_OR_KEYWORD
]
373 options
.append(Parameter
.VAR_KEYWORD
)
374 return self
.get_kind() in options
376 def _kind_string(self
):
377 kind
= self
.get_kind()
378 if kind
== Parameter
.VAR_POSITIONAL
: # *args
380 if kind
== Parameter
.VAR_KEYWORD
: # **kwargs
384 def get_qualified_names(self
, include_module_names
=False):
388 class ParamNameInterface(_ParamMixin
):
392 raise NotImplementedError
395 raise NotImplementedError
397 def get_executed_param_name(self
):
399 For dealing with type inference and working around the graph, we
400 sometimes want to have the param name of the execution. This feels a
401 bit strange and we might have to refactor at some point.
403 For now however it exists to avoid infering params when we don't really
404 need them (e.g. when we can just instead use annotations.
409 def star_count(self
):
410 kind
= self
.get_kind()
411 if kind
== Parameter
.VAR_POSITIONAL
:
413 if kind
== Parameter
.VAR_KEYWORD
:
417 def infer_default(self
):
421 class BaseTreeParamName(ParamNameInterface
, AbstractTreeName
):
422 annotation_node
= None
426 output
= self
._kind
_string
() + self
.get_public_name()
427 annotation
= self
.annotation_node
428 default
= self
.default_node
429 if annotation
is not None:
430 output
+= ': ' + annotation
.get_code(include_prefix
=False)
431 if default
is not None:
432 output
+= '=' + default
.get_code(include_prefix
=False)
435 def get_public_name(self
):
436 name
= self
.string_name
437 if name
.startswith('__'):
438 # Params starting with __ are an equivalent to positional only
439 # variables in typeshed.
443 def goto(self
, **kwargs
):
447 class _ActualTreeParamName(BaseTreeParamName
):
448 def __init__(self
, function_value
, tree_name
):
450 function_value
.get_default_param_context(), tree_name
)
451 self
.function_value
= function_value
453 def _get_param_node(self
):
454 return search_ancestor(self
.tree_name
, 'param')
457 def annotation_node(self
):
458 return self
._get
_param
_node
().annotation
460 def infer_annotation(self
, execute_annotation
=True, ignore_stars
=False):
461 from jedi
.inference
.gradual
.annotation
import infer_param
462 values
= infer_param(
463 self
.function_value
, self
._get
_param
_node
(),
464 ignore_stars
=ignore_stars
)
465 if execute_annotation
:
466 values
= values
.execute_annotation()
469 def infer_default(self
):
470 node
= self
.default_node
473 return self
.parent_context
.infer_node(node
)
476 def default_node(self
):
477 return self
._get
_param
_node
().default
480 tree_param
= self
._get
_param
_node
()
481 if tree_param
.star_count
== 1: # *args
482 return Parameter
.VAR_POSITIONAL
483 if tree_param
.star_count
== 2: # **kwargs
484 return Parameter
.VAR_KEYWORD
486 # Params starting with __ are an equivalent to positional only
487 # variables in typeshed.
488 if tree_param
.name
.value
.startswith('__'):
489 return Parameter
.POSITIONAL_ONLY
491 parent
= tree_param
.parent
492 param_appeared
= False
493 for p
in parent
.children
:
496 return Parameter
.POSITIONAL_ONLY
499 return Parameter
.KEYWORD_ONLY
500 if p
.type == 'param':
502 return Parameter
.KEYWORD_ONLY
504 param_appeared
= True
505 return Parameter
.POSITIONAL_OR_KEYWORD
508 values
= self
.infer_annotation()
512 doc_params
= docstrings
.infer_param(self
.function_value
, self
._get
_param
_node
())
516 class AnonymousParamName(_ActualTreeParamName
):
517 @plugin_manager.decorate(name
='goto_anonymous_param')
519 return super().goto()
521 @plugin_manager.decorate(name
='infer_anonymous_param')
523 values
= super().infer()
526 from jedi
.inference
.dynamic_params
import dynamic_param_lookup
527 param
= self
._get
_param
_node
()
528 values
= dynamic_param_lookup(self
.function_value
, param
.position_index
)
532 if param
.star_count
== 1:
533 from jedi
.inference
.value
.iterable
import FakeTuple
534 value
= FakeTuple(self
.function_value
.inference_state
, [])
535 elif param
.star_count
== 2:
536 from jedi
.inference
.value
.iterable
import FakeDict
537 value
= FakeDict(self
.function_value
.inference_state
, {})
538 elif param
.default
is None:
541 return self
.function_value
.parent_context
.infer_node(param
.default
)
542 return ValueSet({value}
)
545 class ParamName(_ActualTreeParamName
):
546 def __init__(self
, function_value
, tree_name
, arguments
):
547 super().__init
__(function_value
, tree_name
)
548 self
.arguments
= arguments
551 values
= super().infer()
555 return self
.get_executed_param_name().infer()
557 def get_executed_param_name(self
):
558 from jedi
.inference
.param
import get_executed_param_names
559 params_names
= get_executed_param_names(self
.function_value
, self
.arguments
)
560 return params_names
[self
._get
_param
_node
().position_index
]
563 class ParamNameWrapper(_ParamMixin
):
564 def __init__(self
, param_name
):
565 self
._wrapped
_param
_name
= param_name
567 def __getattr__(self
, name
):
568 return getattr(self
._wrapped
_param
_name
, name
)
571 return '<%s: %s>' % (self
.__class
__.__name
__, self
._wrapped
_param
_name
)
574 class ImportName(AbstractNameDefinition
):
578 def __init__(self
, parent_context
, string_name
):
579 self
._from
_module
_context
= parent_context
580 self
.string_name
= string_name
582 def get_qualified_names(self
, include_module_names
=False):
583 if include_module_names
:
585 assert self
._level
== 1, "Everything else is not supported for now"
586 module_names
= self
._from
_module
_context
.string_names
587 if module_names
is None:
589 return module_names
+ (self
.string_name
,)
590 return (self
.string_name
,)
594 def parent_context(self
):
595 m
= self
._from
_module
_context
596 import_values
= self
.infer()
597 if not import_values
:
599 # It's almost always possible to find the import or to not find it. The
600 # importing returns only one value, pretty much always.
601 return next(iter(import_values
)).as_context()
605 from jedi
.inference
.imports
import Importer
606 m
= self
._from
_module
_context
607 return Importer(m
.inference_state
, [self
.string_name
], m
, level
=self
._level
).follow()
610 return [m
.name
for m
in self
.infer()]
617 return _merge_name_docs(self
.goto())
620 class SubModuleName(ImportName
):
625 def __init__(self
, wrapped_name
):
626 self
._wrapped
_name
= wrapped_name
628 def __getattr__(self
, name
):
629 return getattr(self
._wrapped
_name
, name
)
632 return '%s(%s)' % (self
.__class
__.__name
__, self
._wrapped
_name
)
637 from jedi
.inference
.gradual
.conversion
import convert_names
638 # Stubs are not complicated and we can just follow simple statements
639 # that have an equals in them, because they typically make something
640 # else public. See e.g. stubs for `requests`.
642 if self
.api_type
== 'statement' and '=' in self
.tree_name
.get_definition().children
:
643 names
= [v
.name
for v
in self
.infer()]
645 names
= convert_names(names
, prefer_stub_to_compiled
=False)
647 return super().py__doc__()
649 # We have signatures ourselves in stubs, so don't use signatures
650 # from the implementation.
651 return _merge_name_docs(names
)
654 # From here on down we make looking up the sys.version_info fast.
655 class StubName(StubNameMixin
, TreeNameDefinition
):
657 inferred
= super().infer()
658 if self
.string_name
== 'version_info' and self
.get_root_context().py__name__() == 'sys':
659 from jedi
.inference
.gradual
.stub_value
import VersionInfo
660 return ValueSet(VersionInfo(c
) for c
in inferred
)
664 class ModuleName(ValueNameMixin
, AbstractNameDefinition
):
667 def __init__(self
, value
, name
):
672 def string_name(self
):
676 class StubModuleName(StubNameMixin
, ModuleName
):