1import re
2from textwrap import dedent
3from typing import Any
4from inspect import Parameter
5
6from parso.python.token import PythonTokenTypes
7from parso.python import tree
8from parso.tree import Leaf
9from parso import split_lines
10
11from jedi import debug
12from jedi import settings
13from jedi.api import classes
14from jedi.api import helpers
15from jedi.api import keywords
16from jedi.api.strings import complete_dict
17from jedi.api.file_name import complete_file_name
18from jedi.inference import imports
19from jedi.inference.base_value import ValueSet
20from jedi.inference.helpers import infer_call_of_leaf, parse_dotted_names
21from jedi.inference.context import get_global_filters
22from jedi.inference.value import TreeInstance
23from jedi.inference.docstring_utils import DocstringModule
24from jedi.inference.names import ParamNameWrapper, SubModuleName
25from jedi.inference.gradual.conversion import convert_values, convert_names
26from jedi.parser_utils import cut_value_at_position
27from jedi.plugins import plugin_manager
28
29
30class ParamNameWithEquals(ParamNameWrapper):
31 def get_public_name(self):
32 return self.string_name + '='
33
34
35def _get_signature_param_names(signatures, positional_count, used_kwargs):
36 # Add named params
37 for call_sig in signatures:
38 for i, p in enumerate(call_sig.params):
39 kind = p.kind
40 if i < positional_count and kind == Parameter.POSITIONAL_OR_KEYWORD:
41 continue
42 if kind in (Parameter.POSITIONAL_OR_KEYWORD, Parameter.KEYWORD_ONLY) \
43 and p.name not in used_kwargs:
44 yield ParamNameWithEquals(p._name)
45
46
47def _must_be_kwarg(signatures, positional_count, used_kwargs):
48 if used_kwargs:
49 return True
50
51 must_be_kwarg = True
52 for signature in signatures:
53 for i, p in enumerate(signature.params):
54 kind = p.kind
55 if kind is Parameter.VAR_POSITIONAL:
56 # In case there were not already kwargs, the next param can
57 # always be a normal argument.
58 return False
59
60 if i >= positional_count and kind in (Parameter.POSITIONAL_OR_KEYWORD,
61 Parameter.POSITIONAL_ONLY):
62 must_be_kwarg = False
63 break
64 if not must_be_kwarg:
65 break
66 return must_be_kwarg
67
68
69def filter_names(inference_state, completion_names, stack, like_name, fuzzy,
70 imported_names, cached_name):
71 comp_dct = set()
72 if settings.case_insensitive_completion:
73 like_name = like_name.lower()
74 for name in completion_names:
75 string = name.string_name
76 if string in imported_names and string != like_name:
77 continue
78 if settings.case_insensitive_completion:
79 string = string.lower()
80 if helpers.match(string, like_name, fuzzy=fuzzy):
81 new = classes.Completion(
82 inference_state,
83 name,
84 stack,
85 len(like_name),
86 is_fuzzy=fuzzy,
87 cached_name=cached_name,
88 )
89 k = (new.name, new.complete) # key
90 if k not in comp_dct:
91 comp_dct.add(k)
92 tree_name = name.tree_name
93 if tree_name is not None:
94 definition = tree_name.get_definition()
95 if definition is not None and definition.type == 'del_stmt':
96 continue
97 yield new
98
99
100def _remove_duplicates(completions, other_completions):
101 names = {d.name for d in other_completions}
102 return [c for c in completions if c.name not in names]
103
104
105def get_user_context(module_context, position):
106 """
107 Returns the scope in which the user resides. This includes flows.
108 """
109 leaf = module_context.tree_node.get_leaf_for_position(position, include_prefixes=True)
110 return module_context.create_context(leaf)
111
112
113def get_flow_scope_node(module_node, position):
114 node = module_node.get_leaf_for_position(position, include_prefixes=True)
115 while not isinstance(node, (tree.Scope, tree.Flow)):
116 node = node.parent
117
118 return node
119
120
121@plugin_manager.decorate()
122def complete_param_names(context, function_name, decorator_nodes):
123 # Basically there's no way to do param completion. The plugins are
124 # responsible for this.
125 return []
126
127
128class Completion:
129 def __init__(self, inference_state, module_context, code_lines, position,
130 signatures_callback, fuzzy=False):
131 self._inference_state = inference_state
132 self._module_context = module_context
133 self._module_node = module_context.tree_node
134 self._code_lines = code_lines
135
136 # The first step of completions is to get the name
137 self._like_name = helpers.get_on_completion_name(self._module_node, code_lines, position)
138 # The actual cursor position is not what we need to calculate
139 # everything. We want the start of the name we're on.
140 self._original_position = position
141 self._signatures_callback = signatures_callback
142
143 self._fuzzy = fuzzy
144
145 # Return list of completions in this order:
146 # - Beginning with what user is typing
147 # - Public (alphabet)
148 # - Private ("_xxx")
149 # - Dunder ("__xxx")
150 def complete(self):
151 leaf = self._module_node.get_leaf_for_position(
152 self._original_position,
153 include_prefixes=True
154 )
155 string, start_leaf, quote = _extract_string_while_in_string(leaf, self._original_position)
156
157 prefixed_completions = complete_dict(
158 self._module_context,
159 self._code_lines,
160 start_leaf or leaf,
161 self._original_position,
162 None if string is None else quote + string,
163 fuzzy=self._fuzzy,
164 )
165
166 if string is not None and not prefixed_completions:
167 prefixed_completions = list(complete_file_name(
168 self._inference_state, self._module_context, start_leaf, quote, string,
169 self._like_name, self._signatures_callback,
170 self._code_lines, self._original_position,
171 self._fuzzy
172 ))
173 if string is not None:
174 if not prefixed_completions and '\n' in string:
175 # Complete only multi line strings
176 prefixed_completions = self._complete_in_string(start_leaf, string)
177 return prefixed_completions
178
179 cached_name, completion_names = self._complete_python(leaf)
180
181 imported_names = []
182 if leaf.parent is not None and leaf.parent.type in ['import_as_names', 'dotted_as_names']:
183 imported_names.extend(extract_imported_names(leaf.parent))
184
185 completions = list(filter_names(self._inference_state, completion_names,
186 self.stack, self._like_name,
187 self._fuzzy, imported_names, cached_name=cached_name))
188
189 return (
190 # Removing duplicates mostly to remove False/True/None duplicates.
191 _remove_duplicates(prefixed_completions, completions)
192 + sorted(completions, key=lambda x: (not x.name.startswith(self._like_name),
193 x.name.startswith('__'),
194 x.name.startswith('_'),
195 x.name.lower()))
196 )
197
198 def _complete_python(self, leaf):
199 """
200 Analyzes the current context of a completion and decides what to
201 return.
202
203 Technically this works by generating a parser stack and analysing the
204 current stack for possible grammar nodes.
205
206 Possible enhancements:
207 - global/nonlocal search global
208 - yield from / raise from <- could be only exceptions/generators
209 - In args: */**: no completion
210 - In params (also lambda): no completion before =
211 """
212 grammar = self._inference_state.grammar
213 self.stack = stack = None
214 self._position = (
215 self._original_position[0],
216 self._original_position[1] - len(self._like_name)
217 )
218 cached_name = None
219
220 try:
221 self.stack = stack = helpers.get_stack_at_position(
222 grammar, self._code_lines, leaf, self._position
223 )
224 except helpers.OnErrorLeaf as e:
225 value = e.error_leaf.value
226 if value == '.':
227 # After ErrorLeaf's that are dots, we will not do any
228 # completions since this probably just confuses the user.
229 return cached_name, []
230
231 # If we don't have a value, just use global completion.
232 return cached_name, self._complete_global_scope()
233
234 allowed_transitions = \
235 list(stack._allowed_transition_names_and_token_types())
236
237 if 'if' in allowed_transitions:
238 leaf = self._module_node.get_leaf_for_position(self._position, include_prefixes=True)
239 previous_leaf = leaf.get_previous_leaf()
240
241 indent = self._position[1]
242 if not (leaf.start_pos <= self._position <= leaf.end_pos):
243 indent = leaf.start_pos[1]
244
245 if previous_leaf is not None:
246 stmt = previous_leaf
247 while True:
248 stmt = stmt.search_ancestor(
249 'if_stmt', 'for_stmt', 'while_stmt', 'try_stmt',
250 'error_node',
251 )
252 if stmt is None:
253 break
254
255 type_ = stmt.type
256 if type_ == 'error_node':
257 first = stmt.children[0]
258 if isinstance(first, Leaf):
259 type_ = first.value + '_stmt'
260 # Compare indents
261 if stmt.start_pos[1] == indent:
262 if type_ == 'if_stmt':
263 allowed_transitions += ['elif', 'else']
264 elif type_ == 'try_stmt':
265 allowed_transitions += ['except', 'finally', 'else']
266 elif type_ == 'for_stmt':
267 allowed_transitions.append('else')
268
269 completion_names: list[Any] = []
270
271 kwargs_only = False
272 if any(t in allowed_transitions for t in (PythonTokenTypes.NAME,
273 PythonTokenTypes.INDENT)):
274 # This means that we actually have to do type inference.
275
276 nonterminals = [stack_node.nonterminal for stack_node in stack]
277
278 nodes = _gather_nodes(stack)
279 if nodes and nodes[-1] in ('as', 'def', 'class'):
280 # No completions for ``with x as foo`` and ``import x as foo``.
281 # Also true for defining names as a class or function.
282 return cached_name, list(self._complete_inherited(is_function=True))
283 elif "import_stmt" in nonterminals:
284 level, names = parse_dotted_names(nodes, "import_from" in nonterminals)
285
286 only_modules = not ("import_from" in nonterminals and 'import' in nodes)
287 completion_names += self._get_importer_names(
288 names,
289 level,
290 only_modules=only_modules,
291 )
292 elif nonterminals[-1] in ('trailer', 'dotted_name') and nodes[-1] == '.':
293 dot = self._module_node.get_leaf_for_position(self._position)
294 if dot.type == "newline":
295 dot = dot.get_previous_leaf()
296 if dot.type == "endmarker":
297 # This is a bit of a weird edge case, maybe we can somehow
298 # generalize this.
299 dot = leaf.get_previous_leaf()
300 cached_name, n = self._complete_trailer(dot.get_previous_leaf())
301 completion_names += n
302 elif self._is_parameter_completion():
303 completion_names += self._complete_params(leaf)
304 else:
305 # Apparently this looks like it's good enough to filter most cases
306 # so that signature completions don't randomly appear.
307 # To understand why this works, three things are important:
308 # 1. trailer with a `,` in it is either a subscript or an arglist.
309 # 2. If there's no `,`, it's at the start and only signatures start
310 # with `(`. Other trailers could start with `.` or `[`.
311 # 3. Decorators are very primitive and have an optional `(` with
312 # optional arglist in them.
313 if nodes[-1] in ['(', ','] \
314 and nonterminals[-1] in ('trailer', 'arglist', 'decorator'):
315 signatures = self._signatures_callback(*self._position)
316 if signatures:
317 call_details = signatures[0]._call_details
318 used_kwargs = list(call_details.iter_used_keyword_arguments())
319 positional_count = call_details.count_positional_arguments()
320
321 completion_names += _get_signature_param_names(
322 signatures,
323 positional_count,
324 used_kwargs,
325 )
326
327 kwargs_only = _must_be_kwarg(signatures, positional_count, used_kwargs)
328
329 if not kwargs_only:
330 completion_names += self._complete_global_scope()
331 completion_names += self._complete_inherited(is_function=False)
332
333 if not kwargs_only:
334 current_line = self._code_lines[self._position[0] - 1][:self._position[1]]
335 completion_names += self._complete_keywords(
336 allowed_transitions,
337 only_values=not (not current_line or current_line[-1] in ' \t.;'
338 and current_line[-3:] != '...')
339 )
340
341 return cached_name, completion_names
342
343 def _is_parameter_completion(self):
344 tos = self.stack[-1]
345 if tos.nonterminal == 'lambdef' and len(tos.nodes) == 1:
346 # We are at the position `lambda `, where basically the next node
347 # is a param.
348 return True
349 if tos.nonterminal in 'parameters':
350 # Basically we are at the position `foo(`, there's nothing there
351 # yet, so we have no `typedargslist`.
352 return True
353 # var args is for lambdas and typed args for normal functions
354 return tos.nonterminal in ('typedargslist', 'varargslist') and tos.nodes[-1] == ','
355
356 def _complete_params(self, leaf):
357 stack_node = self.stack[-2]
358 if stack_node.nonterminal == 'parameters':
359 stack_node = self.stack[-3]
360 if stack_node.nonterminal == 'funcdef':
361 context = get_user_context(self._module_context, self._position)
362 node = leaf.search_ancestor('error_node', 'funcdef')
363 if node is not None:
364 if node.type == 'error_node':
365 n = node.children[0]
366 if n.type == 'decorators':
367 decorators = n.children
368 elif n.type == 'decorator':
369 decorators = [n]
370 else:
371 decorators = []
372 else:
373 decorators = node.get_decorators()
374 function_name = stack_node.nodes[1]
375
376 return complete_param_names(context, function_name.value, decorators)
377 return []
378
379 def _complete_keywords(self, allowed_transitions, only_values):
380 for k in allowed_transitions:
381 if isinstance(k, str) and k.isalpha():
382 if not only_values or k in ('True', 'False', 'None'):
383 yield keywords.KeywordName(self._inference_state, k)
384
385 def _complete_global_scope(self):
386 context = get_user_context(self._module_context, self._position)
387 debug.dbg('global completion scope: %s', context)
388 flow_scope_node = get_flow_scope_node(self._module_node, self._position)
389 filters = get_global_filters(
390 context,
391 self._position,
392 flow_scope_node
393 )
394 completion_names = []
395 for filter in filters:
396 completion_names += filter.values()
397 return completion_names
398
399 def _complete_trailer(self, previous_leaf):
400 inferred_context = self._module_context.create_context(previous_leaf)
401 values = infer_call_of_leaf(inferred_context, previous_leaf)
402 debug.dbg('trailer completion values: %s', values, color='MAGENTA')
403
404 # The cached name simply exists to make speed optimizations for certain
405 # modules.
406 cached_name = None
407 if len(values) == 1:
408 v, = values
409 if v.is_module():
410 if len(v.string_names) == 1:
411 module_name = v.string_names[0]
412 if module_name in ('numpy', 'tensorflow', 'matplotlib', 'pandas'):
413 cached_name = module_name
414
415 return cached_name, self._complete_trailer_for_values(values)
416
417 def _complete_trailer_for_values(self, values):
418 user_context = get_user_context(self._module_context, self._position)
419
420 return complete_trailer(user_context, values)
421
422 def _get_importer_names(self, names, level=0, only_modules=True):
423 names = [n.value for n in names]
424 i = imports.Importer(self._inference_state, names, self._module_context, level)
425 return i.completion_names(self._inference_state, only_modules=only_modules)
426
427 def _complete_inherited(self, is_function=True):
428 """
429 Autocomplete inherited methods when overriding in child class.
430 """
431 leaf = self._module_node.get_leaf_for_position(self._position, include_prefixes=True)
432 cls = leaf.search_ancestor('classdef')
433 if cls is None:
434 return
435
436 # Complete the methods that are defined in the super classes.
437 class_value = self._module_context.create_value(cls)
438
439 if cls.start_pos[1] >= leaf.start_pos[1]:
440 return
441
442 filters = class_value.get_filters(is_instance=True)
443 # The first dict is the dictionary of class itself.
444 next(filters)
445 for filter in filters:
446 for name in filter.values():
447 # TODO we should probably check here for properties
448 if (name.api_type == 'function') == is_function:
449 yield name
450
451 def _complete_in_string(self, start_leaf, string):
452 """
453 To make it possible for people to have completions in doctests or
454 generally in "Python" code in docstrings, we use the following
455 heuristic:
456
457 - Having an indented block of code
458 - Having some doctest code that starts with `>>>`
459 - Having backticks that doesn't have whitespace inside it
460 """
461
462 def iter_relevant_lines(lines):
463 include_next_line = False
464 for l in code_lines:
465 if include_next_line or l.startswith('>>>') or l.startswith(' '):
466 yield re.sub(r'^( *>>> ?| +)', '', l)
467 else:
468 yield None
469
470 include_next_line = bool(re.match(' *>>>', l))
471
472 string = dedent(string)
473 code_lines = split_lines(string, keepends=True)
474 relevant_code_lines = list(iter_relevant_lines(code_lines))
475 if relevant_code_lines[-1] is not None:
476 # Some code lines might be None, therefore get rid of that.
477 relevant_code_lines = ['\n' if c is None else c for c in relevant_code_lines]
478 return self._complete_code_lines(relevant_code_lines)
479 match = re.search(r'`([^`\s]+)', code_lines[-1])
480 if match:
481 return self._complete_code_lines([match.group(1)])
482 return []
483
484 def _complete_code_lines(self, code_lines):
485 module_node = self._inference_state.grammar.parse(''.join(code_lines))
486 module_value = DocstringModule(
487 in_module_context=self._module_context,
488 inference_state=self._inference_state,
489 module_node=module_node,
490 code_lines=code_lines,
491 )
492 return Completion(
493 self._inference_state,
494 module_value.as_context(),
495 code_lines=code_lines,
496 position=module_node.end_pos,
497 signatures_callback=lambda *args, **kwargs: [],
498 fuzzy=self._fuzzy
499 ).complete()
500
501
502def _gather_nodes(stack):
503 nodes = []
504 for stack_node in stack:
505 if stack_node.dfa.from_rule == 'small_stmt':
506 nodes = []
507 else:
508 nodes += stack_node.nodes
509 return nodes
510
511
512_string_start = re.compile(r'^\w*(\'{3}|"{3}|\'|")')
513
514
515def _extract_string_while_in_string(leaf, position):
516 def return_part_of_leaf(leaf):
517 kwargs = {}
518 if leaf.line == position[0]:
519 kwargs['endpos'] = position[1] - leaf.column
520 match = _string_start.match(leaf.value, **kwargs)
521 if not match:
522 return None, None, None
523 start = match.group(0)
524 if leaf.line == position[0] and position[1] < leaf.column + match.end():
525 return None, None, None
526 return cut_value_at_position(leaf, position)[match.end():], leaf, start
527
528 if position < leaf.start_pos:
529 return None, None, None
530
531 if leaf.type == 'string':
532 return return_part_of_leaf(leaf)
533
534 leaves = []
535 while leaf is not None:
536 if leaf.type == 'error_leaf' and ('"' in leaf.value or "'" in leaf.value):
537 if len(leaf.value) > 1:
538 return return_part_of_leaf(leaf)
539 prefix_leaf = None
540 if not leaf.prefix:
541 prefix_leaf = leaf.get_previous_leaf()
542 if prefix_leaf is None or prefix_leaf.type != 'name' \
543 or not all(c in 'rubf' for c in prefix_leaf.value.lower()):
544 prefix_leaf = None
545
546 return (
547 ''.join(cut_value_at_position(l, position) for l in leaves),
548 prefix_leaf or leaf,
549 ('' if prefix_leaf is None else prefix_leaf.value)
550 + cut_value_at_position(leaf, position),
551 )
552 if leaf.line != position[0]:
553 # Multi line strings are always simple error leaves and contain the
554 # whole string, single line error leaves are atherefore important
555 # now and since the line is different, it's not really a single
556 # line string anymore.
557 break
558 leaves.insert(0, leaf)
559 leaf = leaf.get_previous_leaf()
560 return None, None, None
561
562
563def complete_trailer(user_context, values):
564 completion_names = []
565 for value in values:
566 for filter in value.get_filters(origin_scope=user_context.tree_node):
567 completion_names += filter.values()
568
569 if not value.is_stub() and isinstance(value, TreeInstance):
570 completion_names += _complete_getattr(user_context, value)
571
572 python_values = convert_values(values)
573 for c in python_values:
574 if c not in values:
575 for filter in c.get_filters(origin_scope=user_context.tree_node):
576 completion_names += filter.values()
577 return completion_names
578
579
580def _complete_getattr(user_context, instance):
581 """
582 A heuristic to make completion for proxy objects work. This is not
583 intended to work in all cases. It works exactly in this case:
584
585 def __getattr__(self, name):
586 ...
587 return getattr(any_object, name)
588
589 It is important that the return contains getattr directly, otherwise it
590 won't work anymore. It's really just a stupid heuristic. It will not
591 work if you write e.g. `return (getatr(o, name))`, because of the
592 additional parentheses. It will also not work if you move the getattr
593 to some other place that is not the return statement itself.
594
595 It is intentional that it doesn't work in all cases. Generally it's
596 really hard to do even this case (as you can see below). Most people
597 will write it like this anyway and the other ones, well they are just
598 out of luck I guess :) ~dave.
599 """
600 names = (instance.get_function_slot_names('__getattr__')
601 or instance.get_function_slot_names('__getattribute__'))
602 functions = ValueSet.from_sets(
603 name.infer()
604 for name in names
605 )
606 for func in functions:
607 tree_node = func.tree_node
608 if tree_node is None or tree_node.type != 'funcdef':
609 continue
610
611 for return_stmt in tree_node.iter_return_stmts():
612 # Basically until the next comment we just try to find out if a
613 # return statement looks exactly like `return getattr(x, name)`.
614 if return_stmt.type != 'return_stmt':
615 continue
616 atom_expr = return_stmt.children[1]
617 if atom_expr.type != 'atom_expr':
618 continue
619 atom = atom_expr.children[0]
620 trailer = atom_expr.children[1]
621 if len(atom_expr.children) != 2 or atom.type != 'name' \
622 or atom.value != 'getattr':
623 continue
624 arglist = trailer.children[1]
625 if arglist.type != 'arglist' or len(arglist.children) < 3:
626 continue
627 context = func.as_context()
628 object_node = arglist.children[0]
629
630 # Make sure it's a param: foo in __getattr__(self, foo)
631 name_node = arglist.children[2]
632 name_list = context.goto(name_node, name_node.start_pos)
633 if not any(n.api_type == 'param' for n in name_list):
634 continue
635
636 # Now that we know that these are most probably completion
637 # objects, we just infer the object and return them as
638 # completions.
639 objects = context.infer_node(object_node)
640 return complete_trailer(user_context, objects)
641 return []
642
643
644def search_in_module(inference_state, module_context, names, wanted_names,
645 wanted_type, complete=False, fuzzy=False,
646 ignore_imports=False, convert=False):
647 for s in wanted_names[:-1]:
648 new_names = []
649 for n in names:
650 if s == n.string_name:
651 if n.tree_name is not None and n.api_type in ('module', 'namespace') \
652 and ignore_imports:
653 continue
654 new_names += complete_trailer(
655 module_context,
656 n.infer()
657 )
658 debug.dbg('dot lookup on search %s from %s', new_names, names[:10])
659 names = new_names
660
661 last_name = wanted_names[-1].lower()
662 for n in names:
663 string = n.string_name.lower()
664 if complete and helpers.match(string, last_name, fuzzy=fuzzy) \
665 or not complete and string == last_name:
666 if isinstance(n, SubModuleName):
667 names = [v.name for v in n.infer()]
668 else:
669 names = [n]
670 if convert:
671 names = convert_names(names)
672 for n2 in names:
673 if complete:
674 def_ = classes.Completion(
675 inference_state, n2,
676 stack=None,
677 like_name_length=len(last_name),
678 is_fuzzy=fuzzy,
679 )
680 else:
681 def_ = classes.Name(inference_state, n2)
682 if not wanted_type or wanted_type == def_.type:
683 yield def_
684
685
686def extract_imported_names(node):
687 imported_names = []
688
689 if node.type in ['import_as_names', 'dotted_as_names', 'dotted_as_name', 'import_as_name']:
690 for index, child in enumerate(node.children):
691 if child.type == 'name':
692 if (index > 1 and node.children[index - 1].type == "keyword"
693 and node.children[index - 1].value == "as"):
694 continue
695 imported_names.append(child.value)
696 elif child.type in ('import_as_name', 'dotted_as_name'):
697 imported_names.extend(extract_imported_names(child))
698
699 return imported_names