Exemple #1
0
    def get_return_values(self, check_yields=False):
        funcdef = self.tree_node
        if funcdef.type == 'lambdef':
            return self.eval_node(funcdef.children[-1])

        if check_yields:
            context_set = NO_CONTEXTS
            returns = get_yield_exprs(self.evaluator, funcdef)
        else:
            returns = funcdef.iter_return_stmts()
            context_set = docstrings.infer_return_types(self.function_context)
            context_set |= pep0484.infer_return_types(self.function_context)

        for r in returns:
            check = flow_analysis.reachability_check(self, funcdef, r)
            if check is flow_analysis.UNREACHABLE:
                debug.dbg('Return unreachable: %s', r)
            else:
                if check_yields:
                    context_set |= ContextSet.from_sets(
                        lazy_context.infer()
                        for lazy_context in self._get_yield_lazy_context(r)
                    )
                else:
                    try:
                        children = r.children
                    except AttributeError:
                        ctx = compiled.builtin_from_name(self.evaluator, u'None')
                        context_set |= ContextSet(ctx)
                    else:
                        context_set |= self.eval_node(children[1])
            if check is flow_analysis.REACHABLE:
                debug.dbg('Return reachable: %s', r)
                break
        return context_set
Exemple #2
0
    def infer_function_execution(self, function_execution):
        """
        Created to be used by inheritance.
        """
        is_coroutine = self.tree_node.parent.type == 'async_stmt'
        is_generator = bool(get_yield_exprs(self.evaluator, self.tree_node))

        if is_coroutine:
            if is_generator:
                if self.evaluator.environment.version_info < (3, 6):
                    return NO_CONTEXTS
                return ContextSet(
                    asynchronous.AsyncGenerator(self.evaluator,
                                                function_execution))
            else:
                if self.evaluator.environment.version_info < (3, 5):
                    return NO_CONTEXTS
                return ContextSet(
                    asynchronous.Coroutine(self.evaluator, function_execution))
        else:
            if is_generator:
                return ContextSet(
                    iterable.Generator(self.evaluator, function_execution))
            else:
                return function_execution.get_return_values()
Exemple #3
0
    def get_return_values(self, check_yields=False):
        funcdef = self.tree_node
        if funcdef.type == 'lambdef':
            return self.eval_node(funcdef.children[-1])

        if check_yields:
            context_set = NO_CONTEXTS
            returns = get_yield_exprs(self.evaluator, funcdef)
        else:
            returns = funcdef.iter_return_stmts()
            context_set = docstrings.infer_return_types(self.function_context)
            context_set |= pep0484.infer_return_types(self.function_context)

        for r in returns:
            check = flow_analysis.reachability_check(self, funcdef, r)
            if check is flow_analysis.UNREACHABLE:
                debug.dbg('Return unreachable: %s', r)
            else:
                if check_yields:
                    context_set |= ContextSet.from_sets(
                        lazy_context.infer()
                        for lazy_context in self._get_yield_lazy_context(r)
                    )
                else:
                    try:
                        children = r.children
                    except AttributeError:
                        ctx = compiled.builtin_from_name(self.evaluator, u'None')
                        context_set |= ContextSet(ctx)
                    else:
                        context_set |= self.eval_node(children[1])
            if check is flow_analysis.REACHABLE:
                debug.dbg('Return reachable: %s', r)
                break
        return context_set
    def get_return_values(self, check_yields=False):
        funcdef = self.tree_node
        if funcdef.type == 'lambdef':
            return self.evaluator.eval_element(self, funcdef.children[-1])

        if check_yields:
            types = set()
            returns = get_yield_exprs(self.evaluator, funcdef)
        else:
            returns = funcdef.iter_return_stmts()
            types = set(docstrings.infer_return_types(self.function_context))
            types |= set(pep0484.infer_return_types(self.function_context))

        for r in returns:
            check = flow_analysis.reachability_check(self, funcdef, r)
            if check is flow_analysis.UNREACHABLE:
                debug.dbg('Return unreachable: %s', r)
            else:
                if check_yields:
                    types |= set(self._eval_yield(r))
                else:
                    try:
                        children = r.children
                    except AttributeError:
                        types.add(compiled.create(self.evaluator, None))
                    else:
                        types |= self.eval_node(children[1])
            if check is flow_analysis.REACHABLE:
                debug.dbg('Return reachable: %s', r)
                break
        return types
    def get_return_values(self, check_yields=False):
        funcdef = self.tree_node
        if funcdef.type == 'lambdef':
            return self.evaluator.eval_element(self, funcdef.children[-1])

        if check_yields:
            types = set()
            returns = get_yield_exprs(self.evaluator, funcdef)
        else:
            returns = funcdef.iter_return_stmts()
            types = set(docstrings.infer_return_types(self.function_context))
            types |= set(pep0484.infer_return_types(self.function_context))

        for r in returns:
            check = flow_analysis.reachability_check(self, funcdef, r)
            if check is flow_analysis.UNREACHABLE:
                debug.dbg('Return unreachable: %s', r)
            else:
                if check_yields:
                    types |= set(self._eval_yield(r))
                else:
                    try:
                        children = r.children
                    except AttributeError:
                        types.add(compiled.create(self.evaluator, None))
                    else:
                        types |= self.eval_node(children[1])
            if check is flow_analysis.REACHABLE:
                debug.dbg('Return reachable: %s', r)
                break
        return types
 def infer_function_execution(self, function_execution):
     """
     Created to be used by inheritance.
     """
     yield_exprs = get_yield_exprs(self.evaluator, self.tree_node)
     if yield_exprs:
         return set([iterable.Generator(self.evaluator, function_execution)])
     else:
         return function_execution.get_return_values()
 def infer_function_execution(self, function_execution):
     """
     Created to be used by inheritance.
     """
     yield_exprs = get_yield_exprs(self.evaluator, self.tree_node)
     if yield_exprs:
         return set(
             [iterable.Generator(self.evaluator, function_execution)])
     else:
         return function_execution.get_return_values()
Exemple #8
0
    def get_yield_lazy_contexts(self, is_async=False):
        # TODO: if is_async, wrap yield statements in Awaitable/async_generator_asend
        for_parents = [(y,
                        tree.search_ancestor(y, 'for_stmt', 'funcdef',
                                             'while_stmt', 'if_stmt'))
                       for y in get_yield_exprs(self.evaluator, self.tree_node)
                       ]

        # Calculate if the yields are placed within the same for loop.
        yields_order = []
        last_for_stmt = None
        for yield_, for_stmt in for_parents:
            # For really simple for loops we can predict the order. Otherwise
            # we just ignore it.
            parent = for_stmt.parent
            if parent.type == 'suite':
                parent = parent.parent
            if for_stmt.type == 'for_stmt' and parent == self.tree_node \
                    and parser_utils.for_stmt_defines_one_name(for_stmt):  # Simplicity for now.
                if for_stmt == last_for_stmt:
                    yields_order[-1][1].append(yield_)
                else:
                    yields_order.append((for_stmt, [yield_]))
            elif for_stmt == self.tree_node:
                yields_order.append((None, [yield_]))
            else:
                types = self.get_return_values(check_yields=True)
                if types:
                    yield LazyKnownContexts(types)
                return
            last_for_stmt = for_stmt

        for for_stmt, yields in yields_order:
            if for_stmt is None:
                # No for_stmt, just normal yields.
                for yield_ in yields:
                    for result in self._get_yield_lazy_context(yield_):
                        yield result
            else:
                input_node = for_stmt.get_testlist()
                cn = ContextualizedNode(self, input_node)
                ordered = cn.infer().iterate(cn)
                ordered = list(ordered)
                for lazy_context in ordered:
                    dct = {
                        str(for_stmt.children[1].value): lazy_context.infer()
                    }
                    with helpers.predefine_names(self, for_stmt, dct):
                        for yield_in_same_for_stmt in yields:
                            for result in self._get_yield_lazy_context(
                                    yield_in_same_for_stmt):
                                yield result
Exemple #9
0
    def get_yield_lazy_contexts(self, is_async=False):
        # TODO: if is_async, wrap yield statements in Awaitable/async_generator_asend
        for_parents = [(y, tree.search_ancestor(y, 'for_stmt', 'funcdef',
                                                'while_stmt', 'if_stmt'))
                       for y in get_yield_exprs(self.evaluator, self.tree_node)]

        # Calculate if the yields are placed within the same for loop.
        yields_order = []
        last_for_stmt = None
        for yield_, for_stmt in for_parents:
            # For really simple for loops we can predict the order. Otherwise
            # we just ignore it.
            parent = for_stmt.parent
            if parent.type == 'suite':
                parent = parent.parent
            if for_stmt.type == 'for_stmt' and parent == self.tree_node \
                    and parser_utils.for_stmt_defines_one_name(for_stmt):  # Simplicity for now.
                if for_stmt == last_for_stmt:
                    yields_order[-1][1].append(yield_)
                else:
                    yields_order.append((for_stmt, [yield_]))
            elif for_stmt == self.tree_node:
                yields_order.append((None, [yield_]))
            else:
                types = self.get_return_values(check_yields=True)
                if types:
                    yield LazyKnownContexts(types)
                return
            last_for_stmt = for_stmt

        for for_stmt, yields in yields_order:
            if for_stmt is None:
                # No for_stmt, just normal yields.
                for yield_ in yields:
                    for result in self._get_yield_lazy_context(yield_):
                        yield result
            else:
                input_node = for_stmt.get_testlist()
                cn = ContextualizedNode(self, input_node)
                ordered = cn.infer().iterate(cn)
                ordered = list(ordered)
                for lazy_context in ordered:
                    dct = {str(for_stmt.children[1].value): lazy_context.infer()}
                    with helpers.predefine_names(self, for_stmt, dct):
                        for yield_in_same_for_stmt in yields:
                            for result in self._get_yield_lazy_context(yield_in_same_for_stmt):
                                yield result
Exemple #10
0
    def infer(self):
        """
        Created to be used by inheritance.
        """
        evaluator = self.evaluator
        is_coroutine = self.tree_node.parent.type in ('async_stmt',
                                                      'async_funcdef')
        is_generator = bool(get_yield_exprs(evaluator, self.tree_node))
        from jedi.evaluate.gradual.typing import GenericClass

        if is_coroutine:
            if is_generator:
                if evaluator.environment.version_info < (3, 6):
                    return NO_CONTEXTS
                async_generator_classes = evaluator.typing_module \
                    .py__getattribute__('AsyncGenerator')

                yield_contexts = self.merge_yield_contexts(is_async=True)
                # The contravariant doesn't seem to be defined.
                generics = (yield_contexts.py__class__(), NO_CONTEXTS)
                return ContextSet(
                    # In Python 3.6 AsyncGenerator is still a class.
                    GenericClass(c, generics)
                    for c in async_generator_classes).execute_annotation()
            else:
                if evaluator.environment.version_info < (3, 5):
                    return NO_CONTEXTS
                async_classes = evaluator.typing_module.py__getattribute__(
                    'Coroutine')
                return_contexts = self.get_return_values()
                # Only the first generic is relevant.
                generics = (return_contexts.py__class__(), NO_CONTEXTS,
                            NO_CONTEXTS)
                return ContextSet(
                    GenericClass(c, generics)
                    for c in async_classes).execute_annotation()
        else:
            if is_generator:
                return ContextSet([iterable.Generator(evaluator, self)])
            else:
                return self.get_return_values()
Exemple #11
0
    def infer_function_execution(self, function_execution):
        """
        Created to be used by inheritance.
        """
        is_coroutine = self.tree_node.parent.type == 'async_stmt'
        is_generator = bool(get_yield_exprs(self.evaluator, self.tree_node))

        if is_coroutine:
            if is_generator:
                if self.evaluator.environment.version_info < (3, 6):
                    return NO_CONTEXTS
                return ContextSet(asynchronous.AsyncGenerator(self.evaluator, function_execution))
            else:
                if self.evaluator.environment.version_info < (3, 5):
                    return NO_CONTEXTS
                return ContextSet(asynchronous.Coroutine(self.evaluator, function_execution))
        else:
            if is_generator:
                return ContextSet(iterable.Generator(self.evaluator, function_execution))
            else:
                return function_execution.get_return_values()
Exemple #12
0
    def get_return_values(self, check_yields=False):
        funcdef = self.tree_node
        if funcdef.type == 'lambdef':
            return self.eval_node(funcdef.children[-1])

        if check_yields:
            context_set = NO_CONTEXTS
            returns = get_yield_exprs(self.evaluator, funcdef)
        else:
            returns = funcdef.iter_return_stmts()
            from jedi.evaluate.gradual.annotation import infer_return_types
            context_set = infer_return_types(self)
            if context_set:
                # If there are annotations, prefer them over anything else.
                # This will make it faster.
                return context_set
            context_set |= docstrings.infer_return_types(self.function_context)

        for r in returns:
            check = flow_analysis.reachability_check(self, funcdef, r)
            if check is flow_analysis.UNREACHABLE:
                debug.dbg('Return unreachable: %s', r)
            else:
                if check_yields:
                    context_set |= ContextSet.from_sets(
                        lazy_context.infer()
                        for lazy_context in self._get_yield_lazy_context(r))
                else:
                    try:
                        children = r.children
                    except AttributeError:
                        ctx = compiled.builtin_from_name(
                            self.evaluator, u'None')
                        context_set |= ContextSet([ctx])
                    else:
                        context_set |= self.eval_node(children[1])
            if check is flow_analysis.REACHABLE:
                debug.dbg('Return reachable: %s', r)
                break
        return context_set