diff --git a/jedi/evaluate/representation.py b/jedi/evaluate/representation.py index 7de3d6eb..ad04ff41 100644 --- a/jedi/evaluate/representation.py +++ b/jedi/evaluate/representation.py @@ -677,12 +677,25 @@ class FunctionExecution(Executed): if check is flow_analysis.UNREACHABLE: debug.dbg('Return unreachable: %s', r) else: - types |= self._evaluator.eval_element(r.children[1]) + if check_yields: + types |= iterable.unite(self._eval_yield(r)) + else: + types |= self._evaluator.eval_element(r.children[1]) if check is flow_analysis.REACHABLE: debug.dbg('Return reachable: %s', r) break return types + def _eval_yield(self, yield_expr): + element = yield_expr.children[1] + if element.type == 'yield_arg': + # It must be a yield from. + yield_from_types = self._evaluator.eval_element(element.children[1]) + for result in iterable.py__iter__(self._evaluator, yield_from_types, element): + yield result + else: + yield self._evaluator.eval_element(element) + # TODO add execution_recursion_decorator?! def get_yield_types(self): yields = self.yields @@ -716,7 +729,8 @@ class FunctionExecution(Executed): if for_stmt is None: # No for_stmt, just normal yields. for yield_ in yields: - yield evaluator.eval_element(yield_.children[1]) + for result in self._eval_yield(yield_): + yield result else: input_node = for_stmt.get_input_node() for_types = evaluator.eval_element(input_node) @@ -725,7 +739,8 @@ class FunctionExecution(Executed): dct = {str(for_stmt.children[1]): index_types} evaluator.predefined_if_name_dict_dict[for_stmt] = dct for yield_in_same_for_stmt in yields: - yield evaluator.eval_element(yield_in_same_for_stmt.children[1]) + for result in self._eval_yield(yield_in_same_for_stmt): + yield result del evaluator.predefined_if_name_dict_dict[for_stmt] def names_dicts(self, search_global): diff --git a/test/completion/generators.py b/test/completion/generators.py index faf65bf7..d8eba2dd 100644 --- a/test/completion/generators.py +++ b/test/completion/generators.py @@ -175,3 +175,25 @@ gen().send() #? gen()() + +# ----------------- +# yield from +# ----------------- + +# python >= 3.3 + +def yield_from(): + yield from iter([1]) + +#? int() +next(yield_from()) + +def yield_from_multiple(): + yield from iter([1]) + yield str() + +x, y = yield_from_multiple() +#? int() +x +#? str() +y diff --git a/test/completion/pep0484_comments.py b/test/completion/pep0484_comments.py index 050eeb30..7d5f7c2e 100644 --- a/test/completion/pep0484_comments.py +++ b/test/completion/pep0484_comments.py @@ -49,7 +49,7 @@ class Employee: # The typing library is not installable for Python 2.6, therefore ignore the # following tests. -# python > 2.6 +# python >= 2.7 from typing import List x = [] # type: List[Employee] diff --git a/test/run.py b/test/run.py index cdb499df..3eef7343 100755 --- a/test/run.py +++ b/test/run.py @@ -240,8 +240,8 @@ def skip_python_version(line): '==': 'eq', '<=': 'le', '>=': 'ge', - '<': 'gk', - '>': 'lt', + '<': 'lt', + '>': 'gt', } # check for python minimal version number match = re.match(r" *# *python *([<>]=?|==) *(\d+(?:\.\d+)?)$", line)