Skip to content

linkcheck: replace 'linkcheck_allowed_redirects' default sentinel with boolean false value #13483

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 13 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ Features added
Patch by Till Hoffmann.
* #13439: linkcheck: Permit warning on every redirect with
``linkcheck_allowed_redirects = {}``.
Patch by Adam Turner.
Patch by Adam Turner and James Addison.
* #13497: Support C domain objects in the table of contents.
* #13500: LaTeX: add support for ``fontawesome6`` package.
Patch by Jean-François B.
Expand Down
10 changes: 3 additions & 7 deletions sphinx/builders/linkcheck.py
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ def process_result(self, result: CheckResult) -> None:
text = 'with unknown code'
linkstat['text'] = text
redirection = f'{text} to {result.message}'
if self.config.linkcheck_allowed_redirects is not None:
if self.config.linkcheck_allowed_redirects is not False:
msg = f'redirect {res_uri} - {redirection}'
logger.warning(msg, location=(result.docname, result.lineno))
else:
Expand Down Expand Up @@ -750,8 +750,7 @@ def rewrite_github_anchor(app: Sphinx, uri: str) -> str | None:

def compile_linkcheck_allowed_redirects(app: Sphinx, config: Config) -> None:
"""Compile patterns to the regexp objects."""
if config.linkcheck_allowed_redirects is _sentinel_lar:
config.linkcheck_allowed_redirects = None
if config.linkcheck_allowed_redirects is False:
return
if not isinstance(config.linkcheck_allowed_redirects, dict):
msg = __(
Expand All @@ -772,9 +771,6 @@ def compile_linkcheck_allowed_redirects(app: Sphinx, config: Config) -> None:
config.linkcheck_allowed_redirects = allowed_redirects


_sentinel_lar = object()


def setup(app: Sphinx) -> ExtensionMetadata:
app.add_builder(CheckExternalLinksBuilder)
app.add_post_transform(HyperlinkCollector)
Expand All @@ -784,7 +780,7 @@ def setup(app: Sphinx) -> ExtensionMetadata:
'linkcheck_exclude_documents', [], '', types=frozenset({list, tuple})
)
app.add_config_value(
'linkcheck_allowed_redirects', _sentinel_lar, '', types=frozenset({dict})
'linkcheck_allowed_redirects', False, '', types=frozenset({dict})
)
app.add_config_value('linkcheck_auth', [], '', types=frozenset({list, tuple}))
app.add_config_value('linkcheck_request_headers', {}, '', types=frozenset({dict}))
Expand Down
35 changes: 34 additions & 1 deletion tests/test_builders/test_build_linkcheck.py
Original file line number Diff line number Diff line change
Expand Up @@ -680,7 +680,7 @@ def check_headers(self):
assert content['status'] == 'working'


def make_redirect_handler(*, support_head: bool) -> type[BaseHTTPRequestHandler]:
def make_redirect_handler(*, support_head: bool = True) -> type[BaseHTTPRequestHandler]:
class RedirectOnceHandler(BaseHTTPRequestHandler):
protocol_version = 'HTTP/1.1'

Expand Down Expand Up @@ -715,6 +715,7 @@ def log_date_time_string(self):
)
def test_follows_redirects_on_HEAD(app, capsys):
with serve_application(app, make_redirect_handler(support_head=True)) as address:
compile_linkcheck_allowed_redirects(app, app.config)
app.build()
_stdout, stderr = capsys.readouterr()
content = (app.outdir / 'output.txt').read_text(encoding='utf8')
Expand All @@ -728,6 +729,9 @@ def test_follows_redirects_on_HEAD(app, capsys):
127.0.0.1 - - [] "HEAD /?redirected=1 HTTP/1.1" 204 -
""",
)
assert (
f'redirect http://{address}/ - with Found to http://{address}/?redirected=1\n'
) in strip_escape_sequences(app.status.getvalue())
assert app.warning.getvalue() == ''


Expand All @@ -738,6 +742,7 @@ def test_follows_redirects_on_HEAD(app, capsys):
)
def test_follows_redirects_on_GET(app, capsys):
with serve_application(app, make_redirect_handler(support_head=False)) as address:
compile_linkcheck_allowed_redirects(app, app.config)
app.build()
_stdout, stderr = capsys.readouterr()
content = (app.outdir / 'output.txt').read_text(encoding='utf8')
Expand All @@ -752,9 +757,37 @@ def test_follows_redirects_on_GET(app, capsys):
127.0.0.1 - - [] "GET /?redirected=1 HTTP/1.1" 204 -
""",
)
assert (
f'redirect http://{address}/ - with Found to http://{address}/?redirected=1\n'
) in strip_escape_sequences(app.status.getvalue())
assert app.warning.getvalue() == ''


@pytest.mark.sphinx(
'linkcheck',
testroot='linkcheck-localserver',
freshenv=True,
confoverrides={'linkcheck_allowed_redirects': {}}, # warn about any redirects
)
def test_warns_disallowed_redirects(app, capsys):
with serve_application(app, make_redirect_handler()) as address:
compile_linkcheck_allowed_redirects(app, app.config)
app.build()
_stdout, stderr = capsys.readouterr()
content = (app.outdir / 'output.txt').read_text(encoding='utf8')
assert content == (
'index.rst:1: [redirected with Found] '
f'http://{address}/ to http://{address}/?redirected=1\n'
)
assert stderr == textwrap.dedent(
"""\
127.0.0.1 - - [] "HEAD / HTTP/1.1" 302 -
127.0.0.1 - - [] "HEAD /?redirected=1 HTTP/1.1" 204 -
""",
)
assert len(app.warning.getvalue().splitlines()) == 1


def test_linkcheck_allowed_redirects_config(
make_app: Callable[..., SphinxTestApp], tmp_path: Path
) -> None:
Expand Down
Loading