mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
Generalize to disable specific refs as well.
This commit is contained in:
parent
84238dfd39
commit
0d9f4cd469
5
CHANGES
5
CHANGES
@ -50,6 +50,11 @@ Features added
|
|||||||
* #2068, add :confval:`intersphinx_disabled_domains` for disabling
|
* #2068, add :confval:`intersphinx_disabled_domains` for disabling
|
||||||
interphinx resolution of cross-references in specific domains when they
|
interphinx resolution of cross-references in specific domains when they
|
||||||
do not have an explicit inventory specification.
|
do not have an explicit inventory specification.
|
||||||
|
* #2068, add :confval:`intersphinx_disabled_refs` for disabling
|
||||||
|
interphinx resolution of cross-references that do not have an explicit
|
||||||
|
inventory specification. Specific types of cross-references can be disabled,
|
||||||
|
e.g., ``std:doc`` or all cross-references in a specific domain,
|
||||||
|
e.g., ``std``.
|
||||||
|
|
||||||
Bugs fixed
|
Bugs fixed
|
||||||
----------
|
----------
|
||||||
|
@ -148,21 +148,28 @@ linking:
|
|||||||
exception is raised if the server has not issued a response for timeout
|
exception is raised if the server has not issued a response for timeout
|
||||||
seconds.
|
seconds.
|
||||||
|
|
||||||
.. confval:: intersphinx_disabled_domains
|
.. confval:: intersphinx_disabled_refs
|
||||||
|
|
||||||
.. versionadded:: 4.2
|
.. versionadded:: 4.3
|
||||||
|
|
||||||
|
A list of strings being either:
|
||||||
|
|
||||||
|
- the name of a specific reference type,
|
||||||
|
e.g., ``std:doc``, ``py:func``, or ``cpp:class``,
|
||||||
|
- the name of a whole domain, e.g., ``std``, ``py``, or ``cpp``, or
|
||||||
|
- the special name ``all``.
|
||||||
|
|
||||||
A list of strings being the name of a domain, or the special name ``all``.
|
|
||||||
When a cross-reference without an explicit inventory specification is being
|
When a cross-reference without an explicit inventory specification is being
|
||||||
resolved by intersphinx, skip resolution if either the domain of the
|
resolved by intersphinx, skip resolution it matches one of the
|
||||||
cross-reference is in this list or the special name ``all`` is in the list.
|
specifications in this list.
|
||||||
|
|
||||||
For example, with ``intersphinx_disabled_domains = ['std']`` a cross-reference
|
For example, with ``intersphinx_disabled_refs = ['std:doc']``
|
||||||
``:doc:`installation``` will not be attempted to be resolved by intersphinx, but
|
a cross-reference ``:doc:`installation``` will not be attempted to be
|
||||||
``:doc:`otherbook:installation``` will be attempted to be resolved in the
|
resolved by intersphinx, but ``:doc:`otherbook:installation``` will be
|
||||||
inventory named ``otherbook`` in :confval:`intersphinx_mapping`.
|
attempted to be resolved in the inventory named ``otherbook`` in
|
||||||
At the same time, all cross-references generated in, e.g., Python, declarations
|
:confval:`intersphinx_mapping`.
|
||||||
will still be attempted to be resolved by intersphinx.
|
At the same time, all cross-references generated in, e.g., Python,
|
||||||
|
declarations will still be attempted to be resolved by intersphinx.
|
||||||
|
|
||||||
If ``all`` is in the list of domains, then no references without an explicit
|
If ``all`` is in the list of domains, then no references without an explicit
|
||||||
inventory will be resolved by intersphinx.
|
inventory will be resolved by intersphinx.
|
||||||
|
@ -321,7 +321,9 @@ def _resolve_reference_in_domain_by_target(
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
def _resolve_reference_in_domain(inv_name: Optional[str], inventory: Inventory,
|
def _resolve_reference_in_domain(env: BuildEnvironment,
|
||||||
|
inv_name: Optional[str], inventory: Inventory,
|
||||||
|
honor_disabled_refs: bool,
|
||||||
domain: Domain, objtypes: List[str],
|
domain: Domain, objtypes: List[str],
|
||||||
node: pending_xref, contnode: TextElement
|
node: pending_xref, contnode: TextElement
|
||||||
) -> Optional[Element]:
|
) -> Optional[Element]:
|
||||||
@ -336,6 +338,11 @@ def _resolve_reference_in_domain(inv_name: Optional[str], inventory: Inventory,
|
|||||||
# the inventory contains domain:type as objtype
|
# the inventory contains domain:type as objtype
|
||||||
objtypes = ["{}:{}".format(domain.name, t) for t in objtypes]
|
objtypes = ["{}:{}".format(domain.name, t) for t in objtypes]
|
||||||
|
|
||||||
|
# now that the objtypes list is complete we can remove the disabled ones
|
||||||
|
if honor_disabled_refs:
|
||||||
|
disabled = env.config.intersphinx_disabled_refs
|
||||||
|
objtypes = [o for o in objtypes if o not in disabled]
|
||||||
|
|
||||||
# without qualification
|
# without qualification
|
||||||
res = _resolve_reference_in_domain_by_target(inv_name, inventory, domain, objtypes,
|
res = _resolve_reference_in_domain_by_target(inv_name, inventory, domain, objtypes,
|
||||||
node['reftarget'], node, contnode)
|
node['reftarget'], node, contnode)
|
||||||
@ -351,22 +358,23 @@ def _resolve_reference_in_domain(inv_name: Optional[str], inventory: Inventory,
|
|||||||
|
|
||||||
|
|
||||||
def _resolve_reference(env: BuildEnvironment, inv_name: Optional[str], inventory: Inventory,
|
def _resolve_reference(env: BuildEnvironment, inv_name: Optional[str], inventory: Inventory,
|
||||||
honor_disabled_domains: bool,
|
honor_disabled_refs: bool,
|
||||||
node: pending_xref, contnode: TextElement) -> Optional[Element]:
|
node: pending_xref, contnode: TextElement) -> Optional[Element]:
|
||||||
# disabling should only be done if no inventory is given
|
# disabling should only be done if no inventory is given
|
||||||
honor_disabled_domains = honor_disabled_domains and inv_name is None
|
honor_disabled_refs = honor_disabled_refs and inv_name is None
|
||||||
|
|
||||||
if honor_disabled_domains and 'all' in env.config.intersphinx_disabled_domains:
|
if honor_disabled_refs and 'all' in env.config.intersphinx_disabled_refs:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
typ = node['reftype']
|
typ = node['reftype']
|
||||||
if typ == 'any':
|
if typ == 'any':
|
||||||
for domain_name, domain in env.domains.items():
|
for domain_name, domain in env.domains.items():
|
||||||
if honor_disabled_domains \
|
if honor_disabled_refs \
|
||||||
and domain_name in env.config.intersphinx_disabled_domains:
|
and domain_name in env.config.intersphinx_disabled_refs:
|
||||||
continue
|
continue
|
||||||
objtypes = list(domain.object_types)
|
objtypes = list(domain.object_types)
|
||||||
res = _resolve_reference_in_domain(inv_name, inventory,
|
res = _resolve_reference_in_domain(env, inv_name, inventory,
|
||||||
|
honor_disabled_refs,
|
||||||
domain, objtypes,
|
domain, objtypes,
|
||||||
node, contnode)
|
node, contnode)
|
||||||
if res is not None:
|
if res is not None:
|
||||||
@ -377,14 +385,15 @@ def _resolve_reference(env: BuildEnvironment, inv_name: Optional[str], inventory
|
|||||||
if not domain_name:
|
if not domain_name:
|
||||||
# only objects in domains are in the inventory
|
# only objects in domains are in the inventory
|
||||||
return None
|
return None
|
||||||
if honor_disabled_domains \
|
if honor_disabled_refs \
|
||||||
and domain_name in env.config.intersphinx_disabled_domains:
|
and domain_name in env.config.intersphinx_disabled_refs:
|
||||||
return None
|
return None
|
||||||
domain = env.get_domain(domain_name)
|
domain = env.get_domain(domain_name)
|
||||||
objtypes = domain.objtypes_for_role(typ)
|
objtypes = domain.objtypes_for_role(typ)
|
||||||
if not objtypes:
|
if not objtypes:
|
||||||
return None
|
return None
|
||||||
return _resolve_reference_in_domain(inv_name, inventory,
|
return _resolve_reference_in_domain(env, inv_name, inventory,
|
||||||
|
honor_disabled_refs,
|
||||||
domain, objtypes,
|
domain, objtypes,
|
||||||
node, contnode)
|
node, contnode)
|
||||||
|
|
||||||
@ -409,7 +418,7 @@ def resolve_reference_in_inventory(env: BuildEnvironment,
|
|||||||
|
|
||||||
|
|
||||||
def resolve_reference_any_inventory(env: BuildEnvironment,
|
def resolve_reference_any_inventory(env: BuildEnvironment,
|
||||||
honor_disabled_domains: bool,
|
honor_disabled_refs: bool,
|
||||||
node: pending_xref, contnode: TextElement
|
node: pending_xref, contnode: TextElement
|
||||||
) -> Optional[Element]:
|
) -> Optional[Element]:
|
||||||
"""Attempt to resolve a missing reference via intersphinx references.
|
"""Attempt to resolve a missing reference via intersphinx references.
|
||||||
@ -417,12 +426,12 @@ def resolve_reference_any_inventory(env: BuildEnvironment,
|
|||||||
Resolution is tried with the target as is in any inventory.
|
Resolution is tried with the target as is in any inventory.
|
||||||
"""
|
"""
|
||||||
return _resolve_reference(env, None, InventoryAdapter(env).main_inventory,
|
return _resolve_reference(env, None, InventoryAdapter(env).main_inventory,
|
||||||
honor_disabled_domains,
|
honor_disabled_refs,
|
||||||
node, contnode)
|
node, contnode)
|
||||||
|
|
||||||
|
|
||||||
def resolve_reference_detect_inventory(env: BuildEnvironment,
|
def resolve_reference_detect_inventory(env: BuildEnvironment,
|
||||||
honor_disabled_domains: bool,
|
honor_disabled_refs: bool,
|
||||||
node: pending_xref, contnode: TextElement
|
node: pending_xref, contnode: TextElement
|
||||||
) -> Optional[Element]:
|
) -> Optional[Element]:
|
||||||
"""Attempt to resolve a missing reference via intersphinx references.
|
"""Attempt to resolve a missing reference via intersphinx references.
|
||||||
@ -434,7 +443,7 @@ def resolve_reference_detect_inventory(env: BuildEnvironment,
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
# ordinary direct lookup, use data as is
|
# ordinary direct lookup, use data as is
|
||||||
res = resolve_reference_any_inventory(env, honor_disabled_domains, node, contnode)
|
res = resolve_reference_any_inventory(env, honor_disabled_refs, node, contnode)
|
||||||
if res is not None:
|
if res is not None:
|
||||||
return res
|
return res
|
||||||
|
|
||||||
@ -486,7 +495,7 @@ def setup(app: Sphinx) -> Dict[str, Any]:
|
|||||||
app.add_config_value('intersphinx_mapping', {}, True)
|
app.add_config_value('intersphinx_mapping', {}, True)
|
||||||
app.add_config_value('intersphinx_cache_limit', 5, False)
|
app.add_config_value('intersphinx_cache_limit', 5, False)
|
||||||
app.add_config_value('intersphinx_timeout', None, False)
|
app.add_config_value('intersphinx_timeout', None, False)
|
||||||
app.add_config_value('intersphinx_disabled_domains', [], True)
|
app.add_config_value('intersphinx_disabled_refs', [], True)
|
||||||
app.connect('config-inited', normalize_intersphinx_mapping, priority=800)
|
app.connect('config-inited', normalize_intersphinx_mapping, priority=800)
|
||||||
app.connect('builder-inited', load_mappings)
|
app.connect('builder-inited', load_mappings)
|
||||||
app.connect('missing-reference', missing_reference)
|
app.connect('missing-reference', missing_reference)
|
||||||
|
@ -45,7 +45,7 @@ def reference_check(app, *args, **kwds):
|
|||||||
def set_config(app, mapping):
|
def set_config(app, mapping):
|
||||||
app.config.intersphinx_mapping = mapping
|
app.config.intersphinx_mapping = mapping
|
||||||
app.config.intersphinx_cache_limit = 0
|
app.config.intersphinx_cache_limit = 0
|
||||||
app.config.intersphinx_disabled_domains = []
|
app.config.intersphinx_disabled_refs = []
|
||||||
|
|
||||||
|
|
||||||
@mock.patch('sphinx.ext.intersphinx.InventoryFile')
|
@mock.patch('sphinx.ext.intersphinx.InventoryFile')
|
||||||
@ -303,7 +303,7 @@ def test_missing_reference_disabled_domain(tempdir, app, status, warning):
|
|||||||
normalize_intersphinx_mapping(app, app.config)
|
normalize_intersphinx_mapping(app, app.config)
|
||||||
load_mappings(app)
|
load_mappings(app)
|
||||||
|
|
||||||
def case(std_without, std_with, py_without, py_with):
|
def case(*, term, doc, py):
|
||||||
def assert_(rn, expected):
|
def assert_(rn, expected):
|
||||||
if expected is None:
|
if expected is None:
|
||||||
assert rn is None
|
assert rn is None
|
||||||
@ -312,34 +312,46 @@ def test_missing_reference_disabled_domain(tempdir, app, status, warning):
|
|||||||
|
|
||||||
kwargs = {}
|
kwargs = {}
|
||||||
|
|
||||||
|
node, contnode = fake_node('std', 'term', 'a term', 'a term', **kwargs)
|
||||||
|
rn = missing_reference(app, app.env, node, contnode)
|
||||||
|
assert_(rn, 'a term' if term else None)
|
||||||
|
|
||||||
|
node, contnode = fake_node('std', 'term', 'inv:a term', 'a term', **kwargs)
|
||||||
|
rn = missing_reference(app, app.env, node, contnode)
|
||||||
|
assert_(rn, 'a term')
|
||||||
|
|
||||||
node, contnode = fake_node('std', 'doc', 'docname', 'docname', **kwargs)
|
node, contnode = fake_node('std', 'doc', 'docname', 'docname', **kwargs)
|
||||||
rn = missing_reference(app, app.env, node, contnode)
|
rn = missing_reference(app, app.env, node, contnode)
|
||||||
assert_(rn, std_without)
|
assert_(rn, 'docname' if doc else None)
|
||||||
|
|
||||||
node, contnode = fake_node('std', 'doc', 'inv:docname', 'docname', **kwargs)
|
node, contnode = fake_node('std', 'doc', 'inv:docname', 'docname', **kwargs)
|
||||||
rn = missing_reference(app, app.env, node, contnode)
|
rn = missing_reference(app, app.env, node, contnode)
|
||||||
assert_(rn, std_with)
|
assert_(rn, 'docname')
|
||||||
|
|
||||||
# an arbitrary ref in another domain
|
# an arbitrary ref in another domain
|
||||||
node, contnode = fake_node('py', 'func', 'module1.func', 'func()', **kwargs)
|
node, contnode = fake_node('py', 'func', 'module1.func', 'func()', **kwargs)
|
||||||
rn = missing_reference(app, app.env, node, contnode)
|
rn = missing_reference(app, app.env, node, contnode)
|
||||||
assert_(rn, py_without)
|
assert_(rn, 'func()' if py else None)
|
||||||
|
|
||||||
node, contnode = fake_node('py', 'func', 'inv:module1.func', 'func()', **kwargs)
|
node, contnode = fake_node('py', 'func', 'inv:module1.func', 'func()', **kwargs)
|
||||||
rn = missing_reference(app, app.env, node, contnode)
|
rn = missing_reference(app, app.env, node, contnode)
|
||||||
assert_(rn, py_with)
|
assert_(rn, 'func()')
|
||||||
|
|
||||||
# the base case, everything should resolve
|
# the base case, everything should resolve
|
||||||
assert app.config.intersphinx_disabled_domains == []
|
assert app.config.intersphinx_disabled_refs == []
|
||||||
case('docname', 'docname', 'func()', 'func()')
|
case(term=True, doc=True, py=True)
|
||||||
|
|
||||||
# disabled one domain
|
# disabled a single ref type
|
||||||
app.config.intersphinx_disabled_domains = ['std']
|
app.config.intersphinx_disabled_refs = ['std:doc']
|
||||||
case(None, 'docname', 'func()', 'func()')
|
case(term=True, doc=False, py=True)
|
||||||
|
|
||||||
|
# disabled a whole domain
|
||||||
|
app.config.intersphinx_disabled_refs = ['std']
|
||||||
|
case(term=False, doc=False, py=True)
|
||||||
|
|
||||||
# disabled all domains
|
# disabled all domains
|
||||||
app.config.intersphinx_disabled_domains = ['all']
|
app.config.intersphinx_disabled_refs = ['all']
|
||||||
case(None, 'docname', None, 'func()')
|
case(term=False, doc=False, py=False)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.xfail(os.name != 'posix', reason="Path separator mismatch issue")
|
@pytest.mark.xfail(os.name != 'posix', reason="Path separator mismatch issue")
|
||||||
|
Loading…
Reference in New Issue
Block a user