Mypy如何识别.pyi文件?配置类型检查时.pyi文件未生效排查
Mypy存根文件(.pyi)未生效问题排查及机制解析
问题场景
文件内容
blah.pyi存根文件:
def func(x : int) -> int : ...
blah.py实现文件:
def func(x): return x reveal_type(func) print(func(''))
目录结构
root |- blah.pyi |- blah.py
执行命令及输出
直接检查blah.py时,Mypy未识别存根:
...\root> python -m mypy blah.py blah.py:4: note: Revealed type is "def (x: Any) -> Any" Success: no issues found in 1 source file
用stubtest检查时报错:
...\root> python -m mypy.stubtest blah.py error: blah.py failed to find stubs Stub: MISSING Runtime: N/A
Mypy识别.pyi存根的核心机制
- Mypy优先匹配与模块同名的.pyi文件,但前提是模块处于Python可导入路径下(比如当前工作目录默认在sys.path里)
- 当同目录存在
.py和.pyi时,Mypy的默认逻辑是:- 如果是导入模块(比如在其他文件里
import blah),则优先用.pyi的类型定义 - 如果是直接检查单个.py文件,则会忽略同目录的
.pyi,直接解析该文件的代码
- 如果是导入模块(比如在其他文件里
stubtest工具是用来校验已导入模块的存根与实现是否匹配,不能直接传入单个.py文件路径
问题根源
- 直接执行
mypy blah.py时,Mypy把文件当作独立脚本处理,不会关联同目录的.pyi存根,所以识别到的是func的动态类型Any - 执行
mypy.stubtest blah.py是用法错误,stubtest需要传入模块名(比如blah)而非文件路径,所以找不到存根
修复方法
方法1:通过导入模块的方式检查
在root目录下新建test.py:
import blah blah.reveal_type(blah.func) blah.func('') # 这里会触发类型错误
执行命令:
python -m mypy test.py
此时Mypy会加载blah.pyi的类型定义,输出会显示Revealed type is "def (x: int) -> int",同时报错Argument 1 to "func" has incompatible type "str"; expected "int"
方法2:强制指定存根文件检查单个.py
如果要直接检查blah.py,可以用--pyi参数关联存根:
python -m mypy --pyi blah.pyi blah.py
这样Mypy会用存根的类型规则校验blah.py的代码,比如检测到func('')的类型不匹配
方法3:正确使用stubtest校验存根与实现
在root目录下执行:
python -m mypy.stubtest blah
此时stubtest会找到blah.pyi存根,并对比blah.py的实现是否符合存根定义
内容的提问来源于stack exchange,提问作者Anonymous
相关产品推荐
相关产品推荐

