Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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/5026.feature.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Assertion failure messages for sequences and dicts contain the number of different items now.
56 changes: 38 additions & 18 deletions src/_pytest/assertion/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -285,20 +285,30 @@ def _compare_eq_iterable(left, right, verbose=0):

def _compare_eq_sequence(left, right, verbose=0):
explanation = []
for i in range(min(len(left), len(right))):
len_left = len(left)
len_right = len(right)
for i in range(min(len_left, len_right)):
if left[i] != right[i]:
explanation += [u"At index %s diff: %r != %r" % (i, left[i], right[i])]
break
if len(left) > len(right):
explanation += [
u"Left contains more items, first extra item: %s"
% saferepr(left[len(right)])
]
elif len(left) < len(right):
explanation += [
u"Right contains more items, first extra item: %s"
% saferepr(right[len(left)])
]
len_diff = len_left - len_right

if len_diff:
if len_diff > 0:
dir_with_more = "Left"
extra = saferepr(left[len_right])
else:
len_diff = 0 - len_diff
dir_with_more = "Right"
extra = saferepr(right[len_left])

if len_diff == 1:
explanation += [u"%s contains one more item: %s" % (dir_with_more, extra)]
else:
explanation += [
u"%s contains %d more items, first extra item: %s"
% (dir_with_more, len_diff, extra)
]
return explanation


Expand All @@ -319,7 +329,9 @@ def _compare_eq_set(left, right, verbose=0):

def _compare_eq_dict(left, right, verbose=0):
explanation = []
common = set(left).intersection(set(right))
set_left = set(left)
set_right = set(right)
common = set_left.intersection(set_right)
same = {k: left[k] for k in common if left[k] == right[k]}
if same and verbose < 2:
explanation += [u"Omitting %s identical items, use -vv to show" % len(same)]
Expand All @@ -331,15 +343,23 @@ def _compare_eq_dict(left, right, verbose=0):
explanation += [u"Differing items:"]
for k in diff:
explanation += [saferepr({k: left[k]}) + " != " + saferepr({k: right[k]})]
extra_left = set(left) - set(right)
if extra_left:
explanation.append(u"Left contains more items:")
extra_left = set_left - set_right
len_extra_left = len(extra_left)
if len_extra_left:
explanation.append(
u"Left contains %d more item%s:"
% (len_extra_left, "" if len_extra_left == 1 else "s")
)
explanation.extend(
pprint.pformat({k: left[k] for k in extra_left}).splitlines()
)
extra_right = set(right) - set(left)
if extra_right:
explanation.append(u"Right contains more items:")
extra_right = set_right - set_left
len_extra_right = len(extra_right)
if len_extra_right:
explanation.append(
u"Right contains %d more item%s:"
% (len_extra_right, "" if len_extra_right == 1 else "s")
)
explanation.extend(
pprint.pformat({k: right[k] for k in extra_right}).splitlines()
)
Expand Down
44 changes: 44 additions & 0 deletions testing/test_assertion.py
Original file line number Diff line number Diff line change
Expand Up @@ -446,6 +446,50 @@ def test_dict_omitting_with_verbosity_2(self):
assert "Omitting" not in lines[1]
assert lines[2] == "{'b': 1}"

def test_dict_different_items(self):
lines = callequal({"a": 0}, {"b": 1, "c": 2}, verbose=2)
assert lines == [
"{'a': 0} == {'b': 1, 'c': 2}",
"Left contains 1 more item:",
"{'a': 0}",
"Right contains 2 more items:",
"{'b': 1, 'c': 2}",
"Full diff:",
"- {'a': 0}",
"+ {'b': 1, 'c': 2}",
]
lines = callequal({"b": 1, "c": 2}, {"a": 0}, verbose=2)
assert lines == [
"{'b': 1, 'c': 2} == {'a': 0}",
"Left contains 2 more items:",
"{'b': 1, 'c': 2}",
"Right contains 1 more item:",
"{'a': 0}",
"Full diff:",
"- {'b': 1, 'c': 2}",
"+ {'a': 0}",
]

def test_sequence_different_items(self):
lines = callequal((1, 2), (3, 4, 5), verbose=2)
assert lines == [
"(1, 2) == (3, 4, 5)",
"At index 0 diff: 1 != 3",
"Right contains one more item: 5",
"Full diff:",
"- (1, 2)",
"+ (3, 4, 5)",
]
lines = callequal((1, 2, 3), (4,), verbose=2)
assert lines == [
"(1, 2, 3) == (4,)",
"At index 0 diff: 1 != 4",
"Left contains 2 more items, first extra item: 2",
"Full diff:",
"- (1, 2, 3)",
"+ (4,)",
]

def test_set(self):
expl = callequal({0, 1}, {0, 2})
assert len(expl) > 1
Expand Down