diff --git a/jedi/evaluate/__init__.py b/jedi/evaluate/__init__.py index 316f5379..4a9f833c 100644 --- a/jedi/evaluate/__init__.py +++ b/jedi/evaluate/__init__.py @@ -131,7 +131,23 @@ class Evaluator(object): if isinstance(stmt, FakeStatement): return stmt.children # Already contains the results. - result = self.eval_element(stmt.get_rhs()) + types = self.eval_element(stmt.get_rhs()) + + if seek_name: + for index in seek_name.assignment_indexes(): + new_types = [] + for r in types: + try: + func = r.get_exact_index_types + except AttributeError: + debug.warning("Invalid tuple lookup #%s of result %s in %s", + index, types, seek_name) + else: + try: + new_types += func(index) + except IndexError: + pass + types = new_types ass_details = stmt.assignment_details if ass_details and ass_details[0][1] != '=' and not isinstance(stmt, er.InstanceElement): # TODO don't check for this. @@ -160,8 +176,8 @@ class Evaluator(object): for ass_expression_list, op in ass_details: new_result += finder.find_assignments(ass_expression_list[0], result, seek_name) result = new_result - debug.dbg('eval_statement result %s', result) - return result + debug.dbg('eval_statement result %s', types) + return types def eval_element(self, element): if isinstance(element, (pr.Name, pr.Literal)) or pr.is_node(element, 'atom'): diff --git a/jedi/evaluate/finder.py b/jedi/evaluate/finder.py index ada1e492..59695762 100644 --- a/jedi/evaluate/finder.py +++ b/jedi/evaluate/finder.py @@ -275,7 +275,7 @@ class NameFinder(object): check_instance = stmt.instance stmt = stmt.var - types += evaluator.eval_statement(stmt, seek_name=unicode(self.name_str)) + types += evaluator.eval_statement(stmt, seek_name=name) # check for `except X as y` usages, because y needs to be instantiated. p = stmt.parent diff --git a/jedi/parser/representation.py b/jedi/parser/representation.py index 700bcf48..38ca7aa4 100644 --- a/jedi/parser/representation.py +++ b/jedi/parser/representation.py @@ -225,6 +225,28 @@ class Name(_Leaf): def get_definition(self): return self.parent.get_parent_until((ArrayStmt, StatementElement, Node), reverse=True) + def assignment_indexes(self): + """ + Returns an array of ints of the indexes that are used in tuple + assignments. + + For example if the name is ``y`` in the following code:: + + x, (y, z) = 2, '' + + would result in ``[1, 0]``. + """ + indexes = [] + node = self.parent + while node is not None: + if is_node(node, 'testlist_comp') or is_node(node, 'testlist_star_expr'): + for i, child in enumerate(node.children): + if child == self: + indexes.insert(0, i) + + node = node.parent + return indexes + class Literal(_Leaf): def eval(self):