Bottle框架下Mypy类型检查未按预期工作的问题求助
为什么Mypy检测不出Bottle框架中FileUpload的类型错误?
我是Python新手,非常喜欢静态类型检查工具。我用Bottle框架写了处理文件上传的代码:
def transcribe_upload(upload: FileUpload) -> Alternative: audio: AudioSource = upload_source(upload) ... def upload_source(upload: FileUpload) -> AudioSource: ...
我犯了个低级错误——把upload.file(类文件对象)而非完整的FileUpload对象传给了upload_source:
def transcribe_upload(upload: FileUpload) -> Alternative: audio: AudioSource = upload_source(upload.file) # 此处错误!
但类型检查器根本没发现问题,哪怕传完全错误的参数也不会报错:
def transcribe_upload(upload: FileUpload) -> Alternative: audio: AudioSource = upload_source(4) # 为何Mypy不报错? audio: AudioSource = upload_source(upload.asdf) # 为何Mypy不报错?
单独测试基础函数时,Mypy能检测出错误类型参数的问题,为什么在这里不行?
编辑补充
有人指出FileUpload等价于Any类型,我觉得这可能是对的。我通过from bottle import FileUpload导入该类。
如果真是这样,为什么我能把FileUpload当作类型来用?(拼写错误比如FileUpld时会报错)
更关键的是,怎么才能获得真正的类型支持?是不是需要Bottle开发者添加类型定义?
原因分析
FileUpload无类型注解:Bottle框架的FileUpload类未遵循PEP484标准添加类型注解,也没有配套的类型存根文件。在Mypy看来,缺乏类型信息的类会被默认视为Any类型。Any类型的兼容性:当用FileUpload做类型标注时,Mypy仅会校验该名称是否存在(因此拼写错误会触发报错),但不会执行实际的类型校验——Any类型与所有类型兼容,传给期望FileUpload的函数时,任何参数都会被放行。- 单独测试的差异:单独测试基础函数时,你大概率使用了有明确类型注解的对象(比如自定义类或标准库类型),而非
Any,所以Mypy能正常检测类型错误。
解决方法
- 安装第三方类型存根:检查PyPI是否有社区维护的Bottle类型存根包(如
types-bottle),安装后Mypy即可识别FileUpload的真实类型。 - 自定义类型存根:若没有现成存根,可自行编写
.pyi存根文件,为FileUpload补充类型注解。示例如下:
将该文件放置在Mypy的类型搜索路径中(可通过from typing import IO, Optional, Dict class FileUpload: file: IO[bytes] filename: str headers: Optional[Dict[str, str]] def __init__(self, file: IO[bytes], filename: str, headers: Optional[Dict[str, str]] = None) -> None: ... # 根据实际需求补充其他方法的类型注解mypy.ini配置mypypath指定)。 - 推动官方支持:可以向Bottle项目提交PR,添加类型注解或类型存根,帮助官方完善类型支持。
内容的提问来源于stack exchange,提问作者Sean Clark Hess
相关产品推荐
相关产品推荐

