pytest-dev/pytest · error · TypeError
relative tolerance for timedelta must be a number, got
Error message
relative tolerance for timedelta must be a number, got {type(rel).__name__} What it means
Raised by ApproxTimedelta.__init__ when rel is provided for a timedelta comparison but is not an int or float. Relative tolerance for timedelta is a dimensionless multiplier (e.g. 0.01 = 1%), so non-numeric values are rejected with TypeError naming the offending type.
Solutions
- Use abs=timedelta(...) for absolute time tolerance.
- Ensure rel is a numeric literal: rel=0.01.
- Convert config strings with float() before passing.
Example fix
// before approx(td, rel=timedelta(seconds=1)) // after approx(td, abs=timedelta(seconds=1))
Defensive patterns
Strategy: type-guard
Validate before calling
def approx_td_rel(expected, *, rel=None, **kw):
if rel is not None and not isinstance(rel, (int, float)):
raise TypeError('rel must be a number')
return approx(expected, rel=rel, **kw) Type guard
import numbers
def is_number_or_none(v) -> bool:
return v is None or isinstance(v, numbers.Real) Prevention
- rel is a dimensionless float; abs is a timedelta for time values.
- Keep the two parameter types distinct in your test helpers.
When it happens
Trigger: approx(td, rel=timedelta(seconds=1)); approx(td, rel='0.01'); approx(td, rel=None_str).
Common situations: Confusing abs (timedelta) and rel (number) parameter types; passing a string from config into rel.
Related errors
- absolute tolerance for datetime/timedelta must be a…
- absolute tolerance can't be negative
- pytest.approx() only supports ordered sequences, but got
- relative tolerance can't be infinite.
- relative tolerance can't be negative
AI-assisted analysis of pytest-dev/pytest@0d6fbdeffa (2026-08-11).
Data as JSON: /api/errors/a44456c59550bba0.
Report an issue: GitHub.
Appendix: source
Thrown at src/_pytest/approx.py:672
"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:
# Checked above.
assert not isinstance(expected, datetime)
rel_tolerance = rel * builtins.abs(expected)View on GitHub (pinned to 0d6fbdeffa)