pytest-dev/pytest · error · TypeError
pytest.approx() does not support nan_ok for…
Error message
pytest.approx() does not support nan_ok for datetime/timedelta comparisons.
What it means
ApproxTimedelta.__init__ rejects nan_ok=True for any datetime or timedelta comparison because NaN has no representation in datetime/timedelta arithmetic (you cannot have a 'NaN datetime'), so allowing NaN-equality would be meaningless. The check runs after the datetime+rel check and before the explicit-tolerance check.
Solutions
- Drop nan_ok for datetime/timedelta comparisons: `approx(dt, abs=timedelta(seconds=1))`.
- Filter NaN values out of the data before comparison instead of using nan_ok.
- Branch helper logic: only pass nan_ok when the expected value is numeric.
Example fix
# before approx(datetime.now(), abs=timedelta(seconds=1), nan_ok=True) # after approx(datetime.now(), abs=timedelta(seconds=1))
Defensive patterns
Strategy: validation
Validate before calling
from datetime import datetime, timedelta
def safe_nan_ok(expected, nan_ok) -> bool:
if isinstance(expected, (datetime, timedelta)):
return False # nan_ok never valid for datetime/timedelta
return nan_ok
# usage
assert actual == approx(expected, abs=tol, nan_ok=safe_nan_ok(expected, nan_ok)) Type guard
from datetime import datetime, timedelta
def supports_nan_ok(expected) -> bool:
return not isinstance(expected, (datetime, timedelta)) Prevention
- Drop nan_ok for any datetime/timedelta approx.
- In generic helpers, only set nan_ok for numeric expected.
- Filter NaN rows from data instead of relying on nan_ok for time types.
When it happens
Trigger: Calling approx(datetime.now(), abs=timedelta(seconds=1), nan_ok=True); approx(timedelta(seconds=5), rel=0.01, nan_ok=True). Triggered at ApproxTimedelta.__init__ (src/_pytest/approx.py:651-655).
Common situations: Copy-pasting nan_ok=True from a numeric array test into a datetime test; using a generic helper that always sets nan_ok.
Related errors
- absolute tolerance can't be NaN.
- approx() is not supported in a boolean context. Did you…
- pytest.approx() does not support relative tolerance for…
- pytest.approx() requires an explicit tolerance for…
- relative tolerance can't be NaN.
AI-assisted analysis of pytest-dev/pytest@0d6fbdeffa (2026-08-11).
Data as JSON: /api/errors/6d4d170f628221b6.
Report an issue: GitHub.
Appendix: source
Thrown at src/_pytest/approx.py:652
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 "
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:View on GitHub (pinned to 0d6fbdeffa)