Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions AUTHORS
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ Carlos Jenkins
Ceridwen
Charles Cloud
Charles Machalow
Charles-Meldhine Madi Mnemoi (cmnemoi)
Charnjit SiNGH (CCSJ)
Cheuk Ting Ho
Chris Mahoney
Expand Down
1 change: 1 addition & 0 deletions changelog/13816.bugfix.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fixed :func:`pytest.approx` which now returns a clearer error message when comparing mappings with different keys.
6 changes: 6 additions & 0 deletions src/_pytest/python_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,12 @@ def _repr_compare(self, other_side: Mapping[object, float]) -> list[str]:
f"Lengths: {len(self.expected)} and {len(other_side)}",
]

if set(self.expected.keys()) != set(other_side.keys()):
return [
"comparison failed.",
f"Mappings has different keys: expected {self.expected.keys()} but got {other_side.keys()}",
]

approx_side_as_map = {
k: self._approx_scalar(v) for k, v in self.expected.items()
}
Expand Down
15 changes: 15 additions & 0 deletions testing/python/approx.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import operator
from operator import eq
from operator import ne
import re

from _pytest.pytester import Pytester
from _pytest.python_api import _recursive_sequence_map
Expand Down Expand Up @@ -1048,6 +1049,20 @@ def test_strange_sequence(self):
assert b == pytest.approx(a, abs=2)
assert b != pytest.approx(a, abs=0.5)

def test_approx_dicts_with_mismatch_on_keys(self) -> None:
"""https://github.com/pytest-dev/pytest/issues/13816"""
expected = {"a": 1, "b": 3}
actual = {"a": 1, "c": 3}

with pytest.raises(
AssertionError,
match=re.escape(
"comparison failed.\n Mappings has different keys: "
"expected dict_keys(['a', 'b']) but got dict_keys(['a', 'c'])"
),
):
assert actual == approx(expected)


class MyVec3: # incomplete
"""sequence like"""
Expand Down