1
0
forked from VimPlug/jedi

Add a method 'Name.assignment_indexes', to process tuple assignments.

This commit is contained in:
Dave Halter
2014-10-21 15:45:29 +02:00
parent c1807e5f33
commit 5b29e2c54d
3 changed files with 42 additions and 4 deletions

View File

@@ -131,7 +131,23 @@ class Evaluator(object):
if isinstance(stmt, FakeStatement): if isinstance(stmt, FakeStatement):
return stmt.children # Already contains the results. 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 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. 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: for ass_expression_list, op in ass_details:
new_result += finder.find_assignments(ass_expression_list[0], result, seek_name) new_result += finder.find_assignments(ass_expression_list[0], result, seek_name)
result = new_result result = new_result
debug.dbg('eval_statement result %s', result) debug.dbg('eval_statement result %s', types)
return result return types
def eval_element(self, element): def eval_element(self, element):
if isinstance(element, (pr.Name, pr.Literal)) or pr.is_node(element, 'atom'): if isinstance(element, (pr.Name, pr.Literal)) or pr.is_node(element, 'atom'):

View File

@@ -275,7 +275,7 @@ class NameFinder(object):
check_instance = stmt.instance check_instance = stmt.instance
stmt = stmt.var 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. # check for `except X as y` usages, because y needs to be instantiated.
p = stmt.parent p = stmt.parent

View File

@@ -225,6 +225,28 @@ class Name(_Leaf):
def get_definition(self): def get_definition(self):
return self.parent.get_parent_until((ArrayStmt, StatementElement, Node), reverse=True) 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): class Literal(_Leaf):
def eval(self): def eval(self):