Skip to content

Commit 16cb87b

Browse files
pytest.fail: fix ANSI escape codes for colored output (#12959) (#12990)
- When `ReprEntry.style == "value"` (happens when calling `pytest.fail(..., pytrace=False)`, the message should not be printed to terminal using `TerminalWriter._write_source` because then it'll try to highlight the message as source code - The message should be printed to terminal directly using `TerminalWriter.line` or `TerminalWriter.write`, I went with the later for testing purposes #12959 (comment) Closes #12849 (cherry picked from commit 76e0444) Co-authored-by: Leonardus Chen <[email protected]>
1 parent be6bc81 commit 16cb87b

File tree

5 files changed

+32
-7
lines changed

5 files changed

+32
-7
lines changed

AUTHORS

+1
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,7 @@ Kristoffer Nordström
245245
Kyle Altendorf
246246
Lawrence Mitchell
247247
Lee Kamentsky
248+
Leonardus Chen
248249
Lev Maximov
249250
Levon Saldamli
250251
Lewis Cowles

changelog/12849.bugfix.rst

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
ANSI escape codes for colored output now handled correctly in :func:`pytest.fail` with `pytrace=False`.

src/_pytest/_code/code.py

+11-5
Original file line numberDiff line numberDiff line change
@@ -1221,6 +1221,15 @@ def _write_entry_lines(self, tw: TerminalWriter) -> None:
12211221
if not self.lines:
12221222
return
12231223

1224+
if self.style == "value":
1225+
# Using tw.write instead of tw.line for testing purposes due to TWMock implementation;
1226+
# lines written with TWMock.line and TWMock._write_source cannot be distinguished
1227+
# from each other, whereas lines written with TWMock.write are marked with TWMock.WRITE
1228+
for line in self.lines:
1229+
tw.write(line)
1230+
tw.write("\n")
1231+
return
1232+
12241233
# separate indents and source lines that are not failures: we want to
12251234
# highlight the code but not the indentation, which may contain markers
12261235
# such as "> assert 0"
@@ -1236,11 +1245,8 @@ def _write_entry_lines(self, tw: TerminalWriter) -> None:
12361245
failure_lines.extend(self.lines[index:])
12371246
break
12381247
else:
1239-
if self.style == "value":
1240-
source_lines.append(line)
1241-
else:
1242-
indents.append(line[:indent_size])
1243-
source_lines.append(line[indent_size:])
1248+
indents.append(line[:indent_size])
1249+
source_lines.append(line[indent_size:])
12441250

12451251
tw._write_source(source_lines, indents)
12461252

testing/code/test_excinfo.py

+17
Original file line numberDiff line numberDiff line change
@@ -1194,6 +1194,23 @@ def f():
11941194
line = tw_mock.lines[-1]
11951195
assert line == ":3: ValueError"
11961196

1197+
def test_toterminal_value(self, importasmod, tw_mock):
1198+
mod = importasmod(
1199+
"""
1200+
def g(x):
1201+
raise ValueError(x)
1202+
def f():
1203+
g('some_value')
1204+
"""
1205+
)
1206+
excinfo = pytest.raises(ValueError, mod.f)
1207+
excinfo.traceback = excinfo.traceback.filter(excinfo)
1208+
repr = excinfo.getrepr(style="value")
1209+
repr.toterminal(tw_mock)
1210+
1211+
assert tw_mock.get_write_msg(0) == "some_value"
1212+
assert tw_mock.get_write_msg(1) == "\n"
1213+
11971214
@pytest.mark.parametrize(
11981215
"reproptions",
11991216
[

testing/conftest.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -119,8 +119,8 @@ def markup(self, text, **kw):
119119
return text
120120

121121
def get_write_msg(self, idx):
122-
flag, msg = self.lines[idx]
123-
assert flag == TWMock.WRITE
122+
assert self.lines[idx][0] == TWMock.WRITE
123+
msg = self.lines[idx][1]
124124
return msg
125125

126126
fullwidth = 80

0 commit comments

Comments
 (0)