mypy字面量类型检查异常:分支类型推断不符预期求助
解决mypy字面量类型检查错误
问题原因
你定义的函数返回两种元组的联合类型,但Python元组解构后,mypy无法跟踪a的布尔值与b的类型之间的关联——它只会把b推断为两种返回类型的交集,也就是Optional[Type[Temp]],所以无论if a还是else分支,都会触发union-attr错误。
解决方案
方法1:用NamedTuple定义明确的返回类型(推荐)
通过两个NamedTuple分别对应两种返回场景,让mypy能通过flag的值自动窄化关联字段的类型:
from typing import Literal, Optional, Type, Union, NamedTuple class Temp: @staticmethod def pankaj(): print("pankaj") class TrueResult(NamedTuple): flag: Literal[True] cls: Type[Temp] class FalseResult(NamedTuple): flag: Literal[False] cls: Optional[Type[Temp]] def accepts_only_int(x: int) -> Union[TrueResult, FalseResult]: # 可根据实际逻辑返回TrueResult或FalseResult return FalseResult(False, Temp) result = accepts_only_int(6) if result.flag: print(result.cls.pankaj()) else: if result.cls is not None: print(result.flag, result.cls.pankaj()) else: print(result.flag, "cls is None")
方法2:添加类型断言
在分支中用assert明确告诉mypy当前分支下b的类型,同时在else分支先检查b是否为None:
from typing import Literal, Optional, Type, Union class Temp: @staticmethod def pankaj(): print("pankaj") def accepts_only_int(x: int) -> Union[tuple[Literal[True],Type[Temp]],tuple[Literal[False],Optional[Type[Temp]]]]: return (False,Temp) a, b = accepts_only_int(6) if a: assert b is not None, "当a为True时b不可能为None" print(b.pankaj()) else: if b is not None: print(a, b.pankaj()) else: print(a, "b is None")
方法3:强制类型转换
使用cast手动指定b在对应分支的类型,适合不想修改返回类型定义的场景:
from typing import Literal, Optional, Type, Union, cast class Temp: @staticmethod def pankaj(): print("pankaj") def accepts_only_int(x: int) -> Union[tuple[Literal[True],Type[Temp]],tuple[Literal[False],Optional[Type[Temp]]]]: return (False,Temp) a, b = accepts_only_int(6) if a: b = cast(Type[Temp], b) print(b.pankaj()) else: if b is not None: print(a, b.pankaj()) else: print(a, "b is None")
内容的提问来源于stack exchange,提问作者Pankaj Singh Rana
相关产品推荐
相关产品推荐

