Skip to content

Commit

Permalink
Use node.findall if available (docutils 18.x) (#403)
Browse files Browse the repository at this point in the history
* use node.findall if available (docutils 18.x)

* fix test_reference

* keep test_reference backwards-compatible

* Add comments about when triage becomes unnecessary/obsolete

Co-authored-by: Jarrod Millman <jarrod.millman@gmail.com>

* whitespace

* fix docutils version as noted in docstring

Co-authored-by: Jarrod Millman <jarrod.millman@gmail.com>
Co-authored-by: Eric Larson <larson.eric.d@gmail.com>
  • Loading branch information
3 people committed Jun 2, 2022
1 parent 85a4327 commit 601642b
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 7 deletions.
29 changes: 23 additions & 6 deletions numpydoc/numpydoc.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,19 @@
HASH_LEN = 12


def _traverse_or_findall(node, condition, **kwargs):
"""Triage node.traverse (docutils <0.18.1) vs node.findall.
TODO: This check can be removed when the minimum supported docutils version
for numpydoc is docutils>=0.18.1
"""
return (
node.findall(condition, **kwargs)
if hasattr(node, "findall")
else node.traverse(condition, **kwargs)
)


def rename_references(app, what, name, obj, options, lines):
# decorate reference numbers so that there are no duplicates
# these are later undecorated in the doctree, in relabel_references
Expand Down Expand Up @@ -81,8 +94,12 @@ def is_docstring_section(node):
return False

sibling_sections = itertools.chain(
section_node.traverse(
is_docstring_section, include_self=True, descend=False, siblings=True
_traverse_or_findall(
section_node,
is_docstring_section,
include_self=True,
descend=False,
siblings=True,
)
)
for sibling_section in sibling_sections:
Expand All @@ -101,7 +118,7 @@ def is_docstring_section(node):

def relabel_references(app, doc):
# Change 'hash-ref' to 'ref' in label text
for citation_node in doc.traverse(citation):
for citation_node in _traverse_or_findall(doc, citation):
if not _is_cite_in_numpydoc_docstring(citation_node):
continue
label_node = citation_node[0]
Expand All @@ -121,18 +138,18 @@ def matching_pending_xref(node):
and node[0].astext() == f"[{ref_text}]"
)

for xref_node in ref.parent.traverse(matching_pending_xref):
for xref_node in _traverse_or_findall(ref.parent, matching_pending_xref):
xref_node.replace(xref_node[0], Text(f"[{new_text}]"))
ref.replace(ref_text, new_text.copy())


def clean_backrefs(app, doc, docname):
# only::latex directive has resulted in citation backrefs without reference
known_ref_ids = set()
for ref in doc.traverse(reference, descend=True):
for ref in _traverse_or_findall(doc, reference, descend=True):
for id_ in ref["ids"]:
known_ref_ids.add(id_)
for citation_node in doc.traverse(citation, descend=True):
for citation_node in _traverse_or_findall(doc, citation, descend=True):
# remove backrefs to non-existent refs
citation_node["backrefs"] = [
id_ for id_ in citation_node["backrefs"] if id_ in known_ref_ids
Expand Down
11 changes: 10 additions & 1 deletion numpydoc/tests/test_full.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import os.path as op
import re
import shutil
from packaging import version

import pytest
import sphinx
from sphinx.application import Sphinx
from sphinx.util.docutils import docutils_namespace
from docutils import __version__ as docutils_version


# Test framework adapted from sphinx-gallery (BSD 3-clause)
Expand Down Expand Up @@ -89,7 +91,14 @@ def test_reference(sphinx_app, html_file, expected_length):
with open(op.join(out_dir, *html_file)) as fid:
html = fid.read()

reference_list = re.findall(r'<a class="fn-backref" href="\#id\d+">(.*)<\/a>', html)
# TODO: This check can be removed when the minimum supported docutils version
# for numpydoc is docutils>=0.18
pattern = (
'role="doc-backlink"'
if version.parse(docutils_version) >= version.parse("0.18")
else 'class="fn-backref"'
)
reference_list = re.findall(rf'<a {pattern} href="\#id\d+">(.*)<\/a>', html)

assert len(reference_list) == expected_length
for ref in reference_list:
Expand Down

0 comments on commit 601642b

Please sign in to comment.