gpt4 book ai didi

python-3.x - 为什么 mypy 提示 TextIOWrapper 接收 GzipFile 作为参数 1?

转载 作者:行者123 更新时间:2023-12-03 16:38:13 28 4
gpt4 key购买 nike

我正在将内容写入内存中的二进制流,以便将内容上传到 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)

mvce.py
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)



为什么 mypy 会失败,我该如何让它工作?是否存在隐藏的潜在问题?

最佳答案

为什么 MyPy 会失败?

MyPy 使用一组名为 Typeshed 的类型 stub 为标准库定义类型。在 Typeshed,gzip.GzipFile不继承自 typing.IO[bytes] .

类层次结构是:gzip.GzipFile -> _compression.BaseStream -> io.BufferedIOBase -> io.IOBase .

我如何使它工作?

您可以使用 typing.cast(IO[bytes], gzip_handler)向 MyPy 暗示 GzipFile实例应该被认为是一个二进制文件对象。见 documentation有关 Actor 的更多信息。

或者,您可以使用 gzip.open(inmem, mode='wt', encoding="utf-8")直接获取文本文件对象(本质上与您正在执行的操作相同,请参见下文)。此函数具有返回类型 IO[Any]在 Typeshed 中。

是否存在隐藏的潜在问题?

gzip documentation关于 gzip.open() 的说法功能:

For text mode, a GzipFile object is created, and wrapped in an io.TextIOWrapper instance with the specified encoding, error handling behavior, and line ending(s).



所以你的代码在实践中应该可以正常工作。

这可以在 Typeshed 中修复吗?

我尝试添加 IO[bytes]作为 GZipFile 的父类(super class)在 Typeshed 中,我在测试中遇到了一个错误:
stdlib/3/gzip.pyi:17: error: Definition of "__enter__" in base class "IOBase" is incompatible with definition in base class "IO"

这个问题的解决方案留给读者作为练习。

关于python-3.x - 为什么 mypy 提示 TextIOWrapper 接收 GzipFile 作为参数 1?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58394410/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com