summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTakeshi KOMIYA <i.tkomiya@gmail.com>2021-05-19 22:47:01 +0900
committerGitHub <noreply@github.com>2021-05-19 22:47:01 +0900
commitca36c9ab171da5a7b31e8351e4967d3b4e205478 (patch)
tree0014064043c4044a503df9d84ef387953bedbe21
parent630e5bd15f43c6cd91e61723f40b6c94ef622060 (diff)
parent2d3d668856e518203200e95b8b64788c98d39d9a (diff)
downloadsphinx-git-ca36c9ab171da5a7b31e8351e4967d3b4e205478.tar.gz
Merge pull request #9246 from tk0miya/9240_unknown_node_pending_xref_condition
Fix #9240: Unknown node error for pending_xref_condition is raised
-rw-r--r--CHANGES2
-rw-r--r--sphinx/transforms/post_transforms/__init__.py28
-rw-r--r--tests/roots/test-transforms-post_transforms-missing-reference/conf.py1
-rw-r--r--tests/roots/test-transforms-post_transforms-missing-reference/index.rst5
-rw-r--r--tests/test_transforms_post_transforms.py58
5 files changed, 85 insertions, 9 deletions
diff --git a/CHANGES b/CHANGES
index 67ef71dd7..143e236a4 100644
--- a/CHANGES
+++ b/CHANGES
@@ -10,6 +10,8 @@ Incompatible changes
* #9222: Update Underscore.js to 1.13.1
* #9217: manpage: Stop creating a section directory on build manpage by default
(see :confval:`man_make_section_directory`)
+* #9240: Unknown node error for pending_xref_condition is raised if an extension
+ that does not support the node installs a missing-reference handler
Deprecated
----------
diff --git a/sphinx/transforms/post_transforms/__init__.py b/sphinx/transforms/post_transforms/__init__.py
index e2899d994..dde06fae1 100644
--- a/sphinx/transforms/post_transforms/__init__.py
+++ b/sphinx/transforms/post_transforms/__init__.py
@@ -8,10 +8,10 @@
:license: BSD, see LICENSE for details.
"""
-from typing import Any, Dict, List, Optional, Tuple, Type, cast
+from typing import Any, Dict, List, Optional, Sequence, Tuple, Type, cast
from docutils import nodes
-from docutils.nodes import Element
+from docutils.nodes import Element, Node
from sphinx import addnodes
from sphinx.addnodes import pending_xref
@@ -26,10 +26,6 @@ from sphinx.util.nodes import find_pending_xref_condition, process_only_nodes
logger = logging.getLogger(__name__)
-if False:
- # For type annotation
- from docutils.nodes import Node
-
class SphinxPostTransform(SphinxTransform):
"""A base class of post-transforms.
@@ -71,7 +67,12 @@ class ReferencesResolver(SphinxPostTransform):
def run(self, **kwargs: Any) -> None:
for node in self.document.traverse(addnodes.pending_xref):
- contnode = cast(nodes.TextElement, node[0].deepcopy())
+ content = self.find_pending_xref_condition(node, ("resolved", "*"))
+ if content:
+ contnode = cast(Element, content[0].deepcopy())
+ else:
+ contnode = cast(Element, node[0].deepcopy())
+
newnode = None
typ = node['reftype']
@@ -108,9 +109,9 @@ class ReferencesResolver(SphinxPostTransform):
else:
newnodes = [contnode]
if newnode is None and isinstance(node[0], addnodes.pending_xref_condition):
- matched = find_pending_xref_condition(node, "*")
+ matched = self.find_pending_xref_condition(node, ("*",))
if matched:
- newnodes = matched.children
+ newnodes = matched
else:
logger.warning(__('Could not determine the fallback text for the '
'cross-reference. Might be a bug.'), location=node)
@@ -193,6 +194,15 @@ class ReferencesResolver(SphinxPostTransform):
msg = __('%r reference target not found: %s') % (typ, target)
logger.warning(msg, location=node, type='ref', subtype=typ)
+ def find_pending_xref_condition(self, node: pending_xref, conditions: Sequence[str]
+ ) -> Optional[List[Node]]:
+ for condition in conditions:
+ matched = find_pending_xref_condition(node, condition)
+ if matched:
+ return matched.children
+ else:
+ return None
+
class OnlyNodeTransform(SphinxPostTransform):
default_priority = 50
diff --git a/tests/roots/test-transforms-post_transforms-missing-reference/conf.py b/tests/roots/test-transforms-post_transforms-missing-reference/conf.py
new file mode 100644
index 000000000..2db221cc6
--- /dev/null
+++ b/tests/roots/test-transforms-post_transforms-missing-reference/conf.py
@@ -0,0 +1 @@
+nitpicky = True
diff --git a/tests/roots/test-transforms-post_transforms-missing-reference/index.rst b/tests/roots/test-transforms-post_transforms-missing-reference/index.rst
new file mode 100644
index 000000000..7180978b2
--- /dev/null
+++ b/tests/roots/test-transforms-post_transforms-missing-reference/index.rst
@@ -0,0 +1,5 @@
+transforms-post_transforms-missing-reference
+============================================
+
+:class:`io.StringIO`
+
diff --git a/tests/test_transforms_post_transforms.py b/tests/test_transforms_post_transforms.py
new file mode 100644
index 000000000..26af55031
--- /dev/null
+++ b/tests/test_transforms_post_transforms.py
@@ -0,0 +1,58 @@
+"""
+ test_transforms_post_transforms
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ Tests the post_transforms
+
+ :copyright: Copyright 2007-2021 by the Sphinx team, see AUTHORS.
+ :license: BSD, see LICENSE for details.
+"""
+
+import pytest
+from docutils import nodes
+
+
+@pytest.mark.sphinx('html', testroot='transforms-post_transforms-missing-reference')
+def test_nitpicky_warning(app, status, warning):
+ app.build()
+ assert ('index.rst:4: WARNING: py:class reference target '
+ 'not found: io.StringIO' in warning.getvalue())
+
+ content = (app.outdir / 'index.html').read_text()
+ assert ('<p><code class="xref py py-class docutils literal notranslate"><span class="pre">'
+ 'io.StringIO</span></code></p>' in content)
+
+
+@pytest.mark.sphinx('html', testroot='transforms-post_transforms-missing-reference',
+ freshenv=True)
+def test_missing_reference(app, status, warning):
+ def missing_reference(app, env, node, contnode):
+ assert app is app
+ assert env is app.env
+ assert node['reftarget'] == 'io.StringIO'
+ assert contnode.astext() == 'io.StringIO'
+
+ return nodes.inline('', 'missing-reference.StringIO')
+
+ warning.truncate(0)
+ app.connect('missing-reference', missing_reference)
+ app.build()
+ assert warning.getvalue() == ''
+
+ content = (app.outdir / 'index.html').read_text()
+ assert '<p><span>missing-reference.StringIO</span></p>' in content
+
+
+@pytest.mark.sphinx('html', testroot='domain-py-python_use_unqualified_type_names',
+ freshenv=True)
+def test_missing_reference_conditional_pending_xref(app, status, warning):
+ def missing_reference(app, env, node, contnode):
+ return contnode
+
+ warning.truncate(0)
+ app.connect('missing-reference', missing_reference)
+ app.build()
+ assert warning.getvalue() == ''
+
+ content = (app.outdir / 'index.html').read_text()
+ assert '<span class="n"><span class="pre">Age</span></span>' in content