I have a Python function used as a runtime check that ensures an object is an instance of at least one class in a tuple. It works and my type-checker (pyright) correctly infers the return type from the arguments:
from typing import Union, Type, Tuple, Any, TypeVar
T = TypeVar('T')
def inst(obj: Any, type: Union[Type[T], Tuple[Type[T], ...]]) -> T:
if isinstance(obj, type):
return obj
raise Exception(f'{obj} must be an instance of {type}')
x = inst(3, (int, str)) # => pyright correctly says x is `int | str`
However, when I attempt to factor out the pattern Union[Type[T], Tuple[T, ...]]
into a type alias, it breaks type inference:
from typing import Union, Type, Tuple, Any, TypeVar
T = TypeVar('T')
TypeOrTupleOfTypes = Union[T, Tuple[T, ...]]
def inst(obj: Any, type: TypeOrTupleOfTypes[Type[T]]) -> T:
if isinstance(obj, type):
return obj
raise Exception(f'{obj} must be an instance of {type}')
x = inst(3, (int, str)) # => pyright now thinks x is `tuple[Type[int], Type[str]]`
Why can't I use a type alias here?