我正在将内容写入内存中的二进制流,以便将内容上传到 S3,而不将其存储在本地文件中(我的内存比磁盘空间多)。以下代码正在运行,但mypy mvce.py失败了
mvce.py:6: error: Argument 1 to "TextIOWrapper" has incompatible type "GzipFile";
expected "IO[bytes]"
Found 1 error in 1 file (checked 1 source file)
Run Code Online (Sandbox Code Playgroud)
from io import BytesIO, TextIOWrapper
import gzip
inmem = BytesIO()
with gzip.GzipFile(fileobj=inmem, mode="wb") as gzip_handler, TextIOWrapper(
gzip_handler, encoding="utf-8"
) as wrapper:
wrapper.write("some test string")
# Check if this actually worked
with open("foobar.gzip", "wb") as f1:
inmem.seek(0)
f1.write(inmem.read())
with gzip.open("foobar.gzip", "rb") as f2:
data = f2.read()
print(data)
Run Code Online (Sandbox Code Playgroud)
为什么 mypy 会失败,我该如何让它工作?是否存在隐藏的潜在问题?
aug*_*rar 10
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具有指定编码、错误处理行为和行结尾的实例中。
所以你的代码在实践中应该可以正常工作。
我尝试添加为 TypeshedIO[bytes]的超类GZipFile,但在测试中出现一个错误:
stdlib/3/gzip.pyi:17: error: Definition of "__enter__" in base class "IOBase" is incompatible with definition in base class "IO"
Run Code Online (Sandbox Code Playgroud)
这个问题的解决方案留给读者作为练习。
| 归档时间: |
|
| 查看次数: |
588 次 |
| 最近记录: |