pytest-dev/pytest · error · TypeError
pytest.approx() does not support relative tolerance for…
Error message
pytest.approx() does not support relative tolerance for datetime comparisons. Use abs=timedelta(...) instead.
What it means
ApproxTimedelta.__init__ explicitly rejects a relative tolerance (rel) when the expected value is a datetime. Relative tolerance for an absolute timestamp is undefined (a 'fraction of' a datetime has no useful meaning and would yield a float, not a datetime), so pytest requires an absolute timedelta tolerance instead. The error message suggests the correct abs=timedelta(...) form.
Solutions
- Use an absolute timedelta tolerance: `approx(dt, abs=timedelta(seconds=1))`.
- If comparing durations (timedelta expected), rel is fine: `approx(td, rel=0.01)`.
- Convert datetimes to a common reference and compare the deltas with abs tolerance.
Example fix
# before approx(datetime.now(), rel=0.01) # after approx(datetime.now(), abs=timedelta(seconds=1))
Defensive patterns
Strategy: type-guard
Validate before calling
from datetime import datetime, timedelta
def datetime_approx_kwargs(expected):
if isinstance(expected, datetime):
return {'abs': timedelta(seconds=1)} # never rel for datetime
return {'rel': 0.01} # rel ok for timedelta
# usage
assert actual == approx(expected, **datetime_approx_kwargs(expected)) Type guard
from datetime import datetime, timedelta
def is_datetime(v) -> bool:
return isinstance(v, datetime) Prevention
- Never pass rel for datetime expected; use abs=timedelta(...).
- In helpers, branch on isinstance(expected, datetime) before choosing tolerance.
- Remember rel IS valid for timedelta (durations), just not datetime.
When it happens
Trigger: Calling approx(datetime.now(), rel=0.01); approx(datetime(2024,1,1), rel=0.001). Triggered at ApproxTimedelta.__init__ (src/_pytest/approx.py:646-650). Note: rel IS supported for timedelta expected values (where it represents a fraction of the duration), just not for datetime.
Common situations: Generalizing a timedelta test to datetime without changing the tolerance style; copy-pasting numeric rel syntax into datetime comparisons.
Related errors
- pytest.approx() requires an explicit tolerance for…
- relative tolerance can't be NaN.
- relative tolerance can't be negative
- absolute tolerance can't be NaN.
- absolute tolerance can't be negative
AI-assisted analysis of pytest-dev/pytest@0d6fbdeffa (2026-08-11).
Data as JSON: /api/errors/326a947ddbbead2b.
Report an issue: GitHub.
Appendix: source
Thrown at src/_pytest/approx.py:647
class ApproxTimedelta(Approx[datetime | timedelta]):
"""Perform approximate comparisons where the expected value is a
datetime or timedelta.
Requires an explicit tolerance as a timedelta for abs, or a float for rel.
Relative tolerance is not supported for datetime comparisons.
"""
def __init__(
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 "View on GitHub (pinned to 0d6fbdeffa)