mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
Fix #9240: Unknown node error for pending_xref_condition is raised
Unknown node error for pending_xref_condition is raised if an extension that does not support the node installs a missing-reference handler.
This commit is contained in:
parent
630e5bd15f
commit
2d3d668856
2
CHANGES
2
CHANGES
@ -10,6 +10,8 @@ Incompatible changes
|
|||||||
* #9222: Update Underscore.js to 1.13.1
|
* #9222: Update Underscore.js to 1.13.1
|
||||||
* #9217: manpage: Stop creating a section directory on build manpage by default
|
* #9217: manpage: Stop creating a section directory on build manpage by default
|
||||||
(see :confval:`man_make_section_directory`)
|
(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
|
Deprecated
|
||||||
----------
|
----------
|
||||||
|
@ -8,10 +8,10 @@
|
|||||||
:license: BSD, see LICENSE for details.
|
: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 import nodes
|
||||||
from docutils.nodes import Element
|
from docutils.nodes import Element, Node
|
||||||
|
|
||||||
from sphinx import addnodes
|
from sphinx import addnodes
|
||||||
from sphinx.addnodes import pending_xref
|
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__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
if False:
|
|
||||||
# For type annotation
|
|
||||||
from docutils.nodes import Node
|
|
||||||
|
|
||||||
|
|
||||||
class SphinxPostTransform(SphinxTransform):
|
class SphinxPostTransform(SphinxTransform):
|
||||||
"""A base class of post-transforms.
|
"""A base class of post-transforms.
|
||||||
@ -71,7 +67,12 @@ class ReferencesResolver(SphinxPostTransform):
|
|||||||
|
|
||||||
def run(self, **kwargs: Any) -> None:
|
def run(self, **kwargs: Any) -> None:
|
||||||
for node in self.document.traverse(addnodes.pending_xref):
|
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
|
newnode = None
|
||||||
|
|
||||||
typ = node['reftype']
|
typ = node['reftype']
|
||||||
@ -108,9 +109,9 @@ class ReferencesResolver(SphinxPostTransform):
|
|||||||
else:
|
else:
|
||||||
newnodes = [contnode]
|
newnodes = [contnode]
|
||||||
if newnode is None and isinstance(node[0], addnodes.pending_xref_condition):
|
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:
|
if matched:
|
||||||
newnodes = matched.children
|
newnodes = matched
|
||||||
else:
|
else:
|
||||||
logger.warning(__('Could not determine the fallback text for the '
|
logger.warning(__('Could not determine the fallback text for the '
|
||||||
'cross-reference. Might be a bug.'), location=node)
|
'cross-reference. Might be a bug.'), location=node)
|
||||||
@ -193,6 +194,15 @@ class ReferencesResolver(SphinxPostTransform):
|
|||||||
msg = __('%r reference target not found: %s') % (typ, target)
|
msg = __('%r reference target not found: %s') % (typ, target)
|
||||||
logger.warning(msg, location=node, type='ref', subtype=typ)
|
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):
|
class OnlyNodeTransform(SphinxPostTransform):
|
||||||
default_priority = 50
|
default_priority = 50
|
||||||
|
@ -0,0 +1 @@
|
|||||||
|
nitpicky = True
|
@ -0,0 +1,5 @@
|
|||||||
|
transforms-post_transforms-missing-reference
|
||||||
|
============================================
|
||||||
|
|
||||||
|
:class:`io.StringIO`
|
||||||
|
|
58
tests/test_transforms_post_transforms.py
Normal file
58
tests/test_transforms_post_transforms.py
Normal file
@ -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
|
Loading…
Reference in New Issue
Block a user