pytest-dev/pytest · error · AssertionError
approx() is not supported in a boolean context. Did you…
Error message
approx() is not supported in a boolean context. Did you mean: `assert a == approx(b)`?
What it means
pytest.approx() returns an Approx object whose only meaningful operation is equality comparison (e.g. `a == approx(b)`). The class deliberately defines __bool__ to raise AssertionError so that misuses like `assert approx(x)` or `if approx(x):` fail loudly instead of silently passing or failing. pytest throws this because a bare truthiness check on an Approx value has no sensible meaning and would otherwise evaluate to True/False unpredictably.
Solutions
- Always write approx() on the right-hand side of ==: `assert actual == approx(expected)`.
- If you stored approx in a variable, compare it explicitly: `assert actual == expected_approx`.
- Search the failing test file for `assert approx(` (regex) and add the missing `actual ==` operand.
Example fix
# before assert approx(0.3) # after assert 0.1 + 0.2 == approx(0.3)
Defensive patterns
Strategy: validation
Validate before calling
# Before using an approx value, ensure it is always compared, never evaluated as bool.
# Static check (regex in pre-commit / lint): reject `assert approx(` without `==`.
import re
def assert_uses_comparison(line: str) -> bool:
# flag bare `assert approx(...)` or `assert <name> ` where name holds an Approx
return bool(re.search(r'\bassert\s+approx\(', line)) and '==' not in line Type guard
from pytest import Approx
def is_approx(obj) -> bool:
return isinstance(obj, Approx) Prevention
- Always write approx() on the right of ==: assert actual == approx(expected).
- Lint for the regex `assert\s+approx\(` to catch bare boolean-context usage.
- Never pass an Approx object to a function that evaluates truthiness.
When it happens
Trigger: Calling bool(approx(x)), using approx(x) in an if/while/and/or expression, writing `assert approx(x)` without a comparison operand, passing approx(x) to a function that evaluates its argument's truthiness, or storing the result and later using it in a conditional. Triggered at Approx.__bool__ (src/_pytest/approx.py:110-114).
Common situations: Copy-pasting a test skeleton and forgetting the left-hand operand (assert approx(expected) instead of assert actual == approx(expected)); refactoring a comparison into a helper that returns the approx object; using approx() with pytest.warns/raises which evaluate truthiness of the returned context.
Related errors
- pytest.approx() does not support nan_ok for…
- absolute tolerance can't be NaN.
- absolute tolerance can't be negative
- absolute tolerance for a scalar value must be an int, float…
- cannot compare ' ' to numpy.ndarray
AI-assisted analysis of pytest-dev/pytest@0d6fbdeffa (2026-08-11).
Data as JSON: /api/errors/05b56d3b2fda749a.
Report an issue: GitHub.
Appendix: source
Thrown at src/_pytest/approx.py:112
@abc.abstractmethod
def __repr__(self) -> str:
raise NotImplementedError
def _repr_compare(self, other_side) -> list[str]:
return [
"comparison failed",
f"Obtained: {other_side}",
f"Expected: {self}",
]
def __eq__(self, actual) -> bool:
return all(
a == self._approx_scalar(x) for a, x in self._yield_comparisons(actual)
)
def __bool__(self):
__tracebackhide__ = True
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
def _approx_scalar(self, x) -> ApproxScalar[Any] | ApproxTimedelta:
if isinstance(x, Decimal):
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)
return ApproxScalar(x, rel=self.rel, abs=self.abs, nan_ok=self.nan_ok)
def _yield_comparisons(self, actual: object):
"""Yield all the pairs of numbers to be compared.
This is used to implement the `__eq__` method.
"""View on GitHub (pinned to 0d6fbdeffa)