diff --git a/CHANGES b/CHANGES index 443ef7d6865..a62c6e00f49 100644 --- a/CHANGES +++ b/CHANGES @@ -16,6 +16,10 @@ Features added Bugs fixed ---------- +* #11542: linkcheck: Properly respect :confval:`linkcheck_anchors` + and do not spuriously report failures to validate anchors. + Patch by James Addison. + Testing ------- diff --git a/sphinx/builders/linkcheck.py b/sphinx/builders/linkcheck.py index 1b7b56eeea3..81b1e145f8e 100644 --- a/sphinx/builders/linkcheck.py +++ b/sphinx/builders/linkcheck.py @@ -406,7 +406,8 @@ def _check_uri(self, uri: str, hyperlink: Hyperlink) -> tuple[str, str, int]: _user_agent=self.user_agent, _tls_info=(self.tls_verify, self.tls_cacerts), ) as response: - if response.ok and anchor and not contains_anchor(response, anchor): + if (self.check_anchors and response.ok and anchor + and not contains_anchor(response, anchor)): raise Exception(__(f'Anchor {anchor!r} not found')) # Copy data we need from the (closed) response diff --git a/tests/test_build_linkcheck.py b/tests/test_build_linkcheck.py index 42e4e03521b..04b09314044 100644 --- a/tests/test_build_linkcheck.py +++ b/tests/test_build_linkcheck.py @@ -152,6 +152,7 @@ def test_defaults(app): } # looking for '#top' and '#does-not-exist' not found should fail assert rowsby["http://localhost:7777/#top"]["info"] == "Anchor 'top' not found" + assert rowsby["http://localhost:7777/#top"]["status"] == "broken" assert rowsby["http://localhost:7777#does-not-exist"]["info"] == "Anchor 'does-not-exist' not found" # images should fail assert "Not Found for url: http://localhost:7777/image.png" in rowsby["http://localhost:7777/image.png"]["info"] @@ -166,6 +167,22 @@ def test_defaults(app): } +@pytest.mark.sphinx( + 'linkcheck', testroot='linkcheck', freshenv=True, + confoverrides={'linkcheck_anchors': False}) +def test_check_link_response_only(app): + with http_server(DefaultsHandler): + app.build() + + # JSON output + assert (app.outdir / 'output.json').exists() + content = (app.outdir / 'output.json').read_text(encoding='utf8') + + rows = [json.loads(x) for x in content.splitlines()] + rowsby = {row["uri"]: row for row in rows} + assert rowsby["http://localhost:7777/#top"]["status"] == "working" + + @pytest.mark.sphinx('linkcheck', testroot='linkcheck-too-many-retries', freshenv=True) def test_too_many_retries(app): with http_server(DefaultsHandler):