Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 5813302

Browse files
committed
fix: don't unlink roles that are explicit references
1 parent f4b5d52 commit 5813302

4 files changed

Lines changed: 65 additions & 0 deletions

File tree

README.rst

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,14 @@ hard-code the decisions.
6767
Changes
6868
=======
6969

70+
Unreleased
71+
----------
72+
73+
A number of roles (``:ref:``, ``:doc:`` and others) were being unlinked when
74+
they seemed excessive, but shouldn't have been. They are explicit references to
75+
other parts of the documentation, so should never be removed. This is now
76+
fixed.
77+
7078
v0.3.1 (2026-03-01)
7179
-------------------
7280

src/linklint/linklint.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,9 @@ def decorator(func):
9696
),
9797
]
9898

99+
# Sphinx roles that are explicit references elsewhere and should always be links.
100+
ALWAYS_REF = {"doc", "download", "numref", "ref"}
101+
99102

100103
@check("self")
101104
def check_self_links(work: LintWork) -> Iterable[LintIssue]:
@@ -135,6 +138,11 @@ def __init__(self, doctree: nodes.document) -> None:
135138
def visit_pending_xref(self, node: addnodes.pending_xref) -> None:
136139
line = node_line_number(node)
137140
reftype = node.get("reftype")
141+
if reftype in ALWAYS_REF:
142+
# :ref: references are explicitly meant to be links, so should
143+
# never be unlinked. I don't know why someone would put a :ref:
144+
# to its own section, but who are we to judge?
145+
return
138146
target = node.get("reftarget")
139147

140148
if reftype == "meth" and "." not in target:
@@ -199,6 +207,10 @@ def find_duplicate_refs(doctree: nodes.document) -> Iterable[nodes.Node]:
199207
refs_by_target = defaultdict(list)
200208
for ref in para.findall(addnodes.pending_xref):
201209
reftype = ref.get("reftype")
210+
if reftype in ALWAYS_REF:
211+
# :ref: references are explicitly meant to be links, so should
212+
# never be unlinked.
213+
continue
202214
target = ref.get("reftarget")
203215
assert reftype and target, (
204216
f"Reference missing reftype or target: {ref}\n{node_traceback(ref)}"

tests/data/ref_references.rst

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
Some docs
2+
=========
3+
4+
You can specify a :ref:`static context <contexts>` for a coverage run with
5+
``--context``. This can be any label you want, and will be recorded with the
6+
data. See :ref:`contexts` for more information.
7+
8+
.. _contexts:
9+
10+
Measurement contexts
11+
--------------------
12+
13+
They are important! This section is :ref:`contexts`.
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<section id="some-docs">
2+
<h1>
3+
Some docs
4+
</h1>
5+
<p>
6+
You can specify a
7+
<a href="#contexts">
8+
static context
9+
</a>
10+
for a coverage run with
11+
<code>
12+
--context
13+
</code>
14+
. This can be any label you want, and will be recorded with the data. See
15+
<a href="#contexts">
16+
Measurement contexts
17+
</a>
18+
for more information.
19+
</p>
20+
<section id="measurement-contexts">
21+
<h2>
22+
Measurement contexts
23+
</h2>
24+
<p>
25+
They are important! This section is
26+
<a href="#contexts">
27+
Measurement contexts
28+
</a>
29+
.
30+
</p>
31+
</section>
32+
</section>

0 commit comments

Comments
 (0)