Skip to content

Commit af42e71

Browse files
authored
Prevent approx from being used without a comparison (#9061)
Some of the top search-engine hits for pytest.approx use the function without actually comparing it to anything. This PR will cause these tests to fail by implementing approx.__bool__() to raise an AssertionError that briefly explains how to correctly use approx.
1 parent 771c4b9 commit af42e71

File tree

3 files changed

+26
-0
lines changed

3 files changed

+26
-0
lines changed

changelog/9061.breaking.rst

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
Using :func:`pytest.approx` in a boolean context now raises an error hinting at the proper usage.
2+
3+
It is apparently common for users to mistakenly use ``pytest.approx`` like this:
4+
5+
.. code-block:: python
6+
7+
assert pytest.approx(actual, expected)
8+
9+
While the correct usage is:
10+
11+
.. code-block:: python
12+
13+
assert actual == pytest.approx(expected)
14+
15+
The new error message helps catch those mistakes.

src/_pytest/python_api.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,11 @@ def __eq__(self, actual) -> bool:
100100
a == self._approx_scalar(x) for a, x in self._yield_comparisons(actual)
101101
)
102102

103+
def __bool__(self):
104+
raise AssertionError(
105+
"approx() is not supported in a boolean context.\nDid you mean: `assert a == approx(b)`?"
106+
)
107+
103108
# Ignore type because of https://github.com/python/mypy/issues/4266.
104109
__hash__ = None # type: ignore
105110

testing/python/approx.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -319,6 +319,12 @@ def test_repr_nd_array(self, value, expected_repr_string):
319319
np_array = np.array(value)
320320
assert repr(approx(np_array)) == expected_repr_string
321321

322+
def test_bool(self):
323+
with pytest.raises(AssertionError) as err:
324+
assert approx(1)
325+
326+
assert err.match(r"approx\(\) is not supported in a boolean context")
327+
322328
def test_operator_overloading(self):
323329
assert 1 == approx(1, rel=1e-6, abs=1e-12)
324330
assert not (1 != approx(1, rel=1e-6, abs=1e-12))

0 commit comments

Comments
 (0)