diff --git a/jedi/evaluate.py b/jedi/evaluate.py index 758524dc..db375f1a 100644 --- a/jedi/evaluate.py +++ b/jedi/evaluate.py @@ -72,7 +72,6 @@ from _compatibility import next, hasattr, is_py3k, unicode import sys import itertools -import copy import common import cache @@ -566,10 +565,10 @@ def follow_call_list(call_list, follow_array=False): # is nested LC input = nested_lc.stmt module = input.get_parent_until() - loop = pr.ForFlow(module, [input], lc.stmt.start_pos, - lc.middle, True) + # create a for loop, which does the same as list comprehensions + loop = pr.ForFlow(module, [input], lc.stmt.start_pos, lc.middle, True) - loop.parent = lc.stmt.parent if parent is None else parent + loop.parent = lc.parent if parent is None else parent if isinstance(nested_lc, pr.ListComprehension): loop = evaluate_list_comprehension(nested_lc, loop) @@ -593,11 +592,10 @@ def follow_call_list(call_list, follow_array=False): position=call.start_pos) elif isinstance(call, pr.ListComprehension): loop = evaluate_list_comprehension(call) - stmt = copy.copy(call.stmt) - stmt.parent = loop - # create a for loop which does the same as list - # comprehensions - result += follow_statement(stmt) + # Caveat: parents are being changed, but this doesn't matter, + # because nothing else uses it. + call.stmt.parent = loop + result += follow_statement(call.stmt) else: if isinstance(call, pr.Lambda): result.append(er.Function(call)) diff --git a/jedi/parsing.py b/jedi/parsing.py index 8aef9fcb..a38aa82a 100644 --- a/jedi/parsing.py +++ b/jedi/parsing.py @@ -435,8 +435,7 @@ class Parser(object): st = pr.Statement(self.module, src, [], [], [], toks, first_pos, self.end_pos) - tok = pr.ListComprehension(st, middle, in_clause, - self.scope) + tok = pr.ListComprehension(st, middle, in_clause) tok_list.append(tok) if list_comp: string = '' diff --git a/jedi/parsing_representation.py b/jedi/parsing_representation.py index de7eaf3e..ac50c3d9 100644 --- a/jedi/parsing_representation.py +++ b/jedi/parsing_representation.py @@ -93,8 +93,8 @@ class Simple(Base): def __repr__(self): code = self.get_code().replace('\n', ' ') - return "<%s: %s@%s>" % \ - (type(self).__name__, code, self.start_pos[0]) + return "<%s: %s@%s,%s>" % \ + (type(self).__name__, code, self.start_pos[0], self.start_pos[0]) class IsScope(Base): @@ -479,6 +479,7 @@ class Flow(Scope): self.set_vars = set_vars for s in self.set_vars: s.parent.parent = self.use_as_parent + # TODO strange!!! don't know why this exist s.parent = self.use_as_parent @property @@ -545,6 +546,7 @@ class ForFlow(Flow): super(ForFlow, self).__init__(module, 'for', inputs, start_pos, set_stmt.used_vars) self.set_stmt = set_stmt + set_stmt.parent = self.use_as_parent self.is_list_comp = is_list_comp def get_code(self, first_indent=False, indention=" " * 4): @@ -819,6 +821,9 @@ class Statement(Simple): start_pos = tok.start_pos first = False end_pos = tok.end_pos + if isinstance(tok, ListComprehension): + # it's not possible to set it earlier + tok.parent = self else: token_type, tok, start_tok_pos = tok_temp end_pos = start_tok_pos[0], start_tok_pos[1] + len(tok) @@ -1169,13 +1174,13 @@ class Name(Simple): class ListComprehension(Base): """ Helper class for list comprehensions """ - def __init__(self, stmt, middle, input, parent): + def __init__(self, stmt, middle, input): self.stmt = stmt self.middle = middle self.input = input for s in [stmt, middle, input]: s.parent = self - self.parent = parent + self.parent = None def get_parent_until(self, *args, **kwargs): return Simple.get_parent_until(self, *args, **kwargs)