diff --git a/jedi/evaluate/__init__.py b/jedi/evaluate/__init__.py index ea76ed76..3197bba3 100644 --- a/jedi/evaluate/__init__.py +++ b/jedi/evaluate/__init__.py @@ -192,10 +192,10 @@ class Evaluator(object): next(call_path, None) # the first one has been used already return self.follow_path(call_path, r, element.parent) elif isinstance(element, pr.ListComprehension): - loop = _evaluate_list_comprehension(element) + #lc = element.get_most_inner_lc() # Caveat: parents are being changed, but this doesn't matter, # because nothing else uses it. - element.stmt.parent = loop + #element.stmt.parent = loop return self.eval_statement(element.stmt) elif isinstance(element, pr.Lambda): return [er.Function(self, element)] @@ -377,17 +377,3 @@ def filter_private_variable(scope, call_scope, var_name): if s != scope.base.base: return True return False - - -def _evaluate_list_comprehension(lc, parent=None): - # create a for loop, which does the same as list comprehensions - input = lc.input - nested_lc = input.expression_list()[0] - if isinstance(nested_lc, pr.ListComprehension): - # is nested LC - input = nested_lc.stmt - loop = iterable.ListComprehensionFlow(lc, input, parent) - - if isinstance(nested_lc, pr.ListComprehension): - loop = _evaluate_list_comprehension(nested_lc, loop) - return loop diff --git a/jedi/evaluate/iterable.py b/jedi/evaluate/iterable.py index ccfeab3f..aad1faf5 100644 --- a/jedi/evaluate/iterable.py +++ b/jedi/evaluate/iterable.py @@ -513,13 +513,3 @@ def create_indexes_or_slices(evaluator, index_array): return (Slice(evaluator, start, stop, step),) else: return tuple(evaluator.process_precedence_element(prec)) - - -class ListComprehensionFlow(pr.ForFlow): - """Fake implementation to pretend being a ForFlow.""" - def __init__(self, list_comprehension, input, parent): - lc = list_comprehension - sup = super(ListComprehensionFlow, self) - sup.__init__(helpers.FakeSubModule, [input], lc.parent.start_pos, lc.middle) - self.parent = parent or lc.get_parent_until(pr.IsScope) - self.list_comprehension = list_comprehension diff --git a/jedi/parser/representation.py b/jedi/parser/representation.py index b7fbca7a..ed1d1bfa 100644 --- a/jedi/parser/representation.py +++ b/jedi/parser/representation.py @@ -1094,7 +1094,7 @@ isinstance(c, (tokenize.Token, Operator)) else unicode(c) debug.warning('list comprehension in @%s', start_pos) return None, tok - return ListComprehension(st, middle, in_clause, self), tok + return ListComprehension(self._sub_module, st, middle, in_clause, self), tok # initializations result = [] @@ -1480,22 +1480,29 @@ class Name(Simple): return len(self.names) -class ListComprehension(Base): +class ListComprehension(ForFlow): """ Helper class for list comprehensions """ - def __init__(self, stmt, middle, input, parent): + def __init__(self, module, stmt, middle, input, parent): self.stmt = stmt self.middle = middle self.input = input - for s in stmt, middle, input: + for s in middle, input: s.parent = self + stmt.parent = self._get_most_inner_lc() self.parent = parent - def get_parent_until(self, *args, **kwargs): - return Simple.get_parent_until(self, *args, **kwargs) + nested_lc = input.expression_list()[0] + if isinstance(nested_lc, ListComprehension): + # is nested LC + input = nested_lc.stmt + super(ListComprehension, self).__init__(module, [input], + stmt.start_pos, middle) - @property - def start_pos(self): - return self.stmt.start_pos + def _get_most_inner_lc(self): + nested_lc = self.input.expression_list()[0] + if isinstance(nested_lc, ListComprehension): + return nested_lc._get_most_inner_lc() + return self @property def end_pos(self): @@ -1510,6 +1517,31 @@ class ListComprehension(Base): return "%s for %s in %s" % tuple(code) +def _evaluate_list_comprehension(lc, parent=None): + # create a for loop, which does the same as list comprehensions + input = lc.input + nested_lc = input.expression_list()[0] + if isinstance(nested_lc, ListComprehension): + # is nested LC + input = nested_lc.stmt + loop = ListComprehensionFlow(lc, input, parent) + + if isinstance(nested_lc, ListComprehension): + loop = _evaluate_list_comprehension(nested_lc, loop) + return loop + + +class ListComprehensionFlow(ForFlow): + """Fake implementation to pretend being a ForFlow.""" + def __init__(self, list_comprehension, input, parent): + lc = list_comprehension + sup = super(ListComprehensionFlow, self) + module = list_comprehension.get_parent_until() + sup.__init__(module, [input], lc.parent.start_pos, lc.middle) + self.parent = parent or lc.get_parent_until(IsScope) + self.list_comprehension = list_comprehension + + class Operator(Base): __slots__ = ('string', '_line', '_column')