mirror of
https://github.com/RustPython/RustPython.git
synced 2026-06-02 19:39:49 +09:00
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:
@@ -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")))
|
||||
}
|
||||
|
||||
@@ -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))
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user