On Mon, Jan 25, 2021 at 9:44 AM Eric Traut <eric@traut.com> wrote:
I've run across a few additional questions:

1. PEP 484 indicates that if a type argument is omitted from a generic type, that type argument is assumed to be `Any`. What is the assumption with a variadic TypeVar? Should it default to `()` (empty tuple)? If we support open-ended tuples, then we could also opt for `(Any, ...)`.

The default is actually as many copies of Any as are needed to make the type valid. So we should use (Any, …).
2. What is the type of `def foo(*args: Ts) -> Union[Ts]` if foo is called with no arguments? In other words, what is the type of `Union[*()]`? Is it `Any`? Is this considered an error?

The type of foo() would be NoReturn, since there is no valid value in an empty union, and NoReturn is how we spell the type with no values. It could also be an error. Any seems just wrong.
3. When the constraint solver is solving for a variadic type variable, does it need to solve for the individual elements of the tuple independently? Consider, for example, `def foo(a: Tuple[Ts], b: Tuple[Ts]) -> Tuple[Ts]`. Now, let's consider the expression `foo((3, "hi"), ("hi", 5.6))`? Would this be an error? Or would you expect that the constraint solver produce an answer of `Tuple[int | str, str | float]` (or `Tuple[object, object]`)? It's much easier to implement if we can treat this as an error, but I don't know if that satisfies the use cases you have in mind.

I'd prefer it if I could think of e.g. `def foo(a: Tuple[Ts], b: Tuple[Ts])` as a series of overloads including `def foo(a: Tuple[T1, T2], b: Tuple[T1, T2])`. That should answer the question, right? Ts stands for `(T1, T2, …, Tn)` for some n (we seem to have an issue about whether n can be zero).  If different checkers produce different answers for the latter, e.g. due to different attitudes about unions, that's okay, but checkers should be consistent with themselves.
4. Along the lines of the previous question, consider the expression `foo((3, "hi"), ("hi", ))`. In this case, the lengths of the tuples don't match. If we don't support open-ended variadics, this needs to be an error. If we support open-ended variadics, we have the option of solving this as `Tuple[int | str, ...]` (or `Tuple[object, ...]`). Once again, it's easiest if we don't allow this and treat it as an error.

Interesting example. This makes me wonder if open-ended-ness should be an option to the TypeVar/TypeVarTuple definition? (Didn't we discuss that before?
--Guido van Rossum (python.org/~guido)