pytest-dev/pytest · error · ValueError
absolute tolerance can't be negative: {abs}
Error message
absolute tolerance can't be negative: {abs} What it means
ApproxTimedelta.__init__ rejects a negative timedelta absolute tolerance. A negative tolerance makes the comparison meaningless (no value would be within a negative distance of the expected).
Source
Thrown at src/_pytest/approx.py:669
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__}"
)
if rel < 0:
raise ValueError(f"relative tolerance can't be negative: {rel}")
if math.isnan(rel):
raise ValueError("relative tolerance can't be NaN.")
if math.isinf(rel):
raise ValueError("relative tolerance can't be infinite.")
# Compute the effective tolerance. abs_tolerance is a timedelta, rel * expected
# gives a timedelta (timedelta * float works in Python).
abs_tolerance = abs
if rel is None:
rel_tolerance = None
else:View on GitHub (pinned to 98b357f69e)
Solutions
- Use abs(timedelta(...)) or ensure the value is non-negative: abs=timedelta(seconds=1).
- Sanitize the source so negative durations are clamped to zero or corrected.
- Add an assertion in the fixture producing the tolerance.
Example fix
// before assert got == approx(dt, abs=timedelta(seconds=-1)) // after assert got == approx(dt, abs=timedelta(seconds=1))
Defensive patterns
Strategy: validation
Validate before calling
from datetime import timedelta
def approx_dt(value, abs_tol):
if isinstance(abs_tol, timedelta) and abs_tol < timedelta(0):
abs_tol = -abs_tol
return pytest.approx(value, abs=abs_tol) Type guard
from datetime import timedelta
def is_nonneg_timedelta(v) -> bool:
return isinstance(v, timedelta) and v >= timedelta(0) Prevention
- Use abs(timedelta(...)) when tolerances are derived from subtractions.
- Validate fixture-produced durations are non-negative.
When it happens
Trigger: Call pytest.approx(dt, abs=timedelta(seconds=-1)) or any call where the abs timedelta is less than timedelta(0).
Common situations: Tolerance computed from a subtraction that can go negative; sign error when constructing the timedelta; parametrized fixture that inadvertently yields negative durations.
Related errors
- absolute tolerance can't be NaN.
- relative tolerance can't be negative: {relative_tolerance}
- relative tolerance can't be NaN.
- pytest.approx() does not support relative tolerance for date
- pytest.approx() does not support nan_ok for datetime/timedel
AI-assisted analysis of pytest-dev/pytest@98b357f69e (2026-08-04).
Data as JSON: /data/errors/be9be101889764ff.json.
Report an issue: GitHub.