From 408eee50dd071e98b716e92131397d9bd2791281 Mon Sep 17 00:00:00 2001 From: Dave Halter Date: Wed, 12 Nov 2014 14:54:52 +0100 Subject: [PATCH] Start fixing issues with for loops and += operations. --- jedi/evaluate/__init__.py | 22 ++++++++++------------ jedi/evaluate/finder.py | 6 +++++- jedi/evaluate/iterable.py | 4 ++-- jedi/parser/representation.py | 11 ++++++++++- 4 files changed, 27 insertions(+), 16 deletions(-) diff --git a/jedi/evaluate/__init__.py b/jedi/evaluate/__init__.py index 0bb98433..71c1f388 100644 --- a/jedi/evaluate/__init__.py +++ b/jedi/evaluate/__init__.py @@ -136,26 +136,24 @@ class Evaluator(object): if seek_name: types = finder.check_tuple_assignments(types, seek_name) - #ass_details = stmt.assignment_details - if False and stmt.assignment_details and ass_details[0][1] != '=' and not isinstance(stmt, er.InstanceElement): # TODO don't check for this. - expr_list, _operator = ass_details[0] + ass_details = stmt.assignment_details + first_operation = stmt.first_operation() + if first_operation not in ('=', None) and not isinstance(stmt, er.InstanceElement): # TODO don't check for this. # `=` is always the last character in aug assignments -> -1 - operator = copy.copy(_operator) - operator.string = operator.string[:-1] - name = str(expr_list[0].name) - parent = stmt.parent.get_parent_until(pr.Flow, reverse=True) - if isinstance(parent, (pr.SubModule, fast.Module)): - parent = er.ModuleWrapper(self, parent) + operator = copy.copy(first_operation) + operator.value = operator.value[:-1] + name = str(stmt.get_defined_names()[0]) + parent = er.wrap(self, stmt.get_parent_scope()) left = self.find_types(parent, name, stmt.start_pos) if isinstance(stmt.parent, pr.ForFlow): # iterate through result and add the values, that's possible # only in for loops without clutter, because they are # predictable. - for r in result: + for r in types: left = precedence.calculate(self, left, operator, [r]) - result = left + types = left else: - result = precedence.calculate(self, left, operator, result) + types = precedence.calculate(self, left, operator, types) elif False and len(stmt.get_defined_names()) > 1 and seek_name and ass_details: # Assignment checking is only important if the statement defines # multiple variables. diff --git a/jedi/evaluate/finder.py b/jedi/evaluate/finder.py index 50e1e928..b2898cbc 100644 --- a/jedi/evaluate/finder.py +++ b/jedi/evaluate/finder.py @@ -82,10 +82,14 @@ class NameFinder(object): # Only the names defined in the last position are valid definitions. last_names = [] for name in reversed(sorted(names, key=lambda name: name.start_pos)): + if isinstance(self.name_str, pr.Name): + origin_scope = self.name_str.get_definition().parent + else: + origin_scope = None check = flow_analysis.break_check(self._evaluator, scope, name.get_definition(), - self.name_str.get_definition().parent) + origin_scope) if check is not flow_analysis.UNREACHABLE: last_names.append(name) if check is flow_analysis.REACHABLE: diff --git a/jedi/evaluate/iterable.py b/jedi/evaluate/iterable.py index 26cdc64d..fa517f3a 100644 --- a/jedi/evaluate/iterable.py +++ b/jedi/evaluate/iterable.py @@ -330,10 +330,10 @@ class FakeDict(Array): class MergedArray(Array): def __init__(self, evaluator, arrays): - super(MergedArray, self).__init__(evaluator, arrays[-1]._array) + super(MergedArray, self).__init__(evaluator, arrays[-1]._atom) self._arrays = arrays - def get_index_types(self, mixed_index): + def get_index_types(self, evaluator, mixed_index): return list(chain(*(a.values() for a in self._arrays))) def get_exact_index_types(self, mixed_index): diff --git a/jedi/parser/representation.py b/jedi/parser/representation.py index 1b2cac45..746a326c 100644 --- a/jedi/parser/representation.py +++ b/jedi/parser/representation.py @@ -1204,7 +1204,7 @@ class Statement(Simple, DocstringMixin): def get_defined_names(self): return list(chain.from_iterable(_defined_names(self.children[i]) for i in range(0, len(self.children) - 2, 2) - if self.children[i + 1].value == '=')) + if '=' in self.children[i + 1].value)) """Get the names for the statement.""" @@ -1266,6 +1266,15 @@ class Statement(Simple, DocstringMixin): as_name.start_pos, as_name.end_pos, self)) return dct + def first_operation(self): + """ + Returns `+=`, `=`, etc or None if there is no operation. + """ + try: + return self.children[1] + except IndexError: + return None + @property def assignment_details(self): """