Use generic types in TypeGuard function with mypy

Viewed 488

I have a function that checks if a list contains None and I want to use it to narrow the type of the input variable:

from typing import List, Optional, TypeVar
from typing_extensions import TypeGuard

_ListElementsType = TypeVar("_ListElementsType")


def sequence_not_contains_none(maybe_optional_list: List[Optional[_ListElementsType]]) -> TypeGuard[List[_ListElementsType]]:
    return not (None in maybe_optional_list)

When using this function with input List[Optional[int]]:

integer_list: List[Optional[int]] = [10, 11, 12]
reveal_type(integer_list)
if int_sequence_not_contains_none(integer_list):
    reveal_type(integer_list)

I get the wrong return type:

note: Revealed type is "builtins.list[Union[builtins.int, None]]"
note: Revealed type is "builtins.list[_ListElementsType`-1]"

where I would have expected that the second type is List[int].

If I switch out the generic type with a fixed int it works. As far as I understand PEP 647 the version using generics should also be supported. The mypy version used is mypy 0.910 (python 3.8.10)

1 Answers

This issue has been reported: #11428

The Pylance type hinting gets it right though. (Tested with: Pylance v2021.11.0 and Python 3.10.0)

Related