mirror of
https://github.com/davidhalter/jedi.git
synced 2026-02-03 17:22:44 +08:00
support tuple-assignment
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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("#"):]
|
||||
|
||||
@@ -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]
|
||||
|
||||
Reference in New Issue
Block a user