From 807beb5fd6b38ff82577ca0c9d119976274300c9 Mon Sep 17 00:00:00 2001 From: Kale Kundert Date: Mon, 30 Aug 2021 11:44:45 -0400 Subject: [PATCH 1/5] fix: prevent approx from being used without a comparison --- src/_pytest/python_api.py | 3 +++ testing/python/approx.py | 6 ++++++ 2 files changed, 9 insertions(+) diff --git a/src/_pytest/python_api.py b/src/_pytest/python_api.py index 847991a3708..40542d5f98b 100644 --- a/src/_pytest/python_api.py +++ b/src/_pytest/python_api.py @@ -100,6 +100,9 @@ def __eq__(self, actual) -> bool: a == self._approx_scalar(x) for a, x in self._yield_comparisons(actual) ) + def __bool__(self): + raise AssertionError("use approx() like this: `assert a == approx(b)`") + # Ignore type because of https://github.com/python/mypy/issues/4266. __hash__ = None # type: ignore diff --git a/testing/python/approx.py b/testing/python/approx.py index d4a152f3ea4..022829e5bf0 100644 --- a/testing/python/approx.py +++ b/testing/python/approx.py @@ -319,6 +319,12 @@ def test_repr_nd_array(self, value, expected_repr_string): np_array = np.array(value) assert repr(approx(np_array)) == expected_repr_string + def test_bool(self): + with pytest.raises(AssertionError) as err: + assert approx(1) + + assert err.match(r"use approx\(\) like this") + def test_operator_overloading(self): assert 1 == approx(1, rel=1e-6, abs=1e-12) assert not (1 != approx(1, rel=1e-6, abs=1e-12)) From b669e56f8bd10564222a75985b8ee6cafb351b53 Mon Sep 17 00:00:00 2001 From: Kale Kundert Date: Mon, 30 Aug 2021 13:05:27 -0400 Subject: [PATCH 2/5] chore: address requested changes --- changelog/9061.improvement.rst | 15 +++++++++++++++ src/_pytest/python_api.py | 2 +- testing/python/approx.py | 2 +- 3 files changed, 17 insertions(+), 2 deletions(-) create mode 100644 changelog/9061.improvement.rst diff --git a/changelog/9061.improvement.rst b/changelog/9061.improvement.rst new file mode 100644 index 00000000000..bf639e13214 --- /dev/null +++ b/changelog/9061.improvement.rst @@ -0,0 +1,15 @@ +Using :func:`pytest.approx` in a boolean context now raises an error hinting at the proper usage. + +It is apparently common for users to mistakenly use ``pytest.approx`` like this: + +.. code-block:: python + + assert pytest.approx(actual, expected) + +While the correct usage is: + +.. code-block:: python + + assert actual == pytest.approx(expected) + +The new error message helps catch those mistakes. diff --git a/src/_pytest/python_api.py b/src/_pytest/python_api.py index 40542d5f98b..6fb8c260c2e 100644 --- a/src/_pytest/python_api.py +++ b/src/_pytest/python_api.py @@ -101,7 +101,7 @@ def __eq__(self, actual) -> bool: ) def __bool__(self): - raise AssertionError("use approx() like this: `assert a == approx(b)`") + raise AssertionError("approx() is not supported in a boolean context.\nDid you mean: `assert a == approx(b)`") # Ignore type because of https://github.com/python/mypy/issues/4266. __hash__ = None # type: ignore diff --git a/testing/python/approx.py b/testing/python/approx.py index 022829e5bf0..0d411d8a6da 100644 --- a/testing/python/approx.py +++ b/testing/python/approx.py @@ -323,7 +323,7 @@ def test_bool(self): with pytest.raises(AssertionError) as err: assert approx(1) - assert err.match(r"use approx\(\) like this") + assert err.match(r"approx\(\) is not supported in a boolean context") def test_operator_overloading(self): assert 1 == approx(1, rel=1e-6, abs=1e-12) From 71d9bf52ef6eb7c21933062d6f507b3a3b919c3e Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 30 Aug 2021 17:05:38 +0000 Subject: [PATCH 3/5] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- src/_pytest/python_api.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/_pytest/python_api.py b/src/_pytest/python_api.py index 6fb8c260c2e..0f93eb08c92 100644 --- a/src/_pytest/python_api.py +++ b/src/_pytest/python_api.py @@ -101,7 +101,9 @@ def __eq__(self, actual) -> bool: ) def __bool__(self): - raise AssertionError("approx() is not supported in a boolean context.\nDid you mean: `assert a == approx(b)`") + raise AssertionError( + "approx() is not supported in a boolean context.\nDid you mean: `assert a == approx(b)`" + ) # Ignore type because of https://github.com/python/mypy/issues/4266. __hash__ = None # type: ignore From 581c8bb0788b723d449eab1c60e70abccb0272c2 Mon Sep 17 00:00:00 2001 From: Kale Kundert Date: Mon, 30 Aug 2021 13:13:59 -0400 Subject: [PATCH 4/5] tweak error message Co-authored-by: Bruno Oliveira --- src/_pytest/python_api.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/_pytest/python_api.py b/src/_pytest/python_api.py index 0f93eb08c92..8332bbe0a7b 100644 --- a/src/_pytest/python_api.py +++ b/src/_pytest/python_api.py @@ -102,7 +102,7 @@ def __eq__(self, actual) -> bool: def __bool__(self): raise AssertionError( - "approx() is not supported in a boolean context.\nDid you mean: `assert a == approx(b)`" + "approx() is not supported in a boolean context.\nDid you mean: `assert a == approx(b)`?" ) # Ignore type because of https://github.com/python/mypy/issues/4266. From 6e79e9d5551018b743adafa043f41be0cf2ba4f8 Mon Sep 17 00:00:00 2001 From: Kale Kundert Date: Mon, 30 Aug 2021 14:04:01 -0400 Subject: [PATCH 5/5] rename changelog file --- changelog/{9061.improvement.rst => 9061.breaking.rst} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename changelog/{9061.improvement.rst => 9061.breaking.rst} (100%) diff --git a/changelog/9061.improvement.rst b/changelog/9061.breaking.rst similarity index 100% rename from changelog/9061.improvement.rst rename to changelog/9061.breaking.rst