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以保留原函数的类型信息:
- 先安装依赖:
pip install mypy_extensions
- 实现自定义装饰器:
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直接识别正确的装饰器行为:
- 在项目根目录创建
typings/aiocache文件夹 - 创建
__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]]: ...
- 确保mypy配置(
mypy.ini或pyproject.toml)中包含typings目录:
[mypy] python_version = 3.9 strict = true include = typings/
设置完成后,mypy会优先使用自定义存根,正确检查被@cached装饰函数的参数合法性。
内容的提问来源于stack exchange,提问作者Vitor EL
相关产品推荐
相关产品推荐

