Shouldn't the return type of `__reversed__` be an `Iterable[T]` instead of `Iterator[T]`?
還沒有人認領這個 Issue。
評估
研究方向
先從連結行中的 stdlib/typing.pyi 裡的 Reversible 定義開始,然後比較 issue 中的兩個 mypy Playground 範例。確定一個既能接受所示 reversed 實作、又能維持 reversed(my_iter) 型別檢查的簽章;當兩個回報的錯誤都獲得解決,且沒有削弱無關的型別行為時,即視為完成。
由索引模型根據 Issue 內容生成。
描述
Currently the return type of Reversible.__reversed__ is typed as Iterator[T], which suggests that the returned instance must have both an __next__ and an __iter__ method.
However, the following code seems to work fine at runtime:
from dataclasses import dataclass
from typing import Iterator, Iterable
@dataclass
class MyIter:
_values: list[int]
def __iter__(self) -> Iterator[int]:
return iter(self._values)
def __reversed__(self) -> Iterator[int]:
return MyIter(self._values[::-1])
my_iter = MyIter([1, 2, 3])
for x in my_iter:
print(x)
for x in reversed(my_iter):
print(x)
Note that __reversed__ here returns a MyIter instance, which has an __iter__ method, but no __next__, i.e., it is an Iterable but not an Iterator. The Python interpreter seems to deal with that fine at runtime, i.e., it doesn't actually seem to need the __next__ method. This is slightly surprising, because the docs specify:
It should return a new iterator object that iterates over all the objects in the container in reverse order.
I.e., it doesn't use the word "iterable object".
Unfortunately, the current signature of __reversed__ means that this example does not type check: Obviously the type checker has to complain about the return MyIter(...) line, because MyIter is indeed only an Iterable (example on mypy playground):
main.py:13: error: Incompatible return value type (got "MyIter", expected "Iterator[int]") [return-value]
main.py:13: note: "MyIter" is missing following "Iterator" protocol member:
main.py:13: note: __next__
Found 1 error in 1 file (checked 1 source file)
Now I'm wondering if the signature should actually be def __reversed__(self) -> Iterable[int] to lessen the requirement and match the runtime behavior?
Note that simply changing the return type to Iterable on user side means that the return statement now type checks, but then all usages (reversed(my_iter)) stop to type check because the type checker will no longer consider MyIter as a valid Reversible (modified example on mypy playground):
main.py:18: error: No overload variant of "reversed" matches argument type "MyIter" [call-overload]
main.py:18: note: Possible overload variants:
main.py:18: note: def [_T] __new__(cls, Reversible[_T], /) -> reversed[_T]
main.py:18: note: def [_T] __new__(cls, SupportsLenAndGetItem[_T], /) -> reversed[_T]
Found 1 error in 1 file (checked 1 source file)
- 主要語言
- Python
- 星號
- 5.1k
- 分支
- 2.1k
- 平均合併
- 1 天 19 小時
- 30 天內合併 PR
- 82
貢獻指南
從這裡開始
- 先讀完整個 Issue,再讀專案的貢獻指南。
- 在 Issue 下留言說明你要接手 —— 這能避免兩個人做同樣的事。
- Fork 儲存庫,在一個分支上完成修改。
- 送出 Pull Request,並在描述裡引用這個 Issue 編號。
python/typeshed 的其他 Issue
-
難度 2/5 1-3 小時 新手友好度 72/100
-
難度 2/5 1-3 小時 新手友好度 68/100
-
難度 2/5 1-3 小時 新手友好度 76/100
-
project: infrastructure
難度 2/5 1-3 小時 新手友好度 68/100
-
stubs: improvement
難度 2/5 1-3 小時 新手友好度 72/100
相似的 Issue
-
area/auth bug comp/agent P3 platform/discord type/security
難度 2/5 1-3 小時 新手友好度 88/100
NousResearch/hermes-agent#117848 ·
-
難度 2/5 1-3 小時 新手友好度 74/100
bancolombia/sentinel#23 ·
-
test md 未關閉CI
難度 2/5 1-3 小時 新手友好度 74/100
-
integration:quickjs org:external priority:backlog topic:code-interpreter topic:middleware type:feature
難度 2/5 1-3 小時 新手友好度 74/100
langchain-ai/deepagents#6450 ·
-
bug client
難度 2/5 1-3 小時 新手友好度 88/100