pythonpython-typing

Type hinting a non-generator (non-consumable) iterable


I'd like to type hint a function like this:

from types import Iterable

def func(thing: Iterable[str]) -> None:
    for i in range(10):
        for x in thing:
            do_thing(x)

PyCharm will (correctly) let me get away with passing in a generator to this function, but I want to type hint it in a way that it won't allow me to, while still accepting other iterables.

Using Sequence[str] isn't an option, iterables like KeyView aren't sequences, but I would still like to be able to include them.

Someone mentioned using a Union with a Sequence + KeyView, which would work, but I was wondering if there was a more elegant and universal solution

Of course, I could just convert thing to a list no matter what, but I'd rather just have this function type hinted correctly.

Using Python 3.7


Solution

  • Unfortunately I think this is just not possible with Python's type system.

    Straight from Guido (source):

    Our type system doesn't allow you to express that -- it's like asking for any Animal except Cat. Adding an "except" clause like that to the type system would be a very difficult operation.

    Since there's no solution, I'm going to close this as "won't fix".

    His suggestion:

    Yeah, the practical solution is Sequence|Set|Mapping. The needed negation is years off.