使用typing.overload与Literal时Mypy报错问题排查
关于typing.overload与Literal类型匹配的Mypy报错问题
问题场景
我正在学习typing.overload的用法,编写了一个简单函数:接收类型为Literal["foo", "bar"]的参数x,返回列表[x]。希望Mypy能根据x的值,将返回列表类型推断为list[Literal["foo"]]或list[Literal["bar"]]。我知道可以用TypeVar实现该需求,但想了解为何以下代码触发Mypy报错:
报错信息
test.py:14: error: Overloaded function implementation cannot produce return type of signature 1 test.py:14: error: Overloaded function implementation cannot produce return type of signature 2
代码示例
from typing import Literal, overload @overload def f(x: Literal["foo"]) -> list[Literal["foo"]]: ... @overload def f(x: Literal["bar"]) -> list[Literal["bar"]]: ... def f(x: Literal["foo", "bar"]) -> list[Literal["foo", "bar"]]: return [x]
报错原因
Mypy对重载函数的实现有严格的类型兼容性要求:实现函数的返回类型必须能被每个重载签名的返回类型兼容(即实现的返回类型是各重载返回类型的子类型)。
这里的核心矛盾在于:
- 重载签名承诺返回更具体的窄类型:
list[Literal["foo"]]或list[Literal["bar"]],这两种类型的列表只能包含对应单一字面量。 - 而实现函数返回的是更宽泛的父类型:
list[Literal["foo", "bar"]],这种列表可以包含"foo"或"bar"任意一个值。
Mypy判定,实现函数的返回值无法保证满足每个重载签名的严格约束——比如当调用f("foo")时,重载签名要求返回仅含"foo"的列表,但实现返回的列表类型理论上可以被修改为加入"bar",因此不匹配重载签名的返回类型要求,从而抛出报错。
内容的提问来源于stack exchange,提问作者Roméo Desprès
相关产品推荐
相关产品推荐

