mirror of
https://github.com/davidhalter/jedi.git
synced 2025-12-08 14:54:47 +08:00
Fix issues with generators, fixes #1624
This commit is contained in:
@@ -202,7 +202,7 @@ class MethodValue(FunctionValue):
|
|||||||
|
|
||||||
|
|
||||||
class BaseFunctionExecutionContext(ValueContext, TreeContextMixin):
|
class BaseFunctionExecutionContext(ValueContext, TreeContextMixin):
|
||||||
def _infer_annotations(self):
|
def infer_annotations(self):
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
@inference_state_method_cache(default=NO_VALUES)
|
@inference_state_method_cache(default=NO_VALUES)
|
||||||
@@ -216,7 +216,7 @@ class BaseFunctionExecutionContext(ValueContext, TreeContextMixin):
|
|||||||
value_set = NO_VALUES
|
value_set = NO_VALUES
|
||||||
returns = get_yield_exprs(self.inference_state, funcdef)
|
returns = get_yield_exprs(self.inference_state, funcdef)
|
||||||
else:
|
else:
|
||||||
value_set = self._infer_annotations()
|
value_set = self.infer_annotations()
|
||||||
if value_set:
|
if value_set:
|
||||||
# If there are annotations, prefer them over anything else.
|
# If there are annotations, prefer them over anything else.
|
||||||
# This will make it faster.
|
# This will make it faster.
|
||||||
@@ -373,7 +373,7 @@ class FunctionExecutionContext(BaseFunctionExecutionContext):
|
|||||||
arguments=self._arguments
|
arguments=self._arguments
|
||||||
)
|
)
|
||||||
|
|
||||||
def _infer_annotations(self):
|
def infer_annotations(self):
|
||||||
from jedi.inference.gradual.annotation import infer_return_types
|
from jedi.inference.gradual.annotation import infer_return_types
|
||||||
return infer_return_types(self._value, self._arguments)
|
return infer_return_types(self._value, self._arguments)
|
||||||
|
|
||||||
@@ -385,7 +385,7 @@ class FunctionExecutionContext(BaseFunctionExecutionContext):
|
|||||||
|
|
||||||
|
|
||||||
class AnonymousFunctionExecution(BaseFunctionExecutionContext):
|
class AnonymousFunctionExecution(BaseFunctionExecutionContext):
|
||||||
def _infer_annotations(self):
|
def infer_annotations(self):
|
||||||
# I don't think inferring anonymous executions is a big thing.
|
# I don't think inferring anonymous executions is a big thing.
|
||||||
# Anonymous contexts are mostly there for the user to work in. ~ dave
|
# Anonymous contexts are mostly there for the user to work in. ~ dave
|
||||||
return NO_VALUES
|
return NO_VALUES
|
||||||
|
|||||||
@@ -49,13 +49,12 @@ class GeneratorBase(LazyAttributeOverwrite, IterableMixin):
|
|||||||
array_type = None
|
array_type = None
|
||||||
|
|
||||||
def _get_wrapped_value(self):
|
def _get_wrapped_value(self):
|
||||||
generator, = self.inference_state.typing_module \
|
instance, = self._get_cls().execute_annotation()
|
||||||
.py__getattribute__('Generator') \
|
return instance
|
||||||
.execute_annotation()
|
|
||||||
return generator
|
|
||||||
|
|
||||||
def is_instance(self):
|
def _get_cls(self):
|
||||||
return False
|
generator, = self.inference_state.typing_module.py__getattribute__('Generator')
|
||||||
|
return generator
|
||||||
|
|
||||||
def py__bool__(self):
|
def py__bool__(self):
|
||||||
return True
|
return True
|
||||||
@@ -77,6 +76,12 @@ class GeneratorBase(LazyAttributeOverwrite, IterableMixin):
|
|||||||
def name(self):
|
def name(self):
|
||||||
return compiled.CompiledValueName(self, 'Generator')
|
return compiled.CompiledValueName(self, 'Generator')
|
||||||
|
|
||||||
|
def get_annotated_class_object(self):
|
||||||
|
from jedi.inference.gradual.generics import TupleGenericManager
|
||||||
|
gen_values = self.merge_types_of_iterate().py__class__()
|
||||||
|
gm = TupleGenericManager((gen_values, NO_VALUES, NO_VALUES))
|
||||||
|
return self._get_cls().with_generics(gm)
|
||||||
|
|
||||||
|
|
||||||
class Generator(GeneratorBase):
|
class Generator(GeneratorBase):
|
||||||
"""Handling of `yield` functions."""
|
"""Handling of `yield` functions."""
|
||||||
@@ -85,6 +90,9 @@ class Generator(GeneratorBase):
|
|||||||
self._func_execution_context = func_execution_context
|
self._func_execution_context = func_execution_context
|
||||||
|
|
||||||
def py__iter__(self, contextualized_node=None):
|
def py__iter__(self, contextualized_node=None):
|
||||||
|
iterators = self._func_execution_context.infer_annotations()
|
||||||
|
if iterators:
|
||||||
|
return iterators.iterate(contextualized_node)
|
||||||
return self._func_execution_context.get_yield_lazy_values()
|
return self._func_execution_context.get_yield_lazy_values()
|
||||||
|
|
||||||
def py__stop_iteration_returns(self):
|
def py__stop_iteration_returns(self):
|
||||||
|
|||||||
@@ -292,3 +292,22 @@ def test_in_brackets():
|
|||||||
x = yield from [1]
|
x = yield from [1]
|
||||||
#? None
|
#? None
|
||||||
x
|
x
|
||||||
|
|
||||||
|
|
||||||
|
# -----------------
|
||||||
|
# Annotations
|
||||||
|
# -----------------
|
||||||
|
|
||||||
|
from typing import Iterator
|
||||||
|
|
||||||
|
def annotation1() -> float:
|
||||||
|
yield 1
|
||||||
|
|
||||||
|
def annotation2() -> Iterator[float]:
|
||||||
|
yield 1
|
||||||
|
|
||||||
|
|
||||||
|
#?
|
||||||
|
next(annotation1())
|
||||||
|
#? float()
|
||||||
|
next(annotation2())
|
||||||
|
|||||||
@@ -253,12 +253,34 @@ z.read('name').upper
|
|||||||
# -----------------
|
# -----------------
|
||||||
# contextlib
|
# contextlib
|
||||||
# -----------------
|
# -----------------
|
||||||
|
# python > 2.7
|
||||||
|
from typing import Iterator
|
||||||
import contextlib
|
import contextlib
|
||||||
with contextlib.closing('asd') as string:
|
with contextlib.closing('asd') as string:
|
||||||
#? str()
|
#? str()
|
||||||
string
|
string
|
||||||
|
|
||||||
|
@contextlib.contextmanager
|
||||||
|
def cm1() -> Iterator[float]:
|
||||||
|
yield 1
|
||||||
|
with cm1() as x:
|
||||||
|
#? float()
|
||||||
|
x
|
||||||
|
|
||||||
|
@contextlib.contextmanager
|
||||||
|
def cm2() -> float:
|
||||||
|
yield 1
|
||||||
|
with cm2() as x:
|
||||||
|
#?
|
||||||
|
x
|
||||||
|
|
||||||
|
@contextlib.contextmanager
|
||||||
|
def cm3():
|
||||||
|
yield 3
|
||||||
|
with cm3() as x:
|
||||||
|
#? int()
|
||||||
|
x
|
||||||
|
|
||||||
# -----------------
|
# -----------------
|
||||||
# operator
|
# operator
|
||||||
# -----------------
|
# -----------------
|
||||||
|
|||||||
Reference in New Issue
Block a user