mirror of
https://github.com/RustPython/RustPython.git
synced 2026-10-28 18:59:04 +08:00
Implement objcomplex::parse_str() to replace Complex64::from_str()
This commit is contained in:
1 parent
d4a35b9a92
commit
ec5d168de2
2 files changed
+86
-4
No files matched your search
@@ -164,3 +164,48 @@ assert complex("5-2j") == 5 - 2j
|
||||
assert complex("-2j") == -2j
|
||||
assert_raises(TypeError, lambda: complex("5+2j", 1))
|
||||
assert_raises(ValueError, lambda: complex("abc"))
|
||||
|
||||
assert complex("1+10j") == 1+10j
|
||||
assert complex(10) == 10+0j
|
||||
assert complex(10.0) == 10+0j
|
||||
assert complex(10) == 10+0j
|
||||
assert complex(10+0j) == 10+0j
|
||||
assert complex(1, 10) == 1+10j
|
||||
assert complex(1, 10) == 1+10j
|
||||
assert complex(1, 10.0) == 1+10j
|
||||
assert complex(1, 10) == 1+10j
|
||||
assert complex(1, 10) == 1+10j
|
||||
assert complex(1, 10.0) == 1+10j
|
||||
assert complex(1.0, 10) == 1+10j
|
||||
assert complex(1.0, 10) == 1+10j
|
||||
assert complex(1.0, 10.0) == 1+10j
|
||||
assert complex(3.14+0j) == 3.14+0j
|
||||
assert complex(3.14) == 3.14+0j
|
||||
assert complex(314) == 314.0+0j
|
||||
assert complex(314) == 314.0+0j
|
||||
assert complex(3.14+0j, 0j) == 3.14+0j
|
||||
assert complex(3.14, 0.0) == 3.14+0j
|
||||
assert complex(314, 0) == 314.0+0j
|
||||
assert complex(314, 0) == 314.0+0j
|
||||
assert complex(0j, 3.14j) == -3.14+0j
|
||||
assert complex(0.0, 3.14j) == -3.14+0j
|
||||
assert complex(0j, 3.14) == 3.14j
|
||||
assert complex(0.0, 3.14) == 3.14j
|
||||
assert complex("1") == 1+0j
|
||||
assert complex("1j") == 1j
|
||||
assert complex() == 0
|
||||
assert complex("-1") == -1
|
||||
assert complex("+1") == +1
|
||||
assert complex("(1+2j)") == 1+2j
|
||||
assert complex("(1.3+2.2j)") == 1.3+2.2j
|
||||
assert complex("3.14+1J") == 3.14+1j
|
||||
assert complex(" ( +3.14-6J )") == 3.14-6j
|
||||
assert complex(" ( +3.14-J )") == 3.14-1j
|
||||
assert complex(" ( +3.14+j )") == 3.14+1j
|
||||
assert complex("J") == 1j
|
||||
assert complex("( j )") == 1j
|
||||
assert complex("+J") == 1j
|
||||
assert complex("( -j)") == -1j
|
||||
assert complex('1e-500') == 0.0 + 0.0j
|
||||
assert complex('-1e-500j') == 0.0 - 0.0j
|
||||
assert complex('-1e-500+1e-500j') == -0.0 + 0.0j
|
||||
@@ -1,6 +1,5 @@
|
||||
use num_complex::Complex64;
|
||||
use num_traits::Zero;
|
||||
use std::str::FromStr;
|
||||
|
||||
use super::objfloat;
|
||||
use super::objstr::PyString;
|
||||
@@ -10,7 +9,7 @@ use crate::pyobject::{
|
||||
PyObjectRef, PyRef, PyResult, PyValue, TypeProtocol,
|
||||
};
|
||||
use crate::vm::VirtualMachine;
|
||||
use rustpython_common::hash;
|
||||
use rustpython_common::{float_ops, hash};
|
||||
|
||||
/// Create a complex number from a real part and an optional imaginary part.
|
||||
///
|
||||
@@ -254,8 +253,9 @@ impl PyComplex {
|
||||
"complex() can't take second arg if first is a string".to_owned(),
|
||||
));
|
||||
}
|
||||
let value = Complex64::from_str(s.borrow_value())
|
||||
.map_err(|err| vm.new_value_error(err.to_string()))?;
|
||||
let value = parse_str(s.borrow_value().trim()).ok_or_else(|| {
|
||||
vm.new_value_error("complex() arg is a malformed string".to_owned())
|
||||
})?;
|
||||
return Self::from(value).into_ref_with_type(vm, cls);
|
||||
} else {
|
||||
return Err(vm.new_type_error(format!(
|
||||
@@ -308,3 +308,40 @@ struct ComplexArgs {
|
||||
#[pyarg(positional_or_keyword, default = "None")]
|
||||
imag: Option<PyObjectRef>,
|
||||
}
|
||||
|
||||
fn parse_str(s: &str) -> Option<Complex64> {
|
||||
// Handle parentheses
|
||||
let s = match s.strip_prefix('(') {
|
||||
None => s,
|
||||
Some(s) => match s.strip_suffix(')') {
|
||||
None => return None,
|
||||
Some(s) => s.trim(),
|
||||
},
|
||||
};
|
||||
|
||||
let value = match s.strip_suffix(|c| c == 'j' || c == 'J') {
|
||||
None => Complex64::new(float_ops::parse_str(s)?, 0.0),
|
||||
Some(mut s) => {
|
||||
let mut real = 0.0;
|
||||
// Find the central +/- operator. If it exists, parse the real part.
|
||||
for (i, w) in s.as_bytes().windows(2).enumerate() {
|
||||
if (w[1] == b'+' || w[1] == b'-') && !(w[0] == b'e' || w[0] == b'E') {
|
||||
real = float_ops::parse_str(&s[..=i])?;
|
||||
s = &s[i + 1..];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
let imag = match s {
|
||||
// "j", "+j"
|
||||
"" | "+" => 1.0,
|
||||
// "-j"
|
||||
"-" => -1.0,
|
||||
s => float_ops::parse_str(s)?,
|
||||
};
|
||||
|
||||
Complex64::new(real, imag)
|
||||
}
|
||||
};
|
||||
Some(value)
|
||||
}
|
||||
Reference in new issue
Block a user