mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
linkcheck: Update configuration defaults for Sphinx 8.0 (#12630)
- Links that respond with HTTP 401 (unauthorized) responses are now considered ``broken`` by default. - Timeouts that occur when checking a link are now reported with a distinct `timeout` status code, instead of the previous ``broken``. - The previous behaviours are still available and can be configured on an opt-in basis per-project using ``conf.py``. Co-authored-by: Adam Turner <9087854+aa-turner@users.noreply.github.com>
This commit is contained in:
@@ -51,6 +51,12 @@ Incompatible changes
|
||||
Patch by Adam Turner.
|
||||
* Removed the tuple interface to :py:class:`!sphinx.ext.autodoc.ObjectMember`.
|
||||
Patch by Adam Turner.
|
||||
* #12630: Sphinx 8 makes two changes to the ``linkcheck`` configuration defaults:
|
||||
|
||||
* :confval:`linkcheck_allow_unauthorized` is now ``False`` by default.
|
||||
* :confval:`linkcheck_report_timeouts_as_broken` is now ``False`` by default.
|
||||
|
||||
Patch by James Addison.
|
||||
|
||||
Deprecated
|
||||
----------
|
||||
|
||||
@@ -3714,20 +3714,17 @@ and the number of workers to use.
|
||||
|
||||
.. confval:: linkcheck_allow_unauthorized
|
||||
:type: :code-py:`bool`
|
||||
:default: :code-py:`True`
|
||||
:default: :code-py:`False`
|
||||
|
||||
When a webserver responds with an HTTP 401 (unauthorised) response,
|
||||
the current default behaviour of the *linkcheck* builder is
|
||||
to treat the link as "working".
|
||||
To change that behaviour, set this option to :code-py:`False`.
|
||||
to treat the link as "broken".
|
||||
To change that behaviour, set this option to :code-py:`True`.
|
||||
|
||||
.. attention::
|
||||
The default value for this option will be changed in Sphinx 8.0;
|
||||
from that version onwards,
|
||||
HTTP 401 responses to checked hyperlinks will be treated
|
||||
as "broken" by default.
|
||||
|
||||
.. xref RemovedInSphinx80Warning
|
||||
.. versionchanged:: 8.0
|
||||
The default value for this option changed to :code-py:`False`,
|
||||
meaning HTTP 401 responses to checked hyperlinks
|
||||
are treated as "broken" by default.
|
||||
|
||||
.. versionadded:: 7.3
|
||||
|
||||
@@ -3755,21 +3752,18 @@ and the number of workers to use.
|
||||
|
||||
.. confval:: linkcheck_report_timeouts_as_broken
|
||||
:type: :code-py:`bool`
|
||||
:default: :code-py:`True`
|
||||
:default: :code-py:`False`
|
||||
|
||||
When an HTTP response is not received from a webserver before the configured
|
||||
:confval:`linkcheck_timeout` expires,
|
||||
the current default behaviour of the *linkcheck* builder is
|
||||
to treat the link as 'broken'.
|
||||
To report timeouts using a distinct report code of ``timeout``,
|
||||
set :confval:`linkcheck_report_timeouts_as_broken` to :code-py:`False`.
|
||||
If :confval:`linkcheck_timeout` expires while waiting for a response from
|
||||
a hyperlink, the *linkcheck* builder will report the link as a ``timeout``
|
||||
by default. To report timeouts as ``broken`` instead, you can
|
||||
set :confval:`linkcheck_report_timeouts_as_broken` to :code-py:`True`.
|
||||
|
||||
.. attention::
|
||||
From Sphinx 8.0 onwards, timeouts that occur while checking hyperlinks
|
||||
.. versionchanged:: 8.0
|
||||
The default value for this option changed to :code-py:`False`,
|
||||
meaning timeouts that occur while checking hyperlinks
|
||||
will be reported using the new 'timeout' status code.
|
||||
|
||||
.. xref RemovedInSphinx80Warning
|
||||
|
||||
.. versionadded:: 7.3
|
||||
|
||||
.. confval:: linkcheck_request_headers
|
||||
|
||||
@@ -7,7 +7,6 @@ import json
|
||||
import re
|
||||
import socket
|
||||
import time
|
||||
import warnings
|
||||
from html.parser import HTMLParser
|
||||
from os import path
|
||||
from queue import PriorityQueue, Queue
|
||||
@@ -20,7 +19,6 @@ from requests.exceptions import ConnectionError, HTTPError, SSLError, TooManyRed
|
||||
from requests.exceptions import Timeout as RequestTimeout
|
||||
|
||||
from sphinx.builders.dummy import DummyBuilder
|
||||
from sphinx.deprecation import RemovedInSphinx80Warning
|
||||
from sphinx.locale import __
|
||||
from sphinx.transforms.post_transforms import SphinxPostTransform
|
||||
from sphinx.util import encode_uri, logging, requests
|
||||
@@ -66,25 +64,6 @@ class CheckExternalLinksBuilder(DummyBuilder):
|
||||
# set a timeout for non-responding servers
|
||||
socket.setdefaulttimeout(5.0)
|
||||
|
||||
if not self.config.linkcheck_allow_unauthorized:
|
||||
deprecation_msg = (
|
||||
"The default value for 'linkcheck_allow_unauthorized' will change "
|
||||
"from `True` in Sphinx 7.3+ to `False`, meaning that HTTP 401 "
|
||||
"unauthorized responses will be reported as broken by default. "
|
||||
"See https://github.com/sphinx-doc/sphinx/issues/11433 for details."
|
||||
)
|
||||
warnings.warn(deprecation_msg, RemovedInSphinx80Warning, stacklevel=1)
|
||||
|
||||
if self.config.linkcheck_report_timeouts_as_broken:
|
||||
deprecation_msg = (
|
||||
"The default value for 'linkcheck_report_timeouts_as_broken' will change "
|
||||
'to False in Sphinx 8, meaning that request timeouts '
|
||||
"will be reported with a new 'timeout' status, instead of as 'broken'. "
|
||||
'This is intended to provide more detail as to the failure mode. '
|
||||
'See https://github.com/sphinx-doc/sphinx/issues/11868 for details.'
|
||||
)
|
||||
warnings.warn(deprecation_msg, RemovedInSphinx80Warning, stacklevel=1)
|
||||
|
||||
def finish(self) -> None:
|
||||
checker = HyperlinkAvailabilityChecker(self.config)
|
||||
logger.info('')
|
||||
@@ -510,27 +489,6 @@ class HyperlinkAvailabilityCheckWorker(Thread):
|
||||
|
||||
# Unauthorized: the client did not provide required credentials
|
||||
if status_code == 401:
|
||||
if self._allow_unauthorized:
|
||||
deprecation_msg = (
|
||||
"\n---\n"
|
||||
"The linkcheck builder encountered an HTTP 401 "
|
||||
"(unauthorized) response, and will report it as "
|
||||
"'working' in this version of Sphinx to maintain "
|
||||
"backwards-compatibility."
|
||||
"\n"
|
||||
"This logic will change in Sphinx 8.0 which will "
|
||||
"report the hyperlink as 'broken'."
|
||||
"\n"
|
||||
"To explicitly continue treating unauthorized "
|
||||
"hyperlink responses as 'working', set the "
|
||||
"'linkcheck_allow_unauthorized' config option to "
|
||||
"``True``."
|
||||
"\n"
|
||||
"See https://github.com/sphinx-doc/sphinx/issues/11433 "
|
||||
"for details."
|
||||
"\n---"
|
||||
)
|
||||
warnings.warn(deprecation_msg, RemovedInSphinx80Warning, stacklevel=1)
|
||||
status = 'working' if self._allow_unauthorized else 'broken'
|
||||
return status, 'unauthorized', 0
|
||||
|
||||
@@ -717,8 +675,8 @@ def setup(app: Sphinx) -> ExtensionMetadata:
|
||||
app.add_config_value('linkcheck_anchors_ignore', ['^!'], '')
|
||||
app.add_config_value('linkcheck_anchors_ignore_for_url', (), '', (tuple, list))
|
||||
app.add_config_value('linkcheck_rate_limit_timeout', 300.0, '', (int, float))
|
||||
app.add_config_value('linkcheck_allow_unauthorized', True, '')
|
||||
app.add_config_value('linkcheck_report_timeouts_as_broken', True, '', bool)
|
||||
app.add_config_value('linkcheck_allow_unauthorized', False, '')
|
||||
app.add_config_value('linkcheck_report_timeouts_as_broken', False, '', bool)
|
||||
|
||||
app.add_event('linkcheck-process-uri')
|
||||
|
||||
|
||||
@@ -27,7 +27,6 @@ from sphinx.builders.linkcheck import (
|
||||
RateLimit,
|
||||
compile_linkcheck_allowed_redirects,
|
||||
)
|
||||
from sphinx.deprecation import RemovedInSphinx80Warning
|
||||
from sphinx.util import requests
|
||||
from sphinx.util.console import strip_colors
|
||||
|
||||
@@ -503,7 +502,6 @@ def test_auth_header_uses_first_match(app: Sphinx) -> None:
|
||||
assert content["status"] == "working"
|
||||
|
||||
|
||||
@pytest.mark.filterwarnings('ignore::sphinx.deprecation.RemovedInSphinx80Warning')
|
||||
@pytest.mark.sphinx(
|
||||
'linkcheck', testroot='linkcheck-localserver', freshenv=True,
|
||||
confoverrides={'linkcheck_allow_unauthorized': False})
|
||||
@@ -522,18 +520,14 @@ def test_unauthorized_broken(app: Sphinx) -> None:
|
||||
'linkcheck', testroot='linkcheck-localserver', freshenv=True,
|
||||
confoverrides={'linkcheck_auth': [(r'^$', ('user1', 'password'))]})
|
||||
def test_auth_header_no_match(app: Sphinx) -> None:
|
||||
with (
|
||||
serve_application(app, custom_handler(valid_credentials=("user1", "password"))),
|
||||
pytest.warns(RemovedInSphinx80Warning, match='linkcheck builder encountered an HTTP 401'),
|
||||
):
|
||||
with serve_application(app, custom_handler(valid_credentials=("user1", "password"))):
|
||||
app.build()
|
||||
|
||||
with open(app.outdir / "output.json", encoding="utf-8") as fp:
|
||||
content = json.load(fp)
|
||||
|
||||
# This link is considered working based on the default linkcheck_allow_unauthorized=true
|
||||
assert content["info"] == "unauthorized"
|
||||
assert content["status"] == "working"
|
||||
assert content["status"] == "broken"
|
||||
|
||||
|
||||
@pytest.mark.sphinx('linkcheck', testroot='linkcheck-localserver', freshenv=True)
|
||||
|
||||
Reference in New Issue
Block a user