mirror of
https://github.com/davidhalter/jedi.git
synced 2025-12-09 07:14:48 +08:00
Add basic yield from type inference. References #647.
This commit is contained in:
@@ -676,6 +676,9 @@ class FunctionExecution(Executed):
|
||||
check = flow_analysis.break_check(self._evaluator, self, r)
|
||||
if check is flow_analysis.UNREACHABLE:
|
||||
debug.dbg('Return unreachable: %s', r)
|
||||
else:
|
||||
if check_yields:
|
||||
types |= iterable.unite(self._eval_yield(r))
|
||||
else:
|
||||
types |= self._evaluator.eval_element(r.children[1])
|
||||
if check is flow_analysis.REACHABLE:
|
||||
@@ -683,6 +686,16 @@ class FunctionExecution(Executed):
|
||||
break
|
||||
return types
|
||||
|
||||
def _eval_yield(self, yield_expr):
|
||||
element = yield_expr.children[1]
|
||||
if element.type == 'yield_arg':
|
||||
# It must be a yield from.
|
||||
yield_from_types = self._evaluator.eval_element(element.children[1])
|
||||
for result in iterable.py__iter__(self._evaluator, yield_from_types, element):
|
||||
yield result
|
||||
else:
|
||||
yield self._evaluator.eval_element(element)
|
||||
|
||||
# TODO add execution_recursion_decorator?!
|
||||
def get_yield_types(self):
|
||||
yields = self.yields
|
||||
@@ -716,7 +729,8 @@ class FunctionExecution(Executed):
|
||||
if for_stmt is None:
|
||||
# No for_stmt, just normal yields.
|
||||
for yield_ in yields:
|
||||
yield evaluator.eval_element(yield_.children[1])
|
||||
for result in self._eval_yield(yield_):
|
||||
yield result
|
||||
else:
|
||||
input_node = for_stmt.get_input_node()
|
||||
for_types = evaluator.eval_element(input_node)
|
||||
@@ -725,7 +739,8 @@ class FunctionExecution(Executed):
|
||||
dct = {str(for_stmt.children[1]): index_types}
|
||||
evaluator.predefined_if_name_dict_dict[for_stmt] = dct
|
||||
for yield_in_same_for_stmt in yields:
|
||||
yield evaluator.eval_element(yield_in_same_for_stmt.children[1])
|
||||
for result in self._eval_yield(yield_in_same_for_stmt):
|
||||
yield result
|
||||
del evaluator.predefined_if_name_dict_dict[for_stmt]
|
||||
|
||||
def names_dicts(self, search_global):
|
||||
|
||||
@@ -175,3 +175,25 @@ gen().send()
|
||||
|
||||
#?
|
||||
gen()()
|
||||
|
||||
# -----------------
|
||||
# yield from
|
||||
# -----------------
|
||||
|
||||
# python >= 3.3
|
||||
|
||||
def yield_from():
|
||||
yield from iter([1])
|
||||
|
||||
#? int()
|
||||
next(yield_from())
|
||||
|
||||
def yield_from_multiple():
|
||||
yield from iter([1])
|
||||
yield str()
|
||||
|
||||
x, y = yield_from_multiple()
|
||||
#? int()
|
||||
x
|
||||
#? str()
|
||||
y
|
||||
|
||||
@@ -49,7 +49,7 @@ class Employee:
|
||||
|
||||
# The typing library is not installable for Python 2.6, therefore ignore the
|
||||
# following tests.
|
||||
# python > 2.6
|
||||
# python >= 2.7
|
||||
|
||||
from typing import List
|
||||
x = [] # type: List[Employee]
|
||||
|
||||
@@ -240,8 +240,8 @@ def skip_python_version(line):
|
||||
'==': 'eq',
|
||||
'<=': 'le',
|
||||
'>=': 'ge',
|
||||
'<': 'gk',
|
||||
'>': 'lt',
|
||||
'<': 'lt',
|
||||
'>': 'gt',
|
||||
}
|
||||
# check for python minimal version number
|
||||
match = re.match(r" *# *python *([<>]=?|==) *(\d+(?:\.\d+)?)$", line)
|
||||
|
||||
Reference in New Issue
Block a user