Skip to content

Commit 73c0643

Browse files
committed
Use code highlighting if pygments is installed
1 parent 39b25dd commit 73c0643

File tree

4 files changed

+50
-17
lines changed

4 files changed

+50
-17
lines changed

src/_pytest/_code/code.py

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1038,20 +1038,27 @@ def __init__(
10381038
self.style = style
10391039

10401040
def toterminal(self, tw: TerminalWriter) -> None:
1041+
error_prefix = "E "
1042+
src = "\n".join(x for x in self.lines if not x.startswith(error_prefix))
1043+
error_lines = (x for x in self.lines if x.startswith(error_prefix))
1044+
10411045
if self.style == "short":
10421046
assert self.reprfileloc is not None
10431047
self.reprfileloc.toterminal(tw)
1044-
for line in self.lines:
1045-
red = line.startswith("E ")
1046-
tw.line(line, bold=True, red=red)
1048+
tw.write_source(src + "\n")
1049+
for line in error_lines:
1050+
tw.line(line, red=True, bold=True)
10471051
if self.reprlocals:
10481052
self.reprlocals.toterminal(tw, indent=" " * 8)
10491053
return
1054+
10501055
if self.reprfuncargs:
10511056
self.reprfuncargs.toterminal(tw)
1052-
for line in self.lines:
1053-
red = line.startswith("E ")
1054-
tw.line(line, bold=True, red=red)
1057+
1058+
tw.write_source(src + "\n")
1059+
for line in error_lines:
1060+
tw.line(line, red=True, bold=True)
1061+
10551062
if self.reprlocals:
10561063
tw.line("")
10571064
self.reprlocals.toterminal(tw)

src/_pytest/_io/__init__.py

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,22 @@
11
# Reexport TerminalWriter from here instead of py, to make it easier to
22
# extend or swap our own implementation in the future.
3-
from py.io import TerminalWriter as TerminalWriter # noqa: F401
3+
from py.io import TerminalWriter as BaseTerminalWriter # noqa: F401
4+
5+
6+
class TerminalWriter(BaseTerminalWriter):
7+
def write_source(self, source: str) -> None:
8+
"""Write lines of source code possibly highlighted."""
9+
self.write(self._highlight(source))
10+
11+
def _highlight(self, source):
12+
"""Highlight the given source code according to the "code_highlight" option"""
13+
if not self.hasmarkup:
14+
return source
15+
try:
16+
from pygments.formatters.terminal import TerminalFormatter
17+
from pygments.lexers.python import PythonLexer
18+
from pygments import highlight
19+
except ImportError:
20+
return source
21+
else:
22+
return highlight(source, PythonLexer(), TerminalFormatter())

testing/test_terminal.py

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -916,16 +916,9 @@ def test_this():
916916
"=*= FAILURES =*=",
917917
"{red}{bold}_*_ test_this _*_{reset}",
918918
"",
919-
"{bold} def test_this():{reset}",
920-
"{bold}> fail(){reset}",
921-
"",
922919
"{bold}{red}test_color_yes.py{reset}:5: ",
923920
"_ _ * _ _*",
924921
"",
925-
"{bold} def fail():{reset}",
926-
"{bold}> assert 0{reset}",
927-
"{bold}{red}E assert 0{reset}",
928-
"",
929922
"{bold}{red}test_color_yes.py{reset}:2: AssertionError",
930923
"{red}=*= {red}{bold}1 failed{reset}{red} in *s{reset}{red} =*={reset}",
931924
]
@@ -944,10 +937,7 @@ def test_this():
944937
"=*= FAILURES =*=",
945938
"{red}{bold}_*_ test_this _*_{reset}",
946939
"{bold}{red}test_color_yes.py{reset}:5: in test_this",
947-
"{bold} fail(){reset}",
948940
"{bold}{red}test_color_yes.py{reset}:2: in fail",
949-
"{bold} assert 0{reset}",
950-
"{bold}{red}E assert 0{reset}",
951941
"{red}=*= {red}{bold}1 failed{reset}{red} in *s{reset}{red} =*={reset}",
952942
]
953943
]
@@ -2019,3 +2009,19 @@ def test_via_exec(testdir: Testdir) -> None:
20192009
result.stdout.fnmatch_lines(
20202010
["test_via_exec.py::test_via_exec <- <string> PASSED*", "*= 1 passed in *"]
20212011
)
2012+
2013+
2014+
def test_code_highlight(testdir: Testdir) -> None:
2015+
testdir.makepyfile(
2016+
"""
2017+
def test_foo():
2018+
assert 1 == 10
2019+
"""
2020+
)
2021+
result = testdir.runpytest("--color=yes")
2022+
result.stdout.fnmatch_lines(
2023+
[
2024+
"*\x1b[34mdef\x1b[39;49;00m \x1b[32mtest_foo\x1b[39;49;00m():",
2025+
"*E assert 1 == 10*",
2026+
]
2027+
)

tox.ini

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ deps =
4949
numpy: numpy
5050
pexpect: pexpect
5151
pluggymaster: git+https://github.com/pytest-dev/pluggy.git@master
52+
pygments
5253
twisted: twisted
5354
xdist: pytest-xdist>=1.13
5455
{env:_PYTEST_TOX_EXTRA_DEP:}

0 commit comments

Comments
 (0)