intersphinx role, implement warning scheme

and temporarily remove explicit inventories
This commit is contained in:
Jakob Lykke Andersen 2021-11-06 13:25:49 +01:00
parent 184fd6a4aa
commit ce5512e3af
3 changed files with 29 additions and 48 deletions

View File

@ -495,20 +495,11 @@ class IntersphinxRole(SphinxRole):
location=(self.env.docname, self.lineno))
return [], []
# extract inventory specification
inventory = None
if self.text.startswith('\\:'):
# escaped :, so not a real inventory specification
self.text = self.text[1:]
elif self.text[0] == ':': # format: :inv:normalRoleArg
inventory = self.text.split(':')[1]
self.text = self.text[(len(inventory) + 2):]
result, messages = self.invoke_role(role_name)
for node in result:
if isinstance(node, pending_xref):
node['intersphinx'] = True
node['inventory'] = inventory
node['inventory'] = None
return result, messages
@ -574,8 +565,11 @@ class IntersphinxRoleResolver(ReferencesResolver):
else:
newnode = resolve_reference_any_inventory(self.env, False, node, contnode)
if newnode is None:
# no warning, the normal missing_reference handler will do that
pass
typ = node['reftype']
msg = (__('external %s:%s reference target not found: %s') %
(node['refdomain'], typ, node['reftarget']))
logger.warning(msg, location=node, type='ref', subtype=typ)
node.replace_self(contnode)
else:
node.replace_self(newnode)

View File

@ -1,26 +1,21 @@
:external:py:mod:`module1`
:external:py:mod:`inv:module2`
- ``module1`` is only defined in ``inv``:
:external:py:mod:`module1`
.. py:module:: module1
.. py:module:: module2
:external:py:func:`func`
:external:py:func:`inv:func`
:external:py:meth:`Foo.bar`
:external:py:meth:`inv:Foo.bar`
- ``module2`` is defined here and also in ``inv``, but should resolve to inv:
:external:py:mod:`module2`
:external:c:func:`CFunc`
:external:c:func:`inv:CFunc`
:external:doc:`docname`
:external:doc:`inv:docname`
:external:option:`ls -l`
:external:option:`inv:ls -l`
- ``module3`` is not defined anywhere, so should warn:
:external:py:mod:`module3`
.. cpp:type:: std::uint8_t
.. cpp:class:: foo::Bar
.. py:module:: module10
:external:cpp:type:`std::uint8_t`
:external:cpp:class:`inv:foo::Bar`
:external:cpp:func:`:inv2:foo::Bar::baz`
- ``module10`` is only defined here, but should still not be resolved to:
:external:py:mod:`module10`
:external:cpp:type:`FoonsTitle <foons>`
:external:cpp:type:`inv:BarType <foons::bartype>`
- a function in inv:
:external:py:func:`module1.func`
- a method, but with old style inventory prefix, which shouldn't work:
:external:py:meth:`inv:Foo.bar`

View File

@ -527,7 +527,7 @@ def test_inspect_main_url(capsys):
@pytest.mark.sphinx('html', testroot='ext-intersphinx-role')
def test_intersphinx_role(app):
def test_intersphinx_role(app, warning):
inv_file = app.srcdir / 'inventory'
inv_file.write_bytes(inventory_v2)
app.config.intersphinx_mapping = {
@ -542,21 +542,13 @@ def test_intersphinx_role(app):
app.build()
content = (app.outdir / 'index.html').read_text()
wStr = warning.getvalue()
targets = (
'foo.html#module-module1',
'foo.html#module-module2',
'sub/foo.html#module1.func',
'index.html#foo.Bar.baz',
'cfunc.html#CFunc',
'docname.html',
'index.html#cmdoption-ls-l',
'index.html#std_uint8_t',
'index.html#foons',
'index.html#foons_bartype',
)
html = '<a class="reference external" href="http://example.org/{}" title="(in foo v2.0)">'
for t in targets:
assert html.format(t) in content
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('index.html#cpp_foo_bar_baz') not in content
assert html.format('sub/foo.html#module1.func') in content
assert "WARNING: external py:meth reference target not found: inv:Foo.bar" in wStr