Python中typing.Literal含|字符串引发mypy报错的解决办法
解决Literal注解中包含竖线|的mypy解析错误
问题原因
在Python 3.8中启用from __future__ import annotations后,注解会以字符串形式存储。mypy解析Literal["foo", "bar", "foo|bar"]时,会误将字符串内部的|识别为类型联合运算符,把"foo|bar"解析成foo | bar,从而抛出名称foo未定义的错误,最终导致整个注解被识别为Any,失去类型检查意义。
解决方案
方案1:将整个Literal注解包裹为字符串
直接把Literal表达式用引号包裹,让mypy按字符串原内容解析,避免把内部的|当成类型运算符:
from typing import Literal from __future__ import annotations def fn(x: "Literal['foo', 'bar', 'foo|bar']") -> None: reveal_type(x)
这样mypy会正确识别"foo|bar"为字面量字符串,不会进行错误的联合类型解析。
方案2:禁用from __future__ import annotations(如果允许)
如果代码不需要延迟注解求值的特性,可以移除from __future__ import annotations导入,此时注解会直接求值,字符串字面量里的|会被正确识别为普通字符:
from typing import Literal def fn(x: Literal["foo", "bar", "foo|bar"]) -> None: reveal_type(x)
验证效果
使用上述任一方案后,运行mypy检查代码,reveal_type(x)会输出Literal['foo', 'bar', 'foo|bar'],说明类型注解已被正确识别。
内容的提问来源于stack exchange,提问作者Håkon T.
相关产品推荐
相关产品推荐

