Skip to content

Commit dd92e90

Browse files
committed
Add str.__format__
1 parent 53a6bc3 commit dd92e90

File tree

2 files changed

+21
-4
lines changed

2 files changed

+21
-4
lines changed

vm/src/format.rs

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -422,7 +422,7 @@ impl FormatSpec {
422422
}
423423
};
424424

425-
self.format_sign_and_align(magnitude_string, sign_str)
425+
self.format_sign_and_align(&magnitude_string, sign_str)
426426
}
427427

428428
pub fn format_int(&self, num: &BigInt) -> Result<String, &'static str> {
@@ -486,12 +486,19 @@ impl FormatSpec {
486486
},
487487
};
488488

489-
self.format_sign_and_align(magnitude_string, sign_str)
489+
self.format_sign_and_align(&magnitude_string, sign_str)
490+
}
491+
492+
pub fn format_string(&self, s: &str) -> Result<String, &'static str> {
493+
match self.format_type {
494+
Some(FormatType::String) | None => self.format_sign_and_align(s, ""),
495+
_ => Err("Unknown format code for object of type 'str'"),
496+
}
490497
}
491498

492499
fn format_sign_and_align(
493500
&self,
494-
magnitude_string: String,
501+
magnitude_string: &str,
495502
sign_str: &str,
496503
) -> Result<String, &'static str> {
497504
let align = self.align.unwrap_or(FormatAlign::Right);

vm/src/obj/objstr.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ use crate::cformat::{
2626
CFormatPart, CFormatPreconversor, CFormatQuantity, CFormatSpec, CFormatString, CFormatType,
2727
CNumberType,
2828
};
29-
use crate::format::{FormatParseError, FormatPart, FormatPreconversor, FormatString};
29+
use crate::format::{FormatParseError, FormatPart, FormatPreconversor, FormatSpec, FormatString};
3030
use crate::function::{single_or_tuple_any, OptionalArg, PyFuncArgs};
3131
use crate::pyhash;
3232
use crate::pyobject::{
@@ -727,6 +727,16 @@ impl PyString {
727727
}
728728
}
729729

730+
#[pymethod(name = "__format__")]
731+
fn format_str(&self, spec: PyStringRef, vm: &VirtualMachine) -> PyResult<String> {
732+
match FormatSpec::parse(spec.as_str())
733+
.and_then(|format_spec| format_spec.format_string(&self.value))
734+
{
735+
Ok(string) => Ok(string),
736+
Err(err) => Err(vm.new_value_error(err.to_string())),
737+
}
738+
}
739+
730740
/// Return a titlecased version of the string where words start with an
731741
/// uppercase character and the remaining characters are lowercase.
732742
#[pymethod]

0 commit comments

Comments
 (0)