【发布时间】:2020-07-20 16:09:31
【问题描述】:
这样做的动机是检查事件处理程序的类型,以确保已注册事件期望作为参数的类型与处理程序准备提供的类型之间匹配。
我正在尝试在基于类的函数装饰器的类型注释中跟踪函数签名。这只是一个 mypy 存根项目:实际实现将以不同的方式获得相同的结果。
所以,我们有一个像这样的基本装饰器骨架
from typing import Any, Callable, Generic, TypeVar
FuncT = TypeVar("FuncT", bound=Callable)
class decorator(Generic[FuncT]):
def __init__(self, method: FuncT) -> None:
... # Allows mypy to infer the parameter type
__call__: FuncT
execute: FuncT
使用以下存根示例
class Widget:
def bar(self: Any, a: int) -> int:
...
@decorator
def foo(self: Any, a: int) -> int:
...
w = Widget()
reveal_type(Widget.bar)
reveal_type(w.bar)
reveal_type(Widget.foo.__call__)
reveal_type(w.foo.__call__)
揭示的类型如下:
Widget.bar (undecorated class method): 'def (self: demo.Widget, a: builtins.int) -> builtins.int'
w.bar (undecorated instance method): 'def (a: builtins.int) -> builtins.int'
Widget.foo.__call__ (decorated class method): 'def (self: demo.Widget, a: builtins.int) -> builtins.int'
w.foo.__call__ (decorated instance method): 'def (self: demo.Widget, a: builtins.int) -> builtins.int'
这意味着如果我调用w.bar(2) 它会通过类型检查器,但是如果我调用w.foo(2) 或w.foo.execute(2) 那么mypy 会抱怨没有足够的参数。同时Widget.bar(w, 2)Widget.foo(w, 2)和Widget.foo.execute(w, 2)都通过了。
我所追求的是一种对此进行注释以说服w.foo.__call__ 和w.foo.execute 给出与w.bar 相同的签名的方法。
【问题讨论】:
标签: python-3.x types mypy