diff --git a/changelog/14050.bugfix.rst b/changelog/14050.bugfix.rst deleted file mode 100644 index 451b248576f..00000000000 --- a/changelog/14050.bugfix.rst +++ /dev/null @@ -1 +0,0 @@ -Display dictionary differences in assertion failures using the original key insertion order instead of sorted order. diff --git a/src/_pytest/_io/pprint.py b/src/_pytest/_io/pprint.py index ec41b449ddf..28f06909206 100644 --- a/src/_pytest/_io/pprint.py +++ b/src/_pytest/_io/pprint.py @@ -162,7 +162,7 @@ def _pprint_dict( ) -> None: write = stream.write write("{") - items = object.items() + items = sorted(object.items(), key=_safe_tuple) self._format_dict_items(items, stream, indent, allowance, context, level) write("}") @@ -608,7 +608,7 @@ def _safe_repr( components: list[str] = [] append = components.append level += 1 - for k, v in object.items(): + for k, v in sorted(object.items(), key=_safe_tuple): krepr = self._safe_repr(k, context, maxlevels, level) vrepr = self._safe_repr(v, context, maxlevels, level) append(f"{krepr}: {vrepr}") diff --git a/src/_pytest/_io/saferepr.py b/src/_pytest/_io/saferepr.py index 3f5c956d9cf..cee70e332f9 100644 --- a/src/_pytest/_io/saferepr.py +++ b/src/_pytest/_io/saferepr.py @@ -1,6 +1,5 @@ from __future__ import annotations -from itertools import islice import pprint import reprlib @@ -78,32 +77,8 @@ def repr_instance(self, x: object, level: int) -> str: s = _format_repr_exception(exc, x) if self.maxsize is not None: s = _ellipsize(s, self.maxsize) - return s - def repr_dict(self, x: dict[object, object], level: int) -> str: - """Represent a dict while preserving its insertion order. - - Differs from ``reprlib.Repr.repr_dict`` by iterating directly over ``x`` - rather than using the stdlib's sorting helper. - """ - fillvalue = "..." - n = len(x) - if n == 0: - return "{}" - if level <= 0: - return "{" + fillvalue + "}" - newlevel = level - 1 - repr1 = self.repr1 - pieces = [] - for key in islice(x, self.maxdict): - keyrepr = repr1(key, newlevel) - valrepr = repr1(x[key], newlevel) - pieces.append(f"{keyrepr}: {valrepr}") - if n > self.maxdict: - pieces.append(fillvalue) - return "{" + ", ".join(pieces) + "}" - def safeformat(obj: object) -> str: """Return a pretty printed string for the given object. diff --git a/src/_pytest/pytester_assertions.py b/src/_pytest/pytester_assertions.py index b8d8a195241..915cc8a10ff 100644 --- a/src/_pytest/pytester_assertions.py +++ b/src/_pytest/pytester_assertions.py @@ -26,11 +26,11 @@ def assertoutcome( realpassed, realskipped, realfailed = outcomes obtained = { - "failed": len(realfailed), "passed": len(realpassed), "skipped": len(realskipped), + "failed": len(realfailed), } - expected = {"failed": failed, "passed": passed, "skipped": skipped} + expected = {"passed": passed, "skipped": skipped, "failed": failed} assert obtained == expected, outcomes diff --git a/testing/io/test_saferepr.py b/testing/io/test_saferepr.py index 2e3dd55b81f..075d40cdf44 100644 --- a/testing/io/test_saferepr.py +++ b/testing/io/test_saferepr.py @@ -2,7 +2,6 @@ from __future__ import annotations from _pytest._io.saferepr import DEFAULT_REPR_MAX_SIZE -from _pytest._io.saferepr import SafeRepr from _pytest._io.saferepr import saferepr from _pytest._io.saferepr import saferepr_unlimited import pytest @@ -193,39 +192,3 @@ def __repr__(self): assert saferepr_unlimited(A()).startswith( "<[ValueError(42) raised in repr()] A object at 0x" ) - - -def test_saferepr_dict_preserves_insertion_order() -> None: - d = { - "b": 2, - "a": 1, - "d": 4, - "e": 5, - "c": 3, - } - s = SafeRepr(maxsize=None) - s.maxdict = 10 - assert s.repr(d) == "{'b': 2, 'a': 1, 'd': 4, 'e': 5, 'c': 3}" - - -def test_saferepr_dict_truncation_preserves_insertion_order() -> None: - d = { - "b": 2, - "a": 1, - "d": 4, - "e": 5, - "c": 3, - } - s = SafeRepr(maxsize=None) - s.maxdict = 1 - assert s.repr(d) == "{'b': 2, ...}" - - -def test_saferepr_dict_fillvalue_when_level_is_zero() -> None: - s = SafeRepr(maxsize=None) - assert s.repr_dict({"a": 1}, level=0) == "{...}" - - -def test_saferepr_dict_empty() -> None: - s = SafeRepr(maxsize=None) - assert s.repr_dict({}, level=1) == "{}" diff --git a/testing/test_assertion.py b/testing/test_assertion.py index 12351a48a7f..5179b13b0e9 100644 --- a/testing/test_assertion.py +++ b/testing/test_assertion.py @@ -2198,34 +2198,3 @@ def test_vvv(): ] ) result.stdout.no_fnmatch_line(expected_non_vvv_arg_line) - - -def test_dict_extra_items_preserve_insertion_order(pytester: Pytester) -> None: - """Assertion output of dict diff shows keys in insertion order (#13503).""" - pytester.makepyfile( - test_order=""" - def test_order(): - a = { - "b": 2, - "a": 1, - "d": 4, - "e": 5, - "c": 3, - } - assert a == {} - """ - ) - - result = pytester.runpytest("-vv") - result.stdout.fnmatch_lines( - [ - "*Left contains 5 more items:*", - "*Full diff:", - "* + *'b': 2,", - "* + *'a': 1,", - "* + *'d': 4,", - "* + *'e': 5,", - "* + *'c': 3,", - "test_order.py:*: AssertionError", - ] - )