让 sphinx 报告损坏的链接

问题描述 投票:0回答:3

构建 html 文档时,如何强制 sphinx 在不存在的链接上报告或创建错误?

具体来说,我的 Python 项目中的属性和方法已被删除或重命名,并且很难找到 sphinx 生成的 html 输出的所有死链接。

我感觉我正在盯着这里的答案: http://sphinx-doc.org/glossary.html,如开头段落所述。

我显然不明白一些事情。

python documentation python-sphinx
3个回答
18
投票

nitpicky 配置变量设置为

True
(运行 sphinx-build 时也可以使用 -n 选项)。

在挑剔模式下,对无法找到的函数(例如

:func:`myfunc`
)、类或其他对象的交叉引用将生成警告消息。


9
投票

我认为

CheckExternalLinksBuilder
就是您要找的。

它基本上是通过使用

-b linkcheck
选项调用“sphinx-build”来使用的。请参阅
sphinx-build
了解更多信息。另外,请查看 sphinx 扩展列表 herehere


0
投票

我想编写一个没有损坏链接的测试,但遇到了几个困难:

    如果您不想在测试中发出实际的 http 请求,则在子进程中运行
  • sphinx build
     不起作用 -> 
    使用带有 pytest.mark.vcr
    的 python API
  • 使用 python api 时访问警告非常困难,我无法使用
  • capfd
     或类似的方法来做到这一点 -> 
    使用 warning
     关键字到 
    Sphinx
     构造函数
  • 记录的警告取决于对象类型(:class: 前缀)。默认情况下,只有
  • :any:
     似乎会抛出警告,但我更喜欢 
    default_role = "py:obj"
     -> 
    使用 nitpicky
     模式
    。幸运的是,如果您不想在那里设置挑剔,很容易覆盖
    conf.py
  • 我使用
  • mypy
     并且类型提示似乎不能很好地解决 
    sphinx
    ,导致大量警告 -> 
    set autodoc_typehints = "none"
  • 运行
  • app.build
     会生成大量标准输出和日志记录(可能通过扩展) -> 
    set status=StringIO()
     并使用 
    caplog
见下图:

import logging import subprocess from io import StringIO from pathlib import Path import pytest from sphinx.application import Sphinx def bad_msg(line: str) -> bool: if "<unknown>" in line: return False return "reference target not found" in line @pytest.fixture def docs_path(): docs_path = Path(__file__).parent.parent / "docs" return docs_path @pytest.fixture def apidocs(docs_path, capfd): subprocess.run(["make", "-C", str(docs_path), "clean", "apidocs"]) capfd.readouterr() # hide stdout output @pytest.fixture def warning_io(): return StringIO() @pytest.fixture def app(docs_path, warning_io): output_dir = docs_path / "build" doctree_dir = docs_path / "build/doctrees" app = Sphinx( str(docs_path), str(docs_path), str(output_dir), str(doctree_dir), buildername="html", status=StringIO(), # hide stdout output warning=warning_io, ) app.config.nitpicky = True app.config.autodoc_typehints = "none" return app @pytest.mark.vcr def test_docs(app, apidocs, warning_io, caplog): with caplog.at_level(logging.CRITICAL): app.build(force_all=True) logs = warning_io.getvalue() bad_messages = [line for line in logs.split("\n") if bad_msg(line)] if bad_messages: bad_logs = "\n".join(bad_messages) raise AssertionError(f"{len(bad_messages)} failure cases: {bad_logs}")
    
© www.soinside.com 2019 - 2024. All rights reserved.