Using Union[Type[T], str] is problematic, because when str is passed, mypy infers T to be Never. Instead, you should use an overload with two cases, so inference would be correct:
from typing import Any, TypeVar, Union, Type, overload
T = TypeVar('T')
class My:
def resolve( # type: ignore[empty-body]
self,
obj_type: Union[Type[T], str],
) -> T:
... # in reallity we would return something here
reveal_type(My().resolve(int))
# N: Revealed type is "builtins.int"
reveal_type(My().resolve('a'))
# N: Revealed type is "Never"
class Other:
@overload
def resolve(self, obj_type: Type[T]) -> T: ...
@overload
def resolve(self, obj_type: str) -> Any: ...
def resolve(self, obj_type: Any) -> Any: ...
reveal_type(Other().resolve(int))
# N: Revealed type is "builtins.int"
reveal_type(Other().resolve('a'))
# N: Revealed type is "Any"
Using
Union[Type[T], str]
is problematic, because whenstr
is passed, mypy infersT
to beNever
. Instead, you should use anoverload
with two cases, so inference would be correct:Link: https://mypy-play.net/?mypy=latest&python=3.12&gist=97dd0c638b48950199067e8290e5595e&flags=strict
This way users can actually use
Any
type, whileNever
type cannot be used for literally anything.