From 7f0b13af6e023382f8bfdaa0916c614a586ff05c Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Sat, 6 Mar 2021 14:43:13 +0900 Subject: [PATCH] intersphinx: Support pending_xref_condition --- sphinx/ext/intersphinx.py | 23 ++++++++++++++++++----- tests/test_ext_intersphinx.py | 8 ++++++++ 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/sphinx/ext/intersphinx.py b/sphinx/ext/intersphinx.py index 5569ad9de..a01bcc37a 100644 --- a/sphinx/ext/intersphinx.py +++ b/sphinx/ext/intersphinx.py @@ -33,10 +33,11 @@ from typing import IO, Any, Dict, List, Tuple from urllib.parse import urlsplit, urlunsplit from docutils import nodes -from docutils.nodes import Element, TextElement +from docutils.nodes import TextElement from docutils.utils import relative_path import sphinx +from sphinx.addnodes import pending_xref from sphinx.application import Sphinx from sphinx.builders.html import INVENTORY_FILENAME from sphinx.config import Config @@ -44,6 +45,7 @@ from sphinx.environment import BuildEnvironment from sphinx.locale import _, __ from sphinx.util import logging, requests from sphinx.util.inventory import InventoryFile +from sphinx.util.nodes import find_pending_xref_condition from sphinx.util.typing import Inventory logger = logging.getLogger(__name__) @@ -257,8 +259,8 @@ def load_mappings(app: Sphinx) -> None: inventories.main_inventory.setdefault(type, {}).update(objects) -def missing_reference(app: Sphinx, env: BuildEnvironment, node: Element, contnode: TextElement - ) -> nodes.reference: +def missing_reference(app: Sphinx, env: BuildEnvironment, node: pending_xref, + contnode: TextElement) -> nodes.reference: """Attempt to resolve a missing reference via intersphinx references.""" target = node['reftarget'] inventories = InventoryAdapter(env) @@ -284,6 +286,17 @@ def missing_reference(app: Sphinx, env: BuildEnvironment, node: Element, contnod if 'py:attribute' in objtypes: # Since Sphinx-2.1, properties are stored as py:method objtypes.append('py:method') + + # determine the contnode by pending_xref_condition + content = find_pending_xref_condition(node, 'resolved') + if content: + # resolved condition found. + contnodes = content.children + contnode = content.children[0] # type: ignore + else: + # not resolved. Use the given contnode + contnodes = [contnode] + to_try = [(inventories.main_inventory, target)] if domain: full_qualified_name = env.get_domain(domain).get_full_qualified_name(node) @@ -316,7 +329,7 @@ def missing_reference(app: Sphinx, env: BuildEnvironment, node: Element, contnod newnode = nodes.reference('', '', internal=False, refuri=uri, reftitle=reftitle) if node.get('refexplicit'): # use whatever title was given - newnode.append(contnode) + newnode.extend(contnodes) elif dispname == '-' or \ (domain == 'std' and node['reftype'] == 'keyword'): # use whatever title was given, but strip prefix @@ -325,7 +338,7 @@ def missing_reference(app: Sphinx, env: BuildEnvironment, node: Element, contnod newnode.append(contnode.__class__(title[len(in_set) + 1:], title[len(in_set) + 1:])) else: - newnode.append(contnode) + newnode.extend(contnodes) else: # else use the given display name (used for :ref:) newnode.append(contnode.__class__(dispname, dispname)) diff --git a/tests/test_ext_intersphinx.py b/tests/test_ext_intersphinx.py index a87677525..523ed2acc 100644 --- a/tests/test_ext_intersphinx.py +++ b/tests/test_ext_intersphinx.py @@ -196,6 +196,14 @@ def test_missing_reference_pydomain(tempdir, app, status, warning): rn = missing_reference(app, app.env, node, contnode) assert rn.astext() == 'Foo.bar' + # pending_xref_condition="resolved" + node = addnodes.pending_xref('', reftarget='Foo.bar', refdomain='py', reftype='attr') + node['py:module'] = 'module1' + node += addnodes.pending_xref_condition('', 'Foo.bar', condition='resolved') + node += addnodes.pending_xref_condition('', 'module1.Foo.bar', condition='*') + rn = missing_reference(app, app.env, node, nodes.Text('dummy-cont-node')) + assert rn.astext() == 'Foo.bar' + def test_missing_reference_stddomain(tempdir, app, status, warning): inv_file = tempdir / 'inventory'