Пример #1
0
def _evaluate_for_statement_string(module_context, string):
    code = dedent(u("""
    def pseudo_docstring_stuff():
        '''
        Create a pseudo function for docstring statements.
        Need this docstring so that if the below part is not valid Python this
        is still a function.
        '''
    {}
    """))
    if string is None:
        return []

    for element in re.findall(r'((?:\w+\.)*\w+)\.', string):
        # Try to import module part in dotted name.
        # (e.g., 'threading' in 'threading.Thread').
        string = 'import %s\n' % element + string

    # Take the default grammar here, if we load the Python 2.7 grammar here, it
    # will be impossible to use `...` (Ellipsis) as a token. Docstring types
    # don't need to conform with the current grammar.
    grammar = module_context.evaluator.latest_grammar
    try:
        module = grammar.parse(code.format(indent_block(string)), error_recovery=False)
    except ParserSyntaxError:
        return []
    try:
        funcdef = next(module.iter_funcdefs())
        # First pick suite, then simple_stmt and then the node,
        # which is also not the last item, because there's a newline.
        stmt = funcdef.children[-1].children[-1].children[-2]
    except (AttributeError, IndexError):
        return []

    if stmt.type not in ('name', 'atom', 'atom_expr'):
        return []

    from jedi.evaluate.context import FunctionContext
    function_context = FunctionContext(
        module_context.evaluator,
        module_context,
        funcdef
    )
    func_execution_context = function_context.get_function_execution()
    # Use the module of the param.
    # TODO this module is not the module of the param in case of a function
    # call. In that case it's the module of the function call.
    # stuffed with content from a function call.
    return list(_execute_types_in_stmt(func_execution_context, stmt))
Пример #2
0
def _evaluate_for_statement_string(module_context, string):
    code = dedent(
        u("""
    def pseudo_docstring_stuff():
        '''
        Create a pseudo function for docstring statements.
        Need this docstring so that if the below part is not valid Python this
        is still a function.
        '''
    {}
    """))
    if string is None:
        return []

    for element in re.findall(r'((?:\w+\.)*\w+)\.', string):
        # Try to import module part in dotted name.
        # (e.g., 'threading' in 'threading.Thread').
        string = 'import %s\n' % element + string

    # Take the default grammar here, if we load the Python 2.7 grammar here, it
    # will be impossible to use `...` (Ellipsis) as a token. Docstring types
    # don't need to conform with the current grammar.
    debug.dbg('Parse docstring code %s', string, color='BLUE')
    grammar = module_context.evaluator.latest_grammar
    try:
        module = grammar.parse(code.format(indent_block(string)),
                               error_recovery=False)
    except ParserSyntaxError:
        return []
    try:
        funcdef = next(module.iter_funcdefs())
        # First pick suite, then simple_stmt and then the node,
        # which is also not the last item, because there's a newline.
        stmt = funcdef.children[-1].children[-1].children[-2]
    except (AttributeError, IndexError):
        return []

    if stmt.type not in ('name', 'atom', 'atom_expr'):
        return []

    from jedi.evaluate.context import FunctionContext
    function_context = FunctionContext(module_context.evaluator,
                                       module_context, funcdef)
    func_execution_context = function_context.get_function_execution()
    # Use the module of the param.
    # TODO this module is not the module of the param in case of a function
    # call. In that case it's the module of the function call.
    # stuffed with content from a function call.
    return list(_execute_types_in_stmt(func_execution_context, stmt))
Пример #3
0
        def from_scope_node(scope_node, is_nested=True, node_is_object=False):
            if scope_node == base_node:
                return base_context

            is_funcdef = scope_node.type in ('funcdef', 'lambdef')
            parent_scope = parser_utils.get_parent_scope(scope_node)
            parent_context = from_scope_node(parent_scope)

            if is_funcdef:
                func = FunctionContext.from_context(parent_context, scope_node)
                if parent_context.is_class():
                    instance = AnonymousInstance(
                        self, parent_context.parent_context, parent_context)
                    func = BoundMethod(
                        instance=instance,
                        function=func
                    )

                if is_nested and not node_is_object:
                    return func.get_function_execution()
                return func
            elif scope_node.type == 'classdef':
                return ClassContext(self, parent_context, scope_node)
            elif scope_node.type == 'comp_for':
                if node.start_pos >= scope_node.children[-1].start_pos:
                    return parent_context
                return CompForContext.from_comp_for(parent_context, scope_node)
            raise Exception("There's a scope that was not managed.")
Пример #4
0
    def goto_stub_definitions(self, context, name):
        def_ = name.get_definition(import_name_always=True)
        if def_ is not None:
            type_ = def_.type
            is_classdef = type_ == 'classdef'
            if is_classdef or type_ == 'funcdef':
                if is_classdef:
                    c = ClassContext(self, context, name.parent)
                else:
                    c = FunctionContext.from_context(context, name.parent)
                return ContextSet([c])

            if type_ == 'expr_stmt':
                is_simple_name = name.parent.type not in ('power', 'trailer')
                if is_simple_name:
                    return eval_expr_stmt(context, def_, name)
            if type_ == 'for_stmt':
                container_types = context.eval_node(def_.children[3])
                cn = ContextualizedNode(context, def_.children[3])
                for_types = iterate_contexts(container_types, cn)
                c_node = ContextualizedName(context, name)
                return check_tuple_assignments(self, c_node, for_types)
            if type_ in ('import_from', 'import_name'):
                return imports.infer_import(context, name)
        else:
            result = self._follow_error_node_imports_if_possible(context, name)
            if result is not None:
                return result

        return helpers.evaluate_call_of_leaf(context, name)
Пример #5
0
def _apply_decorators(context, node):
    """
    Returns the function, that should to be executed in the end.
    This is also the places where the decorators are processed.
    """
    if node.type == 'classdef':
        decoratee_context = ClassContext(context.evaluator,
                                         parent_context=context,
                                         tree_node=node)
    else:
        decoratee_context = FunctionContext.from_context(context, node)
    initial = values = ContextSet(decoratee_context)
    for dec in reversed(node.get_decorators()):
        debug.dbg('decorator: %s %s', dec, values)
        dec_values = context.eval_node(dec.children[1])
        trailer_nodes = dec.children[2:-1]
        if trailer_nodes:
            # Create a trailer and evaluate it.
            trailer = tree.PythonNode('trailer', trailer_nodes)
            trailer.parent = dec
            dec_values = eval_trailer(context, dec_values, trailer)

        if not len(dec_values):
            debug.warning('decorator not found: %s on %s', dec, node)
            return initial

        values = dec_values.execute(arguments.ValuesArguments([values]))
        if not len(values):
            debug.warning('not possible to resolve wrappers found %s', node)
            return initial

        debug.dbg('decorator end %s', values)
    return values
Пример #6
0
def _apply_decorators(context, node):
    """
    Returns the function, that should to be executed in the end.
    This is also the places where the decorators are processed.
    """
    if node.type == 'classdef':
        decoratee_context = ClassContext(
            context.evaluator,
            parent_context=context,
            tree_node=node
        )
    else:
        decoratee_context = FunctionContext.from_context(context, node)
    initial = values = ContextSet(decoratee_context)
    for dec in reversed(node.get_decorators()):
        debug.dbg('decorator: %s %s', dec, values)
        dec_values = context.eval_node(dec.children[1])
        trailer_nodes = dec.children[2:-1]
        if trailer_nodes:
            # Create a trailer and evaluate it.
            trailer = tree.PythonNode('trailer', trailer_nodes)
            trailer.parent = dec
            dec_values = eval_trailer(context, dec_values, trailer)

        if not len(dec_values):
            debug.warning('decorator not found: %s on %s', dec, node)
            return initial

        values = dec_values.execute(arguments.ValuesArguments([values]))
        if not len(values):
            debug.warning('not possible to resolve wrappers found %s', node)
            return initial

        debug.dbg('decorator end %s', values)
    return values
Пример #7
0
        def from_scope_node(scope_node, child_is_funcdef=None, is_nested=True, node_is_object=False):
            if scope_node == base_node:
                return base_context

            is_funcdef = scope_node.type in ('funcdef', 'lambdef')
            parent_scope = parser_utils.get_parent_scope(scope_node)
            parent_context = from_scope_node(parent_scope, child_is_funcdef=is_funcdef)

            if is_funcdef:
                func = FunctionContext.from_context(
                    parent_context,
                    scope_node
                )
                if isinstance(parent_context, AnonymousInstance):
                    func = BoundMethod(
                        instance=parent_context,
                        klass=parent_context.class_context,
                        function=func
                    )
                if is_nested and not node_is_object:
                    return func.get_function_execution()
                return func
            elif scope_node.type == 'classdef':
                class_context = ClassContext(self, parent_context, scope_node)
                if child_is_funcdef:
                    # anonymous instance
                    return AnonymousInstance(self, parent_context, class_context)
                else:
                    return class_context
            elif scope_node.type == 'comp_for':
                if node.start_pos >= scope_node.children[-1].start_pos:
                    return parent_context
                return CompForContext.from_comp_for(parent_context, scope_node)
            raise Exception("There's a scope that was not managed.")
Пример #8
0
    def parent(self):
        context = self._name.parent_context
        if context is None:
            return None

        if isinstance(context, FunctionExecutionContext):
            # TODO the function context should be a part of the function
            # execution context.
            context = FunctionContext(
                self._evaluator, context.parent_context, context.tree_node)
        return Definition(self._evaluator, context.name)
Пример #9
0
def _apply_decorators(context, node):
    """
    Returns the function, that should to be executed in the end.
    This is also the places where the decorators are processed.
    """
    if node.type == 'classdef':
        decoratee_context = ClassContext(
            context.evaluator,
            parent_context=context,
            tree_node=node
        )
    else:
        decoratee_context = FunctionContext.from_context(context, node)
    initial = values = ContextSet([decoratee_context])
    for dec in reversed(node.get_decorators()):
        debug.dbg('decorator: %s %s', dec, values, color="MAGENTA")
        with debug.increase_indent_cm():
            dec_values = context.eval_node(dec.children[1])
            trailer_nodes = dec.children[2:-1]
            if trailer_nodes:
                # Create a trailer and evaluate it.
                trailer = tree.PythonNode('trailer', trailer_nodes)
                trailer.parent = dec
                dec_values = eval_trailer(context, dec_values, trailer)

            if not len(dec_values):
                code = dec.get_code(include_prefix=False)
                # For the short future, we don't want to hear about the runtime
                # decorator in typing that was intentionally omitted. This is not
                # "correct", but helps with debugging.
                if code != '@runtime\n':
                    debug.warning('decorator not found: %s on %s', dec, node)
                return initial

            values = dec_values.execute(arguments.ValuesArguments([values]))
            if not len(values):
                debug.warning('not possible to resolve wrappers found %s', node)
                return initial

        debug.dbg('decorator end %s', values, color="MAGENTA")
    if values != initial:
        return ContextSet([Decoratee(c, decoratee_context) for c in values])
    return values
Пример #10
0
    def goto_definitions(self, context, name):
        def_ = name.get_definition(import_name_always=True)
        if def_ is not None:
            type_ = def_.type
            if type_ == 'classdef':
                return [ClassContext(self, context, name.parent)]
            elif type_ == 'funcdef':
                return [FunctionContext(self, context, name.parent)]

            if type_ == 'expr_stmt':
                is_simple_name = name.parent.type not in ('power', 'trailer')
                if is_simple_name:
                    return eval_expr_stmt(context, def_, name)
            if type_ == 'for_stmt':
                container_types = context.eval_node(def_.children[3])
                cn = ContextualizedNode(context, def_.children[3])
                for_types = iterate_contexts(container_types, cn)
                c_node = ContextualizedName(context, name)
                return check_tuple_assignments(self, c_node, for_types)
            if type_ in ('import_from', 'import_name'):
                return imports.infer_import(context, name)

        return helpers.evaluate_call_of_leaf(context, name)
Пример #11
0
    def goto_definitions(self, context, name):
        def_ = name.get_definition(import_name_always=True)
        if def_ is not None:
            type_ = def_.type
            if type_ == 'classdef':
                return [ClassContext(self, context, name.parent)]
            elif type_ == 'funcdef':
                return [FunctionContext.from_context(context, name.parent)]

            if type_ == 'expr_stmt':
                is_simple_name = name.parent.type not in ('power', 'trailer')
                if is_simple_name:
                    return eval_expr_stmt(context, def_, name)
            if type_ == 'for_stmt':
                container_types = context.eval_node(def_.children[3])
                cn = ContextualizedNode(context, def_.children[3])
                for_types = iterate_contexts(container_types, cn)
                c_node = ContextualizedName(context, name)
                return check_tuple_assignments(self, c_node, for_types)
            if type_ in ('import_from', 'import_name'):
                return imports.infer_import(context, name)

        return helpers.evaluate_call_of_leaf(context, name)
Пример #12
0
def eval_node(context, element):
    debug.dbg('eval_node %s@%s in %s', element, element.start_pos, context)
    evaluator = context.evaluator
    typ = element.type
    if typ in ('name', 'number', 'string', 'atom', 'strings', 'keyword',
               'fstring'):
        return eval_atom(context, element)
    elif typ == 'lambdef':
        return ContextSet([FunctionContext.from_context(context, element)])
    elif typ == 'expr_stmt':
        return eval_expr_stmt(context, element)
    elif typ in ('power', 'atom_expr'):
        first_child = element.children[0]
        children = element.children[1:]
        had_await = False
        if first_child.type == 'keyword' and first_child.value == 'await':
            had_await = True
            first_child = children.pop(0)

        context_set = context.eval_node(first_child)
        for (i, trailer) in enumerate(children):
            if trailer == '**':  # has a power operation.
                right = context.eval_node(children[i + 1])
                context_set = _eval_comparison(evaluator, context, context_set,
                                               trailer, right)
                break
            context_set = eval_trailer(context, context_set, trailer)

        if had_await:
            return context_set.py__await__().py__stop_iteration_returns()
        return context_set
    elif typ in (
            'testlist_star_expr',
            'testlist',
    ):
        # The implicit tuple in statements.
        return ContextSet(
            [iterable.SequenceLiteralContext(evaluator, context, element)])
    elif typ in ('not_test', 'factor'):
        context_set = context.eval_node(element.children[-1])
        for operator in element.children[:-1]:
            context_set = eval_factor(context_set, operator)
        return context_set
    elif typ == 'test':
        # `x if foo else y` case.
        return (context.eval_node(element.children[0])
                | context.eval_node(element.children[-1]))
    elif typ == 'operator':
        # Must be an ellipsis, other operators are not evaluated.
        # In Python 2 ellipsis is coded as three single dot tokens, not
        # as one token 3 dot token.
        if element.value not in ('.', '...'):
            origin = element.parent
            raise AssertionError("unhandled operator %s in %s " %
                                 (repr(element.value), origin))
        return ContextSet([compiled.builtin_from_name(evaluator, u'Ellipsis')])
    elif typ == 'dotted_name':
        context_set = eval_atom(context, element.children[0])
        for next_name in element.children[2::2]:
            # TODO add search_global=True?
            context_set = context_set.py__getattribute__(next_name,
                                                         name_context=context)
        return context_set
    elif typ == 'eval_input':
        return eval_node(context, element.children[0])
    elif typ == 'annassign':
        return annotation.eval_annotation(context, element.children[1]) \
            .execute_annotation()
    elif typ == 'yield_expr':
        if len(element.children) and element.children[1].type == 'yield_arg':
            # Implies that it's a yield from.
            element = element.children[1].children[1]
            generators = context.eval_node(element) \
                .py__getattribute__('__iter__').execute_evaluated()
            return generators.py__stop_iteration_returns()

        # Generator.send() is not implemented.
        return NO_CONTEXTS
    elif typ == 'namedexpr_test':
        return eval_node(context, element.children[2])
    else:
        return eval_or_test(context, element)
Пример #13
0
def eval_node(context, element):
    debug.dbg('eval_element %s@%s', element, element.start_pos)
    evaluator = context.evaluator
    typ = element.type
    if typ in ('name', 'number', 'string', 'atom'):
        return eval_atom(context, element)
    elif typ == 'keyword':
        # For False/True/None
        if element.value in ('False', 'True', 'None'):
            return ContextSet(
                compiled.builtin_from_name(evaluator, element.value))
        # else: print e.g. could be evaluated like this in Python 2.7
        return NO_CONTEXTS
    elif typ == 'lambdef':
        return ContextSet(FunctionContext(evaluator, context, element))
    elif typ == 'expr_stmt':
        return eval_expr_stmt(context, element)
    elif typ in ('power', 'atom_expr'):
        first_child = element.children[0]
        if not (first_child.type == 'keyword'
                and first_child.value == 'await'):
            context_set = eval_atom(context, first_child)
            for trailer in element.children[1:]:
                if trailer == '**':  # has a power operation.
                    right = evaluator.eval_element(context,
                                                   element.children[2])
                    context_set = _eval_comparison(evaluator, context,
                                                   context_set, trailer, right)
                    break
                context_set = eval_trailer(context, context_set, trailer)
            return context_set
        return NO_CONTEXTS
    elif typ in (
            'testlist_star_expr',
            'testlist',
    ):
        # The implicit tuple in statements.
        return ContextSet(
            iterable.SequenceLiteralContext(evaluator, context, element))
    elif typ in ('not_test', 'factor'):
        context_set = context.eval_node(element.children[-1])
        for operator in element.children[:-1]:
            context_set = eval_factor(context_set, operator)
        return context_set
    elif typ == 'test':
        # `x if foo else y` case.
        return (context.eval_node(element.children[0])
                | context.eval_node(element.children[-1]))
    elif typ == 'operator':
        # Must be an ellipsis, other operators are not evaluated.
        # In Python 2 ellipsis is coded as three single dot tokens, not
        # as one token 3 dot token.
        assert element.value in ('.', '...')
        return ContextSet(compiled.create(evaluator, Ellipsis))
    elif typ == 'dotted_name':
        context_set = eval_atom(context, element.children[0])
        for next_name in element.children[2::2]:
            # TODO add search_global=True? id:489 gh:490
            context_set = context_set.py__getattribute__(next_name,
                                                         name_context=context)
        return context_set
    elif typ == 'eval_input':
        return eval_node(context, element.children[0])
    elif typ == 'annassign':
        return pep0484._evaluate_for_annotation(context, element.children[1])
    else:
        return eval_or_test(context, element)
Пример #14
0
def eval_node(context, element):
    debug.dbg('eval_node %s@%s', element, element.start_pos)
    evaluator = context.evaluator
    typ = element.type
    if typ in ('name', 'number', 'string', 'atom', 'strings', 'keyword'):
        return eval_atom(context, element)
    elif typ == 'lambdef':
        return ContextSet(FunctionContext.from_context(context, element))
    elif typ == 'expr_stmt':
        return eval_expr_stmt(context, element)
    elif typ in ('power', 'atom_expr'):
        first_child = element.children[0]
        children = element.children[1:]
        had_await = False
        if first_child.type == 'keyword' and first_child.value == 'await':
            had_await = True
            first_child = children.pop(0)

        context_set = eval_atom(context, first_child)
        for trailer in children:
            if trailer == '**':  # has a power operation.
                right = context.eval_node(children[1])
                context_set = _eval_comparison(
                    evaluator,
                    context,
                    context_set,
                    trailer,
                    right
                )
                break
            context_set = eval_trailer(context, context_set, trailer)

        if had_await:
            await_context_set = context_set.py__getattribute__(u"__await__")
            if not await_context_set:
                debug.warning('Tried to run py__await__ on context %s', context)
            context_set = ContextSet()
            return _py__stop_iteration_returns(await_context_set.execute_evaluated())
        return context_set
    elif typ in ('testlist_star_expr', 'testlist',):
        # The implicit tuple in statements.
        return ContextSet(iterable.SequenceLiteralContext(evaluator, context, element))
    elif typ in ('not_test', 'factor'):
        context_set = context.eval_node(element.children[-1])
        for operator in element.children[:-1]:
            context_set = eval_factor(context_set, operator)
        return context_set
    elif typ == 'test':
        # `x if foo else y` case.
        return (context.eval_node(element.children[0]) |
                context.eval_node(element.children[-1]))
    elif typ == 'operator':
        # Must be an ellipsis, other operators are not evaluated.
        # In Python 2 ellipsis is coded as three single dot tokens, not
        # as one token 3 dot token.
        if element.value not in ('.', '...'):
            origin = element.parent
            raise AssertionError("unhandled operator %s in %s " % (repr(element.value), origin))
        return ContextSet(compiled.builtin_from_name(evaluator, u'Ellipsis'))
    elif typ == 'dotted_name':
        context_set = eval_atom(context, element.children[0])
        for next_name in element.children[2::2]:
            # TODO add search_global=True?
            context_set = context_set.py__getattribute__(next_name, name_context=context)
        return context_set
    elif typ == 'eval_input':
        return eval_node(context, element.children[0])
    elif typ == 'annassign':
        return pep0484._evaluate_for_annotation(context, element.children[1])
    elif typ == 'yield_expr':
        if len(element.children) and element.children[1].type == 'yield_arg':
            # Implies that it's a yield from.
            element = element.children[1].children[1]
            generators = context.eval_node(element)
            return _py__stop_iteration_returns(generators)

        # Generator.send() is not implemented.
        return NO_CONTEXTS
    else:
        return eval_or_test(context, element)
Пример #15
0
def eval_node(context, element):
    debug.dbg('eval_element %s@%s', element, element.start_pos)
    evaluator = context.evaluator
    typ = element.type
    if typ in ('name', 'number', 'string', 'atom'):
        return eval_atom(context, element)
    elif typ == 'keyword':
        # For False/True/None
        if element.value in ('False', 'True', 'None'):
            return ContextSet(compiled.builtin_from_name(evaluator, element.value))
        # else: print e.g. could be evaluated like this in Python 2.7
        return NO_CONTEXTS
    elif typ == 'lambdef':
        return ContextSet(FunctionContext(evaluator, context, element))
    elif typ == 'expr_stmt':
        return eval_expr_stmt(context, element)
    elif typ in ('power', 'atom_expr'):
        first_child = element.children[0]
        children = element.children[1:]
        had_await = False
        if first_child.type == 'keyword' and first_child.value == 'await':
            had_await = True
            first_child = children.pop(0)

        context_set = eval_atom(context, first_child)
        for trailer in children:
            if trailer == '**':  # has a power operation.
                right = evaluator.eval_element(context, children[1])
                context_set = _eval_comparison(
                    evaluator,
                    context,
                    context_set,
                    trailer,
                    right
                )
                break
            context_set = eval_trailer(context, context_set, trailer)

        if had_await:
            await_context_set = context_set.py__getattribute__(u"__await__")
            if not await_context_set:
                debug.warning('Tried to run py__await__ on context %s', context)
            context_set = ContextSet()
            return _py__stop_iteration_returns(await_context_set.execute_evaluated())
        return context_set
    elif typ in ('testlist_star_expr', 'testlist',):
        # The implicit tuple in statements.
        return ContextSet(iterable.SequenceLiteralContext(evaluator, context, element))
    elif typ in ('not_test', 'factor'):
        context_set = context.eval_node(element.children[-1])
        for operator in element.children[:-1]:
            context_set = eval_factor(context_set, operator)
        return context_set
    elif typ == 'test':
        # `x if foo else y` case.
        return (context.eval_node(element.children[0]) |
                context.eval_node(element.children[-1]))
    elif typ == 'operator':
        # Must be an ellipsis, other operators are not evaluated.
        # In Python 2 ellipsis is coded as three single dot tokens, not
        # as one token 3 dot token.
        assert element.value in ('.', '...'), "The unhandled operator %s" % repr(element.value)
        return ContextSet(compiled.builtin_from_name(evaluator, u'Ellipsis'))
    elif typ == 'dotted_name':
        context_set = eval_atom(context, element.children[0])
        for next_name in element.children[2::2]:
            # TODO add search_global=True?
            context_set = context_set.py__getattribute__(next_name, name_context=context)
        return context_set
    elif typ == 'eval_input':
        return eval_node(context, element.children[0])
    elif typ == 'annassign':
        return pep0484._evaluate_for_annotation(context, element.children[1])
    elif typ == 'yield_expr':
        if len(element.children) and element.children[1].type == 'yield_arg':
            # Implies that it's a yield from.
            element = element.children[1].children[1]
            generators = context.eval_node(element)
            return _py__stop_iteration_returns(generators)

        # Generator.send() is not implemented.
        return NO_CONTEXTS
    else:
        return eval_or_test(context, element)