Here's a short example of what I'd think should be a correctly typed program...
from typing import Iterable
def f() -> Iterable[int]:
yield 1
print(next(f()))
Running mypy on this (under Python 3.4, no strict mode, no other flags at all) results in the following error:
error: No overload variant of "next" matches argument types [typing.Iterable[builtins.int]]
Is this a bug, or am I doing something wrong?
Try Iterator instead.
Sometimes I wonder if mypy should warn if an incompatible return type is specified on a generator...
Oh, but it does check the return type. Only Generator and its superclasses are allowed, i.e. Iterator, Iterable, and object. This gives the author some freedom in how much they freedom they want for future changes to that particular function (maybe they'd like to be able to turn it into something else that can be iterated over without breaking the callers). It's just that next() wants an Iterator. But most of the time people don't use next() with a generator, they just use a for-loop over it.
The error message isn't very useful though. Mypy should really tell that the expected type is Iterator[T]. #672 would be helpful -- marked it as high priority as confusions like these seem pretty common.
so this is expected behaviour?
things = [1, 2, 3]
first = next(things) # No overload variant of "next" matches argument type List[int]
i know this is more of a support question really, but why is this an error? seems like perfectly cromulent code to me...
@hjwp
In [35]: next([1, 2, 3])
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
... in <module>()
----> 1 next([1, 2, 3])
TypeError: 'list' object is not an iterator
omg _how. embarrassing._ so sorry everyone. thanks Jelle.
for posterity, what I wanted to do was something like
# return the first thing in things, or None if things is empty
next(things, None) # works for iterators/generators
# instead you might prefer
things[0] if things else None # for a list/iterable.
Most helpful comment
The error message isn't very useful though. Mypy should really tell that the expected type is
Iterator[T]. #672 would be helpful -- marked it as high priority as confusions like these seem pretty common.