In your example above, you asked "What is the type of b?". I agree that it should be `Union[int, str]`. That's consistent with pyright's current behavior. Here are a few thoughts about how we could generalize variadic type variables to work with tuple. We could extend variadic (list) type variables to accept an optional parameter called `arbitrary_len` that indicates whether variadic type variable supports homogenous, arbitrary-length forms. By default, variadic type variables wouldn't allow this. We'd need to make it illegal to use type variables that support arbitrary lengths with an unpack operator or `Expand` because the result would be undefined. For type variables that support arbitrary length lists, we could define some simple rules for how they "collapse" to traditional (non-list) types. 1. For a variadic TypeVar that is bound to a homogenous, arbitrary-length list, the type list [T, ...] collapses to a type of T. 2. For a variadic TypeVar that is bound to a heterogenous, fixed-length list, the type list collapses to a union of the individual subtypes with literals stripped. For example, [Literal['a'], int] collapses to Union[str, int]. For an explanation of why it's important to strip literals in this case, refer to [this discussion](https://github.com/microsoft/pyright/issues/1249). This would allow us to define the `tuple` class and its constructor as follows: ```python _T = TypeVar("_T") _Ts = TypeVar("_Ts", list=True, arbitrary_len=True) class tuple(Sequence[_Ts]): @overload def __new__(cls: Type[_T], iterable: Tuple[_Ts] = ...) -> _T: ... @overload def __new__(cls: Type[_T], iterable: Iterable[_Ts] = ...) -> _T: ... ``` Thoughts? -- Eric Traut Contributor to pyright/pylance