Raise OverflowError in float pow when complex result overflows (#7727)

* fix: Align error messages with CPython

* fix: Raise overflow error on complex exponentiation overflow

* refactor: Delegate complex pow handling from float pow

* test: Add regression tests for complex pow overflow

---------

Co-authored-by: Jeong, YunWon <69878+youknowone@users.noreply.github.com>
This commit is contained in:
Jeongseop Lim
2026-04-30 04:40:31 +09:00
committed by GitHub
parent 6b67067e9a
commit 6ed2f15b67
3 changed files with 12 additions and 4 deletions

View File

@@ -150,7 +150,11 @@ fn inner_div(v1: Complex64, v2: Complex64, vm: &VirtualMachine) -> PyResult<Comp
Ok(v1.fdiv(v2))
}
fn inner_pow(v1: Complex64, v2: Complex64, vm: &VirtualMachine) -> PyResult<Complex64> {
pub(crate) fn complex_pow(
v1: Complex64,
v2: Complex64,
vm: &VirtualMachine,
) -> PyResult<Complex64> {
if v1.is_zero() {
return if v2.re < 0.0 || v2.im != 0.0 {
let msg = format!("{v1} cannot be raised to a negative or complex power");
@@ -164,7 +168,7 @@ fn inner_pow(v1: Complex64, v2: Complex64, vm: &VirtualMachine) -> PyResult<Comp
let ans = powc(v1, v2);
if ans.is_infinite() && !(v1.is_infinite() || v2.is_infinite()) {
Err(vm.new_overflow_error("complex exponentiation overflow"))
Err(vm.new_overflow_error("complex exponentiation"))
} else {
Ok(ans)
}
@@ -471,7 +475,7 @@ impl AsNumber for PyComplex {
multiply: Some(|a, b, vm| PyComplex::number_op(a, b, |a, b, _vm| a * b, vm)),
power: Some(|a, b, c, vm| {
if vm.is_none(c) {
PyComplex::number_op(a, b, inner_pow, vm)
PyComplex::number_op(a, b, complex_pow, vm)
} else {
Err(vm.new_value_error(String::from("complex modulo")))
}

View File

@@ -161,7 +161,7 @@ pub fn float_pow(v1: f64, v2: f64, vm: &VirtualMachine) -> PyResult {
} else if v1.is_sign_negative() && (v2.floor() - v2).abs() > f64::EPSILON {
let v1 = Complex64::new(v1, 0.);
let v2 = Complex64::new(v2, 0.);
Ok(v1.powc(v2).to_pyobject(vm))
Ok(super::complex::complex_pow(v1, v2, vm)?.to_pyobject(vm))
} else {
Ok(v1.powf(v2).to_pyobject(vm))
}

View File

@@ -22,6 +22,10 @@ assert_raises(TypeError, pow, 2.0, 4, 5)
assert pow(2, -1, 5) == 3
assert_raises(ValueError, pow, 2, 2, 0)
assert_raises(OverflowError, pow, -2, 2000.5)
assert_raises(OverflowError, pow, -2.0, 2000.5)
assert_raises(OverflowError, complex(-2).__pow__, complex(2000.5))
assert_raises(TypeError, pow, 1, None, 0)
assert_raises(TypeError, pow, True, 1.5, False)