Use the generics manager for all the typing classes

This commit is contained in:
Dave Halter
2019-12-08 22:42:01 +01:00
parent 8213d183fb
commit ad92882c48
2 changed files with 34 additions and 54 deletions

View File

@@ -10,18 +10,6 @@ from jedi.inference.value.iterable import SequenceLiteralValue
from jedi.inference.helpers import is_string from jedi.inference.helpers import is_string
def iter_over_arguments(maybe_tuple_value, defining_context):
def iterate():
if isinstance(maybe_tuple_value, SequenceLiteralValue):
for lazy_value in maybe_tuple_value.py__iter__(contextualized_node=None):
yield lazy_value.infer()
else:
yield ValueSet([maybe_tuple_value])
for value_set in iterate():
yield ValueSet(_resolve_forward_references(defining_context, value_set))
def _resolve_forward_references(context, value_set): def _resolve_forward_references(context, value_set):
for value in value_set: for value in value_set:
if is_string(value): if is_string(value):
@@ -69,8 +57,12 @@ class LazyGenericManager(object):
for callable_ in self._tuple(): for callable_ in self._tuple():
yield callable_() yield callable_()
#def __iter__(self): def is_homogenous_tuple(self):
# return iter(self._iterate()) if isinstance(self._index_value, SequenceLiteralValue):
entries = self._index_value.get_tree_entries()
if len(entries) == 2 and entries[1] == '...':
return True
return False
class TupleGenericManager(object): class TupleGenericManager(object):
@@ -83,9 +75,8 @@ class TupleGenericManager(object):
def __len__(self): def __len__(self):
return len(self._tuple) return len(self._tuple)
#def __iter__(self):
# for value_set in self._tuple:
# yield lambda: value_set
def to_tuple(self): def to_tuple(self):
return self._tuple return self._tuple
def is_homogenous_tuple(self):
return False

View File

@@ -11,14 +11,13 @@ from jedi.inference.compiled import builtin_from_name
from jedi.inference.base_value import ValueSet, NO_VALUES, Value, \ from jedi.inference.base_value import ValueSet, NO_VALUES, Value, \
LazyValueWrapper LazyValueWrapper
from jedi.inference.lazy_value import LazyKnownValues from jedi.inference.lazy_value import LazyKnownValues
from jedi.inference.value.iterable import SequenceLiteralValue
from jedi.inference.arguments import repack_with_argument_clinic from jedi.inference.arguments import repack_with_argument_clinic
from jedi.inference.filters import FilterWrapper from jedi.inference.filters import FilterWrapper
from jedi.inference.names import NameWrapper, ValueName from jedi.inference.names import NameWrapper, ValueName
from jedi.inference.value.klass import ClassMixin from jedi.inference.value.klass import ClassMixin
from jedi.inference.gradual.base import BaseTypingValue from jedi.inference.gradual.base import BaseTypingValue
from jedi.inference.gradual.type_var import TypeVarClass from jedi.inference.gradual.type_var import TypeVarClass
from jedi.inference.gradual.generics import iter_over_arguments from jedi.inference.gradual.generics import LazyGenericManager
_PROXY_CLASS_TYPES = 'Tuple Generic Protocol Callable Type'.split() _PROXY_CLASS_TYPES = 'Tuple Generic Protocol Callable Type'.split()
_TYPE_ALIAS_TYPES = { _TYPE_ALIAS_TYPES = {
@@ -99,16 +98,15 @@ class TypingModuleFilterWrapper(FilterWrapper):
class _WithIndexBase(BaseTypingValue): class _WithIndexBase(BaseTypingValue):
def __init__(self, inference_state, parent_context, name, index_value, context_of_index): def __init__(self, inference_state, parent_context, name, generics_manager):
super(_WithIndexBase, self).__init__(inference_state, parent_context, name) super(_WithIndexBase, self).__init__(inference_state, parent_context, name)
self._index_value = index_value self._generics_manager = generics_manager
self._context_of_index = context_of_index
def __repr__(self): def __repr__(self):
return '<%s: %s[%s]>' % ( return '<%s: %s[%s]>' % (
self.__class__.__name__, self.__class__.__name__,
self._tree_name.value, self._tree_name.value,
self._index_value, self._generics_manager,
) )
@@ -127,24 +125,21 @@ class TypingValueWithIndex(_WithIndexBase):
| ValueSet([builtin_from_name(self.inference_state, u'None')]) | ValueSet([builtin_from_name(self.inference_state, u'None')])
elif string_name == 'Type': elif string_name == 'Type':
# The type is actually already given in the index_value # The type is actually already given in the index_value
return ValueSet([self._index_value]) return self._generics_manager[0]
elif string_name == 'ClassVar': elif string_name == 'ClassVar':
# For now don't do anything here, ClassVars are always used. # For now don't do anything here, ClassVars are always used.
return self._index_value.execute_annotation() return self._generics_manager[0].execute_annotation()
cls = globals()[string_name] cls = globals()[string_name]
return ValueSet([cls( return ValueSet([cls(
self.inference_state, self.inference_state,
self.parent_context, self.parent_context,
self._tree_name, self._tree_name,
self._index_value, generics_manager=self._generics_manager,
self._context_of_index
)]) )])
def gather_annotation_classes(self): def gather_annotation_classes(self):
return ValueSet.from_sets( return ValueSet.from_sets(self._generics_manager.to_tuple())
iter_over_arguments(self._index_value, self._context_of_index)
)
class ProxyTypingValue(BaseTypingValue): class ProxyTypingValue(BaseTypingValue):
@@ -157,9 +152,11 @@ class ProxyTypingValue(BaseTypingValue):
self.inference_state, self.inference_state,
self.parent_context, self.parent_context,
self._tree_name, self._tree_name,
index_value, generics_manager=LazyGenericManager(
context_of_index=contextualized_node.context) context_of_index=contextualized_node.context,
for index_value in index_value_set index_value=index_value,
)
) for index_value in index_value_set
) )
@@ -181,7 +178,7 @@ class TypingClassValueWithIndex(_TypingClassMixin, TypingValueWithIndex):
@inference_state_method_cache() @inference_state_method_cache()
def get_generics(self): def get_generics(self):
return list(iter_over_arguments(self._index_value, self._context_of_index)) return self._generics_manager.to_tuple()
class ProxyTypingClassValue(_TypingClassMixin, ProxyTypingValue): class ProxyTypingClassValue(_TypingClassMixin, ProxyTypingValue):
@@ -224,12 +221,10 @@ class TypeAlias(LazyValueWrapper):
class _GetItemMixin(object): class _GetItemMixin(object):
def _get_getitem_values(self, index): def _get_getitem_values(self, index):
args = iter_over_arguments(self._index_value, self._context_of_index) try:
for i, values in enumerate(args): return self._generics_manager[index]
if i == index: except IndexError:
return values debug.warning('No param #%s found for annotation %s', index, self._generics_manager)
debug.warning('No param #%s found for annotation %s', index, self._index_value)
return NO_VALUES return NO_VALUES
@@ -240,20 +235,15 @@ class Callable(_WithIndexBase, _GetItemMixin):
class Tuple(LazyValueWrapper, _GetItemMixin): class Tuple(LazyValueWrapper, _GetItemMixin):
def __init__(self, inference_state, parent_context, name, index_value, context_of_index): def __init__(self, inference_state, parent_context, name, generics_manager):
self.inference_state = inference_state self.inference_state = inference_state
self.parent_context = parent_context self.parent_context = parent_context
self._index_value = index_value self._generics_manager = generics_manager
self._context_of_index = context_of_index
def _is_homogenous(self): def _is_homogenous(self):
# To specify a variable-length tuple of homogeneous type, Tuple[T, ...] # To specify a variable-length tuple of homogeneous type, Tuple[T, ...]
# is used. # is used.
if isinstance(self._index_value, SequenceLiteralValue): return self._generics_manager.is_homogenous_tuple()
entries = self._index_value.get_tree_entries()
if len(entries) == 2 and entries[1] == '...':
return True
return False
def py__simple_getitem__(self, index): def py__simple_getitem__(self, index):
if self._is_homogenous(): if self._is_homogenous():
@@ -269,16 +259,15 @@ class Tuple(LazyValueWrapper, _GetItemMixin):
if self._is_homogenous(): if self._is_homogenous():
yield LazyKnownValues(self._get_getitem_values(0).execute_annotation()) yield LazyKnownValues(self._get_getitem_values(0).execute_annotation())
else: else:
if isinstance(self._index_value, SequenceLiteralValue): for v in self._generics_manager.to_tuple():
for i in range(self._index_value.py__len__()): yield LazyKnownValues(v.execute_annotation())
yield LazyKnownValues(self._get_getitem_values(i).execute_annotation())
def py__getitem__(self, index_value_set, contextualized_node): def py__getitem__(self, index_value_set, contextualized_node):
if self._is_homogenous(): if self._is_homogenous():
return self._get_getitem_values(0).execute_annotation() return self._get_getitem_values(0).execute_annotation()
return ValueSet.from_sets( return ValueSet.from_sets(
iter_over_arguments(self._index_value, self._context_of_index) self._generics_manager.to_tuple()
).execute_annotation() ).execute_annotation()
def _get_wrapped_value(self): def _get_wrapped_value(self):