pythongenericspython-typingvariadic-functions

How to transform or unpack *args types for typing variadics


I want to annotate a function that combines several iterators or generators into one, the case for two iterators is trivial:

def merge_two_iterators[T, H](
    gen1: Iterator[T],
    gen2: Iterator[H]
) -> Iterator[tuple[T, H]]: ...

But I can't make the arbitrary number of iterators work.

def merge_iterators[*Ts](
    *its: *Ts
) -> Iterator[tuple[*Ts]]: ... # wrong

How can I unpack the list of iterators into a tuple? Unpack is not doing the trick.

The result should be something like this:

a: list[int] = [1, 2]
b: list[str] = ['a', 'b']

c = merge_iterators(a, b)
# annotated as -> Iterator[tuple[int, str]]  or list[tuple[int, str]]

Solutions with old python versions <3.11 are accepted, solutions that don´t work in a specific typing tool such as mypy, but comply with the specs and preferably work in at least one tool are accepted as well.


Solution

  • As commented by @InSync this is not currently possible, but a ongoing topic:

    https://discuss.python.org/t/pre-pep-considerations-and-feedback-type-transformations-on-variadic-generics/50605

    However a workaround can be found in the built in implementation of zip:

    https://github.com/python/typeshed/blob/6a9b53e719a139c2d6b41cf265ed0990cf438192/stdlib/builtins.pyi#L1763-L1801

    By overloading as many cases as may be reasonable.