mypy 声明 IO[bytes] 与 BinaryIO 不兼容

mypy declares IO[bytes] incompatible with BinaryIO

考虑以下代码:

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()

运行 Python 3.6.9 下上述代码的 mypy v0.782 失败并出现以下错误:

zfopen.py:8: error: Argument 1 to "TextIOWrapper" has incompatible type "IO[bytes]"; expected "BinaryIO"

不过,我觉得这段代码不应被视为错误,因为 ZipFile.open() return 是二进制文件句柄,TextIOWrapper 接受。此外, IO[bytes]BinaryIO (据我所知)实际上是同一件事;只是 BinaryIO 被声明为 IO[bytes] 的子类。我天真地希望 IO[bytes]BinaryIO 所在的任何地方都能被接受,除非子类不是这样工作的,而且我不确定在输入时如何正确使用这个子类。

谁错了,错误是如何修复的?

这个带有 mypy 0.782 的较短测试用例得到相同的错误:

    binary_file = io.open('foo.bin', 'rb')
    text_file = io.TextIOWrapper(binary_file, encoding='utf-8', newline='')

binary_file 是显式声明为 IO[bytes] 还是推断。

修复: 使用 mypy 0.770mypy 0.790.

这是 mypy 类型流中的回归 (Issue 4349),修复在 mypy 0.790 中,修复了 zipfile.open()io.open()