我有以下代码:
def from_utf8(string: bytes | str) -> str:
if isinstance(string, bytes):
return string.decode("utf-8")
else:
return string # <- type warning on this line
pylance 在这一行给了我一个类型警告return string
:
Type "bytearray | memoryview[_I@memoryview] | str" is not assignable to return type "str"
Type "bytearray | memoryview[_I@memoryview] | str" is not assignable to type "str"
"bytearray" is not assignable to "str"
我的理解是:
类型注释x: bytes
实际上是“运行时类型”的别名x: bytes | bytearray | memoryview[_I@memoryview]
,但isinstance(x, bytes)
只检查bytes
,而不检查另外两个。
我尝试以相反的方式检查类型:
def from_utf8(string: bytes | str) -> str:
if isinstance(string, str):
return string
else:
return string.decode("utf-8") # <- no attribute 'decode' for 'memoryview'
错误现在变成:
Cannot access attribute "decode" for class "memoryview[_I@memoryview]"
Attribute "decode" is unknown
上下文:
- 我的项目使用python 3.11
- 我在 vscode 中看到这些警告,使用 pylance 版本 2025.2.1 和 python (
ms-python.python
) 扩展版本 2025.0.0
我是否有一种方便的方法来编写一个from_utf8(string)
可以通过类型检查器的版本?
另外:我的假设正确吗?有记录吗?
在 Python 3.12 之前,
bytes
被指定为 的别名builtins.bytes | builtins.bytearray | builtins.memoryview
。来自Python 3.10 文档(重点是我的):您看到的静态类型错误是此行为的结果。随着 PEP 688 的引入,此行为现已在 Python 3.12 中删除。
pyright 1.1.329(发布于一年多前)已在严格模式下默认禁用此静态类型行为。如果您不想使用严格模式但仍想禁用此行为,请设置为。
disableBytesTypePromotions
true
正如评论中指出的那样,可能已经根据这种行为开发了类型化的第三方库,在这种情况下,在引用此库中的变量或函数返回值时应小心谨慎。例如,如果没有该
--strict-bytes
选项,mypy 将在类型检查中传递以下内容(请参阅mypy Playground):