pytest-dev/pytest · error · ValueError

absolute tolerance can't be negative: {absolute_tolerance}

Error message

absolute tolerance can't be negative: {absolute_tolerance}

What it means

The absolute tolerance for ApproxScalar cannot be negative, since a negative tolerance would make no values match (abs(expected - actual) is always >= 0). The tolerance property checks absolute_tolerance < 0 and raises ValueError if so. This is a runtime validation, not an __init__ check, so it fires when the first comparison evaluates the tolerance.

Source

Thrown at src/_pytest/approx.py:561

        return result

    __hash__ = None

    @property
    def tolerance(self):
        """Return the tolerance for the comparison.

        This could be either an absolute tolerance or a relative tolerance,
        depending on what the user specified or which would be larger.
        """
        # Figure out what the absolute tolerance should be.  ``self.abs`` is
        # either None or a value specified by the user.
        absolute_tolerance = (
            self.abs if self.abs is not None else self.DEFAULT_ABSOLUTE_TOLERANCE
        )

        if absolute_tolerance < 0:
            raise ValueError(
                f"absolute tolerance can't be negative: {absolute_tolerance}"
            )
        if math.isnan(absolute_tolerance):
            raise ValueError("absolute tolerance can't be NaN.")

        # If the user specified an absolute tolerance but not a relative one,
        # just return the absolute tolerance.
        if self.rel is None:
            if self.abs is not None:
                return absolute_tolerance

        # Figure out what the relative tolerance should be.  ``self.rel`` is
        # either None or a value specified by the user.  This is done after
        # we've made sure the user didn't ask for an absolute tolerance only,
        # because we don't want to raise errors about the relative tolerance if
        # we aren't even going to use it.
        rel = self.rel if self.rel is not None else self.DEFAULT_RELATIVE_TOLERANCE
        # expected is SupportAbs, checked in __init__.

View on GitHub (pinned to 98b357f69e)

Solutions

  1. Use a non-negative absolute tolerance: approx(1.0, abs=0.001).
  2. Fix the computation that produces the tolerance to use abs(): abs_tol = abs(computed_value).
  3. Review the error message to see the offending negative value and trace its source.

Example fix

# before
approx(1.0, abs=-0.001)

# after
approx(1.0, abs=0.001)
Defensive patterns

Strategy: validation

Validate before calling

def validate_abs_tolerance_nonnegative(abs_tol):
    if abs_tol is not None and abs_tol < 0:
        raise ValueError(f'absolute tolerance cannot be negative: {abs_tol}')
    return abs_tol

# usage:
# abs_tol = validate_abs_tolerance_nonnegative(computed_tolerance)
# approx(expected, abs=abs_tol)

Prevention

When it happens

Trigger: Calling approx(1.0, abs=-0.001) and then performing a comparison (assert 1.0 == approx(1.0, abs=-0.001)). The tolerance property computes absolute_tolerance, finds it negative, and raises ValueError.

Common situations: Computed tolerance values with a sign error, a config typo, or subtracting instead of taking absolute value when building the tolerance.

Related errors


AI-assisted analysis of pytest-dev/pytest@98b357f69e (2026-08-04). Data as JSON: /data/errors/405375e8bb014fbd.json. Report an issue: GitHub.