def infer_type_vars(self, value_set, is_class_value=False): # Circular from jedi.inference.gradual.annotation import merge_pairwise_generics, merge_type_var_dicts type_var_dict = {} annotation_generics = self.get_generics() if not annotation_generics: return type_var_dict annotation_name = self.py__name__() if annotation_name == 'Type': if is_class_value: # This only applies if we are comparing something like # 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': if len(annotation_generics) == 2: if is_class_value: # 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': tuple_annotation, = self.execute_annotation() return tuple_annotation.infer_type_vars(value_set, is_class_value) return type_var_dict
def infer_type_vars(self, value_set, is_class_value=False): # Circular from jedi.inference.gradual.annotation import merge_pairwise_generics, merge_type_var_dicts from jedi.inference.gradual.base import GenericClass if self._is_homogenous(): # The parameter annotation is of the form `Tuple[T, ...]`, # so we treat the incoming tuple like a iterable sequence # rather than a positional container of elements. return self.get_generics()[0].infer_type_vars( value_set.merge_types_of_iterate(), ) else: # The parameter annotation has only explicit type parameters # (e.g: `Tuple[T]`, `Tuple[T, U]`, `Tuple[T, U, V]`, etc.) so we # treat the incoming values as needing to match the annotation # exactly, just as we would for non-tuple annotations. type_var_dict = {} for element in value_set: py_class = element.get_annotated_class_object() if not isinstance(py_class, GenericClass): py_class = element merge_type_var_dicts( type_var_dict, merge_pairwise_generics(self, py_class), ) return type_var_dict
def infer_type_vars(self, value_set, is_class_value=False): # Circular from jedi.inference.gradual.annotation import merge_pairwise_generics, merge_type_var_dicts from jedi.inference.gradual.base import GenericClass value_set = value_set.filter( 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(): # The parameter annotation is of the form `Tuple[T, ...]`, # so we treat the incoming tuple like a iterable sequence # rather than a positional container of elements. return self.get_generics()[0].infer_type_vars( value_set.merge_types_of_iterate(), ) else: # The parameter annotation has only explicit type parameters # (e.g: `Tuple[T]`, `Tuple[T, U]`, `Tuple[T, U, V]`, etc.) so we # treat the incoming values as needing to match the annotation # exactly, just as we would for non-tuple annotations. type_var_dict = {} for element in value_set: if not is_class_value: py_class = element.get_annotated_class_object() if not isinstance(py_class, GenericClass): py_class = element else: py_class = element merge_type_var_dicts( type_var_dict, merge_pairwise_generics(self, py_class), ) return type_var_dict
def infer_type_vars(self, value_set): # Circular from jedi.inference.gradual.annotation import merge_pairwise_generics, merge_type_var_dicts value_set = value_set.filter( lambda x: x.py__name__().lower() == 'tuple', ) if self._is_homogenous(): # The parameter annotation is of the form `Tuple[T, ...]`, # so we treat the incoming tuple like a iterable sequence # rather than a positional container of elements. return self._class_value.get_generics()[0].infer_type_vars( value_set.merge_types_of_iterate(), ) else: # The parameter annotation has only explicit type parameters # (e.g: `Tuple[T]`, `Tuple[T, U]`, `Tuple[T, U, V]`, etc.) so we # treat the incoming values as needing to match the annotation # exactly, just as we would for non-tuple annotations. type_var_dict = {} for element in value_set: try: method = element.get_annotated_class_object except AttributeError: # This might still happen, because the tuple name matching # above is not 100% correct, so just catch the remaining # cases here. continue py_class = method() merge_type_var_dicts( type_var_dict, merge_pairwise_generics(self._class_value, py_class), ) return type_var_dict
def infer_type_vars(self, value_set, is_class_value=False): # Circular from jedi.inference.gradual.annotation import merge_pairwise_generics, merge_type_var_dicts annotation_name = self.py__name__() type_var_dict = {} if annotation_name == 'Iterable' and not is_class_value: annotation_generics = self.get_generics() if annotation_generics: return annotation_generics[0].infer_type_vars( value_set.merge_types_of_iterate(), ) else: # 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 # them back in a set afterwards. for py_class in value_set: if not is_class_value: if py_class.is_instance() and not py_class.is_compiled(): py_class = py_class.get_annotated_class_object() else: continue if py_class.api_type != u'class': # Functions & modules don't have an MRO and we're not # expecting a Callable (those are handled separately within # TypingClassValueWithIndex). continue for parent_class in py_class.py__mro__(): class_name = parent_class.py__name__() if annotation_name == class_name: merge_type_var_dicts( type_var_dict, merge_pairwise_generics(self, parent_class), ) break return type_var_dict