pytest-dev/pytest · error · TypeError
pytest.approx() requires an explicit tolerance for…
Error message
pytest.approx() requires an explicit tolerance for datetime/timedelta comparisons: e.g. approx(expected, abs=timedelta(seconds=1)) or approx(expected, rel=0.01)
What it means
ApproxTimedelta.__init__ requires at least one explicit tolerance (abs or rel) for datetime/timedelta comparisons, unlike scalars which default to rel=1e-6/abs=1e-12. datetime/timedelta have no sensible default tolerance window (1e-6 of what unit?), so pytest refuses to guess. The error suggests both valid forms. The check fires when both abs and rel are None.
Solutions
- For datetime, pass an absolute timedelta: `approx(dt, abs=timedelta(seconds=1))`.
- For timedelta, pass rel (a number, fraction of the duration) or abs: `approx(td, rel=0.01)` or `approx(td, abs=timedelta(milliseconds=10))`.
- Centralize the chosen tolerance in a fixture/constant to keep datetime assertions consistent.
Example fix
# before assert actual_dt == approx(expected_dt) # after assert actual_dt == approx(expected_dt, abs=timedelta(seconds=1))
Defensive patterns
Strategy: validation
Validate before calling
from datetime import datetime, timedelta
def ensure_datetime_tolerance(expected, rel, abs):
if isinstance(expected, (datetime, timedelta)) and rel is None and abs is None:
if isinstance(expected, datetime):
return {'abs': timedelta(seconds=1)}
return {'rel': 0.01}
return {'rel': rel, 'abs': abs}
# usage
assert actual == approx(expected, **ensure_datetime_tolerance(expected, rel, abs)) Type guard
from datetime import datetime, timedelta
def needs_explicit_tolerance(expected) -> bool:
return isinstance(expected, (datetime, timedelta)) Prevention
- Always pass abs=timedelta(...) (or rel for timedelta) for time comparisons.
- Centralize datetime tolerance in a fixture/constant.
- Add a helper that injects a default tolerance for datetime/timedelta.
When it happens
Trigger: Calling approx(datetime.now()); approx(timedelta(seconds=5)); approx(dt) with no keyword args. Triggered at ApproxTimedelta.__init__ (src/_pytest/approx.py:656-662).
Common situations: Migrating a numeric approx() call to datetime without adding tolerance; assuming a default tolerance exists; refactoring a test to use datetime while keeping the old bare approx() call.
Related errors
- pytest.approx() does not support relative tolerance for…
- absolute tolerance can't be NaN.
- absolute tolerance can't be negative
- absolute tolerance for a scalar value must be an int, float…
- expected value must support abs(...) when relative…
AI-assisted analysis of pytest-dev/pytest@0d6fbdeffa (2026-08-11).
Data as JSON: /api/errors/5e7b055f34604a5d.
Report an issue: GitHub.
Appendix: source
Thrown at src/_pytest/approx.py:657
self,
expected: datetime | timedelta,
rel: float | Decimal | timedelta | None,
abs: float | Decimal | timedelta | None,
nan_ok: bool,
) -> None:
__tracebackhide__ = True
if isinstance(expected, datetime) and rel is not None:
raise TypeError(
"pytest.approx() does not support relative tolerance for "
"datetime comparisons. Use abs=timedelta(...) instead."
)
if nan_ok:
raise TypeError(
"pytest.approx() does not support nan_ok for "
"datetime/timedelta comparisons."
)
if abs is None and rel is None:
raise TypeError(
"pytest.approx() requires an explicit tolerance for "
"datetime/timedelta comparisons: "
"e.g. approx(expected, abs=timedelta(seconds=1)) "
"or approx(expected, rel=0.01)"
)
if abs is not None and not isinstance(abs, timedelta):
raise TypeError(
f"absolute tolerance for datetime/timedelta must be a "
f"timedelta, got {type(abs).__name__}"
)
if abs is not None and abs < timedelta(0):
raise ValueError(f"absolute tolerance can't be negative: {abs}")
if rel is not None:
if not isinstance(rel, (int, float)):
raise TypeError(
f"relative tolerance for timedelta must be a "
f"number, got {type(rel).__name__}"
)View on GitHub (pinned to 0d6fbdeffa)