-
-
Notifications
You must be signed in to change notification settings - Fork 1.9k
Description
Many functions in stdlib that are documented to accept an "iterable" are annotated as Iterable[T]
. This means the arguments must have __iter__
. However, the actual functions don't require the arguments to have __iter__
, they also work with arguments that have only __getitem__
. That's because internally they use iter
(in Python) or PySequence_Fast (in C).
As the docs for both iter
and PySequence_Fast
functions show, these functions support two protocols for the argument: the "iterable" protocol (__iter__
) and the "sequence" protocol (__getitem__
).
Example functions that have this bug right now:
enumerate
iter
str.join
bytes.__new__
bytes.join
For enumerate, a bug was actually filed on the mypy repo but in fact I believe this should be corrected in typeshed.
Aside: for
loops also similarly accept "iterables" that have only __getitem__
, but that is implemented inside type checkers themselves. For now mypy still doesn't support it properly, but Pyright does.