From 0262fd300dfe521811478255af87e38008b6896b Mon Sep 17 00:00:00 2001 From: Rafi Date: Fri, 26 Dec 2025 18:14:14 +0530 Subject: [PATCH 1/4] Preserve insertion order for extra dict items in assertion output --- src/_pytest/assertion/util.py | 4 ++-- testing/test_assertion.py | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/src/_pytest/assertion/util.py b/src/_pytest/assertion/util.py index f35d83a6fe4..a5bcc5d02ad 100644 --- a/src/_pytest/assertion/util.py +++ b/src/_pytest/assertion/util.py @@ -520,7 +520,7 @@ def _compare_eq_dict( + " != " + highlighter(saferepr({k: right[k]})) ] - extra_left = set_left - set_right + extra_left = [k for k in left if k not in right] len_extra_left = len(extra_left) if len_extra_left: explanation.append( @@ -529,7 +529,7 @@ def _compare_eq_dict( explanation.extend( highlighter(pprint.pformat({k: left[k] for k in extra_left})).splitlines() ) - extra_right = set_right - set_left + extra_right = [k for k in right if k not in left] len_extra_right = len(extra_right) if len_extra_right: explanation.append( diff --git a/testing/test_assertion.py b/testing/test_assertion.py index 5179b13b0e9..a9cb1075dec 100644 --- a/testing/test_assertion.py +++ b/testing/test_assertion.py @@ -2198,3 +2198,36 @@ def test_vvv(): ] ) result.stdout.no_fnmatch_line(expected_non_vvv_arg_line) + +import re + +def test_dict_extra_items_preserve_insertion_order(pytester): + pytester.makepyfile( + test_order=""" + def test_order(): + a = { + "first": 1, + "second": 2, + } + assert a == {} + """ + ) + + result = pytester.runpytest() + + stdout = result.stdout.str() + stdout = re.sub(r"\x1b\[[0-9;]*m", "", stdout) + + assert "Left contains 2 more items:" in stdout + + dict_line = next( + line for line in stdout.splitlines() + if "{" in line and "}" in line and "first" in line + ) + + first = dict_line.find("first") + second = dict_line.find("second") + + assert first != -1 and second != -1 + assert first < second + From 5bb95f2f68150bc812a68fe562a953c02deb7eeb Mon Sep 17 00:00:00 2001 From: RafiB982 Date: Wed, 31 Dec 2025 09:40:49 +0530 Subject: [PATCH 2/4] Fix changelog entry for #13503 --- changelog/13503.bugfix.rst | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 changelog/13503.bugfix.rst diff --git a/changelog/13503.bugfix.rst b/changelog/13503.bugfix.rst new file mode 100644 index 00000000000..3c262652c38 --- /dev/null +++ b/changelog/13503.bugfix.rst @@ -0,0 +1,2 @@ +Preserved insertion order for extra dictionary items in assertion failure output. +Display dictionary differences in assertion failures using the original key insertion order instead of sorted order. From 69ce9532a01755d7fff1010b2fdf911b7abacbc7 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 31 Dec 2025 04:13:40 +0000 Subject: [PATCH 3/4] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- testing/test_assertion.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/testing/test_assertion.py b/testing/test_assertion.py index a9cb1075dec..ae989cc9e54 100644 --- a/testing/test_assertion.py +++ b/testing/test_assertion.py @@ -2199,8 +2199,10 @@ def test_vvv(): ) result.stdout.no_fnmatch_line(expected_non_vvv_arg_line) + import re + def test_dict_extra_items_preserve_insertion_order(pytester): pytester.makepyfile( test_order=""" @@ -2221,7 +2223,8 @@ def test_order(): assert "Left contains 2 more items:" in stdout dict_line = next( - line for line in stdout.splitlines() + line + for line in stdout.splitlines() if "{" in line and "}" in line and "first" in line ) @@ -2230,4 +2233,3 @@ def test_order(): assert first != -1 and second != -1 assert first < second - From 7e7f10096a94bcd47d731fd9d624ab8f7500731d Mon Sep 17 00:00:00 2001 From: RafiB982 Date: Wed, 31 Dec 2025 10:03:35 +0530 Subject: [PATCH 4/4] Fix import order in test_assertion --- testing/test_assertion.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/testing/test_assertion.py b/testing/test_assertion.py index ae989cc9e54..94bb6827ff6 100644 --- a/testing/test_assertion.py +++ b/testing/test_assertion.py @@ -2,6 +2,7 @@ from __future__ import annotations from collections.abc import MutableSequence +import re import sys import textwrap from typing import Any @@ -2200,9 +2201,6 @@ def test_vvv(): result.stdout.no_fnmatch_line(expected_non_vvv_arg_line) -import re - - def test_dict_extra_items_preserve_insertion_order(pytester): pytester.makepyfile( test_order="""