Describe the bug
Description
pow() on float operands silently returns float('inf') when the mathematical result exceeds Double.MAX_VALUE, instead of raising OverflowError as CPython does. This is a CPython compatibility issue that affects pow(float, int), pow(float, float), and pow(int, float) call forms.
Root Cause
FloatBuiltins.PowNode.doOperation returns Math.pow(left, right) directly and never checks Double.isInfinite(result), so an overflow silently surfaces as a float value. The same missing check exists in the sibling specializations doDD and doDDToComplex, which are reached by pow(float, float) and pow(int, float) respectively.
For reference, other paths in the same file already perform this defense (fromhex at lines 653-654, round at 805-806, __int__ at 833-834) — only pow is missing it, breaking in-file consistency.
CPython reference: Objects/floatobject.c#L847-L860
// CPython forces errno = ERANGE when libm pow() overflows to ±HUGE_VAL,
// and then raises OverflowError from errno.
errno = 0;
ix = pow(iv, iw);
_Py_ADJUST_ERANGE1(ix); // if (x == ±Py_HUGE_VAL) errno = ERANGE;
...
if (errno != 0) {
PyErr_SetFromErrno(errno == ERANGE ? PyExc_OverflowError
: PyExc_ValueError);
return NULL;
}
Fix
In all three specializations (doOperation, doDD, doDDToComplex), after calling Math.pow(left, right), raise OverflowError when the result is ±Infinity while both inputs are finite (the Java equivalent of _Py_ADJUST_ERANGE1).
Reproduction
result = pow(8520.852079253338, 965168)
print(result, type(result))
Output
GraalPy:
CPython:
Traceback (most recent call last):
File "/path/to/test.py", line 1, in <module>
result = pow(8520.852079253338, 965168)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
OverflowError: (34, 'Numerical result out of range')
Environment
- GraalPy 25.0.2 (Python 3.12.8)
- CPython 3.12.13
- OS: Debian 12
Describe the bug
Description
pow()onfloatoperands silently returnsfloat('inf')when the mathematical result exceedsDouble.MAX_VALUE, instead of raisingOverflowErroras CPython does. This is a CPython compatibility issue that affectspow(float, int),pow(float, float), andpow(int, float)call forms.Root Cause
FloatBuiltins.PowNode.doOperationreturnsMath.pow(left, right)directly and never checksDouble.isInfinite(result), so an overflow silently surfaces as afloatvalue. The same missing check exists in the sibling specializationsdoDDanddoDDToComplex, which are reached bypow(float, float)andpow(int, float)respectively.FloatBuiltins.java#L503-L508—doOperationFloatBuiltins.java#L510-L526—doDDFloatBuiltins.java#L528-L543—doDDToComplexFor reference, other paths in the same file already perform this defense (
fromhexat lines 653-654,roundat 805-806,__int__at 833-834) — onlypowis missing it, breaking in-file consistency.Fix
In all three specializations (
doOperation,doDD,doDDToComplex), after callingMath.pow(left, right), raiseOverflowErrorwhen the result is±Infinitywhile both inputs are finite (the Java equivalent of_Py_ADJUST_ERANGE1).Reproduction
Output
GraalPy:
CPython:
Environment