python/cpython · error · OverflowError

cannot convert Infinity to integer ratio

Error message

cannot convert Infinity to integer ratio

What it means

Decimal.as_integer_ratio() raises OverflowError('cannot convert Infinity to integer ratio') because infinity has no finite numerator/denominator representation. The sibling NaN case raises ValueError; this asymmetry lets callers distinguish the two special classes.

Source

Thrown at Lib/_pydecimal.py:950

    def as_integer_ratio(self):
        """Express a finite Decimal instance in the form n / d.

        Returns a pair (n, d) of integers.  When called on an infinity
        or NaN, raises OverflowError or ValueError respectively.

        >>> Decimal('3.14').as_integer_ratio()
        (157, 50)
        >>> Decimal('-123e5').as_integer_ratio()
        (-12300000, 1)
        >>> Decimal('0.00').as_integer_ratio()
        (0, 1)

        """
        if self._is_special:
            if self.is_nan():
                raise ValueError("cannot convert NaN to integer ratio")
            else:
                raise OverflowError("cannot convert Infinity to integer ratio")

        if not self:
            return 0, 1

        # Find n, d in lowest terms such that abs(self) == n / d;
        # we'll deal with the sign later.
        n = int(self._int)
        if self._exp >= 0:
            # self is an integer.
            n, d = n * 10**self._exp, 1
        else:
            # Find d2, d5 such that abs(self) = n / (2**d2 * 5**d5).
            d5 = -self._exp
            while d5 > 0 and n % 5 == 0:
                n //= 5
                d5 -= 1

            # (n & -n).bit_length() - 1 counts trailing zeros in binary

View on GitHub (pinned to bc6749cc3b)

Solutions

  1. Check dec.is_infinite() before calling and handle overflow upstream (clamp, rescale with prec, or reject)
  2. If infinity came from an overflowed computation, enable the Overflow trap to catch it at the source
  3. Route non-finite values to an explicit error or a sentinel instead of the ratio path

Example fix

// before
frac = Fraction(*dec.as_integer_ratio())  # OverflowError on Infinity

// after
if dec.is_infinite():
    raise OverflowError(f'input overflowed: {dec}')
frac = Fraction(*dec.as_integer_ratio())
Defensive patterns

Strategy: validation

Validate before calling

def safe_ratio(d):
    if d.is_infinite():
        raise OverflowError(f'cannot ratio infinity: {d}')
    return d.as_integer_ratio()

Type guard

def has_integer_ratio(d) -> bool:
    return not d._is_special

Try / catch

try:
    n, d_ = dec.as_integer_ratio()
except OverflowError:
    # infinity: fail upstream or clamp
    raise OverflowError('overflowed input to ratio conversion') from None

Prevention

When it happens

Trigger: Decimal('Infinity').as_integer_ratio(); Decimal('-inf').as_integer_ratio(); a division that overflowed to infinity (with Overflow trap disabled) then fed into as_integer_ratio.

Common situations: Scientific pipelines where an earlier overflow produced Infinity silently (traps off in the default context for Overflow? default context traps Overflow, so usually parsed input), then exact-ratio conversion for Fraction interop fails.

Related errors


AI-assisted analysis of python/cpython@bc6749cc3b (2026-08-14). Data as JSON: /api/errors/638cf854d0ed322b. Report an issue: GitHub.