TLDR;
我有一个装饰器:
- 更改函数签名
- 包装的函数使用一些泛型类型参数
-
除了我想使用的签名
funtools.wraps
以保留其余部分信息。
有什么办法可以在不抱怨的情况下实现这一目标吗?
mypy
更多背景
一个最小的工作示例如下所示:
这似乎工作正常,但是
from functools import wraps
from typing import Callable, TypeVar
B = TypeVar('B', bound=str)
def str_as_int_wrapper(func: Callable[[int], int]) -> Callable[[B], B]:
WRAPPER_ASSIGNMENTS = ('__module__', '__name__', '__qualname__', '__doc__',)
WRAPPER_UPDATES = ('__dict__', '__annotations__')
@wraps(func, assigned=WRAPPER_ASSIGNMENTS, updated=WRAPPER_UPDATES)
def _wrapped_func(val: B) -> B:
num = int(val)
result = func(num)
return val.__class__(result)
return _wrapped_func
@str_as_int_wrapper
def add_one(val: int) -> int:
return val + 1
(版本1.10.0)不喜欢它。相反,它会抱怨
mypy
如果我删除
test.py:17: error: Incompatible return value type (got "_Wrapped[[int], int, [Never], Never]", expected "Callable[[B], B]") [return-value]
test.py:17: note: "_Wrapped[[int], int, [Never], Never].__call__" has type "Callable[[Arg(Never, 'val')], Never]"
装饰器或用
@wraps
替换
B
类型注释,错误就会消失。
str
问题
我错过了什么吗?这是一些已经报告的错误或限制来自
(找不到任何东西)?是否应该举报?
mypy
谢谢!
Thanks!
发现了一个 mypy 错误!好消息是,它已经在 mypy 0.991 版中修复了。请参阅此处的相关问题以获取更多上下文:
如果无法升级到 mypy 0.991 或更高版本,可以通过删除
WRAPPER_ASSIGNMENTS
和
WRAPPER_UPDATES
参数来解决此问题,以便默认情况下
wraps
装饰器复制所有内容。但是,这可能不是理想的解决方案,因为它可能会复制不必要的属性。