mirror of
https://github.com/RustPython/RustPython.git
synced 2026-10-28 18:59:04 +08:00
Merge pull request #4419 from yt2b/implement_float_format_validation
Implement float format validation
This commit is contained in:
3 files changed
+25
-18
No files matched your search
+18
-12
@@ -422,10 +422,11 @@ impl FormatSpec {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn format_float(&self, num: f64) -> Result<String, &'static str> {
|
||||
pub fn format_float(&self, num: f64) -> Result<String, String> {
|
||||
self.validate_format(FormatType::FixedPointLower)?;
|
||||
let precision = self.precision.unwrap_or(6);
|
||||
let magnitude = num.abs();
|
||||
let raw_magnitude_str: Result<String, &'static str> = match self.format_type {
|
||||
let raw_magnitude_str: Result<String, String> = match self.format_type {
|
||||
Some(FormatType::FixedPointUpper) => Ok(float_ops::format_fixed(
|
||||
precision,
|
||||
magnitude,
|
||||
@@ -436,17 +437,21 @@ impl FormatSpec {
|
||||
magnitude,
|
||||
float_ops::Case::Lower,
|
||||
)),
|
||||
Some(FormatType::Decimal) => Err("Unknown format code 'd' for object of type 'float'"),
|
||||
Some(FormatType::Binary) => Err("Unknown format code 'b' for object of type 'float'"),
|
||||
Some(FormatType::Octal) => Err("Unknown format code 'o' for object of type 'float'"),
|
||||
Some(FormatType::HexLower) => Err("Unknown format code 'x' for object of type 'float'"),
|
||||
Some(FormatType::HexUpper) => Err("Unknown format code 'X' for object of type 'float'"),
|
||||
Some(FormatType::String) => Err("Unknown format code 's' for object of type 'float'"),
|
||||
Some(FormatType::Character) => {
|
||||
Err("Unknown format code 'c' for object of type 'float'")
|
||||
Some(FormatType::Decimal)
|
||||
| Some(FormatType::Binary)
|
||||
| Some(FormatType::Octal)
|
||||
| Some(FormatType::HexLower)
|
||||
| Some(FormatType::HexUpper)
|
||||
| Some(FormatType::String)
|
||||
| Some(FormatType::Character) => {
|
||||
let ch = char::from(self.format_type.as_ref().unwrap());
|
||||
Err(format!(
|
||||
"Unknown format code '{}' for object of type 'float'",
|
||||
ch
|
||||
))
|
||||
}
|
||||
Some(FormatType::Number) => {
|
||||
Err("Format code 'n' for object of type 'float' not implemented yet")
|
||||
Err("Format code 'n' for object of type 'float' not implemented yet".to_owned())
|
||||
}
|
||||
Some(FormatType::GeneralFormatUpper) => {
|
||||
let precision = if precision == 0 { 1 } else { precision };
|
||||
@@ -513,6 +518,7 @@ impl FormatSpec {
|
||||
};
|
||||
let magnitude_str = self.add_magnitude_separators(raw_magnitude_str?, sign_str);
|
||||
self.format_sign_and_align(&magnitude_str, sign_str, FormatAlign::Right)
|
||||
.map_err(|msg| msg.to_owned())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
@@ -574,7 +580,7 @@ impl FormatSpec {
|
||||
| Some(FormatType::ExponentUpper)
|
||||
| Some(FormatType::ExponentLower)
|
||||
| Some(FormatType::Percentage) => match num.to_f64() {
|
||||
Some(float) => return self.format_float(float).map_err(|msg| msg.to_owned()),
|
||||
Some(float) => return self.format_float(float),
|
||||
_ => Err("Unable to convert int to float".to_owned()),
|
||||
},
|
||||
None => self.format_int_radix(magnitude, 10),
|
||||
|
||||
@@ -68,3 +68,5 @@ assert f"{1234:.3g}" == "1.23e+03"
|
||||
assert f"{1234567:.6G}" == "1.23457E+06"
|
||||
assert_raises(ValueError, "{:,o}".format, 1, _msg="ValueError: Cannot specify ',' with 'o'.")
|
||||
assert_raises(ValueError, "{:_n}".format, 1, _msg="ValueError: Cannot specify '_' with 'n'.")
|
||||
assert_raises(ValueError, "{:,o}".format, 1.0, _msg="ValueError: Cannot specify ',' with 'o'.")
|
||||
assert_raises(ValueError, "{:_n}".format, 1.0, _msg="ValueError: Cannot specify '_' with 'n'.")
|
||||
@@ -189,12 +189,11 @@ fn float_from_string(val: PyObjectRef, vm: &VirtualMachine) -> PyResult<f64> {
|
||||
impl PyFloat {
|
||||
#[pymethod(magic)]
|
||||
fn format(&self, spec: PyStrRef, vm: &VirtualMachine) -> PyResult<String> {
|
||||
match FormatSpec::parse(spec.as_str())
|
||||
.and_then(|format_spec| format_spec.format_float(self.value))
|
||||
{
|
||||
Ok(string) => Ok(string),
|
||||
Err(err) => Err(vm.new_value_error(err.to_string())),
|
||||
}
|
||||
let format_spec =
|
||||
FormatSpec::parse(spec.as_str()).map_err(|msg| vm.new_value_error(msg.to_owned()))?;
|
||||
format_spec
|
||||
.format_float(self.value)
|
||||
.map_err(|msg| vm.new_value_error(msg))
|
||||
}
|
||||
|
||||
#[pystaticmethod(magic)]
|
||||
|
||||
Reference in new issue
Block a user