news 2026/9/13 12:03:45

如何为 C 扩展模块用 mypy 的 stubgen --inspect-mode 生成类型存根?

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
如何为 C 扩展模块用 mypy 的 stubgen --inspect-mode 生成类型存根?

如何为 C 扩展模块用 mypy 的 stubgen --inspect-mode 生成类型存根?

【免费下载链接】mypyOptional static typing for Python项目地址: https://gitcode.com/GitHub_Trending/my/mypy

当你的 Python 项目引用了一个没有类型信息的 C 扩展模块时,mypy 无法直接处理该模块,会报出类似这样的错误(frobnicate是文档中的示例模块名,下文均以它为例):

core/config.py:7: error: Cannot find implementation or library stub for module named 'frobnicate'

mypy 自带的stubgen工具可以通过导入模块并做运行时内省(--inspect-mode)为 C 扩展模块生成.pyi类型存根文件。这篇文章给出完整流程:用stubgen --inspect-mode生成存根草稿,把存根放到 mypy 能找到的位置,再用 mypy 和stubtest验证结果。前提是:mypy 已安装,且该 C 扩展模块能在当前 Python 环境中被正常import(stubgen 默认会导入目标模块,而--no-import明确不支持 C 扩展模块)。

准备条件

安装 mypy(安装后即可使用附带的stubgen命令):

$ python3 -m pip install mypy

确认 C 扩展模块可以导入。stubgen 默认会尝试导入目标模块,利用运行时内省为 C 扩展模块生成存根;因此生成存根的 Python 环境必须能 import 该模块。

用 --inspect-mode 生成存根

按模块名生成存根:

$ stubgen --inspect-mode -m frobnicate

关键参数说明:

  • -m MODULE, --module MODULE:按模块名生成存根,可重复使用多次。-m不会递归生成子模块的存根;如果需要递归生成包内所有子模块,改用-p PACKAGE。注意:不能在同一次调用中混合传入文件路径和-m/-p选项。
  • --inspect-mode:导入并内省模块,而不是解析源代码。对 C 模块和仅含 pyc 的包来说这本来就是默认行为,显式加上该参数可以用于强制走内省路径(例如纯 Python 模块中存在动态生成成员的场景)。该参数隐含--no-analysis,因为语义分析需要源代码;--no-analysis本身与--inspect-mode不兼容。
  • -o PATH, --output PATH:修改输出目录。默认输出到./out目录,不存在时自动创建;输出目录中已存在的存根文件会被无警告地覆盖

可选的增强参数(根据需要在同一条命令中添加):

  • --doc-dir PATH:解析PATH下的.rst文档来推断更好的函数签名,可能生成更好的存根,但目前仅对 C 扩展模块有效
  • --include-docstrings:把 docstring 写入存根,包括 C 扩展函数的存根。
  • --include-private:在存根中包含_foo这类单下划线前缀的私有定义。
  • --ignore-errors:某个模块处理过程中抛出异常时,继续处理剩余模块,而不是立即失败。
  • -v, --verbose/-q, --quiet:增加或减少输出信息。

运行完成后,存根会写入out/目录(模块名对应frobnicate.pyi这样的文件名)。需要注意的是:stubgen 生成的是草稿存根,大多数类型默认是Any。对最常用到的 API 手动补充更精确的类型注解,存根才有实际价值。

让 mypy 使用这个存根

生成存根后,mypy 需要能定位到它。文档给出两种方式:

  1. frobnicate.pyi放到与模块实现相同的目录。同一目录下如果同时存在某模块的.py.pyi文件,.pyi优先,这样不用改源码就能为模块补充类型信息。
  2. 把存根集中放在一个专门目录(例如myproject/stubs),再设置MYPYPATH环境变量指向它:
$ export MYPYPATH=~/work/myproject/stubs

也可以在单次运行中临时指定,例如文档中的写法:

$ MYPYPATH=stubs/six mypy ...

配置完成后,对引用该 C 扩展模块的代码运行 mypy。此前报出的Cannot find implementation or library stub for module named 'frobnicate'错误应当消失,mypy 会按照存根做类型检查(文档也确认:一旦存在存根,mypy 会像普通类型信息一样检查该存根,# type: ignore注释将被忽略)。

用 stubtest 核对存根与实现的一致性(可选)

stubtest会导入代码、在运行时内省代码对象,再与存根文件比对,指出两者不一致的地方;由于它完全依赖运行时内省,因此对扩展模块特别适用。

$ python3 -m mypy.stubtest frobnicate

使用要点(来自 stubtest 文档):

  • 运行环境必须能 import 被检查的代码,必要时设置PYTHONPATH
  • 如果提示找不到存根(类似 "failed to find stubs"),设置MYPYPATH指向存根目录。
  • 如果提示 "not checking stubs due to mypy build errors",需要先解决对应的 mypy 错误 stubtest 才会继续。
  • 注意:stubtest 会导入并执行被检查包的 Python 代码。
  • 局限:stubtest 不做静态分析,无法判断函数返回类型是否标注准确;类型检查本身仍用 mypy 完成。

限制与注意

  • --no-import不支持 C 扩展模块:它只用 mypy 的常规搜索机制找源码,并禁用运行时内省(还会导致存根中__all__导出的名字可能不完整)。所以 C 扩展模块的存根生成必须走导入 + 内省路径。
  • 命令行标志可能在不同版本之间变化,具体可用选项以stubgen --help为准。
  • 存根是草稿,Any占位需要人工补全;--doc-dir推断更好签名这一优化目前只对 C 扩展模块生效。

参考文档

  • stubgen 命令行参考:--inspect-mode--no-import-m/-p-o等参数定义。
  • 存根文件说明:.pyi的放置方式与MYPYPATH配置。
  • stubtest 文档:存根与运行时实现的一致性检查。
  • 常见问题的存根示例:frobnicateC 扩展模块的报错与处理示例。

【免费下载链接】mypyOptional static typing for Python项目地址: https://gitcode.com/GitHub_Trending/my/mypy

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/13 12:01:57

单节锂电池升压至48V的拓扑选择与FP7209恒流设计要点

1. 为什么单节电池要升压到48V?——从供电瓶颈看拓扑选择的底层逻辑你手头有一块标称3.7V的锂电,想驱动一个需要48V输入的LED模组或小型电机控制器。直接接上去?灯不亮、电机不动,连IC都可能报欠压锁死。这不是电压不够的问题&…

作者头像 李华
网站建设 2026/9/13 12:01:23

纯Python手写BP神经网络实现鸢尾花分类

简介:本资源是一份面向高校人工智能与机器学习初学者的BP神经网络实践教学包,聚焦鸢尾花多分类任务,完整覆盖算法原理理解、代码实现、数据预处理与模型评估全流程。资源共15个文件,含8个CSV格式数据集(含训练集、测试…

作者头像 李华
网站建设 2026/9/13 11:59:30

WTK6900FC硬件级鼾声检测原理与工程落地指南

1. 为什么睡眠产品必须加鼾声检测——不是锦上添花,而是临床级功能分水岭我做智能睡眠硬件选型这十年,见过太多团队把“鼾声检测”当成App里一个可有可无的彩蛋功能:界面显示个“今晚打鼾32次”,数据来源却模糊不清——是麦克风随…

作者头像 李华