On Thu, Jan 21, 2021 at 10:00 AM Eric Traut email@example.com wrote:
I recommend against using `bound=Tuple` for the following reasons:
- If we drop support for packed (non-unpacked?) usage, it's entirely
unnecessary and is just extra verbosity that provides no value.
- I think it will confuse many users because it means that the `bound`
has a different semantic meaning if the TypeVar is used in both a variadic and non-variadic context.
But it doesn't really have a different meaning, does it? Apart from #4 below `bound=Tuple` just means `bound=`Tuple[Any, ...]` and that's exactly the right upper bound for a type variable used with `*T`, since the *actual* type is always *some* tuple but we can't say more about it.
And if someone wants to have a variadic argument whose items are always instances of some type A, they can use `bound=Tuple[A, ...]`. (Similar to how in TypeScript you could use `<T extends A>`.)
- It eliminates the possibility of using `bound` for variadic TypeVars in
the future. I think there are real use cases that we will want to enable here. For example, a class that accepts an arbitrary number of generic types where all of those types needs to be sized. This could be expressed as:
_T = TypeVar("_T", bound=Sized) class MyClass(Generic[*_T]): ...
Using my current proposal you can express that with `bound=Tuple[Sized, ...]`.
(I wonder if you interpreted my examples too literally and assumed that I wanted to give a special meaning to exactly `bound=Tuple`? I merely intended to indicate that we might as well use `bound=Tuple` because that upperbound is implied by the `*T` notation. Or perhaps I meant that `Ts = TypeVarTuple('Ts')` is for all intents and purposes implying `bound=Tuple`. :-)
- Python developers are still getting used to typing and generics, and
I've found that many of them forget to (or don't understand that they need to) supply type arguments when using a generic type within a type expression. For that reason, Pyright emits a warning (or an error in "strict" mode) if type arguments are not provided. So `Tuple` would emit a warning, whereas `Tuple[Any, ...]` would not. This warning has proven very useful to many users, and I don't want to eliminate it, but I'd probably need to eliminate it (at least in some contexts) if we advocated the use of `T = TypeVar("T", bound=Tuple)` in this PEP.
Yeah, mypy can emit a similar warning. I guess we don't need to specify the bound since it is implied by `*T`.