support tuple-assignment

This commit is contained in:
Claude
2016-02-15 17:04:19 +01:00
parent a658f7940c
commit 8b28678d19
4 changed files with 62 additions and 5 deletions

View File

@@ -355,7 +355,7 @@ def _remove_statements(evaluator, stmt, name):
check_instance = stmt.instance
stmt = stmt.var
pep0484types = pep0484.find_type_from_comment_hint(evaluator, stmt)
pep0484types = pep0484.find_type_from_comment_hint(evaluator, stmt, name)
if pep0484types:
return pep0484types
types |= evaluator.eval_statement(stmt, seek_name=name)

View File

@@ -31,10 +31,20 @@ from jedi import _compatibility
import re
def _evaluate_for_annotation(evaluator, annotation):
def _evaluate_for_annotation(evaluator, annotation, index=None):
"""
Evaluates a string-node, looking for an annotation
If index is not None, the annotation is expected to be a tuple
and we're interested in that index
"""
if annotation is not None:
definitions = evaluator.eval_element(
_fix_forward_reference(evaluator, annotation))
if index is not None:
definitions = list(itertools.chain.from_iterable(
definition.py__getitem__(index) for definition in definitions
if definition.type == 'tuple' and
len(list(definition.py__iter__())) >= index))
return list(itertools.chain.from_iterable(
evaluator.execute(d) for d in definitions))
else:
@@ -139,7 +149,21 @@ def get_types_for_typing_module(evaluator, typ, node):
return result
def find_type_from_comment_hint(evaluator, stmt):
def find_type_from_comment_hint(evaluator, stmt, name):
index = None
if stmt.children[0].type == "testlist_star_expr":
# something like "a, b = 1, 2"
leftside = stmt.children[0]
index = 0
for child in leftside.children:
if child == name:
break
if child.type == "operator":
continue
index += 1
else:
return []
comment = stmt.get_following_comment_same_line()
if comment is None:
return []
@@ -151,4 +175,4 @@ def find_type_from_comment_hint(evaluator, stmt):
repr(str(match.group(1).strip())),
stmt.start_pos)
annotation.parent = stmt.parent
return _evaluate_for_annotation(evaluator, annotation)
return _evaluate_for_annotation(evaluator, annotation, index)

View File

@@ -514,7 +514,7 @@ class BaseNode(Base):
def last_leaf(self):
try:
return self.children[-1].first_leaf()
return self.children[-1].last_leaf()
except AttributeError:
return self.children[-1]
@@ -527,6 +527,10 @@ class BaseNode(Base):
whitespace = self.last_leaf().get_next().prefix
except AttributeError:
return None
except ValueError:
# in some particular cases, the tree doesn't seem to be linked
# correctly
return None
if "#" not in whitespace:
return None
comment = whitespace[whitespace.index("#"):]

View File

@@ -37,3 +37,32 @@ def test(a, b):
d
#? str()
e
a,b = 1, 2 # type: str, float
#? str()
a
#? float()
b
class Employee:
pass
from typing import List
x = [] # type: List[Employee]
#? Employee()
x[1]
x, y, z = [], [], [] # type: List[int], List[int], List[str]
#? int()
y[2]
x, y, z = [], [], [] # type: (List[float], List[float], List[BB])
for zi in z:
#? BB()
zi
x = [
1,
2,
] # type: List[str]
#? str()
x[1]