我有一个decorator,可以无参数调用,也可以有参数调用(所有字符串):
@decorator
def fct0(a: int, b: int) -> int:
return a * b
@decorator("foo", "bar") # any number of arguments
def fct1(a: int, b: int) -> int:
return a * b
我很难提供适当的类型提示,以便类型判断器能够正确验证decorator的使用,尽管已经阅读了related section of the doc of mypy.
以下是我迄今为止所做的try :
from typing import overload, TypeVar, Any, Callable
F = TypeVar("F", bound=Callable[..., Any])
@overload
def decorator(arg: F) -> F:
...
@overload
def decorator(*args: str) -> Callable[[F], F]:
...
def decorator(*args: Any) -> Any:
# python code adapted from https://stackoverflow.com/q/653368
# @decorator -> shorthand for @decorator()
if len(args) == 1 and callable(args[0]):
return decorator()(args[0])
# @decorator(...) -> real implementation
def wrapper(fct: F) -> F:
# real code using `args` and `fct` here redacted for clarity
return fct
return wrapper
这将导致以下mypy
的误差:
error: Overloaded function implementation does not accept all possible arguments of signature 1
我还有一个pyright
的错误:
error: Overloaded implementation is not consistent with signature of overload 1
Type "(*args: Any) -> Any" cannot be assigned to type "(arg: F@decorator) -> F@decorator"
Keyword parameter "arg" is missing in source
I am using python 3.10.4, mypy 0.960, pyright 1.1.249.