pygments themes are customizable

This commit is contained in:
Éloi Rivard 2021-06-11 17:04:27 +02:00
parent 2439729413
commit 7770dacb8d
6 changed files with 99 additions and 4 deletions

View File

@ -106,6 +106,7 @@ Edson Tadeu M. Manoel
Eduardo Schettino Eduardo Schettino
Eli Boyarski Eli Boyarski
Elizaveta Shashkova Elizaveta Shashkova
Éloi Rivard
Endre Galaczi Endre Galaczi
Eric Hunsberger Eric Hunsberger
Eric Liu Eric Liu

View File

@ -0,0 +1 @@
Added two environment variables :envvar:`PYTEST_THEME` and :envvar:`PYTEST_THEME_MODE` to let the users customize the pygments theme used.

View File

@ -239,3 +239,11 @@ Builtin configuration file options
---------------------------------------------- ----------------------------------------------
For the full list of options consult the :ref:`reference documentation <ini options ref>`. For the full list of options consult the :ref:`reference documentation <ini options ref>`.
Syntax highlighting theme customization
---------------------------------------
The syntax highlighting themes used by pytest can be customized using two environment variables:
- :envvar:`PYTEST_THEME` sets a `pygment style <https://pygments.org/docs/styles/>`_ to use.
- :envvar:`PYTEST_THEME_MODE` sets this style to *light* or *dark*.

View File

@ -1075,6 +1075,14 @@ Contains comma-separated list of modules that should be loaded as plugins:
export PYTEST_PLUGINS=mymodule.plugin,xdist export PYTEST_PLUGINS=mymodule.plugin,xdist
.. envvar:: PYTEST_THEME
Sets a `pygment style <https://pygments.org/docs/styles/>`_ to use for the code output.
.. envvar:: PYTEST_THEME_MODE
Sets the :envvar:`PYTEST_THEME` to be either *dark* or *light*.
.. envvar:: PY_COLORS .. envvar:: PY_COLORS
When set to ``1``, pytest will use color in terminal output. When set to ``1``, pytest will use color in terminal output.

View File

@ -195,16 +195,39 @@ class TerminalWriter:
def _highlight(self, source: str) -> str: def _highlight(self, source: str) -> str:
"""Highlight the given source code if we have markup support.""" """Highlight the given source code if we have markup support."""
from _pytest.config.exceptions import UsageError
if not self.hasmarkup or not self.code_highlight: if not self.hasmarkup or not self.code_highlight:
return source return source
try: try:
from pygments.formatters.terminal import TerminalFormatter from pygments.formatters.terminal import TerminalFormatter
from pygments.lexers.python import PythonLexer from pygments.lexers.python import PythonLexer
from pygments import highlight from pygments import highlight
import pygments.util
except ImportError: except ImportError:
return source return source
else: else:
highlighted: str = highlight( try:
source, PythonLexer(), TerminalFormatter(bg="dark") highlighted: str = highlight(
) source,
return highlighted PythonLexer(),
TerminalFormatter(
bg=os.getenv("PYTEST_THEME_MODE", "dark"),
style=os.getenv("PYTEST_THEME"),
),
)
return highlighted
except pygments.util.ClassNotFound:
raise UsageError(
"PYTEST_THEME environment variable had an invalid value: '{}'. "
"Only valid pygment styles are allowed.".format(
os.getenv("PYTEST_THEME")
)
)
except pygments.util.OptionError:
raise UsageError(
"PYTEST_THEME_MODE environment variable had an invalid value: '{}'. "
"The only allowed values are 'dark' and 'light'.".format(
os.getenv("PYTEST_THEME_MODE")
)
)

View File

@ -2408,6 +2408,60 @@ class TestCodeHighlight:
) )
) )
def test_code_highlight_custom_theme(
self, pytester: Pytester, color_mapping, monkeypatch: MonkeyPatch
) -> None:
pytester.makepyfile(
"""
def test_foo():
assert 1 == 10
"""
)
monkeypatch.setenv("PYTEST_THEME", "solarized-dark")
monkeypatch.setenv("PYTEST_THEME_MODE", "dark")
result = pytester.runpytest("--color=yes")
result.stdout.fnmatch_lines(
color_mapping.format_for_fnmatch(
[
" {kw}def{hl-reset} {function}test_foo{hl-reset}():",
"> {kw}assert{hl-reset} {number}1{hl-reset} == {number}10{hl-reset}",
"{bold}{red}E assert 1 == 10{reset}",
]
)
)
def test_code_highlight_invalid_theme(
self, pytester: Pytester, color_mapping, monkeypatch: MonkeyPatch
) -> None:
pytester.makepyfile(
"""
def test_foo():
assert 1 == 10
"""
)
monkeypatch.setenv("PYTEST_THEME", "invalid")
result = pytester.runpytest_subprocess("--color=yes")
result.stderr.fnmatch_lines(
"ERROR: PYTEST_THEME environment variable had an invalid value: 'invalid'. "
"Only valid pygment styles are allowed."
)
def test_code_highlight_invalid_theme_mode(
self, pytester: Pytester, color_mapping, monkeypatch: MonkeyPatch
) -> None:
pytester.makepyfile(
"""
def test_foo():
assert 1 == 10
"""
)
monkeypatch.setenv("PYTEST_THEME_MODE", "invalid")
result = pytester.runpytest_subprocess("--color=yes")
result.stderr.fnmatch_lines(
"ERROR: PYTEST_THEME_MODE environment variable had an invalid value: 'invalid'. "
"The only allowed values are 'dark' and 'light'."
)
def test_raw_skip_reason_skipped() -> None: def test_raw_skip_reason_skipped() -> None:
report = SimpleNamespace() report = SimpleNamespace()