{"record":{"id":"638cf854d0ed322b","repo":"python/cpython","slug":"cannot-convert-infinity-to-integer-ratio","errorCode":null,"errorMessage":"cannot convert Infinity to integer ratio","messagePattern":"cannot convert Infinity to integer ratio","errorType":"exception","errorClass":"OverflowError","httpStatus":null,"severity":"error","filePath":"Lib/_pydecimal.py","lineNumber":950,"sourceCode":"    def as_integer_ratio(self):\n        \"\"\"Express a finite Decimal instance in the form n / d.\n\n        Returns a pair (n, d) of integers.  When called on an infinity\n        or NaN, raises OverflowError or ValueError respectively.\n\n        >>> Decimal('3.14').as_integer_ratio()\n        (157, 50)\n        >>> Decimal('-123e5').as_integer_ratio()\n        (-12300000, 1)\n        >>> Decimal('0.00').as_integer_ratio()\n        (0, 1)\n\n        \"\"\"\n        if self._is_special:\n            if self.is_nan():\n                raise ValueError(\"cannot convert NaN to integer ratio\")\n            else:\n                raise OverflowError(\"cannot convert Infinity to integer ratio\")\n\n        if not self:\n            return 0, 1\n\n        # Find n, d in lowest terms such that abs(self) == n / d;\n        # we'll deal with the sign later.\n        n = int(self._int)\n        if self._exp >= 0:\n            # self is an integer.\n            n, d = n * 10**self._exp, 1\n        else:\n            # Find d2, d5 such that abs(self) = n / (2**d2 * 5**d5).\n            d5 = -self._exp\n            while d5 > 0 and n % 5 == 0:\n                n //= 5\n                d5 -= 1\n\n            # (n & -n).bit_length() - 1 counts trailing zeros in binary","sourceCodeStart":932,"sourceCodeEnd":968,"githubUrl":"https://github.com/python/cpython/blob/bc6749cc3b5ae4a5e88a6cc2d5b3bebbe354eae6/Lib/_pydecimal.py#L932-L968","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Check dec.is_infinite() before calling and handle overflow upstream (clamp, rescale with prec, or reject)","If infinity came from an overflowed computation, enable the Overflow trap to catch it at the source","Route non-finite values to an explicit error or a sentinel instead of the ratio path"],"exampleFix":"// before\nfrac = Fraction(*dec.as_integer_ratio())  # OverflowError on Infinity\n\n// after\nif dec.is_infinite():\n    raise OverflowError(f'input overflowed: {dec}')\nfrac = Fraction(*dec.as_integer_ratio())","handlingStrategy":"validation","validationCode":"def safe_ratio(d):\n    if d.is_infinite():\n        raise OverflowError(f'cannot ratio infinity: {d}')\n    return d.as_integer_ratio()","typeGuard":"def has_integer_ratio(d) -> bool:\n    return not d._is_special","tryCatchPattern":"try:\n    n, d_ = dec.as_integer_ratio()\nexcept OverflowError:\n    # infinity: fail upstream or clamp\n    raise OverflowError('overflowed input to ratio conversion') from None","preventionTips":["Trap Overflow in the context so computations fail at the source instead of yielding Infinity","Keep one is_finite() gate before all exact-conversion calls (ratio, int, float)","Remember json.loads accepts 'Infinity' — validate parsed numbers"],"tags":["decimal","as-integer-ratio","infinity","overflow","fraction"],"backgroundTag":null,"analyzedSha":"bc6749cc3b5ae4a5e88a6cc2d5b3bebbe354eae6","analyzedAt":"2026-08-14T22:01:13.976Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}