def goto(self, *, follow_imports=False, follow_builtin_imports=False, only_stubs=False, prefer_stubs=False): """ Like :meth:`.Script.goto` (also supports the same params), but does it for the current name. This is typically useful if you are using something like :meth:`.Script.get_names()`. :param follow_imports: The goto call will follow imports. :param follow_builtin_imports: If follow_imports is True will try to look up names in builtins (i.e. compiled or extension modules). :param only_stubs: Only return stubs for this goto call. :param prefer_stubs: Prefer stubs to Python objects for this goto call. :rtype: list of :class:`Name` """ if not self._name.is_value_name: return [] names = self._name.goto() if follow_imports: names = filter_follow_imports(names, follow_builtin_imports) names = convert_names( names, only_stubs=only_stubs, prefer_stubs=prefer_stubs, ) return [ self if n == self._name else Name(self._inference_state, n) for n in names ]
def _goto(self, line, column, follow_imports=False, follow_builtin_imports=False, only_stubs=False, prefer_stubs=False): tree_name = self._module_node.get_name_of_position((line, column)) if tree_name is None: # Without a name we really just want to jump to the result e.g. # executed by `foo()`, if we the cursor is after `)`. return self.infer(line, column, only_stubs=only_stubs, prefer_stubs=prefer_stubs) name = self._get_module_context().create_name(tree_name) # Make it possible to goto the super class function/attribute # definitions, when they are overwritten. names = [] if name.tree_name.is_definition() and name.parent_context.is_class(): class_node = name.parent_context.tree_node class_value = self._get_module_context().create_value(class_node) mro = class_value.py__mro__() next(mro) # Ignore the first entry, because it's the class itself. for cls in mro: names = cls.goto(tree_name.value) if names: break if not names: names = list(name.goto()) if follow_imports: names = helpers.filter_follow_imports(names) names = convert_names( names, only_stubs=only_stubs, prefer_stubs=prefer_stubs, ) defs = [classes.Definition(self._inference_state, d) for d in set(names)] return helpers.sorted_definitions(defs)
def goto(self, line=None, column=None, *, follow_imports=False, follow_builtin_imports=False, only_stubs=False, prefer_stubs=False): """ Goes to the name that defined the object under the cursor. Optionally you can follow imports. Multiple objects may be returned, depending on an if you can have two different versions of a function. :param follow_imports: The method will follow imports. :param follow_builtin_imports: If ``follow_imports`` is True will try to look up names in builtins (i.e. compiled or extension modules). :param only_stubs: Only return stubs for this method. :param prefer_stubs: Prefer stubs to Python objects for this method. :rtype: list of :class:`.Name` """ tree_name = self._module_node.get_name_of_position((line, column)) if tree_name is None: # Without a name we really just want to jump to the result e.g. # executed by `foo()`, if we the cursor is after `)`. return self.infer(line, column, only_stubs=only_stubs, prefer_stubs=prefer_stubs) name = self._get_module_context().create_name(tree_name) # Make it possible to goto the super class function/attribute # definitions, when they are overwritten. names = [] if name.tree_name.is_definition() and name.parent_context.is_class(): class_node = name.parent_context.tree_node class_value = self._get_module_context().create_value(class_node) mro = class_value.py__mro__() next(mro) # Ignore the first entry, because it's the class itself. for cls in mro: names = cls.goto(tree_name.value) if names: break if not names: names = list(name.goto()) if follow_imports: names = helpers.filter_follow_imports(names, follow_builtin_imports) names = convert_names( names, only_stubs=only_stubs, prefer_stubs=prefer_stubs, ) defs = [classes.Name(self._inference_state, d) for d in set(names)] # Avoid duplicates return list(set(helpers.sorted_definitions(defs)))
def _get_signatures(self, for_docstring=False): if for_docstring and self._name.api_type == 'statement' and not self.is_stub(): # For docstrings we don't resolve signatures if they are simple # statements and not stubs. This is a speed optimization. return [] names = convert_names([self._name], prefer_stubs=True) return [sig for name in names for sig in name.infer().get_signatures()]
def py__doc__(self): doc = self._value.py__doc__() if not doc and self._value.is_stub(): from jedi.inference.gradual.conversion import convert_names names = convert_names([self], prefer_stub_to_compiled=False) if self not in names: return _merge_name_docs(names) return doc
def py__doc__(self, include_signatures=False): from jedi.inference.gradual.conversion import convert_names names = convert_names([self], prefer_stub_to_compiled=False) if self in names: doc = super(StubNameMixin, self).py__doc__(include_signatures) else: doc = _merge_name_docs(names) if include_signatures: parent = self.tree_name.parent if parent.type in ('funcdef', 'classdef') and parent.name is self.tree_name: doc = _merge_docs_and_signature(self.infer(), doc) return doc
def _get_signatures(self, for_docstring=False): if for_docstring and self._name.api_type == 'statement' and not self.is_stub( ): # For docstrings we don't resolve signatures if they are simple # statements and not stubs. This is a speed optimization. return [] if isinstance(self._name, MixedName): # While this would eventually happen anyway, it's basically just a # shortcut to not infer anything tree related, because it's really # not necessary. return self._name.infer_compiled_value().get_signatures() names = convert_names([self._name], prefer_stubs=True) return [sig for name in names for sig in name.infer().get_signatures()]
def _goto(self, only_stubs=False, prefer_stubs=False): assert not (only_stubs and prefer_stubs) if not self._name.is_value_name: return [] names = convert_names( self._name.goto(), only_stubs=only_stubs, prefer_stubs=prefer_stubs, ) return [ self if n == self._name else Definition(self._inference_state, n) for n in names ]
def _goto(self, line, column, follow_imports=False, follow_builtin_imports=False, only_stubs=False, prefer_stubs=False): def filter_follow_imports(names): for name in names: if name.is_import(): new_names = list(filter_follow_imports(name.goto())) found_builtin = False if follow_builtin_imports: for new_name in new_names: if new_name.start_pos is None: found_builtin = True if found_builtin: yield name else: for new_name in new_names: yield new_name else: yield name tree_name = self._module_node.get_name_of_position((line, column)) if tree_name is None: # Without a name we really just want to jump to the result e.g. # executed by `foo()`, if we the cursor is after `)`. return self.infer(line, column, only_stubs=only_stubs, prefer_stubs=prefer_stubs) name = self._get_module_context().create_name(tree_name) names = list(name.goto()) if follow_imports: names = filter_follow_imports(names) names = convert_names( names, only_stubs=only_stubs, prefer_stubs=prefer_stubs, ) defs = [ classes.Definition(self._inference_state, d) for d in set(names) ] return helpers.sorted_definitions(defs)
def _goto(self, follow_imports=False, follow_builtin_imports=False, only_stubs=False, prefer_stubs=False): if not self._name.is_value_name: return [] names = self._name.goto() if follow_imports: names = filter_follow_imports(names, follow_builtin_imports) names = convert_names( names, only_stubs=only_stubs, prefer_stubs=prefer_stubs, ) return [self if n == self._name else Definition(self._inference_state, n) for n in names]
def py__doc__(self): from jedi.inference.gradual.conversion import convert_names # Stubs are not complicated and we can just follow simple statements # that have an equals in them, because they typically make something # else public. See e.g. stubs for `requests`. names = [self] if self.api_type == 'statement' and '=' in self.tree_name.get_definition().children: names = [v.name for v in self.infer()] names = convert_names(names, prefer_stub_to_compiled=False) if self in names: return super().py__doc__() else: # We have signatures ourselves in stubs, so don't use signatures # from the implementation. return _merge_name_docs(names)
def _infer(self, only_stubs=False, prefer_stubs=False): assert not (only_stubs and prefer_stubs) if not self._name.is_value_name: return [] # First we need to make sure that we have stub names (if possible) that # we can follow. If we don't do that, we can end up with the inferred # results of Python objects instead of stubs. names = convert_names([self._name], prefer_stubs=True) values = convert_values( ValueSet.from_sets(n.infer() for n in names), only_stubs=only_stubs, prefer_stubs=prefer_stubs, ) resulting_names = [c.name for c in values] return [self if n == self._name else Definition(self._inference_state, n) for n in resulting_names]
def _find_defining_names(module_context, tree_name): found_names = _find_names(module_context, tree_name) for name in list(found_names): # Convert from/to stubs, because those might also be usages. found_names |= set( convert_names([name], only_stubs=not name.get_root_context().is_stub(), prefer_stub_to_compiled=False)) found_names |= set(_find_global_variables(found_names, tree_name.value)) for name in list(found_names): if name.api_type == 'param' or name.tree_name is None \ or name.tree_name.parent.type == 'trailer': continue found_names |= set( _add_names_in_same_context(name.parent_context, name.string_name)) return set(_resolve_names(found_names))
def test_sqlite3_conversion(Script): script1 = Script('import sqlite3; sqlite3.Connection') d, = script1.infer() assert not d.module_path assert d.full_name == 'sqlite3.Connection' assert convert_names([d._name], only_stubs=True) d, = script1.infer(only_stubs=True) assert d.is_stub() assert d.full_name == 'sqlite3.dbapi2.Connection' script2 = Script(path=d.module_path) d, = script2.infer(line=d.line, column=d.column) assert not d.is_stub() assert d.full_name == 'sqlite3.Connection' v, = d._name.infer() assert v.is_compiled()
def search_in_module(inference_state, module_context, names, wanted_names, wanted_type, complete=False, fuzzy=False, ignore_imports=False, convert=False): for s in wanted_names[:-1]: new_names = [] for n in names: if s == n.string_name: if n.tree_name is not None and n.api_type == 'module' \ and ignore_imports: continue new_names += complete_trailer(module_context, n.infer()) debug.dbg('dot lookup on search %s from %s', new_names, names[:10]) names = new_names last_name = wanted_names[-1].lower() for n in names: string = n.string_name.lower() if complete and helpers.match(string, last_name, fuzzy=fuzzy) \ or not complete and string == last_name: if isinstance(n, SubModuleName): names = [v.name for v in n.infer()] else: names = [n] if convert: names = convert_names(names) for n2 in names: if complete: def_ = classes.Completion( inference_state, n2, stack=None, like_name_length=len(last_name), is_fuzzy=fuzzy, ) else: def_ = classes.Name(inference_state, n2) if not wanted_type or wanted_type == def_.type: yield def_
def py__doc__(self): api_type = self.api_type if api_type in ('function', 'class', 'property'): if self.parent_context.get_root_context().is_stub(): from jedi.inference.gradual.conversion import convert_names names = convert_names([self], prefer_stub_to_compiled=False) if self not in names: return _merge_name_docs(names) # Make sure the names are not TreeNameDefinitions anymore. return clean_scope_docstring(self.tree_name.get_definition()) if api_type == 'module': names = self.goto() if self not in names: return _merge_name_docs(names) if api_type == 'statement' and self.tree_name.is_definition(): return find_statement_documentation(self.tree_name.get_definition()) return ''
def infer(self, *, only_stubs=False, prefer_stubs=False): """ Like :meth:`.Script.infer`, it can be useful to understand which type the current name has. Return the actual definitions. I strongly recommend not using it for your completions, because it might slow down |jedi|. If you want to read only a few objects (<=20), it might be useful, especially to get the original docstrings. The basic problem of this function is that it follows all results. This means with 1000 completions (e.g. numpy), it's just very, very slow. :param only_stubs: Only return stubs for this goto call. :param prefer_stubs: Prefer stubs to Python objects for this type inference call. :rtype: list of :class:`Name` """ assert not (only_stubs and prefer_stubs) if not self._name.is_value_name: return [] # First we need to make sure that we have stub names (if possible) that # we can follow. If we don't do that, we can end up with the inferred # results of Python objects instead of stubs. names = convert_names([self._name], prefer_stubs=True) values = convert_values( ValueSet.from_sets(n.infer() for n in names), only_stubs=only_stubs, prefer_stubs=prefer_stubs, ) resulting_names = [c.name for c in values] return [ self if n == self._name else Name(self._inference_state, n) for n in resulting_names ]
def test_os_stat_result(Script): d, = Script('import os; os.stat_result').goto() assert d.is_stub() n = d._name # This should not be a different stub name assert convert_names([n]) == [n]