Sphinx 挑剔模式,但仅适用于我明确编写的链接

Sphinx nit-picky mode but only for links I explicitly wrote

我尝试打开 Sphinx 的挑剔模式 (-n) 来捕获我可能不小心创建的任何损坏的链接。但是,它会为我记录类型的所有地方喷出错误。在某些情况下,我已经在语义上描述了类型(例如“3D 数组”),但它甚至对从类型提示中提取的类型也是如此(即使 intersphinx 设置为提取 Python 类型)。例如,对于这个模块

from typing import Callable

def foo(x: Callable[..., int]):
    pass

我收到错误 docstring of myproj.foo:: WARNING: py:class reference target not found: Callable[..., int]。只有 sphinx.ext.autodocsphinx.ext.intersphinx 扩展以及新生成的 conf.py.

有什么方法可以防止 Sphinx 尝试为类型信息生成链接,或者至少阻止它在它们不存在时抱怨,同时仍然告诉我手写文档中的错误链接?

我正在使用 Sphinx 3.0.3。

也许nitpick_ignore会如你所愿?在你的 conf.py 中,是这样的:

nitpick_ignore = [
    ("py:class", "Callable"),
]

我不确定元组中应该使用的确切值,但我从 this issue and a linked commit 得到了这个想法。

我通过编写自定义 sphinx 转换成功解决了类似问题。我只想要交叉引用我自己的包的 python 文档的警告。以下内容可以保存为 python 文件并添加到 conf.py 中的 extensions 一旦它在 python 路径上。

from sphinx import addnodes
from sphinx.errors import NoUri
from sphinx.transforms.post_transforms import SphinxPostTransform
from sphinx.util import logging

logger = logging.getLogger(__name__)

class MyLinkWarner(SphinxPostTransform):
    """
    Warns about broken cross-reference links, but only for my_package_name. 
    This is very similar to the sphinx option ``nitpicky=True`` (see
    :py:class:`sphinx.transforms.post_transforms.ReferencesResolver`), but there
    is no way to restrict that option to a specific package.
    """

    # this transform needs to happen before ReferencesResolver
    default_priority = 5

    def run(self):
        for node in self.document.traverse(addnodes.pending_xref):
            target = node["reftarget"]

            if target.startswith("my_package_name."):
                found_ref = False

                with suppress(NoUri, KeyError):
                    # let the domain try to resolve the reference
                    found_ref = self.env.domains[node["refdomain"]].resolve_xref(
                        self.env,
                        node.get("refdoc", self.env.docname),
                        self.app.builder,
                        node["reftype"],
                        target,
                        node,
                        nodes.TextElement("", ""),
                    )

                # warn if resolve_xref did not return or raised
                if not found_ref:
                    logger.warning(
                        f"API link {target} is broken.", location=node, type="ref"
                    )


def setup(app):
    app.add_post_transform(MyLinkWarner)