1
0
forked from VimPlug/jedi

Remove is_class_value from infer_type_vars

This commit is contained in:
Dave Halter
2020-05-08 17:49:02 +02:00
parent 12090ce74b
commit 2a227dcc7a
5 changed files with 23 additions and 82 deletions
+3 -11
View File
@@ -268,7 +268,7 @@ class Value(HelperValueMixin):
def get_type_hint(self, add_class_info=True): def get_type_hint(self, add_class_info=True):
return None return None
def infer_type_vars(self, value_set, is_class_value=False): def infer_type_vars(self, value_set):
""" """
When the current instance represents a type annotation, this method When the current instance represents a type annotation, this method
tries to find information about undefined type vars and returns a dict tries to find information about undefined type vars and returns a dict
@@ -294,14 +294,6 @@ class Value(HelperValueMixin):
we're inferrined for, or (for recursive calls) their types. In the we're inferrined for, or (for recursive calls) their types. In the
above example this would first be the representation of the list above example this would first be the representation of the list
`[1]` and then, when recursing, just of `1`. `[1]` and then, when recursing, just of `1`.
`is_class_value`: tells us whether or not to treat the `value_set` as
representing the instances or types being passed, which is neccesary
to correctly cope with `Type[T]` annotations. When it is True, this
means that we are being called with a nested portion of an
annotation and that the `value_set` represents the types of the
arguments, rather than their actual instances. Note: not all
recursive calls will neccesarily set this to True.
""" """
return {} return {}
@@ -538,7 +530,7 @@ class ValueSet(object):
s = 'Optional[%s]' % s s = 'Optional[%s]' % s
return s return s
def infer_type_vars(self, value_set, is_class_value=False): def infer_type_vars(self, value_set):
# Circular # Circular
from jedi.inference.gradual.annotation import merge_type_var_dicts from jedi.inference.gradual.annotation import merge_type_var_dicts
@@ -546,7 +538,7 @@ class ValueSet(object):
for value in self._set: for value in self._set:
merge_type_var_dicts( merge_type_var_dicts(
type_var_dict, type_var_dict,
value.infer_type_vars(value_set, is_class_value), value.infer_type_vars(value_set),
) )
return type_var_dict return type_var_dict
+1 -6
View File
@@ -359,12 +359,7 @@ def merge_pairwise_generics(annotation_value, annotated_argument_class):
for annotation_generics_set, actual_generic_set in zip(annotation_generics, actual_generics): for annotation_generics_set, actual_generic_set in zip(annotation_generics, actual_generics):
merge_type_var_dicts( merge_type_var_dicts(
type_var_dict, type_var_dict,
annotation_generics_set.infer_type_vars( annotation_generics_set.infer_type_vars(actual_generic_set.execute_annotation()),
actual_generic_set,
# This is a note to ourselves that we have already
# converted the instance representation to its class.
is_class_value=True,
),
) )
return type_var_dict return type_var_dict
+6 -8
View File
@@ -200,29 +200,27 @@ class GenericClass(ClassMixin, DefineGenericBase):
return True return True
return self._class_value.is_sub_class_of(class_value) return self._class_value.is_sub_class_of(class_value)
def infer_type_vars(self, value_set, is_class_value=False): def infer_type_vars(self, value_set):
# Circular # Circular
from jedi.inference.gradual.annotation import merge_pairwise_generics, merge_type_var_dicts from jedi.inference.gradual.annotation import merge_pairwise_generics, merge_type_var_dicts
annotation_name = self.py__name__() annotation_name = self.py__name__()
type_var_dict = {} type_var_dict = {}
if annotation_name == 'Iterable' and not is_class_value: if annotation_name == 'Iterable':
annotation_generics = self.get_generics() annotation_generics = self.get_generics()
if annotation_generics: if annotation_generics:
return annotation_generics[0].infer_type_vars( return annotation_generics[0].infer_type_vars(
value_set.merge_types_of_iterate(), value_set.merge_types_of_iterate(),
) )
else: else:
# Note: we need to handle the MRO _in order_, so we need to extract # Note: we need to handle the MRO _in order_, so we need to extract
# the elements from the set first, then handle them, even if we put # the elements from the set first, then handle them, even if we put
# them back in a set afterwards. # them back in a set afterwards.
for py_class in value_set: for py_class in value_set:
if not is_class_value: if py_class.is_instance() and not py_class.is_compiled():
if py_class.is_instance() and not py_class.is_compiled(): py_class = py_class.get_annotated_class_object()
py_class = py_class.get_annotated_class_object() else:
else: continue
continue
if py_class.api_type != u'class': if py_class.api_type != u'class':
# Functions & modules don't have an MRO and we're not # Functions & modules don't have an MRO and we're not
+2 -4
View File
@@ -107,11 +107,9 @@ class TypeVar(BaseTypingValue):
def execute_annotation(self): def execute_annotation(self):
return self._get_classes().execute_annotation() return self._get_classes().execute_annotation()
def infer_type_vars(self, value_set, is_class_value=False): def infer_type_vars(self, value_set):
annotation_name = self.py__name__() annotation_name = self.py__name__()
if not is_class_value: return {annotation_name: value_set.py__class__()}
return {annotation_name: value_set.py__class__()}
return {annotation_name: value_set}
def __repr__(self): def __repr__(self):
return '<%s: %s>' % (self.__class__.__name__, self.py__name__()) return '<%s: %s>' % (self.__class__.__name__, self.py__name__())
+11 -53
View File
@@ -184,7 +184,7 @@ class _TypingClassMixin(ClassMixin):
class TypingClassValueWithIndex(_TypingClassMixin, TypingValueWithIndex): class TypingClassValueWithIndex(_TypingClassMixin, TypingValueWithIndex):
def infer_type_vars(self, value_set, is_class_value=False): def infer_type_vars(self, value_set):
# Circular # Circular
from jedi.inference.gradual.annotation import merge_pairwise_generics, merge_type_var_dicts from jedi.inference.gradual.annotation import merge_pairwise_generics, merge_type_var_dicts
@@ -196,49 +196,18 @@ class TypingClassValueWithIndex(_TypingClassMixin, TypingValueWithIndex):
annotation_name = self.py__name__() annotation_name = self.py__name__()
if annotation_name == 'Type': if annotation_name == 'Type':
if is_class_value: return annotation_generics[0].infer_type_vars(
# This only applies if we are comparing something like value_set.execute_with_values(),
# List[Type[int]] with Iterable[Type[int]]. First, Jedi tries to )
# match List/Iterable. After that we will land here, because
# is_class_value will be True at that point. Obviously we also
# compare below that both sides are `Type`.
for element in value_set:
element_name = element.py__name__()
if element_name == 'Type':
merge_type_var_dicts(
type_var_dict,
merge_pairwise_generics(self, element),
)
else:
return annotation_generics[0].infer_type_vars(
value_set,
is_class_value=True,
)
elif annotation_name == 'Callable': elif annotation_name == 'Callable':
if len(annotation_generics) == 2: return annotation_generics[1].infer_type_vars(
if is_class_value: value_set.execute_annotation(),
# This only applies if we are comparing something like )
# List[Callable[..., T]] with Iterable[Callable[..., T]].
# First, Jedi tries to match List/Iterable. After that we
# will land here, because is_class_value will be True at
# that point. Obviously we also compare below that both
# sides are `Callable`.
for element in value_set:
element_name = element.py__name__()
if element_name == 'Callable':
merge_type_var_dicts(
type_var_dict,
merge_pairwise_generics(self, element),
)
else:
return annotation_generics[1].infer_type_vars(
value_set.execute_annotation(),
)
elif annotation_name == 'Tuple': elif annotation_name == 'Tuple':
tuple_annotation, = self.execute_annotation() tuple_annotation, = self.execute_annotation()
return tuple_annotation.infer_type_vars(value_set, is_class_value) return tuple_annotation.infer_type_vars(value_set)
return type_var_dict return type_var_dict
@@ -337,7 +306,7 @@ class Tuple(BaseTypingValueWithGenerics):
.py__getattribute__('tuple').execute_annotation() .py__getattribute__('tuple').execute_annotation()
return tuple_ return tuple_
def infer_type_vars(self, value_set, is_class_value=False): def infer_type_vars(self, value_set):
# Circular # Circular
from jedi.inference.gradual.annotation import merge_pairwise_generics, merge_type_var_dicts from jedi.inference.gradual.annotation import merge_pairwise_generics, merge_type_var_dicts
from jedi.inference.gradual.base import GenericClass from jedi.inference.gradual.base import GenericClass
@@ -346,14 +315,6 @@ class Tuple(BaseTypingValueWithGenerics):
lambda x: x.py__name__().lower() == 'tuple', lambda x: x.py__name__().lower() == 'tuple',
) )
# Somewhat unusually, this `infer_type_vars` method is on an instance
# representation of a type, rather than the annotation or class
# representation. This means that as a starting point, we need to
# convert the incoming values to their instance style if they're
# classes, rather than the reverse.
if is_class_value:
value_set = value_set.execute_annotation()
if self._is_homogenous(): if self._is_homogenous():
# The parameter annotation is of the form `Tuple[T, ...]`, # The parameter annotation is of the form `Tuple[T, ...]`,
# so we treat the incoming tuple like a iterable sequence # so we treat the incoming tuple like a iterable sequence
@@ -370,11 +331,8 @@ class Tuple(BaseTypingValueWithGenerics):
type_var_dict = {} type_var_dict = {}
for element in value_set: for element in value_set:
if not is_class_value: py_class = element.get_annotated_class_object()
py_class = element.get_annotated_class_object() if not isinstance(py_class, GenericClass):
if not isinstance(py_class, GenericClass):
py_class = element
else:
py_class = element py_class = element
merge_type_var_dicts( merge_type_var_dicts(