文档开发工具【免费下载链接】sphinxThe Sphinx documentation generator项目地址https://gitcode.com/gh_mirrors/sp/sphinx点击查看免费下载Sphinx 自带的sphinx.ext.coverage扩展可以扫描项目中通过 autodoc 或 Python 域记录的对象找出那些写进了代码却从未被文档提到的类、函数和方法并以独立构建器输出覆盖率报告。本文以仓库中 tests/roots/test-ext-coverage/index.rst 这一真实测试项目为骨架结合 coverage 扩展源码 与对应测试用例完整讲解覆盖率构建器的启用方式、全部配置项、忽略规则的作用机制以及如何读懂它生成的python.txt/c.txt报告帮助你直接在自己项目中复现这套文档缺失检测流程。从测试根目录读懂 coverage 扩展的典型用法Sphinx 仓库的测试体系中每个tests/roots/下的目录都是一个独立的迷你文档项目。tests/roots/test-ext-coverage 专为验证sphinx.ext.coverage的忽略规则而设计其结构非常精简tests/roots/test-ext-coverage/ ├── conf.py ├── index.rst └── grog/ ├── __init__.py ├── coverage_ignored.py ├── coverage_missing.py └── coverage_not_ignored.py其中 index.rst 全文只有两个automodule指令.. automodule:: grog.coverage_ignored :members: .. automodule:: grog.coverage_not_ignored :members:也就是说这个测试项目通过 autodoc 只正式记录了grog包下的两个模块而grog.coverage_missing模块虽然存在却没有被任何automodule/py:module指令提及——它正是用来验证覆盖率构建器能否发现被文档遗漏的模块的靶子。这就是 coverage 扩展最核心的场景文档写了什么、源码里有什么两者之间的差集就是未文档化对象。配套的 conf.py 给出了启用该扩展的最小配置import sys from pathlib import Path sys.path.insert(0, str(Path.cwd().resolve())) extensions [sphinx.ext.autodoc, sphinx.ext.coverage] coverage_modules [ grog, ] coverage_ignore_pyobjects [ r^grog\.coverage_ignored(\..*)?$, r\.Ignored$, r\.Documented\.ignored\d$, ]这个配置里有三个关键点值得逐一拆解sys.path调整coverage 构建器会真正import目标模块因此必须让 Sphinx 进程能通过sys.path找到它们官方文档 doc/usage/extensions/coverage.rst 中也明确提示了这一点。extensions同时启用了sphinx.ext.autodoc与sphinx.ext.coverage前者让automodule指令生效并产生已文档化对象记录后者负责扫描源码并对比出未文档化对象。coverage_ignore_pyobjects定义了三条正则用于把有意不写文档的对象从报告中剔除——这正是本测试项目的验证重点。CoverageBuildercoverage 构建器的工作原理启用方式与普通 HTML/PDF 构建器不同sphinx.ext.coverage不产生可浏览的页面而是通过sphinx-build -M coverage在_build/coverage目录下生成文本报告。它的构建器类CoverageBuilder定义在 sphinx/ext/coverage.py在扩展的setup()中通过app.add_builder(CoverageBuilder)注册sphinx/ext/coverage.py。构建器名称coverage与命令行的对应关系为sphinx-build -M coverage sourcedir builddir构建结束后builddir/coverage目录下会产出三类文件文件内容python.txt未文档化的 Python 对象清单函数、类、缺失方法及统计表c.txt未文档化的 C API 元素清单undoc.pickle序列化后的全部未文档化/已文档化数据供后续程序化分析见 sphinx/ext/coverage.py从CoverageBuilder.epilogsphinx/ext/coverage.py可以看到构建完成时会输出提示Testing of coverage in the sources finished, look at the results in builddir/coverage/python.txt.一次构建的执行流程write_documents()sphinx/ext/coverage.py是覆盖率构建的主入口内部顺序执行四个步骤build_py_coverage()扫描 Python 模块产出未文档化对象字典write_py_coverage()把结果写入python.txtbuild_c_coverage()扫描 C 头文件产出未文档化 C API 元素write_c_coverage()把结果写入c.txt。Python 侧扫描build_py_coverage()的核心逻辑Python 侧扫描的逻辑sphinx/ext/coverage.py大致如下从self.env.domaindata[py][objects]和[modules]取回文档树中所有已出现的 Python 对象与模块——这些记录正是由automodule、py:module、py:function等指令在解析阶段写入环境的调用_determine_py_coverage_modules()sphinx/ext/coverage.py确定要检查哪些模块这一步决定了两种工作模式见下文对每个模块执行inspect.getmembers(mod)逐成员过滤以下划线开头的名字、无法归属到本模块的对象obj.__module__ ! mod_name、被coverage_ignore_pyobjects匹配的对象都会被跳过对函数用inspect.isfunction、对类用inspect.isclass分类再对比已在文档中出现的seen_objects凡是在源码中存在却不在文档中的计入py_undoc对已文档化的类还会遍历其dir()中的方法/函数属性找出类写了文档、方法没写的缺口记录为classes[class_name] [缺失的方法名]。关于_determine_py_coverage_modules()源码 docstringsphinx/ext/coverage.py明确描述了两种模式不配置coverage_modules只检查文档树中出现过的模块。此时只能发现这些模块内的缺失对象但无法发现整个模块都没被文档提到的情况配置coverage_modules递归导入指定包及其所有子包/子模块_load_modules使用pkgutil.iter_modules遍历见 sphinx/ext/coverage.py此时既能发现缺失对象也能发现模块级遗漏。如果文档中有模块不在coverage_modules里或coverage_modules里有模块从未被文档化构建器会输出警告但继续执行sphinx/ext/coverage.py。测试项目 conf.py 配置了coverage_modules [grog]因此grog.coverage_missing这个既在源码中、又不在文档中的模块会被发现这正是该测试能验证模块级遗漏检测的原因。C 侧扫描build_c_coverage()的核心逻辑C API 的扫描sphinx/ext/coverage.py机制不同但思路一致先收集c域中所有已文档化的 C 对象self.env.domains.c_domain.get_objects()遍历coverage_c_path匹配到的每个头文件逐行用coverage_c_regexes中的正则去匹配提取对象名若该名字未出现在 C 域文档中则记录为(类型, 名字)元组写入c.txt。配置项全览让覆盖率报告精准可用coverage扩展通过app.add_config_value()注册了 13 个配置项sphinx/ext/coverage.py官方文档 doc/usage/extensions/coverage.rst 对其有完整说明。下面按用途分组列出并补充默认值与类型Python 侧配置配置项类型默认值作用coverage_moduleslist/tuple of str()指定要检查的包/模块列表启用模块级遗漏检测7.4 版本加入coverage_ignore_moduleslist/tuple of str[]匹配完整模块路径的正则列表命中的模块整个跳过coverage_ignore_functionslist/tuple of str[]匹配函数名的正则列表命中的函数跳过coverage_ignore_classeslist/tuple of str[]匹配类名的正则列表命中的类跳过coverage_ignore_pyobjectslist/tuple of str[]匹配任意 Python 对象完整导入路径的正则列表2.1 版本加入这些正则使用 Python 的re语法在构建器init()阶段通过compile_regex_list()统一编译sphinx/ext/coverage.py无效正则会在日志中输出invalid regex ... in 配置项名警告sphinx/ext/coverage.py。C 侧配置配置项类型默认值作用coverage_c_pathlist/tuple of str[]相对于源目录的 C 头文件 glob 模式列表用于定位待检查的.h文件coverage_c_regexesdict[str, str]{}每个条目将对象类型名映射到一条正则正则的第一个捕获组即对象名coverage_ignore_c_itemsdict[str, list of str]{}按对象类型给出正则列表命中的 C 对象不计入缺失报告C 侧的路径、正则同样在init()中预处理sphinx/ext/coverage.py。报告输出配置配置项类型默认值作用coverage_write_headlineboolTrue设为False时不写报告开头的标题行1.1 版本加入coverage_skip_undoc_in_sourceboolFalse跳过源码中本身就没有 docstring 的对象1.1 版本加入coverage_show_missing_itemsboolFalse除了写入报告文件还把缺失对象打印到 stdout / 日志3.1 版本加入coverage_statistics_to_reportboolTrue把统计表格写入报告文件7.2 版本加入coverage_statistics_to_stdoutboolFalse把统计表格打印到标准输出7.2 版本加入注意默认值与_to_report相反忽略规则实战test-ext-coverage 的三种正则模式回到测试项目conf.py 中的coverage_ignore_pyobjects三条正则分别演示了三种常见需求coverage_ignore_pyobjects [ r^grog\.coverage_ignored(\..*)?$, # 模式一忽略整个模块 r\.Ignored$, # 模式二忽略所有名为 Ignored 的类 r\.Documented\.ignored\d$, # 模式三忽略特定类的特定方法 ]结合三个grog子模块的源码内容coverage_ignored.py、coverage_not_ignored.py、coverage_missing.py逐一验证模式一匹配grog.coverage_ignored及其所有子对象(\..*)?捕获后缀。因此即使index.rst通过automodule :members:记录了该模块它内部的Documented.ignored1、Documented.ignored2、NotIgnored等对象也不会进入报告——尽管它们并未被文档提及。模式二匹配所有以.Ignored结尾的完整路径因此两个模块中的Ignored类都被排除。模式三匹配Documented.ignored1/Documented.ignored2这类方法路径因此这两个有意不写文档的方法不会计入缺失。最终只有grog.coverage_not_ignored模块中的Documented.not_ignored1、not_ignored2和NotIgnored类会暴露为未文档化对象。测试用例 tests/test_extensions/test_ext_coverage.py 对这次构建的python.txt做了逐字符断言其统计表原文如下--------------------------------------------------- | Module | Coverage | Undocumented | | grog | 100.00% | 0 | --------------------------------------------------- | grog.coverage_missing | 100.00% | 0 | --------------------------------------------------- | grog.coverage_not_ignored | 0.00% | 2 | --------------------------------------------------- | TOTAL | 0.00% | 2 | ---------------------------------------------------报告主体则精确列出了两个缺失对象grog.coverage_missing --------------------- Classes: * Missing grog.coverage_not_ignored ------------------------- Classes: * Documented -- missing methods: - not_ignored1 - not_ignored2 * NotIgnored这份输出同时证明了两个事实grog.coverage_missing模块因从未出现在文档中而被标记为模块级遗漏而grog.coverage_not_ignored中的Documented类虽然被automodule记录但其方法not_ignored1/not_ignored2仍未文档化。注意测试断言的统计表中两行 Coverage 均为 100.00%、TOTAL 为 0.00%这是因为覆盖率百分比按模块分别计算、而TOTAL行取的是整体交集分母理解这一点有助于读懂真实项目中的统计数字。报告结构解读与进阶输出选项python.txt的完整结构write_py_coverage()sphinx/ext/coverage.py决定了报告文件的内容布局从上到下依次为标题Undocumented Python objects可由coverage_write_headline关闭Statistics 统计表由coverage_statistics_to_report控制表格由_write_py_statistics()生成见 sphinx/ext/coverage.py按模块名排序的未文档化对象明细Functions:段模块级未文档化函数逐行以* 函数名列出Classes:段未文档化类逐行列出对于类已文档化但方法缺失的情况输出* 类名 -- missing methods:后逐行缩进列出缺失方法名Modules that failed to import段无法 import 的模块及其异常信息。_write_py_statistics()中覆盖率的计算公式为模块覆盖率 100.0 * 已文档化对象数 / (已文档化对象数 未文档化对象数)该模块没有发现任何对象时按 100% 处理sphinx/ext/coverage.py。表头行使用分隔、数据行使用-分隔格式与测试断言完全一致。让缺失对象直接出现在构建输出中默认情况下未文档化对象只写入报告文件构建过程中不会有任何提示。设置coverage_show_missing_items True后构建时会同步把缺失对象打印出来默认有进度显示时使用彩色info日志格式如undocumented py function raises - in module autodoc_target使用-q安静模式verbosity 0时改用warning日志格式如undocumented python function: autodoc_target :: raises。测试用例 test_show_missing_items 与 test_show_missing_items_quiet 分别验证了这两种输出路径同时覆盖了 Python 函数、类、方法以及 C API 元素如undocumented c api: Py_SphinxTest [function]四种类型的提示。C 侧报告c.txt的结构与python.txt类似先写Undocumented C API elements标题再按头文件分组列出未文档化元素每行格式为* 名字 [类型]sphinx/ext/coverage.py。在真实项目中落地完整配置示例与注意事项将上述内容整合一个可直接照搬的项目级配置如下在conf.py中extensions [ sphinx.ext.autodoc, sphinx.ext.coverage, ] # 指定要递归检查的包不设置则只检查文档中出现过的模块 coverage_modules [my_package] # 忽略规则可分别针对模块、函数、类、任意对象编写正则 coverage_ignore_modules [rmy_package\.internal] coverage_ignore_functions [r^_] coverage_ignore_classes [] coverage_ignore_pyobjects [r\.Deprecated$] # C API 检查可选 coverage_c_path [include/*.h] coverage_c_regexes {function: r^\w\s(\w)\s*\(} coverage_ignore_c_items {function: [r^internal_]} # 报告输出控制 coverage_show_missing_items True # 构建时直接打印缺失对象 coverage_skip_undoc_in_source False # True 则跳过源码中无 docstring 的对象 coverage_statistics_to_stdout True # 统计表同时输出到 stdout coverage_statistics_to_report True # 统计表写入报告 coverage_write_headline True # False 则不写标题行运行方式sphinx-build -M coverage source _build然后查看_build/coverage/python.txt与_build/coverage/c.txt。结合源码与官方文档doc/usage/extensions/coverage.rst使用时有几点需要注意模块导入副作用coverage 构建器会真实import被检查的模块。如果模块在导入时执行了副作用代码如发请求、写文件这些代码会在sphinx-build运行期间被执行。对于脚本类模块务必用if __name__ __main__:保护入口这是官方文档中明确给出的警告。sys.path可见性被检查的模块必须能被 Python 解释器 import 到必要时像测试项目的 conf.py 一样在sys.path中插入项目根目录。模块级遗漏需要显式配置只有设置coverage_modules后才能发现整个模块都没出现在文档中的遗漏不设置时只能发现已文档化模块内部的缺失对象。忽略规则使用正则匹配coverage_ignore_pyobjects等配置匹配的是对象完整导入路径如grog.coverage_ignored.Documented.ignored1的任意部分^/$/\d等re语法全部可用且匹配使用search语义见 sphinx/ext/coverage.py因此\.Ignored$这类锚定写法可以精确命中类名结尾。小结tests/roots/test-ext-coverage/index.rst虽然只有六行但它背后是sphinx.ext.coverage一整套源码对照文档的扫描机制CoverageBuilder以python.txt/c.txt/undoc.pickle三种形式输出结果13 个配置项覆盖了模块级扫描、正则忽略、统计表格与日志输出等全部需求。借助 conf.py 中的三条忽略规则和 test_ext_coverage.py 的逐字节断言你可以清晰地推演任意对象被纳入或排除的判定路径并把这套能力直接复用到自己的文档项目中——让写了代码却忘了写文档的缺口在每次构建时自动暴露出来。赞分享文档开发工具【免费下载链接】sphinxThe Sphinx documentation generator项目地址https://gitcode.com/gh_mirrors/sp/sphinx点击查看免费下载相关推荐flexivit_base.300ep_in21k vs 传统ViT19.4 GMACs如何实现更优性能flexivit_base.300ep_in21k vs 传统ViT19.4 GMACs如何实现更优性能 在计算机视觉领域视觉TransformerViECC 测试覆盖率实战指南/test-coverage 命令从覆盖率分析到缺口测试生成的完整工作流ECC 测试覆盖率实战指南/test coverage 命令从覆盖率分析到缺口测试生成的完整工作流 本文聚焦 ECCEverything Claude Co人工智能AI 技能AI 插件AI 评测Agent 评测MCP Clients开发工具Grafana仪表板深度解析Kubernetes监控的高级功能与最新特性Grafana仪表板深度解析Kubernetes监控的高级功能与最新特性 Kubernetes监控是现代云原生运维的核心而grafana dashboard上一篇构建响应式应用gh_mirrors/pr/promises事件驱动编程下一篇如何使用DGFraud在5分钟内搭建第一个欺诈检测模型快速入门指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
阅读完成 · 觉得有帮助?