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 changelog/8703.bugfix.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fixed ``pytest.approx()`` silently falling back to exact equality when a dict value is itself a list or dict. Nested sequences and mappings are now compared with the same tolerance as top-level ones.
4 changes: 4 additions & 0 deletions src/_pytest/python_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,10 @@ def _approx_scalar(self, x) -> ApproxBase:
return ApproxDecimal(x, rel=self.rel, abs=self.abs, nan_ok=self.nan_ok)
if isinstance(x, (datetime, timedelta)):
return ApproxTimedelta(x, rel=self.rel, abs=self.abs, nan_ok=self.nan_ok)
if isinstance(x, Mapping):
return ApproxMapping(x, rel=self.rel, abs=self.abs, nan_ok=self.nan_ok)
if _is_sequence_like(x):
return ApproxSequenceLike(x, rel=self.rel, abs=self.abs, nan_ok=self.nan_ok)
return ApproxScalar(x, rel=self.rel, abs=self.abs, nan_ok=self.nan_ok)

def _yield_comparisons(self, actual):
Expand Down
8 changes: 8 additions & 0 deletions testing/python/approx.py
Original file line number Diff line number Diff line change
Expand Up @@ -679,6 +679,10 @@ def test_list_wrong_len(self):
assert [1, 2] != approx([1])
assert [1, 2] != approx([1, 2, 3])

def test_list_with_dict_elements(self):
assert [{"a": 1.0 + 1e-7}] == approx([{"a": 1.0}], abs=1e-5)
assert [{"a": 1.0 + 1e-4}] != approx([{"a": 1.0}], abs=1e-5)

def test_tuple(self):
actual = (1 + 1e-7, 2 + 1e-8)
expected = (1, 2)
Expand Down Expand Up @@ -726,6 +730,10 @@ def test_dict_nonnumeric(self):
assert {"a": 1.0, "b": 1} != pytest.approx({"a": 1.0, "b": None})
assert {"a": 1.0, "b": True} != pytest.approx({"a": 1.0, "b": False}, abs=2)

def test_dict_with_list_values(self):
assert {"a": [1.0, 2.0 + 1e-7]} == approx({"a": [1.0, 2.0]}, abs=1e-5)
assert {"a": [1.0, 2.0 + 1e-4]} != approx({"a": [1.0, 2.0]}, abs=1e-5)

def test_dict_vs_other(self):
assert 1 != approx({"a": 0})

Expand Down
Loading