forked from Rust-related/RustPython
Merge pull request #1386 from j30ng/zero-aware-format
Enable Zero-padding with Format Strings
This commit is contained in:
@@ -12,3 +12,9 @@ class BadFormat:
|
||||
def __format__(self, spec):
|
||||
return 42
|
||||
assert_raises(TypeError, format, BadFormat())
|
||||
|
||||
def test_zero_padding():
|
||||
i = 1
|
||||
assert f'{i:04d}' == '0001'
|
||||
|
||||
test_zero_padding()
|
||||
|
||||
@@ -181,11 +181,11 @@ fn parse_alternate_form(text: &str) -> (bool, &str) {
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_zero(text: &str) -> &str {
|
||||
fn parse_zero(text: &str) -> (bool, &str) {
|
||||
let mut chars = text.chars();
|
||||
match chars.next() {
|
||||
Some('0') => chars.as_str(),
|
||||
_ => text,
|
||||
Some('0') => (true, chars.as_str()),
|
||||
_ => (false, text),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -235,15 +235,20 @@ fn parse_format_type(text: &str) -> (Option<FormatType>, &str) {
|
||||
|
||||
fn parse_format_spec(text: &str) -> FormatSpec {
|
||||
let (preconversor, after_preconversor) = parse_preconversor(text);
|
||||
let (fill, align, after_align) = parse_fill_and_align(after_preconversor);
|
||||
let (mut fill, mut align, after_align) = parse_fill_and_align(after_preconversor);
|
||||
let (sign, after_sign) = parse_sign(after_align);
|
||||
let (alternate_form, after_alternate_form) = parse_alternate_form(after_sign);
|
||||
let after_zero = parse_zero(after_alternate_form);
|
||||
let (zero, after_zero) = parse_zero(after_alternate_form);
|
||||
let (width, after_width) = parse_number(after_zero);
|
||||
let (grouping_option, after_grouping_option) = parse_grouping_option(after_width);
|
||||
let (precision, after_precision) = parse_precision(after_grouping_option);
|
||||
let (format_type, _) = parse_format_type(after_precision);
|
||||
|
||||
if zero && fill.is_none() {
|
||||
fill.replace('0');
|
||||
align = align.or(Some(FormatAlign::AfterSign));
|
||||
}
|
||||
|
||||
FormatSpec {
|
||||
preconversor,
|
||||
fill,
|
||||
|
||||
@@ -1326,9 +1326,7 @@ fn try_update_quantity_from_tuple(
|
||||
Ok(tuple_index)
|
||||
}
|
||||
}
|
||||
None => {
|
||||
Err(vm.new_type_error("not enough arguments for format string".to_string()))
|
||||
}
|
||||
None => Err(vm.new_type_error("not enough arguments for format string".to_string())),
|
||||
}
|
||||
}
|
||||
_ => Ok(tuple_index),
|
||||
|
||||
@@ -620,12 +620,8 @@ fn comprehension_to_ast(
|
||||
|
||||
fn string_to_ast(vm: &VirtualMachine, string: &ast::StringGroup) -> PyResult<AstNodeRef> {
|
||||
let string = match string {
|
||||
ast::StringGroup::Constant { value } => {
|
||||
node!(vm, Str, { s => vm.ctx.new_str(value.clone()) })
|
||||
}
|
||||
ast::StringGroup::FormattedValue { value, .. } => {
|
||||
node!(vm, FormattedValue, { value => expression_to_ast(vm, value)? })
|
||||
}
|
||||
ast::StringGroup::Constant { value } => node!(vm, Str, { s => vm.ctx.new_str(value.clone()) }),
|
||||
ast::StringGroup::FormattedValue { value, .. } => node!(vm, FormattedValue, { value => expression_to_ast(vm, value)? }),
|
||||
ast::StringGroup::Joined { values } => {
|
||||
let py_values = map_ast(string_to_ast, vm, &values)?;
|
||||
node!(vm, JoinedStr, { values => py_values })
|
||||
|
||||
@@ -54,9 +54,7 @@ fn name(
|
||||
} else {
|
||||
match default {
|
||||
OptionalArg::Present(obj) => Ok(obj),
|
||||
OptionalArg::Missing => {
|
||||
Err(vm.new_value_error("character name not found!".to_string()))
|
||||
}
|
||||
OptionalArg::Missing => Err(vm.new_value_error("character name not found!".to_string())),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -137,7 +137,7 @@ fn browser_request_animation_frame(func: PyCallable, vm: &VirtualMachine) -> PyR
|
||||
|
||||
let closure = f.borrow_mut().take();
|
||||
drop(closure);
|
||||
}) as Box<Fn(f64)>));
|
||||
}) as Box<dyn Fn(f64)>));
|
||||
|
||||
let id = window()
|
||||
.request_animation_frame(&js_sys::Function::from(
|
||||
|
||||
Reference in New Issue
Block a user