Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
2d4ed10
show correct extra item in "contains one more item" diffs
SemTiOne Aug 19, 2026
b998798
Merge branch 'main' into fix/13652-misleading-extra-item-message
SemTiOne Aug 22, 2026
30c57ff
Add parametrized case for Left-side fallback
SemTiOne Aug 22, 2026
af7fbb5
Initialize i to fix mypy unbound
SemTiOne Aug 22, 2026
223e8db
Update changelog
SemTiOne Aug 25, 2026
5ad60d5
Update comment in _compare_sequence.py
SemTiOne Aug 25, 2026
0784ec2
Add fallback test
SemTiOne Aug 25, 2026
9769228
Merge branch 'main' into fix/13652-misleading-extra-item-message
SemTiOne Aug 25, 2026
18ecead
Merge branch 'main' into fix/13652-misleading-extra-item-message
SemTiOne Aug 27, 2026
57ed551
Merge branch 'main' into fix/13652-misleading-extra-item-message
SemTiOne Sep 7, 2026
2a21e8a
Harden tail check against exotic __eq__
SemTiOne Sep 7, 2026
d20867d
Merge branch 'main' into fix/13652-misleading-extra-item-message
SemTiOne Sep 8, 2026
fa61412
Cover exotic-eq fallback branches
SemTiOne Sep 8, 2026
71596d2
Merge branch 'main' into fix/13652-misleading-extra-item-message
SemTiOne Sep 8, 2026
68158d8
Merge branch 'main' into fix/13652-misleading-extra-item-message
SemTiOne Sep 16, 2026
272a07e
Harden tail check against slice failures
SemTiOne Sep 16, 2026
ec3511f
Merge branch 'main' of https://github.com/SemTiOne/pytest into fix/13…
SemTiOne Oct 16, 2026
b220629
Simplify extra-item fix to first-differing-index rule
SemTiOne Oct 16, 2026
886f14b
Merge branch 'main' into fix/13652-misleading-extra-item-message
SemTiOne Oct 16, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog/13652.bugfix.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
``contains one more item`` now reports the actual extra item in sequence diffs.
13 changes: 11 additions & 2 deletions src/_pytest/assertion/_compare_sequence.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ def _compare_eq_sequence(
comparing_bytes = isinstance(left, bytes) and isinstance(right, bytes)
len_left = len(left)
len_right = len(right)
found_diff = False
i = -1
for i in range(min(len_left, len_right)):
if left[i] != right[i]:
if comparing_bytes:
Expand All @@ -73,6 +75,7 @@ def _compare_eq_sequence(
f"At index {i} diff:"
f" {highlighter(repr(left_value))} != {highlighter(repr(right_value))}"
)
found_diff = True
break

if comparing_bytes:
Expand All @@ -84,11 +87,17 @@ def _compare_eq_sequence(
if len_diff:
if len_diff > 0:
dir_with_more = "Left"
extra = saferepr(left[len_right])
if found_diff and len_diff == 1:
extra = saferepr(left[i])
else:
extra = saferepr(left[len_right])
else:
len_diff = 0 - len_diff
dir_with_more = "Right"
extra = saferepr(right[len_left])
if found_diff and len_diff == 1:
extra = saferepr(right[i])
else:
extra = saferepr(right[len_left])

if len_diff == 1:
yield f"{dir_with_more} contains one more item: {highlighter(extra)}"
Expand Down
24 changes: 23 additions & 1 deletion testing/test_assertion.py
Original file line number Diff line number Diff line change
Expand Up @@ -1122,7 +1122,7 @@ def test_sequence_different_items(self) -> None:
"(1, 2) == (3, 4, 5)",
"",
"At index 0 diff: 1 != 3",
"Right contains one more item: 5",
"Right contains one more item: 3",
"",
"Full diff: (-: missing in left side, +: extra in left side)",
" (",
Expand Down Expand Up @@ -1170,6 +1170,28 @@ def test_sequence_different_items(self) -> None:
" )",
]

@pytest.mark.parametrize(
("left", "right", "expected"),
[
([], [1], "Right contains one more item: 1"),
([1], [], "Left contains one more item: 1"),
([1, 2, 3], [1, 2, 3, 4], "Right contains one more item: 4"),
([1, 2, 3], [1, 2, 0, 3], "Right contains one more item: 0"),
([1, 2, 0, 3], [1, 2, 3], "Left contains one more item: 0"),
(
[1, 2, 3],
[0, 1, 2, 3, 4],
"Right contains 2 more items, first extra item: 3",
),
],
)
def test_sequence_extra_item_message(
self, left: list[object], right: list[object], expected: str
) -> None:
lines = callequal(left, right, verbose=1)
assert lines is not None
assert expected in lines

def test_set(self) -> None:
expl = callequal({0, 1}, {0, 2})
assert expl is not None
Expand Down
24 changes: 23 additions & 1 deletion testing/test_error_diffs.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ def test_this():
> assert result == expected
E assert [1, 3] == [1, 2, 3]
E At index 1 diff: 3 != 2
E Right contains one more item: 3
E Right contains one more item: 2
E Full diff: (-: missing in left side, +: extra in left side)
E [
E 1,
Expand All @@ -76,6 +76,28 @@ def test_this():
""",
id="Compare lists, one item missing",
),
pytest.param(
"""
def test_this():
result = [1, 2, 3]
expected = [1, 2, 0, 3]
assert result == expected
""",
"""
> assert result == expected
E assert [1, 2, 3] == [1, 2, 0, 3]
E At index 2 diff: 3 != 0
E Right contains one more item: 0
E Full diff: (-: missing in left side, +: extra in left side)
E [
E 1,
E 2,
E - 0,
E 3,
E ]
""",
id="Compare lists, one extra item inserted mid-list",
),
pytest.param(
"""
def test_this():
Expand Down
Loading