Skip to content

Commit a536f49

Browse files
Separate the various parts of the error report with newlines (#11659)
Previously the error report would have all sections glued together: - The assertion representation - The error explanation - The full diff This makes it hard to see at a glance where which one starts and ends. One of the representation (dataclasses, tuples, attrs) does display a newlines at the start already. Let's add a newlines before the error explanation and before the full diff, so we get an easier to read report. This has one disadvantage: we get one line less in the least verbose mode, where the output gets truncated.
1 parent cd269f0 commit a536f49

File tree

4 files changed

+74
-23
lines changed

4 files changed

+74
-23
lines changed

changelog/11520.improvement.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
11
Improved very verbose diff output to color it as a diff instead of only red.
2+
3+
Improved the error reporting to better separate each section.

src/_pytest/assertion/util.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,8 @@ def assertrepr_compare(
230230
if not explanation:
231231
return None
232232

233+
if explanation[0] != "":
234+
explanation = [""] + explanation
233235
return [summary] + explanation
234236

235237

@@ -332,7 +334,7 @@ def _compare_eq_iterable(
332334
left_formatting = PrettyPrinter().pformat(left).splitlines()
333335
right_formatting = PrettyPrinter().pformat(right).splitlines()
334336

335-
explanation = ["Full diff:"]
337+
explanation = ["", "Full diff:"]
336338
# "right" is the expected base against which we compare "left",
337339
# see https://github.com/pytest-dev/pytest/issues/3333
338340
explanation.extend(

testing/python/approx.py

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ def test_error_messages_native_dtypes(self, assert_approx_raises_regex):
9999
2.0,
100100
1.0,
101101
[
102+
"",
102103
" comparison failed",
103104
f" Obtained: {SOME_FLOAT}",
104105
f" Expected: {SOME_FLOAT} ± {SOME_FLOAT}",
@@ -113,6 +114,7 @@ def test_error_messages_native_dtypes(self, assert_approx_raises_regex):
113114
"c": 3000000.0,
114115
},
115116
[
117+
r"",
116118
r" comparison failed. Mismatched elements: 2 / 3:",
117119
rf" Max absolute difference: {SOME_FLOAT}",
118120
rf" Max relative difference: {SOME_FLOAT}",
@@ -130,6 +132,7 @@ def test_error_messages_native_dtypes(self, assert_approx_raises_regex):
130132
"c": None,
131133
},
132134
[
135+
r"",
133136
r" comparison failed. Mismatched elements: 2 / 3:",
134137
r" Max absolute difference: -inf",
135138
r" Max relative difference: -inf",
@@ -143,6 +146,7 @@ def test_error_messages_native_dtypes(self, assert_approx_raises_regex):
143146
[1.0, 2.0, 3.0, 4.0],
144147
[1.0, 3.0, 3.0, 5.0],
145148
[
149+
r"",
146150
r" comparison failed. Mismatched elements: 2 / 4:",
147151
rf" Max absolute difference: {SOME_FLOAT}",
148152
rf" Max relative difference: {SOME_FLOAT}",
@@ -156,6 +160,7 @@ def test_error_messages_native_dtypes(self, assert_approx_raises_regex):
156160
(1, 2.2, 4),
157161
(1, 3.2, 4),
158162
[
163+
r"",
159164
r" comparison failed. Mismatched elements: 1 / 3:",
160165
rf" Max absolute difference: {SOME_FLOAT}",
161166
rf" Max relative difference: {SOME_FLOAT}",
@@ -169,6 +174,7 @@ def test_error_messages_native_dtypes(self, assert_approx_raises_regex):
169174
[0.0],
170175
[1.0],
171176
[
177+
r"",
172178
r" comparison failed. Mismatched elements: 1 / 1:",
173179
rf" Max absolute difference: {SOME_FLOAT}",
174180
r" Max relative difference: inf",
@@ -187,6 +193,7 @@ def test_error_messages_numpy_dtypes(self, assert_approx_raises_regex):
187193
a,
188194
b,
189195
[
196+
r"",
190197
r" comparison failed. Mismatched elements: 1 / 20:",
191198
rf" Max absolute difference: {SOME_FLOAT}",
192199
rf" Max relative difference: {SOME_FLOAT}",
@@ -209,6 +216,7 @@ def test_error_messages_numpy_dtypes(self, assert_approx_raises_regex):
209216
]
210217
),
211218
[
219+
r"",
212220
r" comparison failed. Mismatched elements: 3 / 8:",
213221
rf" Max absolute difference: {SOME_FLOAT}",
214222
rf" Max relative difference: {SOME_FLOAT}",
@@ -224,6 +232,7 @@ def test_error_messages_numpy_dtypes(self, assert_approx_raises_regex):
224232
np.array([0.0]),
225233
np.array([1.0]),
226234
[
235+
r"",
227236
r" comparison failed. Mismatched elements: 1 / 1:",
228237
rf" Max absolute difference: {SOME_FLOAT}",
229238
r" Max relative difference: inf",
@@ -241,6 +250,7 @@ def test_error_messages_invalid_args(self, assert_approx_raises_regex):
241250
message = "\n".join(str(e.value).split("\n")[1:])
242251
assert message == "\n".join(
243252
[
253+
" ",
244254
" Impossible to compare arrays with different shapes.",
245255
" Shapes: (2, 1) and (2, 2)",
246256
]
@@ -251,6 +261,7 @@ def test_error_messages_invalid_args(self, assert_approx_raises_regex):
251261
message = "\n".join(str(e.value).split("\n")[1:])
252262
assert message == "\n".join(
253263
[
264+
" ",
254265
" Impossible to compare lists with different sizes.",
255266
" Lengths: 2 and 3",
256267
]
@@ -264,6 +275,7 @@ def test_error_messages_with_different_verbosity(self, assert_approx_raises_rege
264275
2.0,
265276
1.0,
266277
[
278+
"",
267279
" comparison failed",
268280
f" Obtained: {SOME_FLOAT}",
269281
f" Expected: {SOME_FLOAT} ± {SOME_FLOAT}",
@@ -277,15 +289,15 @@ def test_error_messages_with_different_verbosity(self, assert_approx_raises_rege
277289
a,
278290
b,
279291
[
280-
r" comparison failed. Mismatched elements: 20 / 20:",
281-
rf" Max absolute difference: {SOME_FLOAT}",
282-
rf" Max relative difference: {SOME_FLOAT}",
283-
r" Index \| Obtained\s+\| Expected",
284-
rf" \(0,\)\s+\| {SOME_FLOAT} \| {SOME_FLOAT} ± {SOME_FLOAT}",
285-
rf" \(1,\)\s+\| {SOME_FLOAT} \| {SOME_FLOAT} ± {SOME_FLOAT}",
286-
rf" \(2,\)\s+\| {SOME_FLOAT} \| {SOME_FLOAT} ± {SOME_FLOAT}...",
287-
"",
288-
rf"\s*...Full output truncated \({SOME_INT} lines hidden\), use '-vv' to show",
292+
r"^ $",
293+
r"^ comparison failed. Mismatched elements: 20 / 20:$",
294+
rf"^ Max absolute difference: {SOME_FLOAT}$",
295+
rf"^ Max relative difference: {SOME_FLOAT}$",
296+
r"^ Index \| Obtained\s+\| Expected\s+$",
297+
rf"^ \(0,\)\s+\| {SOME_FLOAT} \| {SOME_FLOAT} ± {SOME_FLOAT}e-{SOME_INT}$",
298+
rf"^ \(1,\)\s+\| {SOME_FLOAT} \| {SOME_FLOAT} ± {SOME_FLOAT}e-{SOME_INT}\.\.\.$",
299+
"^ $",
300+
rf"^ ...Full output truncated \({SOME_INT} lines hidden\), use '-vv' to show$",
289301
],
290302
verbosity_level=0,
291303
)
@@ -294,6 +306,7 @@ def test_error_messages_with_different_verbosity(self, assert_approx_raises_rege
294306
a,
295307
b,
296308
[
309+
r" ",
297310
r" comparison failed. Mismatched elements: 20 / 20:",
298311
rf" Max absolute difference: {SOME_FLOAT}",
299312
rf" Max relative difference: {SOME_FLOAT}",
@@ -652,6 +665,7 @@ def test_dict_for_div_by_zero(self, assert_approx_raises_regex):
652665
{"foo": 42.0},
653666
{"foo": 0.0},
654667
[
668+
r"",
655669
r" comparison failed. Mismatched elements: 1 / 1:",
656670
rf" Max absolute difference: {SOME_FLOAT}",
657671
r" Max relative difference: inf",

0 commit comments

Comments
 (0)