From 278bc9d705129ac7333185c2d2d0eace0d0ded0d Mon Sep 17 00:00:00 2001 From: Dave Halter Date: Fri, 14 Nov 2014 02:05:25 +0100 Subject: [PATCH] Fix generators. --- jedi/evaluate/__init__.py | 1 + jedi/evaluate/iterable.py | 3 ++- jedi/evaluate/recursion.py | 4 ++-- jedi/evaluate/representation.py | 17 ++++++++++++++--- 4 files changed, 19 insertions(+), 6 deletions(-) diff --git a/jedi/evaluate/__init__.py b/jedi/evaluate/__init__.py index 71c1f388..8215bc1b 100644 --- a/jedi/evaluate/__init__.py +++ b/jedi/evaluate/__init__.py @@ -164,6 +164,7 @@ class Evaluator(object): debug.dbg('eval_statement result %s', types) return types + @memoize_default(evaluator_is_first_arg=True) def eval_element(self, element): debug.dbg('eval_element %s', element) if isinstance(element, (pr.Name, pr.Literal)) or pr.is_node(element, 'atom'): diff --git a/jedi/evaluate/iterable.py b/jedi/evaluate/iterable.py index 3d0f8cab..2d6eea30 100644 --- a/jedi/evaluate/iterable.py +++ b/jedi/evaluate/iterable.py @@ -84,7 +84,8 @@ class Generator(use_metaclass(CachedMetaClass, IterableWrapper, GeneratorMixin)) # Directly execute it, because with a normal call to py__call__ a # Generator will be returned. from jedi.evaluate.representation import FunctionExecution - return FunctionExecution(self._evaluator, self.func, self.var_args).get_return_types() + f = FunctionExecution(self._evaluator, self.func, self.var_args) + return f.get_return_types(check_yields=True) def __getattr__(self, name): if name not in ['start_pos', 'end_pos', 'parent', 'get_imports', diff --git a/jedi/evaluate/recursion.py b/jedi/evaluate/recursion.py index f4809db0..19e14095 100644 --- a/jedi/evaluate/recursion.py +++ b/jedi/evaluate/recursion.py @@ -100,12 +100,12 @@ class _RecursionNode(object): def execution_recursion_decorator(func): - def run(execution): + def run(execution, **kwargs): detector = execution._evaluator.execution_recursion_detector if detector.push_execution(execution): result = [] else: - result = func(execution) + result = func(execution, **kwargs) detector.pop_execution() return result diff --git a/jedi/evaluate/representation.py b/jedi/evaluate/representation.py index 7edd880b..72fd731e 100644 --- a/jedi/evaluate/representation.py +++ b/jedi/evaluate/representation.py @@ -567,7 +567,7 @@ class FunctionExecution(Executed): @memoize_default(default=()) @recursion.execution_recursion_decorator - def get_return_types(self): + def get_return_types(self, check_yields=False): func = self.base if func.listeners: @@ -579,8 +579,14 @@ class FunctionExecution(Executed): # inserted params, not in the actual execution of the function. return [] - types = list(docstrings.find_return_types(self._evaluator, func)) - for r in self.returns: + if check_yields: + types = [] + returns = self.yields + else: + returns = self.returns + types = list(docstrings.find_return_types(self._evaluator, func)) + + for r in returns: check = flow_analysis.break_check(self._evaluator, self, r) if check is flow_analysis.UNREACHABLE: debug.dbg('Return unreachable: %s', r) @@ -661,6 +667,11 @@ class FunctionExecution(Executed): def returns(self): return self._copy_list(self.base.returns) + @common.safe_property + @memoize_default([]) + def yields(self): + return self._copy_list(self.base.yields) + @common.safe_property @memoize_default([]) def children(self):