linkcheck: strip query/fragment before local-file existence check - #14552
linkcheck: strip query/fragment before local-file existence check#14552Gooh456 wants to merge 2 commits into
Conversation
Local links like target.html?view=full or target.html#section were checked against the filesystem using the raw URI, so the query string or fragment was treated as part of the filename and the check always failed even when the target file exists. Strip any #fragment and ?query suffix before the exists() check. A link that is only a query/fragment (e.g. ?mode=full) now resolves to the current document, matching how bare #fragment links are already handled a few lines above. Fixes sphinx-doc#14542 Signed-off-by: Kyue <164024549+Gooh456@users.noreply.github.com>
|
checked the 3 failing checks, none of them are this diff's fault. ty and Docutils HEAD both fail on master right now too (ty's just pre-existing type debt across the codebase, Docutils HEAD is a network failure cloning the docutils git mirror, never even gets to running anything). LaTeX's two test failures are in test_epub_anchor_id and test_intl's figure caption test, completely unrelated subsystems to a linkcheck query-string fix. 2415 other tests in that job passed. |
|
Closing until the PR description is updated in accordance with the AI policy, which is intended to ensure appropriate human oversight: https://www.sphinx-doc.org/en/master/internals/ai-policy.html |
|
added the disclosure to the description. can't reopen it myself (not a maintainer), mind reopening when you get a chance? |
…ring Per jdillard's review: confirms stripping the query doesn't bypass the underlying file-existence check.
Found this in #14542. linkcheck's local-file check passes the raw URI straight to
.exists(), so a link liketarget.html?view=fullgets checked against a file literally namedtarget.html?view=full. That file never exists, so it's reported broken even whentarget.htmlis right there.Fix is in
sphinx/builders/linkcheck.py,_check(): strip everything from the first#or?onward before the filesystem check. If nothing's left after stripping (a bare?queryor the link is otherwise empty), treat it as pointing at the current document, same as the existing bare-#fragmenthandling a few lines above.Added a small testroot (
tests/roots/test-linkcheck-local-file) with a target file referenced via query string, fragment, and query-only, plus a test that asserts all three come backworking. Confirmed it fails (all threebroken) on the old code and passes with the fix. Fulltest_build_linkcheck.pysuite still passes (49/49).Didn't touch the uppercase-scheme issue mentioned in the same regression report (#14541) — different code path, leaving that for a separate PR.
Fixes #14542
AI disclosure: yes, I used Claude Code (Anthropic) on this. I had it dig into the regression report, locate the bug in
_check(), write the fix, and write the testroot + test case. I reviewed the diff, ran the full linkcheck test suite locally myself, and checked the 3 unrelated CI failures against master before writing the comment about them. So: code and test are AI-generated, drafting/review/verification is me.