☰
Sphinx 9.1 版本深度解析:add_static_dir 新特性与关键修复的源码级解读
2026/9/26 16:02:28 网站建设 项目流程
  • 文档
  • 开发工具

【免费下载链接】sphinx

The Sphinx documentation generator

项目地址:https://gitcode.com/gh_mirrors/sp/sphinx
点击查看免费下载

Sphinx 是 Python 生态中最主流的文档生成器,其版本变更日志(CHANGES.rst)记录了每个版本的功能新增与缺陷修复。本文以仓库中的变更记录为主体,结合 sphinx/application.py、sphinx/registry.py、sphinx/search/init.py 等源码实现,对 Sphinx 9.1.0 与正在开发的 9.1.1 两个版本做一次深度解读,帮助扩展开发者、LaTeX 用户与多语言文档团队快速评估升级影响并定位修复背后的实现原理。

版本概览与升级基线

Sphinx 9.1.0 已于 2025 年 12 月 31 日正式发布,9.1.1 仍在开发中(Release 9.1.1 (in development))。两个版本的主要差异在于:9.1.0 引入了新特性并调整了依赖基线,9.1.1 则是一批针对 LaTeX 输出与 JavaScript 搜索的缺陷修复。

从仓库的 pyproject.toml 可以确认当前版本的运行环境要求:

  • requires-python = ">=3.12",即最低 Python 版本为 3.12;
  • docutils>=0.21,<0.23,即 Docutils 的受支持区间为 0.21.x ~ 0.22.x。

因此,如果项目仍停留在 Python 3.11 或 Docutils 0.20,需要先升级运行环境再迁移到 Sphinx 9.1。

新特性:Sphinx.add_static_dir()扩展静态资源注册

9.1.0 新增了面向扩展开发者的核心 API——Sphinx.add_static_dir(),用于把扩展包内的静态资源目录复制到构建输出。这是本次版本唯一的功能性新增,也是扩展开发者需要重点关注的接口。

API 签名与行为

在 sphinx/application.py#L1581-L1615 中,该方法的实现如下:

def add_static_dir(self, path: str | os.PathLike[str]) -> None: """Register a static directory to include in HTML output. The given directory's contents will be copied to the ``_static`` directory during an HTML build. Files from extension static directories are copied after theme static files and before any directories from the user-configured ``html_static_path`` setting. ... .. versionadded:: 9.1 """ path = Path(path) logger.debug("[app] adding static_dir: '%s'", path) self.registry.add_static_dir(path)

要点如下:

  • 参数:接受str或os.PathLike,内部统一转换为pathlib.Path;
  • 复制时机:静态目录的内容在 HTML 构建期间被复制到输出的_static目录,并保留子目录结构;
  • 复制顺序:扩展静态目录文件在主题静态文件之后、用户配置的html_static_path目录之前被复制,这意味着用户可以通过html_static_path覆盖扩展提供的同名文件——这条优先级约定对扩展作者设计可定制样式非常重要;
  • 适用对象:主题自带static/目录的支持是 Sphinx 内置的,因此该方法主要面向非主题型扩展(如 autodoc、mathjax、graphviz 这类第三方扩展)注册额外静态资源。

注册机制与调用链

在 sphinx/registry.py#L473-L476 中,SphinxRegistry.add_static_dir()将路径追加到self.static_dirs列表:

def add_static_dir(self, path: Path) -> None: """Register a static directory for extensions.""" logger.debug("[app] adding static_dir: '%s'", path) self.static_dirs.append(path)

构建器在 HTML 构建阶段遍历该列表完成复制,从而实现了"扩展声明静态资源 → 构建器统一收集 → 输出到_static"的完整链路。

扩展中的典型用法

文档给出了标准的扩展接入示例,改造后如下:

from pathlib import Path def setup(app): # 该目录下所有文件(含子目录结构)会被复制到 _static/ app.add_static_dir(Path(__file__).parent / 'static') # 随后以相对 _static/ 的路径引用这些资源 app.add_js_file('js/my_extension.js') app.add_css_file('css/my_extension.css')

这一组合解决了此前扩展只能通过add_js_file/add_css_file逐个注册文件、而无法成目录批量托管的痛点,让扩展可以将图标、字体、独立 JS 模块等整体打包发布。

依赖与兼容性变更

9.1.0 的Dependencies一节明确了两项基线调整,升级时需提前规划:

变更项说明影响
移除 Python 3.11 支持最低要求提升至 Python 3.12使用 3.11 的 CI 与部署环境需升级;pyproject.toml 中requires-python = ">=3.12"已同步更新
移除 Docutils 0.20 支持受支持区间为>=0.21,<0.23锁定了 0.20 的旧项目需升级 Docutils;对 MyST-Parser 等依赖 Docutils 解析管道的生态工具影响尤需关注

9.1.0 还顺带修复了 Python 3.15 下的测试兼容问题(Fix tests for Python 3.15),体现了项目对新版本 Python 的前瞻性适配。

LaTeX 输出链路的密集修复

9.1.0 与 9.1.1 在 LaTeX/PDF 构建方向修复了大量缺陷,是本次版本更新中修复密度最高的领域,典型问题包括:

  • 代码块行数上限崩溃(#3099):code-block中代码超过约 1350 行(默认字号下约 27 页 A4)时 PDF 构建直接崩溃,已在 9.1.0 修复;
  • 合并单元格渲染:网格填充的合并垂直单元格(grid filled merged vertical cell)渲染错误,以及合并垂直表格单元格导致页脚溢出(#14228)均在 9.1.0 修复;
  • colorrows默认样式崩溃(#14465):LaTeX 2026 年 6 月版发布后,使用默认的'colorrows'表格样式时 PDF 构建崩溃,该问题被列为 9.1.1 的优先修复项;
  • 制表符缩进失效(#14064):sphinxVerbatim中出现的 TAB 无法正确遵循制表位,9.1.0 已修复;
  • literalblockcappos回归:9.1.0 修复了自 3.5.0(#8854)起'sphinxsetup'中literalblockcappos键文档被意外移除的问题,恢复了该键在 sphinxsetup 配置体系中的可用性;
  • acronym标准角色(#14050):9.1.0 修复了LaTeXTranslator在文档使用 "acronym" 标准角色时构建失败的问题。

这些修复均落在 sphinx/builders/latex 与 sphinx/texinputs 相关的翻译器与样式宏层面,对以 LaTeX/PDF 为主要发布格式的文档项目价值明显。

JavaScript 搜索:词干提取类名推导修复

9.1.1 修复了一个影响多语言搜索的关键问题(#14229):当某语言的词干提取器(stemmer)类名与该语言名不一致时,JavaScript 搜索无法正确工作。文档明确指出两类典型案例:

  • 中文:SearchChinese复用了英文词干提取器(english-stemmer.js,其定义的是EnglishStemmer类);
  • 荷兰语:使用荷兰 Porter 词干提取器。

在 sphinx/search/init.py#L578-L600 中可以看到修复后的类名推导逻辑:不再从language_name推导,而是从 stemmer 文件名反推类名:

def get_js_stemmer_code(self) -> str: """Returns JS code that will be inserted into language_data.js.""" if not self.lang.js_stemmer_rawcode: return self.lang.js_stemmer_code base_js_path = _MINIFIED_JS_PATH / 'base-stemmer.js' language_js_path = _MINIFIED_JS_PATH / self.lang.js_stemmer_rawcode # Derive the JS class name from the stemmer filename rather than # from language_name, since some languages reuse another language's # stemmer. For example, SearchChinese reuses english-stemmer.js, # which defines EnglishStemmer. stemmer_class = ( self.lang.js_stemmer_rawcode.removesuffix('-stemmer.js') .title() .replace('_', '') .replace('-', '') + 'Stemmer' ) return '\n'.join(( base_js_path.read_text(encoding='utf-8'), language_js_path.read_text(encoding='utf-8'), f'window.Stemmer = {stemmer_class};', ))

该实现同时输出未压缩的 stemmer 源文件(get_js_stemmer_rawcodes,对应 sphinx/search/non-minified-js),并在language_data.js中注入window.Stemmer = ...赋值。对使用中文、荷兰语等"复用他语种词干器"的站点,升级到 9.1.1 后浏览器端搜索的词干归一化即可恢复正常。

autodoc 与扩展 API 的稳定性修复

9.1.0 在 autodoc 与扩展接口方向同样有若干值得注意的修复:

  • 重复的:no-index-entry:(#14189):修复模块级:no-index-entry:选项被重复输出的问题;
  • 默认参数解析(#14089):修复默认选项解析错误,并同时改进了对不可弱引用(non-weakreferencable)对象的支持;
  • HTMLThemeFactory创建(#14207):修复第三方扩展创建HTMLThemeFactory对象时的失败问题,这一改动对主题类扩展的开发者尤为关键;
  • MyST-Parser 兼容性(#13713):修复与 MyST-Parser 的兼容问题,使得基于 MyST 标记的项目可以平滑升级;
  • 类型标注清理:移除了不正确的静态类型断言,配合测试的 Python 3.15 适配,降低了py.typed标注在严格类型检查下的误报。

如何查看完整变更与升级建议

  • 完整历史变更见 CHANGES.rst(仓库根目录),9.1.0 之前各版本的逐版变更记录位于 doc/changes;
  • 升级前建议先核对 pyproject.toml 中的 Python(>=3.12)与 Docutils(>=0.21,<0.23)约束;
  • LaTeX/PDF 用户应重点回归表格样式、长代码块与合并单元格场景;多语言站点应重点回归中文、荷兰语等语言的站内搜索;扩展作者则应关注add_static_dir的复制顺序约定(扩展静态文件在html_static_path之前被复制,可被用户覆盖)。

结合源码与变更日志可以看到,Sphinx 9.1 的发布节奏清晰:9.1.0 以新 API 与兼容性调整为纲,9.1.1 则以 LaTeX 与搜索等用户可感知的缺陷修复为重心,整体上属于低风险、高收益的升级版本。

  • 文档
  • 开发工具

【免费下载链接】sphinx

The Sphinx documentation generator

项目地址:https://gitcode.com/gh_mirrors/sp/sphinx
点击查看免费下载
上一篇:Dozzle 快速入门:单容器部署、Swarm 与 K8s 全场景上手指南
下一篇:deck.gl 图层路线图深度解读:从图层目录演进到通用聚合层架构

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

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询