-
-
Notifications
You must be signed in to change notification settings - Fork 2.9k
Display output failure message in insertion order of dictionary #13587
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 11 commits
896c8b9
4468c17
62f5a34
12b4233
0ce44bb
9205e51
bcaa184
57ecd50
0188efc
f898fdd
29689b2
290e21f
04673d4
d25b699
d4a58da
bb95491
ce769db
969407c
36733f0
816e755
6619690
ffb5e46
0048258
f1d227d
bb7ce38
89edc53
72012e2
cafff20
acd597d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
Fixed the order of dictionary keys in assertion failure messages. | ||
Previously, dictionary diffs were shown in alphabetical order, regardless of how the keys appeared in the original dicts. | ||
Now, common keys are shown in the insertion order of the left-hand dictionary, | ||
and differing keys are shown in the insertion order of their respective dictionaries |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -348,8 +348,8 @@ def _compare_eq_iterable( | |
# dynamic import to speedup pytest | ||
import difflib | ||
|
||
left_formatting = PrettyPrinter().pformat(left).splitlines() | ||
right_formatting = PrettyPrinter().pformat(right).splitlines() | ||
left_formatting = PrettyPrinter(sort_dicts=False).pformat(left).splitlines() | ||
right_formatting = PrettyPrinter(sort_dicts=False).pformat(right).splitlines() | ||
|
||
explanation = ["", "Full diff:"] | ||
# "right" is the expected base against which we compare "left", | ||
|
@@ -505,29 +505,36 @@ def _compare_eq_dict( | |
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]} | ||
same = {k: left[k] for k in left if k in right and left[k] == right[k]} | ||
if same and verbose < 2: | ||
explanation += [f"Omitting {len(same)} identical items, use -vv to show"] | ||
elif same: | ||
explanation += ["Common items:"] | ||
explanation += highlighter(pprint.pformat(same)).splitlines() | ||
# Common items are displayed in the order of the left dict | ||
explanation += highlighter(pprint.pformat(same, sort_dicts=False)).splitlines() | ||
diff = {k for k in common if left[k] != right[k]} | ||
if diff: | ||
explanation += ["Differing items:"] | ||
for k in diff: | ||
explanation += [ | ||
highlighter(saferepr({k: left[k]})) | ||
+ " != " | ||
+ highlighter(saferepr({k: right[k]})) | ||
] | ||
# Differing items are displayed in the order of the left dict | ||
for k in left: | ||
if k in diff: | ||
explanation += [ | ||
highlighter(saferepr({k: left[k]})) | ||
+ " != " | ||
+ highlighter(saferepr({k: right[k]})) | ||
] | ||
extra_left = set_left - set_right | ||
len_extra_left = len(extra_left) | ||
if len_extra_left: | ||
explanation.append( | ||
f"Left contains {len_extra_left} more item{'' if len_extra_left == 1 else 's'}:" | ||
) | ||
explanation.extend( | ||
highlighter(pprint.pformat({k: left[k] for k in extra_left})).splitlines() | ||
highlighter( | ||
pprint.pformat( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This has the caveats of not working for nesting There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I've added a test case for nested dictionaries, and it appears to be working as expected. The |
||
{k: left[k] for k in left if k in extra_left}, sort_dicts=False | ||
) | ||
).splitlines() | ||
) | ||
extra_right = set_right - set_left | ||
len_extra_right = len(extra_right) | ||
|
@@ -536,7 +543,11 @@ def _compare_eq_dict( | |
f"Right contains {len_extra_right} more item{'' if len_extra_right == 1 else 's'}:" | ||
) | ||
explanation.extend( | ||
highlighter(pprint.pformat({k: right[k] for k in extra_right})).splitlines() | ||
highlighter( | ||
pprint.pformat( | ||
{k: right[k] for k in right if k in extra_right}, sort_dicts=False | ||
) | ||
).splitlines() | ||
) | ||
return explanation | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With your changes, the default behaviour of pytest is that dictionaries are not sorted alphabetically.
So the default behaviour is
sort_dicts = False
. But, the default value ofsort_dicts
isTrue
. It seems unintuitive.