设置默认参数的 mypy call-arg 错误

mypy call-arg error where default argument is set

我的代码如下所示:

from typing import Callable


def decorate(func: Callable[[str], None]) -> Callable[[str], None]:
    return func


@decorate
def do_something(some_str: str = 'Hello world') -> None:
    print(some_str)


if __name__ == '__main__':
    do_something()

当运行mypy时,最后一行报如下错误:

error: Too few arguments for "do_something" [call-arg]

如何修复此错误(不将 decorate 的 return 类型更改为 Callable[..., None])?

Protocol__call__ 在表达函数类型时赋予了很多(有点冗长)的权力

class Foo(Protocol):
    def __call__(self, some_str: str = 'Hello world') -> None:
        ...

def decorate(func: Foo) -> Foo:
    return func

@decorate
def do_something(some_str: str = 'Hello world') -> None:
    print(some_str)

if __name__ == '__main__':
    do_something()

不确定如何令人满意地避免“Hello World!”重复。

使用 TypeVar 表示输入和 return 类型 等价 并由接收到的 Callable 定义。由于 Callable 类型包括整个签名,这让类型检查器也可以推断出 positional/optional/keyword 个参数。

from typing import Callable, TypeVar

# A type variable that can represent any Callable type
C = TypeVar("C", bound=Callable)

# The input Callable type defines the output Callable type as well
def decorate(func: C) -> C:
    return func

如果 decorate 只能使用可能带有字符串的可调用对象,请相应地调整 bound

# A type variable that can represent any Callable type that takes a string
C = TypeVar("C", bound=Callable[[str], None])

值得注意的是,采用 str 或使用默认 的可调用对象仍然满足 Callable[[str], None] 因为它可以使用 str 参数调用.