如何编写一个接受任何函数并传递 mypy --disallow-any-decorated 的装饰器?

问题描述 投票:0回答:2

我最后一次尝试编写一个接受任何可能的 python 函数并使用

--disallow-any-decorated
标志进行 mypy 检查的装饰器,如下所示:

from typing import Any, Callable, TypeVar


T = TypeVar('T')


def decorator(func: Callable[..., T]) -> Callable[..., T]:
    def decorated(*args: Any, **kwargs: Any) -> Any:
        print('decorated')
        return func(*args, **kwargs)

    return decorated


@decorator
def foo() -> int:
    print('foo')
    return 42


print(foo())

但是仍然失败

Type of decorated function contains type "Any" ("Callable[..., int]")

我做错了什么?我也尝试使用

VarArg
中的
KwArg
mypy_extensions
代替
...
,但没有帮助。

python python-typing mypy python-decorators
2个回答
0
投票

使用 TypeVar 吞掉整个 Callable,而不仅仅是返回类型。然后,您向 MyPy 澄清,修饰函数的类型与原始函数相同,从而无需担心“哦,但这里的返回类型几乎可以是任何类型。”

可能需要在最终返回行上使用强制转换。

FuncT = TypeVar(FuncT, bound=Callable)

def decorator(func: FuncT) -> FuncT:
   ...
   return cast(FuncT, decorated)

-1
投票

--不允许任何装饰:

不允许在装饰器转换后签名中包含

Any
的函数。

...
中的
Callable[..., T]
是一种表示可调用函数采用零个或多个
Any
参数的方式。因此,即使声明本身不包含
Any
,它仍然会解析为包含
Any
的声明。

© www.soinside.com 2019 - 2024. All rights reserved.