pytest-dev/pytest · error · ValueError

relative tolerance can't be infinite.

Error message

relative tolerance can't be infinite.

What it means

Raised by ApproxTimedelta.__init__ when rel is numeric, non-negative, not NaN, but infinite (math.isinf). An infinite relative tolerance would make approx trivially accept everything, defeating the assertion's purpose. pytest treats this as a user error.

Solutions

  1. Use a finite rel value: rel=0.01.
  2. Guard computations with math.isinf before passing.
  3. Clamp computed tolerances to a reasonable maximum.

Example fix

// before
approx(td, rel=x / 0.0)  # inf
// after
approx(td, rel=0.01)
Defensive patterns

Strategy: validation

Validate before calling

import math
def reject_inf_rel(rel):
    if rel is not None and math.isinf(rel):
        raise ValueError('rel must be finite')
    return rel

Type guard

import math
def is_finite_rel(v) -> bool:
    return v is None or (isinstance(v, (int, float)) and math.isfinite(v))

Prevention

When it happens

Trigger: approx(td, rel=float('inf')); rel computed as x/0.0 producing inf.

Common situations: Division-by-zero yielding inf instead of raising; config-driven tolerances parsed from malformed input.

Related errors


AI-assisted analysis of pytest-dev/pytest@0d6fbdeffa (2026-08-11). Data as JSON: /api/errors/40e1a7ee4082622f. Report an issue: GitHub.

Appendix: source

Thrown at src/_pytest/approx.py:681

        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)
        if abs_tolerance is not None and rel_tolerance is not None:
            tolerance: timedelta | None = max(abs_tolerance, rel_tolerance)
        else:
            tolerance = abs_tolerance if abs_tolerance is not None else rel_tolerance
        super().__init__(expected, rel=rel, abs=tolerance, nan_ok=False)

    def __repr__(self) -> str:
        return f"{self.expected} ± {self.abs}"

View on GitHub (pinned to 0d6fbdeffa)