jwo*_*der 9 python type-hinting mypy
考虑以下代码:
from io import TextIOWrapper
from typing import List
from zipfile import ZipFile
def read_zip_lines(zippath: str, filename: str) -> List[str]:
with ZipFile(zippath) as zf:
with zf.open(filename) as bfp:
with TextIOWrapper(bfp, 'utf-8') as fp:
return fp.readlines()
Run Code Online (Sandbox Code Playgroud)
在 Python 3.6.9 下在上述代码上运行 mypy v0.782 失败并出现以下错误:
zfopen.py:8: error: Argument 1 to "TextIOWrapper" has incompatible type "IO[bytes]"; expected "BinaryIO"
Run Code Online (Sandbox Code Playgroud)
但是,我觉得这段代码不应该被视为错误,因为ZipFile.open()返回了一个TextIOWrapper接受的二进制文件句柄。此外,IO[bytes]和BinaryIO(据我所知)实际上是一回事;它只是BinaryIO被声明为IO[bytes]. 我天真地希望IO[bytes]在任何地方都能被接受BinaryIO,除了这不是子类的工作方式,而且我不确定在打字时如何正确利用这个子类。
谁在这里出错了,如何修复错误?
ZipFile.open()asIO[bytes]而不是typeshed 是否错误BinaryIO?TextIOWrapperasBinaryIO而不是IO[bytes]?typing模块是否在创建BinaryIO子类IO[bytes]而不是别名时出错?bfp?bfp可以通过TextIOWrapper未修改?这个带有 mypy 0.782 的较短测试用例得到相同的错误:
binary_file = io.open('foo.bin', 'rb')
text_file = io.TextIOWrapper(binary_file, encoding='utf-8', newline='')
Run Code Online (Sandbox Code Playgroud)
是否binary_file明确声明为IO[bytes]或推断。
修复:使用mypy 0.770或mypy 0.790。
这是 mypy 排版(问题 4349)中的一个回归,修复在 mypy 0.790 中,修复了zipfile.open()和io.open().