-
-
Notifications
You must be signed in to change notification settings - Fork 3k
Fix: Preserve dict insertion order in assertion output #14116
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
Fix: Preserve dict insertion order in assertion output #14116
Conversation
Remove sorted() calls in PrettyPrinter to preserve dict insertion order. Since Python 3.7+, dicts maintain insertion order. Sorting keys alphabetically in assertion failures is confusing and doesn't match how Python naturally displays dicts. Changes: - _pprint_dict: Remove sorted() on object.items() - _safe_repr: Remove sorted() on dict.items() iteration Fixes pytest-dev#13503
Add test_dict_preserves_insertion_order to verify that dictionary keys maintain their insertion order in assertion output, not alphabetical order. This test ensures the fix for issue pytest-dev#13503 works correctly and prevents future regressions. Related to pytest-dev#13503
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.
Pull request overview
This PR fixes issue #13503 by preserving dictionary insertion order in assertion failure output instead of sorting keys alphabetically, aligning pytest's output with Python 3.7+ dict behavior.
Changes:
- Removed alphabetical sorting of dictionary keys in
PrettyPrinterclass methods - Added test to verify insertion order preservation
- Added changelog entry documenting the bugfix
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| src/_pytest/_io/pprint.py | Removed sorted() calls in _pprint_dict and _safe_repr methods to preserve dict insertion order |
| testing/io/test_pprint.py | Added test_dict_preserves_insertion_order test to verify insertion order is maintained |
| changelog/13503.bugfix.rst | Added changelog entry documenting the bugfix |
Comments suppressed due to low confidence (1)
src/_pytest/_io/pprint.py:37
- The docstring's last sentence mentions 'dict.items() must have _safe_key applied' which is now outdated since the PR removes sorting from dict items. While
_safe_keyis still used for sets (line 239), the documentation should be clarified to avoid confusion. Consider updating to: 'Does not work recursively, so for collections that are sorted (like sets), both key and value must have _safe_key applied.'
class _safe_key:
"""Helper function for key functions when sorting unorderable objects.
The wrapped-object will fallback to a Py2.x style comparison for
unorderable types (sorting first comparing the type name and then by
the obj ids). Does not work recursively, so dict.items() must have
_safe_key applied to both the key and the value.
"""
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
46d077d to
1d2980d
Compare
for more information, see https://pre-commit.ci
Improve code coverage by adding test that triggers the _safe_repr code path with depth limiting, ensuring both modified lines in pprint.py are fully covered. This addresses Codecov target of 100% diff coverage.
for more information, see https://pre-commit.ci
Call _safe_repr directly to ensure the dict sorting code path in _safe_repr is tested, achieving 100% diff coverage.
for more information, see https://pre-commit.ci
|
Thanks, but duplicate of #14066. |
Summary
This PR fixes issue #13503 by preserving dictionary insertion order in assertion failure output instead of sorting keys alphabetically.
Problem
Since Python 3.7+, dictionaries maintain insertion order. However, pytest's assertion output was sorting dictionary keys alphabetically, which:
Solution
Removed
sorted()calls in thePrettyPrinterclass:_pprint_dictmethod: Changedsorted(object.items(), key=_safe_tuple)toobject.items()_safe_reprmethod: Changedsorted(object.items(), key=_safe_tuple)toobject.items()Changes
src/_pytest/_io/pprint.pyto preserve dict insertion order (2 lines changed)test_dict_preserves_insertion_orderintesting/io/test_pprint.py(33 lines added)Example
Before:
After:
Closes #13503