简体   繁体   中英

mypy declares IO[bytes] incompatible with BinaryIO

Consider the following code:

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

Running mypy v0.782 on the above code under Python 3.6.9 fails with the following error:

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

However, I feel that this code should not be regarded as an error, as ZipFile.open() returns a binary filehandle, which TextIOWrapper accepts. Moreover, IO[bytes] and BinaryIO are (as far as I understand) effectively the same thing; it's just that BinaryIO is declared as a subclass of IO[bytes] . I would naïvely expect IO[bytes] to be accepted everywhere that BinaryIO is, except that's not how subclasses work, and I'm not sure how to properly make use of this subclassing when typing.

Who is in error here, and how does the error get fixed?

  • Is typeshed in error for declaring the return type of ZipFile.open() as IO[bytes] instead of BinaryIO ?
  • Is typeshed in error for declaring the type of the first argument to TextIOWrapper as BinaryIO instead of IO[bytes] ?
  • Is the typing module in error for making BinaryIO a subclass of IO[bytes] instead of an alias?
  • Is my code in error for not performing some sort of cast on bfp ?
  • Is my thinking in error for expecting bfp to be passable to TextIOWrapper unmodified?

This shorter test case with mypy 0.782 gets the same error:

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

whether binary_file is explicitly declared as IO[bytes] or inferred.

Fix: Use mypy 0.770 or mypy 0.790 .

It was a regression in mypy's typeshed ( Issue 4349 ) and the fix is in mypy 0.790, fixing both zipfile.open() and io.open() .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM