Skip to content

Failure output order of dictionary keys is alphabetical instead of insertion order #13503

Open
@mcarans

Description

@mcarans
  1. Create a file like this:
class TestDictOrder:
    def test_dict_order(self):
        a = {
            "Existing Hash": "",
            "Existing Modified": "",
            "Existing Size": "",
            "Existing Broken": "",
            "Set Broken": "N",
            "Head Status": "",
            "Head Error": "",
            "Get Status": "",
            "Get Error": "",
            "New ETag": "",
            "ETag Changed": "",
            "New Modified": "",
            "Modified Changed": "",
            "Modified Newer": "",
            "Modified Value": "",
            "New Size": "",
            "Size Changed": "",
            "New Hash": "",
            "Hash Changed": "",
            "Update": "N",
        }
        print(a)
        assert a == {}
  1. run pytest with -vv
  2. The keys in the output failure message are not in insertion order (the guaranteed order since Python 3.7) but are displayed alphabetically instead (presumably because that's easier to implement?). I think there should be an option to have the output order be insertion order (or it should be the standard output order) as that can be helpful with debugging large and nested dictionaries and is the order when you print the dictionary.

In the output from pytest below, "Left contains 20 more items:" and "Full diff:" are alphabetical instead of insertion order:

1 > pytest -vv test_dict_order.py 
=================================================================================================================================== test session starts ===================================================================================================================================
platform linux -- Python 3.13.3, pytest-8.4.0, pluggy-1.6.0 -- /home/mcarans/Code/VirtualEnvs/scratch/bin/python
cachedir: .pytest_cache
rootdir: /home/mcarans/Code/scratch
plugins: typeguard-4.4.2
collected 1 item                                                                                                                                                                                                                                                                          

test_dict_order.py::TestDictOrder::test_dict_order FAILED                                                                                                                                                                                                                           [100%]

======================================================================================================================================== FAILURES =========================================================================================================================================
______________________________________________________________________________________________________________________________ TestDictOrder.test_dict_order ______________________________________________________________________________________________________________________________

self = <test_dict_order.TestDictOrder object at 0x7adebb01f890>

    def test_dict_order(self):
        a = {
            "Existing Hash": "",
            "Existing Modified": "",
            "Existing Size": "",
            "Existing Broken": "",
            "Set Broken": "N",
            "Head Status": "",
            "Head Error": "",
            "Get Status": "",
            "Get Error": "",
            "New ETag": "",
            "ETag Changed": "",
            "New Modified": "",
            "Modified Changed": "",
            "Modified Newer": "",
            "Modified Value": "",
            "New Size": "",
            "Size Changed": "",
            "New Hash": "",
            "Hash Changed": "",
            "Update": "N",
        }
        print(a)
>       assert a == {}
E       AssertionError: assert {'Existing Hash': '', 'Existing Modified': '', 'Existing Size': '', 'Existing Broken': '', 'Set Broken': 'N', 'Head Status': '', 'Head Error': '', 'Get Status': '', 'Get Error': '', 'New ETag': '', 'ETag Changed': '', 'New Modified': '', 'Modified Changed': '', 'Modified Newer': '', 'Modified Value': '', 'New Size': '', 'Size Changed': '', 'New Hash': '', 'Hash Changed': '', 'Update': 'N'} == {}
E         
E         Left contains 20 more items:
E         {'ETag Changed': '',
E          'Existing Broken': '',
E          'Existing Hash': '',
E          'Existing Modified': '',
E          'Existing Size': '',
E          'Get Error': '',
E          'Get Status': '',
E          'Hash Changed': '',
E          'Head Error': '',
E          'Head Status': '',
E          'Modified Changed': '',
E          'Modified Newer': '',
E          'Modified Value': '',
E          'New ETag': '',
E          'New Hash': '',
E          'New Modified': '',
E          'New Size': '',
E          'Set Broken': 'N',
E          'Size Changed': '',
E          'Update': 'N'}
E         
E         Full diff:
E         - {}
E         + {
E         +     'ETag Changed': '',
E         +     'Existing Broken': '',
E         +     'Existing Hash': '',
E         +     'Existing Modified': '',
E         +     'Existing Size': '',
E         +     'Get Error': '',
E         +     'Get Status': '',
E         +     'Hash Changed': '',
E         +     'Head Error': '',
E         +     'Head Status': '',
E         +     'Modified Changed': '',
E         +     'Modified Newer': '',
E         +     'Modified Value': '',
E         +     'New ETag': '',
E         +     'New Hash': '',
E         +     'New Modified': '',
E         +     'New Size': '',
E         +     'Set Broken': 'N',
E         +     'Size Changed': '',
E         +     'Update': 'N',
E         + }

test_dict_order.py:26: AssertionError
---------------------------------------------------------------------------------------------------------------------------------- Captured stdout call -----------------------------------------------------------------------------------------------------------------------------------
{'Existing Hash': '', 'Existing Modified': '', 'Existing Size': '', 'Existing Broken': '', 'Set Broken': 'N', 'Head Status': '', 'Head Error': '', 'Get Status': '', 'Get Error': '', 'New ETag': '', 'ETag Changed': '', 'New Modified': '', 'Modified Changed': '', 'Modified Newer': '', 'Modified Value': '', 'New Size': '', 'Size Changed': '', 'New Hash': '', 'Hash Changed': '', 'Update': 'N'}
================================================================================================================================= short test summary info =================================================================================================================================
FAILED test_dict_order.py::TestDictOrder::test_dict_order - AssertionError: assert {'Existing Hash': '', 'Existing Modified': '', 'Existing Size': '', 'Existing Broken': '', 'Set Broken': 'N', 'Head Status': '', 'Head Error': '', 'Get Status': '', 'Get Error': '', 'New ETag': '', 'ETag Changed': '', 'New Modified': '', 'Modified Changed': '', 'Modified Newer': '', 'Modified Value': '', 'New Size': '', 'Size Changed': '', 'New Hash': '', 'Hash Changed': '', 'Update': 'N'} == {}
  
  Left contains 20 more items:
  {'ETag Changed': '',
   'Existing Broken': '',
   'Existing Hash': '',
   'Existing Modified': '',
   'Existing Size': '',
   'Get Error': '',
   'Get Status': '',
   'Hash Changed': '',
   'Head Error': '',
   'Head Status': '',
   'Modified Changed': '',
   'Modified Newer': '',
   'Modified Value': '',
   'New ETag': '',
   'New Hash': '',
   'New Modified': '',
   'New Size': '',
   'Set Broken': 'N',
   'Size Changed': '',
   'Update': 'N'}
  
  Full diff:
  - {}
  + {
  +     'ETag Changed': '',
  +     'Existing Broken': '',
  +     'Existing Hash': '',
  +     'Existing Modified': '',
  +     'Existing Size': '',
  +     'Get Error': '',
  +     'Get Status': '',
  +     'Hash Changed': '',
  +     'Head Error': '',
  +     'Head Status': '',
  +     'Modified Changed': '',
  +     'Modified Newer': '',
  +     'Modified Value': '',
  +     'New ETag': '',
  +     'New Hash': '',
  +     'New Modified': '',
  +     'New Size': '',
  +     'Set Broken': 'N',
  +     'Size Changed': '',
  +     'Update': 'N',
  + }
==================================================================================================================================== 1 failed in 0.03s ====================================================================================================================================
[

Metadata

Metadata

Assignees

No one assigned

    Labels

    good first issueeasy issue that is friendly to new contributor

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions