You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
When transposing a 2d iterable x: Iterable[Iterable[T]] using zip(*x), I've noticed typeshed's type annotations result in the return type being inferred as zip[tuple[Any, ...]] rather than the expected zip[tuple[T, ...]]. It would be nice if builtins.py1 had an overload for this use case.
Expected behavior
When x has type Iterable[Iterable[T]], the expression zip(*x) should be inferred as zip[tuple[T, ...]], preserving the element type information through the transpose operation.
Actual behavior
The expression zip(*x) is inferred as zip[tuple[Any, ...]].
While I have seen zip(*x) in the wild, I have not seen zip(a,b,c,*x) in any environment before, so I don't think it's necessary to write an overload for that edge case.
Unfortunately your proposed solution doesn't seem to work currently in mypy.
If we add your overload before the final overload then you get the behavior you want for zip(*x), but then zip(a, b, c, d, e, f, g) would no longer return zip[tuple[Any, ...] and if we do make it the final overload, then zip(*x) will still return zip[tuple[Any, ...]]. There's no way to get one behavior with the spread while getting another with the 7+ parameter case, at least not in mypy. Things might look slightly different in pyright.
At least adding it as the final overload doesn't appear to cause any problems in mypy (but you also don't gain anything), so if you get the correct result in pyright that way, it might still be worth changing it.
It's worth pointing out that there have been some recent discussion about solidifying the behavior of overloads in the typing spec, which also includes the special case of spreading homogenous iterables of unknown length into arguments. So depending on which way these decisions go your solution may end up working better or worse in the future.
Description:
When transposing a 2d iterable
x: Iterable[Iterable[T]]
usingzip(*x)
, I've noticed typeshed's type annotations result in the return type being inferred aszip[tuple[Any, ...]]
rather than the expectedzip[tuple[T, ...]]
. It would be nice if builtins.py1 had an overload for this use case.Expected behavior
When
x
has typeIterable[Iterable[T]]
, the expressionzip(*x)
should be inferred aszip[tuple[T, ...]]
, preserving the element type information through the transpose operation.Actual behavior
The expression
zip(*x)
is inferred aszip[tuple[Any, ...]]
.Possible solution
Add the following overloads to zip:
Pre 3.10:
3.10 or later:
While I have seen
zip(*x)
in the wild, I have not seenzip(a,b,c,*x)
in any environment before, so I don't think it's necessary to write an overload for that edge case.Footnotes
https://github.com/python/typeshed/blob/494a5d1b98b3522173dd7e0f00f14a32be00456b/stdlib/builtins.pyi#L1813 ↩
The text was updated successfully, but these errors were encountered: