- 
          
 - 
                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
              a6c7310
              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_dictsisTrue. It seems unintuitive.