diff --git a/jedi/inference/gradual/typing.py b/jedi/inference/gradual/typing.py index 6b3e675b..189fe997 100644 --- a/jedi/inference/gradual/typing.py +++ b/jedi/inference/gradual/typing.py @@ -342,6 +342,18 @@ class Tuple(BaseTypingValueWithGenerics): 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 @@ -358,8 +370,11 @@ class Tuple(BaseTypingValueWithGenerics): type_var_dict = {} for element in value_set: - py_class = element.get_annotated_class_object() - if not isinstance(py_class, GenericClass): + 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( diff --git a/test/completion/pep0484_generic_mismatches.py b/test/completion/pep0484_generic_mismatches.py index fbd3c55a..c848dd10 100644 --- a/test/completion/pep0484_generic_mismatches.py +++ b/test/completion/pep0484_generic_mismatches.py @@ -33,6 +33,7 @@ tpl_typed = ("2", 3) # type: Tuple[str, int] collection = {"a": 1} collection_typed = {"a": 1} # type: Dict[str, int] +list_of_ints = [42] # type: List[int] list_of_funcs = [foo] # type: List[Callable[[T], T]] custom_generic = CustomGeneric(123.45) @@ -319,3 +320,21 @@ x7 for a in list_t_to_list_t(12): #? a + + +def list_tuple_t_to_tuple_list_t(the_list: List[Tuple[T]]) -> Tuple[List[T], ...]: + return tuple(list(x) for x in the_list) + + +for b in list_tuple_t_to_tuple_list_t(list_of_ints): + #? + b[0] + + +def list_tuple_t_elipsis_to_tuple_list_t(the_list: List[Tuple[T, ...]]) -> Tuple[List[T], ...]: + return tuple(list(x) for x in the_list) + + +for b in list_tuple_t_to_tuple_list_t(list_of_ints): + #? + b[0] diff --git a/test/completion/pep0484_generic_parameters.py b/test/completion/pep0484_generic_parameters.py index 4f0f0d1f..9edcd061 100644 --- a/test/completion/pep0484_generic_parameters.py +++ b/test/completion/pep0484_generic_parameters.py @@ -80,6 +80,29 @@ for c2, in list_t_to_list_tuple_t(list_of_ints): c2 +# Test handling of nested tuple input parameters +def list_tuple_t_to_tuple_list_t(the_list: List[Tuple[T]]) -> Tuple[List[T], ...]: + return tuple(list(x) for x in the_list) + + +list_of_int_tuples = [(x,) for x in list_of_ints] # type: List[Tuple[int]] + +for b in list_tuple_t_to_tuple_list_t(list_of_int_tuples): + #? int() + b[0] + + +def list_tuple_t_elipsis_to_tuple_list_t(the_list: List[Tuple[T, ...]]) -> Tuple[List[T], ...]: + return tuple(list(x) for x in the_list) + + +list_of_int_tuple_elipsis = [tuple(list_of_ints)] # type: List[Tuple[int, ...]] + +for b in list_tuple_t_elipsis_to_tuple_list_t(list_of_int_tuple_elipsis): + #? int() + b[0] + + # Test handling of nested callables def foo(x: int) -> int: return x