`pytest.approx` does not raise in mixed data type nested structures
description
when using pytest.approx on nested data structures I'd expect it to raise an exception also for mixed data type containers like a tuple in a list. So far it only works for the same data types e.g. lists in lists, tuples in tuples.
For mixed data structures it incorrectly returns False, even though they should match which is a little misleading (also see below).
output of pip list
(venv) kittnjdr@ububox:~/workspace/pytest$ pip list
Package Version Editable project location
---------- ----------------------- -------------------------------
attrs 22.1.0
iniconfig 1.1.1
packaging 21.3
pip 22.1.2
pluggy 1.0.0
py 1.11.0
pyparsing 3.0.9
pytest 7.2.0.dev232+gcc0092b9d /home/kittnjdr/workspace/pytest
setuptools 63.2.0
tomli 2.0.1
wheel 0.37.1
versions
- pytest: main branch
- OS: ubuntu 22.04
minimal reproduction
>>> import pytest
>>> [(1.0001,)] == pytest.approx([(1,)], rel=1e-2)
False
>>> ({1.0001},) == pytest.approx(({1},), rel=1e-2)
False
>>> ({"key": 1.0001},) == pytest.approx(({"key": 1},), rel=1e-2)
False
>>> (1.0001,) == pytest.approx((1,), rel=1e-2)
True
>>> ((1.0001,),) == pytest.approx(((1,),), rel=1e-2)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/kittnjdr/workspace/pytest/src/_pytest/python_api.py", line 744, in approx
return cls(expected, rel, abs, nan_ok)
File "/home/kittnjdr/workspace/pytest/src/_pytest/python_api.py", line 86, in __init__
self._check_type()
File "/home/kittnjdr/workspace/pytest/src/_pytest/python_api.py", line 381, in _check_type
raise TypeError(msg.format(x, index, pprint.pformat(self.expected)))
TypeError: pytest.approx() does not support nested data structures: (1,) at index 0
full sequence: ((1,),)
however, it works fine if both are exactly the same, but here I'd also expect an exception instead of a result (which is correct, but maybe unintentional)
>>> [(1.0,)] == pytest.approx([(1.0,)])
True
test cases
These test cases fail, but should pass with the potential bug fixed.
diff --git a/testing/python/approx.py b/testing/python/approx.py
index 6acb466ff..31dd4638b 100644
--- a/testing/python/approx.py
+++ b/testing/python/approx.py
@@ -781,6 +781,10 @@ class TestApprox:
"x, name",
[
pytest.param([[1]], "data structures", id="nested-list"),
+ pytest.param([(1,)], "data structures", id="nested-list-tuple"),
+ pytest.param([{1}], "data structures", id="nested-list-set"),
+ pytest.param([{"key": 1}], "data structures", id="nested-list-dict"),
pytest.param({"key": {"key": 1}}, "dictionaries", id="nested-dict"),
],
)
I'm gonna try taking a look at this one, will update if I get stuck(this is my first issue in this project).
This might be a tricky one, since some fundamental changes might be necessary. Ronny wrote:
I agree, feature creep happened, problem is that with a surround for the collection, the errors can't be done sanely
We just finished some early design discussions about that last month and it will take a while to manifest
I released the PR anyway, if anything it might be a decent temporary fix.
Hey guys! Not sure what is the state of this issue, but the bug is still there:
>>> pytest.approx([{"a": 0.1}], rel=1e-1) == [{"a": 0.11}]
False
>>> pytest.approx(0.1, rel=1e-1) == 0.11
True
Pytest version is 7.2.0