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)
Example #3
0
    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)))
Example #4
0
    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()]
Example #5
0
 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
Example #6
0
 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
Example #7
0
    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()]
Example #8
0
    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
        ]
Example #9
0
    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)
Example #10
0
    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)
Example #12
0
    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]
Example #13
0
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))
Example #14
0
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()
Example #15
0
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
        ]
Example #18
0
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]