python / typeshed

Collection of library stubs for Python, with static types
Other
4.35k stars 1.74k forks source link

Many functions that accept Iterable should actually accept Iterable | SupportsGetItem #7814

Closed matangover closed 2 years ago

matangover commented 2 years ago

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 the PySequence_* 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
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.

JelleZijlstra commented 2 years ago

Duplicate of #7813

matangover commented 2 years ago

Sorry, got posted twice for some reason