Merge pull request #4419 from yt2b/implement_float_format_validation

Implement float format validation
This commit is contained in:
Jim Fasarakis-Hilliard authored and GitHub committed 2023-01-04 20:27:20 +02:00
commit 144f61932f
3 files changed
+25 -18

No files matched your search

+18 -12
View File
@@ -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),
+2
View File
@@ -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'.")
+5 -6
View File
@@ -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)]