如何为强制关键字参数转换为可选关键字参数编写装饰器类型?
我有很多函数,它们的结构和基本参数都差不多:
async def get_stuff_from_external_api(*, client: Client | None, id: int) -> Ressource:
if not client:
client = make_client()
return Ressource(await client.get(id))
为了让我的代码更简洁,我把这个逻辑提取成了一个装饰器,现在这个装饰器和函数都是:
def external_api_decorator(func):
@functools.wraps(func)
def wrapped_func(*args, **kwargs):
client = kwargs.pop(client, None)
if not client:
client = make_client()
return await func(*args, client=client, **kwargs)
return inner
@external_api_decorator
async def get_stuff_from_external_api(*, client: Client, id: int) -> Ressource:
return Ressource(await client.get(id))
我现在的问题是,我无法正确地给 external_api_decorator
添加类型,这样就无法保留被装饰函数的初始参数(在我的例子中是 id
)和返回值(在我的例子中是 Ressource
)。
我尝试了很多解决方案(比如 Protocol
、Generic
、ParamSpec
等等),但我觉得我卡在了 Concatenate
/ParamSpec
不支持关键字参数上。我是不是漏掉了什么?这看起来是一个非常经典的用例。
这里有一个 mypy 的在线测试环境,可以复现这个问题。
0 个回答
暂无回答