From 6ed2f15b67ac2eca70c01a9462dbdcc78f358ca2 Mon Sep 17 00:00:00 2001 From: Jeongseop Lim Date: Thu, 30 Apr 2026 04:40:31 +0900 Subject: [PATCH] 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> --- crates/vm/src/builtins/complex.rs | 10 +++++++--- crates/vm/src/builtins/float.rs | 2 +- extra_tests/snippets/builtin_pow.py | 4 ++++ 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/crates/vm/src/builtins/complex.rs b/crates/vm/src/builtins/complex.rs index a284bf4e4..9034c5f3f 100644 --- a/crates/vm/src/builtins/complex.rs +++ b/crates/vm/src/builtins/complex.rs @@ -150,7 +150,11 @@ fn inner_div(v1: Complex64, v2: Complex64, vm: &VirtualMachine) -> PyResult PyResult { +pub(crate) fn complex_pow( + v1: Complex64, + v2: Complex64, + vm: &VirtualMachine, +) -> PyResult { 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 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)) } diff --git a/extra_tests/snippets/builtin_pow.py b/extra_tests/snippets/builtin_pow.py index af21fe459..0d8b906fa 100644 --- a/extra_tests/snippets/builtin_pow.py +++ b/extra_tests/snippets/builtin_pow.py @@ -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)