-
-
Notifications
You must be signed in to change notification settings - Fork 229
Description
Now that the library properly registers as being typed for mypy, alive_it() claims its type is Iterator[YourData]. But this means that trying to, say, call .text() on the iterator no longer type-checks, since obviously that's not a method of generic Iterators.
The correct way to make a type detectable as Iterable is to subclass the Iterable type, like:
from typing import Iterator, Iterable
class AliveIterable(Iterable):
....This way mypy both knows about the class's methods, and knows you can iterate it so you get the right type in your for loops.
That way I could still write code like in the README examples:
progress = alive_it(myIter)
for item in progress:
progress.text(item.name) # type-checks, since mypy knows there's a .text() method
...As it is in 3.3.0, I can now avoid having to manually cast my alive_it to an iterator, but I have to suppress the type error when I call .text(). That's not actually a meaningful improvement over the 3.2.0 behavior, where I had to manually cast the value in the for loop (for item in typing.cast("Iterator[MyData]", progress):) but then could call .text() without it causing an issue in the loop.
On the other hand, alive_bar() still doesn't have a type at all, so it just shows up as Any. It should ideally return the same sort of type as alive_it().
From what I understand from reading the code, you're not actually using a class at all in this library, instead returning an object of closures, right? It would still probably be useful to define a dummy class with the right method signatures, at least, have your functions claim to return that type, and then typing.cast() your actual return value accordingly.
You can define all of that in an if typing.TYPE_CHECKING: block so it doesn't have any runtime effect at all, if you want, but that would require me to do a similar block to import the type for my own use. Not killer, just slightly annoying.