mirror of
https://github.com/davidhalter/jedi.git
synced 2026-03-01 19:56:50 +08:00
Merge branch 'master' into python3
This commit is contained in:
@@ -176,6 +176,9 @@ class Value(HelperValueMixin):
|
||||
message="TypeError: '%s' object is not iterable" % self)
|
||||
return iter([])
|
||||
|
||||
def py__next__(self, contextualized_node=None):
|
||||
return self.py__iter__(contextualized_node)
|
||||
|
||||
def get_signatures(self):
|
||||
return []
|
||||
|
||||
|
||||
@@ -69,12 +69,22 @@ class MixedObject(ValueWrapper):
|
||||
else:
|
||||
return self.compiled_value.get_safe_value(default)
|
||||
|
||||
@property
|
||||
def array_type(self):
|
||||
return self.compiled_value.array_type
|
||||
|
||||
def get_key_values(self):
|
||||
return self.compiled_value.get_key_values()
|
||||
|
||||
def py__simple_getitem__(self, index):
|
||||
python_object = self.compiled_value.access_handle.access._obj
|
||||
if type(python_object) in ALLOWED_GETITEM_TYPES:
|
||||
return self.compiled_value.py__simple_getitem__(index)
|
||||
return self._wrapped_value.py__simple_getitem__(index)
|
||||
|
||||
def negate(self):
|
||||
return self.compiled_value.negate()
|
||||
|
||||
def _as_context(self):
|
||||
if self.parent_context is None:
|
||||
return MixedModuleContext(self)
|
||||
|
||||
@@ -165,21 +165,12 @@ class InferenceStateSubprocess(_InferenceStateProcess):
|
||||
class CompiledSubprocess(object):
|
||||
is_crashed = False
|
||||
|
||||
def __init__(self, executable, env_vars={}):
|
||||
def __init__(self, executable, env_vars=None):
|
||||
self._executable = executable
|
||||
self._env_vars = dict(env_vars)
|
||||
self._env_vars = env_vars
|
||||
self._inference_state_deletion_queue = queue.deque()
|
||||
self._cleanup_callable = lambda: None
|
||||
|
||||
# Use explicit envionment to ensure reliable results (#1540)
|
||||
if os.name == 'nt':
|
||||
# if SYSTEMROOT (or case variant) exists in environment,
|
||||
# ensure it goes to subprocess
|
||||
for k, v in os.environ.items():
|
||||
if 'SYSTEMROOT' == k.upper():
|
||||
self._env_vars.update({k: os.environ[k]})
|
||||
break # don't risk multiple entries
|
||||
|
||||
def __repr__(self):
|
||||
pid = os.getpid()
|
||||
return '<%s _executable=%r, is_crashed=%r, pid=%r>' % (
|
||||
|
||||
@@ -201,7 +201,7 @@ class MethodValue(FunctionValue):
|
||||
|
||||
|
||||
class BaseFunctionExecutionContext(ValueContext, TreeContextMixin):
|
||||
def _infer_annotations(self):
|
||||
def infer_annotations(self):
|
||||
raise NotImplementedError
|
||||
|
||||
@inference_state_method_cache(default=NO_VALUES)
|
||||
@@ -215,7 +215,7 @@ class BaseFunctionExecutionContext(ValueContext, TreeContextMixin):
|
||||
value_set = NO_VALUES
|
||||
returns = get_yield_exprs(self.inference_state, funcdef)
|
||||
else:
|
||||
value_set = self._infer_annotations()
|
||||
value_set = self.infer_annotations()
|
||||
if value_set:
|
||||
# If there are annotations, prefer them over anything else.
|
||||
# This will make it faster.
|
||||
@@ -367,7 +367,7 @@ class FunctionExecutionContext(BaseFunctionExecutionContext):
|
||||
arguments=self._arguments
|
||||
)
|
||||
|
||||
def _infer_annotations(self):
|
||||
def infer_annotations(self):
|
||||
from jedi.inference.gradual.annotation import infer_return_types
|
||||
return infer_return_types(self._value, self._arguments)
|
||||
|
||||
@@ -379,7 +379,7 @@ class FunctionExecutionContext(BaseFunctionExecutionContext):
|
||||
|
||||
|
||||
class AnonymousFunctionExecution(BaseFunctionExecutionContext):
|
||||
def _infer_annotations(self):
|
||||
def infer_annotations(self):
|
||||
# I don't think inferring anonymous executions is a big thing.
|
||||
# Anonymous contexts are mostly there for the user to work in. ~ dave
|
||||
return NO_VALUES
|
||||
|
||||
@@ -255,21 +255,20 @@ class _BaseTreeInstance(AbstractInstanceValue):
|
||||
|
||||
def iterate():
|
||||
for generator in self.execute_function_slots(iter_slot_names):
|
||||
if generator.is_instance() and not generator.is_compiled():
|
||||
# `__next__` logic.
|
||||
name = '__next__'
|
||||
next_slot_names = generator.get_function_slot_names(name)
|
||||
if next_slot_names:
|
||||
yield LazyKnownValues(
|
||||
generator.execute_function_slots(next_slot_names)
|
||||
)
|
||||
else:
|
||||
debug.warning('Instance has no __next__ function in %s.', generator)
|
||||
else:
|
||||
for lazy_value in generator.py__iter__():
|
||||
yield lazy_value
|
||||
for lazy_value in generator.py__next__(contextualized_node):
|
||||
yield lazy_value
|
||||
return iterate()
|
||||
|
||||
def py__next__(self, contextualized_node=None):
|
||||
name = u'__next__'
|
||||
next_slot_names = self.get_function_slot_names(name)
|
||||
if next_slot_names:
|
||||
yield LazyKnownValues(
|
||||
self.execute_function_slots(next_slot_names)
|
||||
)
|
||||
else:
|
||||
debug.warning('Instance has no __next__ function in %s.', self)
|
||||
|
||||
def py__call__(self, arguments):
|
||||
names = self.get_function_slot_names('__call__')
|
||||
if not names:
|
||||
|
||||
@@ -20,6 +20,9 @@ from jedi.inference.value.dynamic_arrays import check_array_additions
|
||||
|
||||
|
||||
class IterableMixin(object):
|
||||
def py__next__(self, contextualized_node=None):
|
||||
return self.py__iter__(contextualized_node)
|
||||
|
||||
def py__stop_iteration_returns(self):
|
||||
return ValueSet([compiled.builtin_from_name(self.inference_state, 'None')])
|
||||
|
||||
@@ -36,13 +39,12 @@ class GeneratorBase(LazyAttributeOverwrite, IterableMixin):
|
||||
array_type = None
|
||||
|
||||
def _get_wrapped_value(self):
|
||||
generator, = self.inference_state.typing_module \
|
||||
.py__getattribute__('Generator') \
|
||||
.execute_annotation()
|
||||
return generator
|
||||
instance, = self._get_cls().execute_annotation()
|
||||
return instance
|
||||
|
||||
def is_instance(self):
|
||||
return False
|
||||
def _get_cls(self):
|
||||
generator, = self.inference_state.typing_module.py__getattribute__('Generator')
|
||||
return generator
|
||||
|
||||
def py__bool__(self):
|
||||
return True
|
||||
@@ -52,9 +54,8 @@ class GeneratorBase(LazyAttributeOverwrite, IterableMixin):
|
||||
return ValueSet([self])
|
||||
|
||||
@publish_method('send')
|
||||
@publish_method('next')
|
||||
@publish_method('__next__')
|
||||
def py__next__(self, arguments):
|
||||
def _next(self, arguments):
|
||||
return ValueSet.from_sets(lazy_value.infer() for lazy_value in self.py__iter__())
|
||||
|
||||
def py__stop_iteration_returns(self):
|
||||
@@ -64,6 +65,12 @@ class GeneratorBase(LazyAttributeOverwrite, IterableMixin):
|
||||
def name(self):
|
||||
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):
|
||||
"""Handling of `yield` functions."""
|
||||
@@ -72,6 +79,9 @@ class Generator(GeneratorBase):
|
||||
self._func_execution_context = func_execution_context
|
||||
|
||||
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()
|
||||
|
||||
def py__stop_iteration_returns(self):
|
||||
|
||||
Reference in New Issue
Block a user