You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python3.9:让mypy识别aiocache@cached装饰器的函数签名

Python 3.9下修复aiocache @cached装饰器的mypy类型检查失效问题

aiocache的@cached装饰器因缺少正确的类型标注,导致mypy无法识别被装饰函数的原始签名,允许不符合参数要求的非法调用。以下是适配Python 3.9的解决方案:

方案一:手动用typing.cast恢复函数类型

通过cast强制指定被装饰函数的原始类型签名,让mypy重新识别参数要求:

from aiocache import cached
from typing import cast, Callable

@cached
def foo_cached(x: str) -> str:
    return x

# 强制恢复函数的原始类型
foo_cached = cast(Callable[[str], str], foo_cached)

foo_cached()  # mypy会报错:缺少必需的位置参数"x"
foo_cached("valid_input")  # 正常通过类型检查

方案二:自定义类型安全的装饰器包装器

借助mypy_extensions提供的类型工具(Python 3.9原生不支持ParamSpec,需额外安装),封装@cached以保留原函数的类型信息:

  1. 先安装依赖:
pip install mypy_extensions
  1. 实现自定义装饰器:
from aiocache import cached
from mypy_extensions import ParamSpec, TypeVar

P = ParamSpec("P")
R = TypeVar("R")

def typed_cached(*args, **kwargs) -> Callable[[Callable[P, R]], Callable[P, R]]:
    def decorator(func: Callable[P, R]) -> Callable[P, R]:
        return cached(*args, **kwargs)(func)
    return decorator

# 使用自定义的类型安全装饰器
@typed_cached
def foo_cached(x: str) -> str:
    return x

foo_cached()  # mypy会提示缺少位置参数"x"

方案三:添加aiocache类型存根文件

创建自定义类型存根文件,修正@cached的类型标注,让mypy直接识别正确的装饰器行为:

  1. 在项目根目录创建typings/aiocache文件夹
  2. 创建__init__.pyi文件,写入以下内容:
from typing import Any, Callable, TypeVar
from mypy_extensions import ParamSpec

P = ParamSpec("P")
R = TypeVar("R")

def cached(
    ttl: int = ...,
    cache: str = ...,
    key: str = ...,
    namespace: str = ...,
    serializer: Any = ...,
    plugins: Any = ...,
    **kwargs: Any
) -> Callable[[Callable[P, R]], Callable[P, R]]: ...
  1. 确保mypy配置(mypy.ini或pyproject.toml)中包含typings目录:
[mypy]
python_version = 3.9
strict = true
include = typings/

设置完成后,mypy会优先使用自定义存根,正确检查被@cached装饰函数的参数合法性。

内容的提问来源于stack exchange,提问作者Vitor EL

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 20:12:52