[cleanup] deprecate `sphinx.testing.util.strip_escseq in favor of sphinx.util.console.strip_colors` (#12186)

This commit is contained in:
Bénédikt Tran 2024-03-24 00:43:54 +01:00 committed by GitHub
parent 22cee42094
commit f24eef7b6b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 56 additions and 28 deletions

View File

@ -18,6 +18,9 @@ Deprecated
the public properties :attr:`!sphinx.testing.util.SphinxTestApp.status` the public properties :attr:`!sphinx.testing.util.SphinxTestApp.status`
and :attr:`!sphinx.testing.util.SphinxTestApp.warning` instead. and :attr:`!sphinx.testing.util.SphinxTestApp.warning` instead.
Patch by Bénédikt Tran. Patch by Bénédikt Tran.
* tests: :func:`!sphinx.testing.util.strip_escseq` is deprecated in favor of
:func:`!sphinx.util.console.strip_colors`.
Patch by Bénédikt Tran.
Features added Features added
-------------- --------------

View File

@ -22,6 +22,11 @@ The following is a list of deprecated interfaces.
- Removed - Removed
- Alternatives - Alternatives
* - ``sphinx.testing.util.strip_escseq``
- 7.3
- 9.0
- ``sphinx.util.console.strip_colors``
* - Old-style Makefiles in ``sphinx-quickstart`` * - Old-style Makefiles in ``sphinx-quickstart``
and the :option:`!-M`, :option:`!-m`, :option:`!--no-use-make-mode`, and the :option:`!-M`, :option:`!-m`, :option:`!--no-use-make-mode`,
and :option:`!--use-make-mode` options and :option:`!--use-make-mode` options

View File

@ -6,7 +6,6 @@ __all__ = ('SphinxTestApp', 'SphinxTestAppWrapperForSkipBuilding')
import contextlib import contextlib
import os import os
import re
import sys import sys
import warnings import warnings
from io import StringIO from io import StringIO
@ -20,12 +19,13 @@ from docutils.parsers.rst import directives, roles
import sphinx.application import sphinx.application
import sphinx.locale import sphinx.locale
import sphinx.pycode import sphinx.pycode
from sphinx.util.console import strip_colors
from sphinx.util.docutils import additional_nodes from sphinx.util.docutils import additional_nodes
if TYPE_CHECKING: if TYPE_CHECKING:
from collections.abc import Mapping from collections.abc import Mapping
from pathlib import Path from pathlib import Path
from typing import Any from typing import Any, Final
from docutils.nodes import Node from docutils.nodes import Node
@ -224,10 +224,6 @@ class SphinxTestAppWrapperForSkipBuilding:
# otherwise, we can use built cache # otherwise, we can use built cache
def strip_escseq(text: str) -> str:
return re.sub('\x1b.*?m', '', text)
def _clean_up_global_state() -> None: def _clean_up_global_state() -> None:
# clean up Docutils global state # clean up Docutils global state
directives._directives.clear() # type: ignore[attr-defined] directives._directives.clear() # type: ignore[attr-defined]
@ -244,3 +240,20 @@ def _clean_up_global_state() -> None:
# clean up autodoc global state # clean up autodoc global state
sphinx.pycode.ModuleAnalyzer.cache.clear() sphinx.pycode.ModuleAnalyzer.cache.clear()
_DEPRECATED_OBJECTS: Final[dict[str, tuple[object, str, tuple[int, int]]]] = {
'strip_escseq': (strip_colors, 'sphinx.util.console.strip_colors', (9, 0)),
}
def __getattr__(name: str) -> Any:
if name not in _DEPRECATED_OBJECTS:
msg = f'module {__name__!r} has no attribute {name!r}'
raise AttributeError(msg)
from sphinx.deprecation import _deprecation_warning
deprecated_object, canonical_name, remove = _DEPRECATED_OBJECTS[name]
_deprecation_warning(__name__, name, canonical_name, remove=remove)
return deprecated_object

View File

@ -6,6 +6,10 @@ import os
import re import re
import shutil import shutil
import sys import sys
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from typing import Final
try: try:
# check if colorama is installed to support color on Windows # check if colorama is installed to support color on Windows
@ -23,6 +27,8 @@ _ansi_re: re.Pattern[str] = re.compile(
\dK # ANSI Erase in Line \dK # ANSI Erase in Line
)""", )""",
re.VERBOSE | re.ASCII) re.VERBOSE | re.ASCII)
_ansi_color_re: Final[re.Pattern[str]] = re.compile('\x1b.*?m')
codes: dict[str, str] = {} codes: dict[str, str] = {}
@ -93,7 +99,7 @@ def colorize(name: str, text: str, input_mode: bool = False) -> str:
def strip_colors(s: str) -> str: def strip_colors(s: str) -> str:
return re.compile('\x1b.*?m').sub('', s) return _ansi_color_re.sub('', s)
def _strip_escape_sequences(s: str) -> str: def _strip_escape_sequences(s: str) -> str:

View File

@ -13,8 +13,9 @@ from docutils import nodes
import sphinx.application import sphinx.application
from sphinx.errors import ExtensionError from sphinx.errors import ExtensionError
from sphinx.testing.util import SphinxTestApp, strip_escseq from sphinx.testing.util import SphinxTestApp
from sphinx.util import logging from sphinx.util import logging
from sphinx.util.console import strip_colors
if TYPE_CHECKING: if TYPE_CHECKING:
import os import os
@ -79,13 +80,13 @@ def test_emit_with_nonascii_name_node(app, status, warning):
def test_extensions(app, status, warning): def test_extensions(app, status, warning):
app.setup_extension('shutil') app.setup_extension('shutil')
warning = strip_escseq(warning.getvalue()) warning = strip_colors(warning.getvalue())
assert "extension 'shutil' has no setup() function" in warning assert "extension 'shutil' has no setup() function" in warning
def test_extension_in_blacklist(app, status, warning): def test_extension_in_blacklist(app, status, warning):
app.setup_extension('sphinxjp.themecore') app.setup_extension('sphinxjp.themecore')
msg = strip_escseq(warning.getvalue()) msg = strip_colors(warning.getvalue())
assert msg.startswith("WARNING: the extension 'sphinxjp.themecore' was") assert msg.startswith("WARNING: the extension 'sphinxjp.themecore' was")

View File

@ -25,8 +25,8 @@ from sphinx.builders.linkcheck import (
RateLimit, RateLimit,
) )
from sphinx.deprecation import RemovedInSphinx80Warning from sphinx.deprecation import RemovedInSphinx80Warning
from sphinx.testing.util import strip_escseq
from sphinx.util import requests from sphinx.util import requests
from sphinx.util.console import strip_colors
from tests.utils import CERT_FILE, http_server from tests.utils import CERT_FILE, http_server
@ -588,7 +588,7 @@ def test_linkcheck_allowed_redirects(app, warning):
} }
assert ("index.rst:3: WARNING: redirect http://localhost:7777/path2 - with Found to " assert ("index.rst:3: WARNING: redirect http://localhost:7777/path2 - with Found to "
"http://localhost:7777/?redirected=1\n" in strip_escseq(warning.getvalue())) "http://localhost:7777/?redirected=1\n" in strip_colors(warning.getvalue()))
assert len(warning.getvalue().splitlines()) == 1 assert len(warning.getvalue().splitlines()) == 1
@ -785,7 +785,7 @@ def test_too_many_requests_retry_after_int_delay(app, capsys, status):
"info": "", "info": "",
} }
rate_limit_log = "-rate limited- http://localhost:7777/ | sleeping...\n" rate_limit_log = "-rate limited- http://localhost:7777/ | sleeping...\n"
assert rate_limit_log in strip_escseq(status.getvalue()) assert rate_limit_log in strip_colors(status.getvalue())
_stdout, stderr = capsys.readouterr() _stdout, stderr = capsys.readouterr()
assert stderr == textwrap.dedent( assert stderr == textwrap.dedent(
"""\ """\

View File

@ -4,7 +4,7 @@ import sys
import pytest import pytest
from sphinx.testing.util import strip_escseq from sphinx.util.console import strip_colors
ENV_WARNINGS = """\ ENV_WARNINGS = """\
{root}/autodoc_fodder.py:docstring of autodoc_fodder.MarkupError:\\d+: \ {root}/autodoc_fodder.py:docstring of autodoc_fodder.MarkupError:\\d+: \
@ -42,7 +42,7 @@ TEXINFO_WARNINGS = ENV_WARNINGS + """\
def _check_warnings(expected_warnings: str, warning: str) -> None: def _check_warnings(expected_warnings: str, warning: str) -> None:
warnings = strip_escseq(re.sub(re.escape(os.sep) + '{1,2}', '/', warning)) warnings = strip_colors(re.sub(re.escape(os.sep) + '{1,2}', '/', warning))
assert re.match(f'{expected_warnings}$', warnings), ( assert re.match(f'{expected_warnings}$', warnings), (
"Warnings don't match:\n" "Warnings don't match:\n"
+ f'--- Expected (regex):\n{expected_warnings}\n' + f'--- Expected (regex):\n{expected_warnings}\n'

View File

@ -15,7 +15,8 @@ from babel.messages.catalog import Catalog
from docutils import nodes from docutils import nodes
from sphinx import locale from sphinx import locale
from sphinx.testing.util import assert_node, etree_parse, strip_escseq from sphinx.testing.util import assert_node, etree_parse
from sphinx.util.console import strip_colors
from sphinx.util.nodes import NodeMatcher from sphinx.util.nodes import NodeMatcher
_CATALOG_LOCALE = 'xx' _CATALOG_LOCALE = 'xx'
@ -1593,7 +1594,7 @@ def test_image_glob_intl_using_figure_language_filename(app):
def getwarning(warnings): def getwarning(warnings):
return strip_escseq(warnings.getvalue().replace(os.sep, '/')) return strip_colors(warnings.getvalue().replace(os.sep, '/'))
@pytest.mark.sphinx('html', testroot='basic', @pytest.mark.sphinx('html', testroot='basic',

View File

@ -2,8 +2,8 @@
import pytest import pytest
from sphinx.testing.util import strip_escseq
from sphinx.util import logging from sphinx.util import logging
from sphinx.util.console import strip_colors
from sphinx.util.display import ( from sphinx.util.display import (
SkipProgressMessage, SkipProgressMessage,
display_chunk, display_chunk,
@ -28,7 +28,7 @@ def test_status_iterator_length_0(app, status, warning):
status.seek(0) status.seek(0)
status.truncate(0) status.truncate(0)
yields = list(status_iterator(['hello', 'sphinx', 'world'], 'testing ... ')) yields = list(status_iterator(['hello', 'sphinx', 'world'], 'testing ... '))
output = strip_escseq(status.getvalue()) output = strip_colors(status.getvalue())
assert 'testing ... hello sphinx world \n' in output assert 'testing ... hello sphinx world \n' in output
assert yields == ['hello', 'sphinx', 'world'] assert yields == ['hello', 'sphinx', 'world']
@ -43,7 +43,7 @@ def test_status_iterator_verbosity_0(app, status, warning, monkeypatch):
status.truncate(0) status.truncate(0)
yields = list(status_iterator(['hello', 'sphinx', 'world'], 'testing ... ', yields = list(status_iterator(['hello', 'sphinx', 'world'], 'testing ... ',
length=3, verbosity=0)) length=3, verbosity=0))
output = strip_escseq(status.getvalue()) output = strip_colors(status.getvalue())
assert 'testing ... [ 33%] hello\r' in output assert 'testing ... [ 33%] hello\r' in output
assert 'testing ... [ 67%] sphinx\r' in output assert 'testing ... [ 67%] sphinx\r' in output
assert 'testing ... [100%] world\r\n' in output assert 'testing ... [100%] world\r\n' in output
@ -60,7 +60,7 @@ def test_status_iterator_verbosity_1(app, status, warning, monkeypatch):
status.truncate(0) status.truncate(0)
yields = list(status_iterator(['hello', 'sphinx', 'world'], 'testing ... ', yields = list(status_iterator(['hello', 'sphinx', 'world'], 'testing ... ',
length=3, verbosity=1)) length=3, verbosity=1))
output = strip_escseq(status.getvalue()) output = strip_colors(status.getvalue())
assert 'testing ... [ 33%] hello\n' in output assert 'testing ... [ 33%] hello\n' in output
assert 'testing ... [ 67%] sphinx\n' in output assert 'testing ... [ 67%] sphinx\n' in output
assert 'testing ... [100%] world\n\n' in output assert 'testing ... [100%] world\n\n' in output
@ -75,14 +75,14 @@ def test_progress_message(app, status, warning):
with progress_message('testing'): with progress_message('testing'):
logger.info('blah ', nonl=True) logger.info('blah ', nonl=True)
output = strip_escseq(status.getvalue()) output = strip_colors(status.getvalue())
assert 'testing... blah done\n' in output assert 'testing... blah done\n' in output
# skipping case # skipping case
with progress_message('testing'): with progress_message('testing'):
raise SkipProgressMessage('Reason: %s', 'error') # NoQA: EM101 raise SkipProgressMessage('Reason: %s', 'error') # NoQA: EM101
output = strip_escseq(status.getvalue()) output = strip_colors(status.getvalue())
assert 'testing... skipped\nReason: error\n' in output assert 'testing... skipped\nReason: error\n' in output
# error case # error case
@ -92,7 +92,7 @@ def test_progress_message(app, status, warning):
except Exception: except Exception:
pass pass
output = strip_escseq(status.getvalue()) output = strip_colors(status.getvalue())
assert 'testing... failed\n' in output assert 'testing... failed\n' in output
# decorator # decorator
@ -101,5 +101,5 @@ def test_progress_message(app, status, warning):
logger.info('in func ', nonl=True) logger.info('in func ', nonl=True)
func() func()
output = strip_escseq(status.getvalue()) output = strip_colors(status.getvalue())
assert 'testing... in func done\n' in output assert 'testing... in func done\n' in output

View File

@ -8,7 +8,6 @@ import pytest
from docutils import nodes from docutils import nodes
from sphinx.errors import SphinxWarning from sphinx.errors import SphinxWarning
from sphinx.testing.util import strip_escseq
from sphinx.util import logging, osutil from sphinx.util import logging, osutil
from sphinx.util.console import colorize, strip_colors from sphinx.util.console import colorize, strip_colors
from sphinx.util.logging import is_suppressed_warning, prefixed_warnings from sphinx.util.logging import is_suppressed_warning, prefixed_warnings
@ -110,7 +109,7 @@ def test_once_warning_log(app, status, warning):
logger.warning('message: %d', 1, once=True) logger.warning('message: %d', 1, once=True)
logger.warning('message: %d', 2, once=True) logger.warning('message: %d', 2, once=True)
assert 'WARNING: message: 1\nWARNING: message: 2\n' in strip_escseq(warning.getvalue()) assert 'WARNING: message: 1\nWARNING: message: 2\n' in strip_colors(warning.getvalue())
def test_is_suppressed_warning(): def test_is_suppressed_warning():
@ -278,7 +277,7 @@ def test_pending_warnings(app, status, warning):
assert 'WARNING: message3' not in warning.getvalue() assert 'WARNING: message3' not in warning.getvalue()
# actually logged as ordered # actually logged as ordered
assert 'WARNING: message2\nWARNING: message3' in strip_escseq(warning.getvalue()) assert 'WARNING: message2\nWARNING: message3' in strip_colors(warning.getvalue())
def test_colored_logs(app, status, warning): def test_colored_logs(app, status, warning):