Пример #1
0
 def wrap(self, element):
     if isinstance(element, tree.Class):
         return er.Class(self, element)
     elif isinstance(element, tree.Function):
         if isinstance(element, tree.Lambda):
             return er.LambdaWrapper(self, element)
         else:
             return er.Function(self, element)
     elif isinstance(element, (tree.Module)) \
             and not isinstance(element, er.ModuleWrapper):
         return er.ModuleWrapper(self, element)
     else:
         return element
Пример #2
0
    def eval_statement(self, stmt, seek_name=None):
        """
        The starting point of the completion. A statement always owns a call
        list, which are the calls, that a statement does. In case multiple
        names are defined in the statement, `seek_name` returns the result for
        this name.

        :param stmt: A `pr.Statement`.
        """
        debug.dbg('eval_statement %s (%s)', stmt, seek_name)
        expression_list = stmt.expression_list()
        if isinstance(stmt, FakeStatement):
            return expression_list  # Already contains the results.

        result = self.eval_expression_list(expression_list)

        ass_details = stmt.assignment_details
        if ass_details and ass_details[0][1] != '=' and not isinstance(
                stmt, er.InstanceElement):  # TODO don't check for this.
            expr_list, operator = ass_details[0]
            # `=` is always the last character in aug assignments -> -1
            operator = operator[:-1]
            name = str(expr_list[0].name)
            parent = stmt.parent
            if isinstance(parent, (pr.SubModule, fast.Module)):
                parent = er.ModuleWrapper(self, parent)
            left = self.find_types(parent, name, stmt.start_pos)
            if isinstance(stmt.parent, pr.ForFlow):
                # iterate through result and add the values, that's possible
                # only in for loops without clutter, because they are
                # predictable.
                for r in result:
                    left = precedence.calculate(self, left, operator, [r])
                result = left
            else:
                result = precedence.calculate(self, left, operator, result)
        elif len(stmt.get_defined_names()) > 1 and seek_name and ass_details:
            # Assignment checking is only important if the statement defines
            # multiple variables.
            new_result = []
            for ass_expression_list, op in ass_details:
                new_result += finder.find_assignments(ass_expression_list[0],
                                                      result, seek_name)
            result = new_result
        return result
Пример #3
0
    def wrap(self, element):
        if isinstance(element,
                      (er.Wrapper, er.InstanceElement, er.ModuleWrapper,
                       er.FunctionExecution, er.Instance,
                       compiled.CompiledObject)) or element is None:
            # TODO this is so ugly, please refactor. id:211 gh:212
            return element

        if element.type == 'classdef':
            return er.Class(self, element)
        elif element.type == 'funcdef':
            return er.Function(self, element)
        elif element.type == 'lambda':
            return er.LambdaWrapper(self, element)
        elif element.type == 'file_input':
            return er.ModuleWrapper(self, element)
        else:
            return element
Пример #4
0
    def _names_to_types(self, names, resolve_decorator):
        types = []
        # Add isinstance and other if/assert knowledge.
        flow_scope = self.scope
        evaluator = self._evaluator
        while flow_scope:
            # TODO check if result is in scope -> no evaluation necessary
            n = check_flow_information(evaluator, flow_scope,
                                       self.name_str, self.position)
            if n:
                return n
            flow_scope = flow_scope.parent

        for name in names:
            typ = name.parent
            if typ.isinstance(pr.ForFlow):
                types += self._handle_for_loops(typ)
            elif isinstance(typ, pr.Param):
                types += self._eval_param(typ)
            elif typ.isinstance(pr.Statement):
                if typ.is_global():
                    # global keyword handling.
                    types += evaluator.find_types(typ.parent.parent, str(name))
                else:
                    types += self._remove_statements(typ, name)
            else:
                if isinstance(typ, pr.Class):
                    typ = er.Class(evaluator, typ)
                elif isinstance(typ, pr.Function):
                    typ = er.Function(evaluator, typ)
                elif isinstance(typ, pr.Module):
                    typ = er.ModuleWrapper(evaluator, typ)

                if typ.isinstance(er.Function) and resolve_decorator:
                    typ = typ.get_decorated_func()
                types.append(typ)

        if not names and isinstance(self.scope, er.Instance):
            # handling __getattr__ / __getattribute__
            types = self._check_getattr(self.scope)

        return types
Пример #5
0
def get_names_of_scope(evaluator, scope, position=None, star_search=True, include_builtin=True):
    """
    Get all completions (names) possible for the current scope. The star search
    option is only here to provide an optimization. Otherwise the whole thing
    would probably start a little recursive madness.

    This function is used to include names from outer scopes. For example, when
    the current scope is function:

    >>> from jedi._compatibility import u
    >>> from jedi.parser import Parser
    >>> parser = Parser(u('''
    ... x = ['a', 'b', 'c']
    ... def func():
    ...     y = None
    ... '''))
    >>> scope = parser.module.subscopes[0]
    >>> scope
    <Function: func@3-5>

    `get_names_of_scope` is a generator.  First it yields names from most inner
    scope.

    >>> from jedi.evaluate import Evaluator
    >>> pairs = list(get_names_of_scope(Evaluator(), scope))
    >>> pairs[0]
    (<Function: func@3-5>, [<Name: y@4,4>])

    Then it yield the names from one level outer scope. For this example, this
    is the most outer scope.

    >>> pairs[1]
    (<ModuleWrapper: <SubModule: None@1-5>>, [<Name: x@2,0>, <Name: func@3,4>])

    After that we have a few underscore names that have been defined

    >>> pairs[2]
    (<ModuleWrapper: <SubModule: None@1-5>>, [<FakeName: __file__@0,0>, ...])


    Finally, it yields names from builtin, if `include_builtin` is
    true (default).

    >>> pairs[3]                                        #doctest: +ELLIPSIS
    (<Builtin: ...builtin...>, [<CompiledName: ...>, ...])

    :rtype: [(pr.Scope, [pr.Name])]
    :return: Return an generator that yields a pair of scope and names.
    """
    if isinstance(scope, pr.ListComprehension):
        position = scope.parent.start_pos

    in_func_scope = scope
    non_flow = scope.get_parent_until(pr.Flow, reverse=True)
    while scope:
        # We don't want submodules to report if we have modules.
        # As well as some non-scopes, which are parents of list comprehensions.
        if isinstance(scope, pr.SubModule) and scope.parent or not scope.is_scope():
            scope = scope.parent
            continue
        # `pr.Class` is used, because the parent is never `Class`.
        # Ignore the Flows, because the classes and functions care for that.
        # InstanceElement of Class is ignored, if it is not the start scope.
        if not (scope != non_flow and scope.isinstance(pr.Class)
                or scope.isinstance(pr.Flow)
                or scope.isinstance(er.Instance)
                and non_flow.isinstance(er.Function)
                or isinstance(scope, compiled.CompiledObject)
                and scope.type() == 'class' and in_func_scope != scope):

            if isinstance(scope, (pr.SubModule, fast.Module)):
                scope = er.ModuleWrapper(evaluator, scope)

            for g in scope.scope_names_generator(position):
                yield g
        if scope.isinstance(pr.ListComprehension):
            # is a list comprehension
            yield scope, scope.get_defined_names(is_internal_call=True)

        scope = scope.parent
        # This is used, because subscopes (Flow scopes) would distort the
        # results.
        if scope and scope.isinstance(er.Function, pr.Function, er.FunctionExecution):
            in_func_scope = scope
        if in_func_scope != scope \
                and isinstance(in_func_scope, (pr.Function, er.FunctionExecution)):
            position = None

    # Add star imports.
    if star_search:
        for s in imports.remove_star_imports(evaluator, non_flow.get_parent_until()):
            for g in get_names_of_scope(evaluator, s, star_search=False):
                yield g

        # Add builtins to the global scope.
        if include_builtin:
            yield compiled.builtin, compiled.builtin.get_defined_names()