Python 键入:当签名不同时,Mypy 会出现重载“重叠”错误

Ped*_*tua 2 python overloading mypy python-typing

以下代码似乎生成两个 mypy 错误:Overloaded function signatures 1 and 3 overlap with incompatible return typesOverloaded function signatures 2 and 3 overlap with incompatible return types; 但所有重载都有不同的签名 - Literal[True]、Literal[False] 和 None 不重叠。

@overload
def func_a(*, a: Literal[False] = ...) -> str:
    ...


@overload
def func_a(*, a: None = ...) -> str:
    ...


@overload
def func_a(*, a: Literal[True] = ...) -> int:
    ...


def func_a(*, a: Optional[bool] = None) -> str | int:
    if a:
        return 1
    return "foo"


var1 = func_a()  # str correctly discovered by VSCode Pylance
var2 = func_a(a=False)  # str correctly discovered by VSCode Pylance
var3 = func_a(a=True)  # int correctly discovered by VSCode Pylance
Run Code Online (Sandbox Code Playgroud)

为什么 Mypy 认为它们重叠,我该如何解决这个问题?

我的版本:0.991

Python版本:3.11.1

use*_*ica 6

问题是,通过为每个重载编写默认值,您已将每个重载= ...中的参数标记为可选。普通调用会匹配函数的每个重载。func_a()

您需要解决这个问题,因此func_a()只匹配一个重载。这是一种方法:

@overload
def func_a(*, a: Literal[False]) -> str:
    ...

@overload
def func_a(*, a: Literal[True]) -> int:
    ...

@overload
def func_a(*, a: None = None) -> str:
    ...
Run Code Online (Sandbox Code Playgroud)

在这里,只有None重载将参数标记为可选,因此func_a()仅匹配该重载。

或者,您可以使无参数版本成为它自己的重载:

@overload
def func_a(*, a: Literal[False]) -> str:
    ...

@overload
def func_a(*, a: Literal[True]) -> int:
    ...

@overload
def func_a(*, a: None) -> str:
    ...

@overload
def func_a() -> str:
    ...
Run Code Online (Sandbox Code Playgroud)