Skip to content

Commit a24b765

Browse files
improve type for itertools.zip_longest (#7655)
1 parent a24ce3f commit a24b765

File tree

1 file changed

+87
-12
lines changed

1 file changed

+87
-12
lines changed

stdlib/itertools.pyi

Lines changed: 87 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import sys
2-
from _typeshed import Self, _T_co
2+
from _typeshed import Self
33
from typing import Any, Callable, Generic, Iterable, Iterator, SupportsComplex, SupportsFloat, SupportsInt, TypeVar, overload
44
from typing_extensions import Literal, SupportsIndex, TypeAlias
55

@@ -9,6 +9,14 @@ if sys.version_info >= (3, 9):
99
_T = TypeVar("_T")
1010
_S = TypeVar("_S")
1111
_N = TypeVar("_N", int, float, SupportsFloat, SupportsInt, SupportsIndex, SupportsComplex)
12+
_T_co = TypeVar("_T_co", covariant=True)
13+
_T1 = TypeVar("_T1")
14+
_T2 = TypeVar("_T2")
15+
_T3 = TypeVar("_T3")
16+
_T4 = TypeVar("_T4")
17+
_T5 = TypeVar("_T5")
18+
_T6 = TypeVar("_T6")
19+
1220
_Step: TypeAlias = int | float | SupportsFloat | SupportsInt | SupportsIndex | SupportsComplex
1321

1422
Predicate: TypeAlias = Callable[[_T], object]
@@ -76,9 +84,6 @@ class filterfalse(Iterator[_T], Generic[_T]):
7684
def __iter__(self: Self) -> Self: ...
7785
def __next__(self) -> _T: ...
7886

79-
_T1 = TypeVar("_T1")
80-
_T2 = TypeVar("_T2")
81-
8287
class groupby(Iterator[tuple[_T, Iterator[_S]]], Generic[_T, _S]):
8388
@overload
8489
def __new__(cls, iterable: Iterable[_T1], key: None = ...) -> groupby[_T1, _T1]: ...
@@ -107,15 +112,85 @@ class takewhile(Iterator[_T], Generic[_T]):
107112

108113
def tee(__iterable: Iterable[_T], __n: int = ...) -> tuple[Iterator[_T], ...]: ...
109114

110-
class zip_longest(Iterator[Any]):
111-
def __init__(self, *p: Iterable[Any], fillvalue: Any = ...) -> None: ...
115+
class zip_longest(Iterator[_T_co], Generic[_T_co]):
116+
# one iterable (fillvalue doesn't matter)
117+
@overload
118+
def __new__(cls, __iter1: Iterable[_T1], *, fillvalue: object = ...) -> zip_longest[tuple[_T1]]: ...
119+
# two iterables
120+
@overload
121+
# In the overloads without fillvalue, all of the tuple members could theoretically be None,
122+
# but we return Any instead to avoid false positives for code where we know one of the iterables
123+
# is longer.
124+
def __new__(cls, __iter1: Iterable[_T1], __iter2: Iterable[_T2]) -> zip_longest[tuple[_T1 | Any, _T2 | Any]]: ...
125+
@overload
126+
def __new__(
127+
cls, __iter1: Iterable[_T1], __iter2: Iterable[_T2], *, fillvalue: _T
128+
) -> zip_longest[tuple[_T1 | _T, _T2 | _T]]: ...
129+
# three iterables
130+
@overload
131+
def __new__(
132+
cls, __iter1: Iterable[_T1], __iter2: Iterable[_T2], __iter3: Iterable[_T3]
133+
) -> zip_longest[tuple[_T1 | Any, _T2 | Any, _T3 | Any]]: ...
134+
@overload
135+
def __new__(
136+
cls, __iter1: Iterable[_T1], __iter2: Iterable[_T2], __iter3: Iterable[_T3], *, fillvalue: _T
137+
) -> zip_longest[tuple[_T1 | _T, _T2 | _T, _T3 | _T]]: ...
138+
# four iterables
139+
@overload
140+
def __new__(
141+
cls, __iter1: Iterable[_T1], __iter2: Iterable[_T2], __iter3: Iterable[_T3], __iter4: Iterable[_T4]
142+
) -> zip_longest[tuple[_T1 | Any, _T2 | Any, _T3 | Any, _T4 | Any]]: ...
143+
@overload
144+
def __new__(
145+
cls, __iter1: Iterable[_T1], __iter2: Iterable[_T2], __iter3: Iterable[_T3], __iter4: Iterable[_T4], *, fillvalue: _T
146+
) -> zip_longest[tuple[_T1 | _T, _T2 | _T, _T3 | _T, _T4 | _T]]: ...
147+
# five iterables
148+
@overload
149+
def __new__(
150+
cls,
151+
__iter1: Iterable[_T1],
152+
__iter2: Iterable[_T2],
153+
__iter3: Iterable[_T3],
154+
__iter4: Iterable[_T4],
155+
__iter5: Iterable[_T5],
156+
) -> zip_longest[tuple[_T1 | Any, _T2 | Any, _T3 | Any, _T4 | Any, _T5 | Any]]: ...
157+
@overload
158+
def __new__(
159+
cls,
160+
__iter1: Iterable[_T1],
161+
__iter2: Iterable[_T2],
162+
__iter3: Iterable[_T3],
163+
__iter4: Iterable[_T4],
164+
__iter5: Iterable[_T5],
165+
*,
166+
fillvalue: _T,
167+
) -> zip_longest[tuple[_T1 | _T, _T2 | _T, _T3 | _T, _T4 | _T, _T5 | _T]]: ...
168+
# six or more iterables
169+
@overload
170+
def __new__(
171+
cls,
172+
__iter1: Iterable[_T],
173+
__iter2: Iterable[_T],
174+
__iter3: Iterable[_T],
175+
__iter4: Iterable[_T],
176+
__iter5: Iterable[_T],
177+
__iter6: Iterable[_T],
178+
*iterables: Iterable[_T],
179+
) -> zip_longest[tuple[_T | Any, ...]]: ...
180+
@overload
181+
def __new__(
182+
cls,
183+
__iter1: Iterable[_T],
184+
__iter2: Iterable[_T],
185+
__iter3: Iterable[_T],
186+
__iter4: Iterable[_T],
187+
__iter5: Iterable[_T],
188+
__iter6: Iterable[_T],
189+
*iterables: Iterable[_T],
190+
fillvalue: _T,
191+
) -> zip_longest[tuple[_T, ...]]: ...
112192
def __iter__(self: Self) -> Self: ...
113-
def __next__(self) -> Any: ...
114-
115-
_T3 = TypeVar("_T3")
116-
_T4 = TypeVar("_T4")
117-
_T5 = TypeVar("_T5")
118-
_T6 = TypeVar("_T6")
193+
def __next__(self) -> _T_co: ...
119194

120195
class product(Iterator[_T_co], Generic[_T_co]):
121196
@overload

0 commit comments

Comments
 (0)