From ed97c6e2b560248b0d1f79f8aa5c8d34dee76ec5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edgar=20Ram=C3=ADrez=20Mondrag=C3=B3n?= Date: Wed, 15 Apr 2026 18:54:30 -0600 Subject: [PATCH 1/2] Fix tests for Python 3.15.0a5+ MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Edgar Ramírez Mondragón --- CHANGES.rst | 6 ++++++ tests/conftest.py | 11 +++++++++-- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 6f7279e8011..999c49f4944 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,3 +1,9 @@ +NEXT +==== + +* Fix tests for Python 3.15.0a5+ + Patch by Edgar Ramírez-Mondragón + Release 9.1.0 (released Dec 31, 2025) ===================================== diff --git a/tests/conftest.py b/tests/conftest.py index b884f132f79..2a91eedb33a 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -27,13 +27,20 @@ def _init_console( locale_dir: str | os.PathLike[str] | None = sphinx.locale._LOCALE_DIR, catalog: str = 'sphinx', ) -> tuple[gettext.NullTranslations, bool]: - """Monkeypatch ``init_console`` to skip its action. + """Monkeypatch ``init_console`` to skip locale loading. Some tests rely on warning messages in English. We don't want CLI tests to bleed over those tests and make their warnings translated. + + We still register a NullTranslations so that ``__()`` (the console + translation function) returns a plain ``str`` rather than a lazy + ``_TranslationProxy``. NullTranslations passes every message through + unchanged, so all strings stay in English. """ - return gettext.NullTranslations(), False + null = gettext.NullTranslations() + sphinx.locale.translators['console', catalog] = null + return null, False sphinx.locale.init_console = _init_console From b8281424c3feb637f597766517ffb793b596a050 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edgar=20Ram=C3=ADrez=20Mondrag=C3=B3n?= Date: Wed, 15 Apr 2026 19:28:41 -0600 Subject: [PATCH 2/2] Strip escape sequences coming from `http.server.BaseHTTPRequestHandler.log_message` MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Edgar Ramírez Mondragón --- tests/test_builders/test_build_linkcheck.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/test_builders/test_build_linkcheck.py b/tests/test_builders/test_build_linkcheck.py index 7b036ec4506..b54cc97268b 100644 --- a/tests/test_builders/test_build_linkcheck.py +++ b/tests/test_builders/test_build_linkcheck.py @@ -720,7 +720,7 @@ def test_follows_redirects_on_HEAD( 'index.rst:1: [redirected with Found] ' f'http://{address}/ to http://{address}/?redirected=1\n' ) - assert stderr == textwrap.dedent( + assert strip_escape_sequences(stderr) == textwrap.dedent( """\ 127.0.0.1 - - [] "HEAD / HTTP/1.1" 302 - 127.0.0.1 - - [] "HEAD /?redirected=1 HTTP/1.1" 204 - @@ -749,7 +749,7 @@ def test_follows_redirects_on_GET( 'index.rst:1: [redirected with Found] ' f'http://{address}/ to http://{address}/?redirected=1\n' ) - assert stderr == textwrap.dedent( + assert strip_escape_sequences(stderr) == textwrap.dedent( """\ 127.0.0.1 - - [] "HEAD / HTTP/1.1" 405 - 127.0.0.1 - - [] "GET / HTTP/1.1" 302 - @@ -780,7 +780,7 @@ def test_warns_disallowed_redirects( 'index.rst:1: [redirected with Found] ' f'http://{address}/ to http://{address}/?redirected=1\n' ) - assert stderr == textwrap.dedent( + assert strip_escape_sequences(stderr) == textwrap.dedent( """\ 127.0.0.1 - - [] "HEAD / HTTP/1.1" 302 - 127.0.0.1 - - [] "HEAD /?redirected=1 HTTP/1.1" 204 - @@ -1136,7 +1136,7 @@ def test_too_many_requests_retry_after_int_delay( rate_limit_log = f'-rate limited- http://{address}/ | sleeping...\n' assert rate_limit_log in strip_escape_sequences(app.status.getvalue()) _stdout, stderr = capsys.readouterr() - assert stderr == textwrap.dedent( + assert strip_escape_sequences(stderr) == textwrap.dedent( """\ 127.0.0.1 - - [] "HEAD / HTTP/1.1" 429 - 127.0.0.1 - - [] "HEAD / HTTP/1.1" 200 - @@ -1188,7 +1188,7 @@ def test_too_many_requests_retry_after_HTTP_date( 'info': '', } _stdout, stderr = capsys.readouterr() - assert stderr == textwrap.dedent( + assert strip_escape_sequences(stderr) == textwrap.dedent( """\ 127.0.0.1 - - [] "HEAD / HTTP/1.1" 429 - 127.0.0.1 - - [] "HEAD / HTTP/1.1" 200 - @@ -1221,7 +1221,7 @@ def test_too_many_requests_retry_after_without_header( 'info': '', } _stdout, stderr = capsys.readouterr() - assert stderr == textwrap.dedent( + assert strip_escape_sequences(stderr) == textwrap.dedent( """\ 127.0.0.1 - - [] "HEAD / HTTP/1.1" 429 - 127.0.0.1 - - [] "HEAD / HTTP/1.1" 200 -