Почему MyPy дает сбой?
MyPy использует набор заглушек типов, называемый Typeshed , чтобы определить типы для стандартной библиотеки. В Typeshed gzip.GzipFile
не наследуется от typing.IO[bytes]
.
Иерархия классов: gzip.GzipFile -> _compression.BaseStream -> io.BufferedIOBase -> io.IOBase
.
Как мне заставить это работать?
Вы можетеиспользуйте typing.cast(IO[bytes], gzip_handler)
, чтобы намекнуть MyPy, что экземпляр GzipFile
следует считать двоичным файловым объектом. См. документацию для получения дополнительной информации о приведениях.
В качестве альтернативы, вы можете использовать gzip.open(inmem, mode='wt', encoding="utf-8")
для непосредственного получения объекта текстового файла (по сути, того же, что вы делаете, см. Ниже),Эта функция имеет тип возврата IO[Any]
в Typeshed.
Есть ли скрытые потенциальные проблемы?
Документация gzip
говорит об этой функции gzip.open()
:
Для текстового режима создается объект GzipFile
, который оборачивается в экземпляр io.TextIOWrapper
с указанным кодированием, поведением обработки ошибок иконец (и) строк.
Таким образом, ваш код должен работать на практике.
Можно ли это исправить в Typeshed?
Я пытался добавить IO[bytes]
каксуперкласс GZipFile
в Typeshed, и я получил одну ошибку в тестах:
stdlib/3/gzip.pyi:17: error: Definition of "__enter__" in base class "IOBase" is incompatible with definition in base class "IO"
Решение этой проблемы оставлено в качестве упражнения для читателя.