👌 Handle external references pointing to object types (#12133)

This commit fixes the issue of `objects.inv` denoting object names, whilst the `external` role only allows for role names. 

As an example, take the `objects.inv` for the sphinx documentation, which contains:

```
py:function
    compile                  : usage/domains/python.html#compile
```

A user might understandably expect that they could reference this using `` :external:py:function:`compile` ``, but actually this would previously error with:

```
WARNING: role for external cross-reference not found: py:function
```

this is because, `function` is the object type, yet `external` expects the related role name `func`.

It should not be necessary for the user to know about this distinction,
so in this commit, we add logic, to first look if the name relates to a role name (as previous, to not be back-breaking) but, if not, then also look if the name relates to an object that has a known role and, if so, use that.

Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com>
This commit is contained in:
Chris Sewell
2024-03-19 13:42:50 +01:00
committed by GitHub
parent b9b0ad856a
commit 565d4104d5
5 changed files with 57 additions and 24 deletions

View File

@@ -18,6 +18,7 @@ from sphinx.ext.intersphinx import (
normalize_intersphinx_mapping,
)
from sphinx.ext.intersphinx import setup as intersphinx_setup
from sphinx.util.console import strip_colors
from tests.test_util.test_util_inventory import inventory_v2, inventory_v2_not_having_version
from tests.utils import http_server
@@ -551,22 +552,25 @@ def test_intersphinx_role(app, warning):
app.build()
content = (app.outdir / 'index.html').read_text(encoding='utf8')
wStr = warning.getvalue()
warnings = strip_colors(warning.getvalue()).splitlines()
index_path = app.srcdir / 'index.rst'
assert warnings == [
f'{index_path}:21: WARNING: role for external cross-reference not found: py:nope',
f'{index_path}:28: WARNING: role for external cross-reference not found: nope',
f'{index_path}:39: WARNING: inventory for external cross-reference not found: invNope',
f'{index_path}:9: WARNING: external py:mod reference target not found: module3',
f'{index_path}:14: WARNING: external py:mod reference target not found: module10',
f'{index_path}:19: WARNING: external py:meth reference target not found: inv:Foo.bar',
]
html = '<a class="reference external" href="https://example.org/{}" title="(in foo v2.0)">'
assert html.format('foo.html#module-module1') in content
assert html.format('foo.html#module-module2') in content
assert "WARNING: external py:mod reference target not found: module3" in wStr
assert "WARNING: external py:mod reference target not found: module10" in wStr
assert html.format('sub/foo.html#module1.func') in content
assert "WARNING: external py:meth reference target not found: inv:Foo.bar" in wStr
assert "WARNING: role for external cross-reference not found: py:nope" in wStr
# default domain
assert html.format('index.html#std_uint8_t') in content
assert "WARNING: role for external cross-reference not found: nope" in wStr
# std roles without domain prefix
assert html.format('docname.html') in content
@@ -574,7 +578,6 @@ def test_intersphinx_role(app, warning):
# explicit inventory
assert html.format('cfunc.html#CFunc') in content
assert "WARNING: inventory for external cross-reference not found: invNope" in wStr
# explicit title
assert html.format('index.html#foons') in content