Exemple #1
0
def follow_call_path(path, scope, position):
    """Follows a path generated by `pr.Call.generate_call_path()`"""
    current = next(path)

    if isinstance(current, pr.Array):
        result = [er.Array(current)]
    else:
        if isinstance(current, pr.NamePart):
            # This is the first global lookup.
            scopes = find_name(scope,
                               current,
                               position=position,
                               search_global=True)
        else:
            if current.type in (pr.Call.STRING, pr.Call.NUMBER):
                t = type(current.name).__name__
                scopes = find_name(builtin.Builtin.scope, t)
            else:
                debug.warning('unknown type:', current.type, current)
                scopes = []
            # Make instances of those number/string objects.
            scopes = [er.Instance(s, (current.name, )) for s in scopes]
        result = imports.strip_imports(scopes)

    return follow_paths(path, result, scope, position=position)
Exemple #2
0
def follow_call_path(path, scope, position):
    """Follows a path generated by `pr.StatementElement.generate_call_path()`"""
    current = next(path)

    if isinstance(current, pr.Array):
        result = [er.Array(current)]
    else:
        if isinstance(current, pr.NamePart):
            # This is the first global lookup.
            scopes = find_name(scope, current, position=position,
                               search_global=True)
        else:
            # for pr.Literal
            scopes = find_name(builtin.Builtin.scope, current.type_as_string())
            # Make instances of those number/string objects.
            scopes = [er.Instance(s, (current.value,)) for s in scopes]
        result = imports.strip_imports(scopes)

    return follow_paths(path, result, scope, position=position)
Exemple #3
0
    def follow_definition(self):
        """ Returns you the original 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). I think 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 PITA slow.
        """
        if self._followed_definitions is None:
            if self.definition.isinstance(parsing.Statement):
                defs = evaluate.follow_statement(self.definition)
            elif self.definition.isinstance(parsing.Import):
                defs = imports.strip_imports([self.definition])
            else:
                return [self]

            self._followed_definitions = \
                            [BaseDefinition(d, d.start_pos) for d in defs]
            _clear_caches()

        return self._followed_definitions
Exemple #4
0
    def follow_definition(self):
        """ Returns you the original 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). I think 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 PITA slow.
        """
        if self._followed_definitions is None:
            if self.definition.isinstance(parsing.Statement):
                defs = evaluate.follow_statement(self.definition)
            elif self.definition.isinstance(parsing.Import):
                defs = imports.strip_imports([self.definition])
            else:
                return [self]

            self._followed_definitions = \
                            [BaseDefinition(d, d.start_pos) for d in defs]
            evaluate.clear_caches()

        return self._followed_definitions
def follow_path(path, scope, call_scope, position=None):
    """
    Uses a generator and tries to complete the path, e.g.::

        foo.bar.baz

    `follow_path` is only responsible for completing `.bar.baz`, the rest is
    done in the `follow_call` function.
    """
    # current is either an Array or a Scope.
    try:
        current = next(path)
    except StopIteration:
        return None
    debug.dbg('follow %s in scope %s' % (current, scope))

    result = []
    if isinstance(current, pr.Array):
        # This must be an execution, either () or [].
        if current.type == pr.Array.LIST:
            if hasattr(scope, 'get_index_types'):
                result = scope.get_index_types(current)
        elif current.type not in [pr.Array.DICT]:
            # Scope must be a class or func - make an instance or execution.
            debug.dbg('exe', scope)
            result = er.Execution(scope, current).get_return_types()
        else:
            # Curly braces are not allowed, because they make no sense.
            debug.warning('strange function call with {}', current, scope)
    else:
        # The function must not be decorated with something else.
        if scope.isinstance(er.Function):
            scope = scope.get_magic_method_scope()
        else:
            # This is the typical lookup while chaining things.
            if filter_private_variable(scope, call_scope, current):
                return []
        result = imports.strip_imports(find_name(scope, current,
                                                    position=position))
    return follow_paths(path, set(result), call_scope, position=position)
Exemple #6
0
def follow_path(path, scope, call_scope, position=None):
    """
    Uses a generator and tries to complete the path, e.g.::

        foo.bar.baz

    `follow_path` is only responsible for completing `.bar.baz`, the rest is
    done in the `follow_call` function.
    """
    # current is either an Array or a Scope.
    try:
        current = next(path)
    except StopIteration:
        return None
    debug.dbg('follow %s in scope %s' % (current, scope))

    result = []
    if isinstance(current, pr.Array):
        # This must be an execution, either () or [].
        if current.type == pr.Array.LIST:
            if hasattr(scope, 'get_index_types'):
                result = scope.get_index_types(current)
        elif current.type not in [pr.Array.DICT]:
            # Scope must be a class or func - make an instance or execution.
            debug.dbg('exe', scope)
            result = er.Execution(scope, current).get_return_types()
        else:
            # Curly braces are not allowed, because they make no sense.
            debug.warning('strange function call with {}', current, scope)
    else:
        # The function must not be decorated with something else.
        if scope.isinstance(er.Function):
            scope = scope.get_magic_method_scope()
        else:
            # This is the typical lookup while chaining things.
            if filter_private_variable(scope, call_scope, current):
                return []
        result = imports.strip_imports(find_name(scope, current,
                                                 position=position))
    return follow_paths(path, set(result), call_scope, position=position)
def follow_call_path(path, scope, position):
    """Follows a path generated by `pr.Call.generate_call_path()`"""
    current = next(path)

    if isinstance(current, pr.Array):
        result = [er.Array(current)]
    else:
        if isinstance(current, pr.NamePart):
            # This is the first global lookup.
            scopes = find_name(scope, current, position=position,
                                            search_global=True)
        else:
            if current.type in (pr.Call.STRING, pr.Call.NUMBER):
                t = type(current.name).__name__
                scopes = find_name(builtin.Builtin.scope, t)
            else:
                debug.warning('unknown type:', current.type, current)
                scopes = []
            # Make instances of those number/string objects.
            scopes = [er.Instance(s, (current.name,)) for s in scopes]
        result = imports.strip_imports(scopes)

    return follow_paths(path, result, scope, position=position)
    def get_return_types(self, evaluate_generator=False):
        """ Get the return types of a function. """
        stmts = []
        if self.base.parent == builtin.Builtin.scope \
                and not isinstance(self.base, (Generator, Array)):
            func_name = str(self.base.name)

            # some implementations of builtins:
            if func_name == 'getattr':
                # follow the first param
                try:
                    objects = self.follow_var_arg(0)
                    names = self.follow_var_arg(1)
                except IndexError:
                    debug.warning('getattr() called with to few args.')
                    return []

                for obj in objects:
                    if not isinstance(obj, (Instance, Class, pr.Module)):
                        debug.warning('getattr called without instance')
                        continue

                    for arr_name in names:
                        if len(arr_name.var_args) != 1:
                            debug.warning('jedi getattr is too simple')
                        key = arr_name.var_args[0]
                        stmts += evaluate.follow_path(iter([key]), obj,
                                                      self.base)
                return stmts
            elif func_name == 'type':
                # otherwise it would be a metaclass
                if len(self.var_args) == 1:
                    objects = self.follow_var_arg(0)
                    return [o.base for o in objects if isinstance(o, Instance)]
            elif func_name == 'super':
                # TODO make this able to detect multiple inheritance supers
                accept = (pr.Function, )
                func = self.var_args.get_parent_until(accept)
                if func.isinstance(*accept):
                    cls = func.get_parent_until(accept + (pr.Class, ),
                                                include_current=False)
                    if isinstance(cls, pr.Class):
                        cls = Class(cls)
                        su = cls.get_super_classes()
                        if su:
                            return [Instance(su[0])]
                return []

        if self.base.isinstance(Class):
            # There maybe executions of executions.
            stmts = [Instance(self.base, self.var_args)]
        elif isinstance(self.base, Generator):
            return self.base.iter_content()
        else:
            # Don't do this with exceptions, as usual, because some deeper
            # exceptions could be catched - and I wouldn't know what happened.
            try:
                self.base.returns
            except (AttributeError, DecoratorNotFound):
                if hasattr(self.base, 'execute_subscope_by_name'):
                    try:
                        stmts = self.base.execute_subscope_by_name(
                            '__call__', self.var_args)
                    except KeyError:
                        debug.warning("no __call__ func available", self.base)
                else:
                    debug.warning("no execution possible", self.base)
            else:
                stmts = self._get_function_returns(evaluate_generator)

        debug.dbg('exec result: %s in %s' % (stmts, self))

        return imports.strip_imports(stmts)
    def get_return_types(self, evaluate_generator=False):
        """ Get the return types of a function. """
        stmts = []
        if self.base.parent == builtin.Builtin.scope \
                and not isinstance(self.base, (Generator, Array)):
            func_name = str(self.base.name)

            # some implementations of builtins:
            if func_name == 'getattr':
                # follow the first param
                try:
                    objects = self.follow_var_arg(0)
                    names = self.follow_var_arg(1)
                except IndexError:
                    debug.warning('getattr() called with to few args.')
                    return []

                for obj in objects:
                    if not isinstance(obj, (Instance, Class, pr.Module)):
                        debug.warning('getattr called without instance')
                        continue

                    for arr_name in names:
                        if len(arr_name.var_args) != 1:
                            debug.warning('jedi getattr is too simple')
                        key = arr_name.var_args[0]
                        stmts += evaluate.follow_path(iter([key]), obj,
                                                        self.base)
                return stmts
            elif func_name == 'type':
                # otherwise it would be a metaclass
                if len(self.var_args) == 1:
                    objects = self.follow_var_arg(0)
                    return [o.base for o in objects if isinstance(o, Instance)]
            elif func_name == 'super':
                # TODO make this able to detect multiple inheritance supers
                accept = (pr.Function,)
                func = self.var_args.get_parent_until(accept)
                if func.isinstance(*accept):
                    cls = func.get_parent_until(accept + (pr.Class,),
                                                    include_current=False)
                    if isinstance(cls, pr.Class):
                        cls = Class(cls)
                        su = cls.get_super_classes()
                        if su:
                            return [Instance(su[0])]
                return []

        if self.base.isinstance(Class):
            # There maybe executions of executions.
            stmts = [Instance(self.base, self.var_args)]
        elif isinstance(self.base, Generator):
            return self.base.iter_content()
        else:
            # Don't do this with exceptions, as usual, because some deeper
            # exceptions could be catched - and I wouldn't know what happened.
            try:
                self.base.returns
            except (AttributeError, DecoratorNotFound):
                if hasattr(self.base, 'execute_subscope_by_name'):
                    try:
                        stmts = self.base.execute_subscope_by_name('__call__',
                                                                self.var_args)
                    except KeyError:
                        debug.warning("no __call__ func available", self.base)
                else:
                    debug.warning("no execution possible", self.base)
            else:
                stmts = self._get_function_returns(evaluate_generator)

        debug.dbg('exec result: %s in %s' % (stmts, self))

        return imports.strip_imports(stmts)