Skip to content

Commit 8ac743d

Browse files
authored
Merge pull request RustPython#1386 from j30ng/zero-aware-format
Enable Zero-padding with Format Strings
2 parents 215eefe + b056044 commit 8ac743d

File tree

6 files changed

+21
-18
lines changed

6 files changed

+21
-18
lines changed

tests/snippets/builtin_format.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,9 @@ class BadFormat:
1212
def __format__(self, spec):
1313
return 42
1414
assert_raises(TypeError, format, BadFormat())
15+
16+
def test_zero_padding():
17+
i = 1
18+
assert f'{i:04d}' == '0001'
19+
20+
test_zero_padding()

vm/src/format.rs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -181,11 +181,11 @@ fn parse_alternate_form(text: &str) -> (bool, &str) {
181181
}
182182
}
183183

184-
fn parse_zero(text: &str) -> &str {
184+
fn parse_zero(text: &str) -> (bool, &str) {
185185
let mut chars = text.chars();
186186
match chars.next() {
187-
Some('0') => chars.as_str(),
188-
_ => text,
187+
Some('0') => (true, chars.as_str()),
188+
_ => (false, text),
189189
}
190190
}
191191

@@ -235,15 +235,20 @@ fn parse_format_type(text: &str) -> (Option<FormatType>, &str) {
235235

236236
fn parse_format_spec(text: &str) -> FormatSpec {
237237
let (preconversor, after_preconversor) = parse_preconversor(text);
238-
let (fill, align, after_align) = parse_fill_and_align(after_preconversor);
238+
let (mut fill, mut align, after_align) = parse_fill_and_align(after_preconversor);
239239
let (sign, after_sign) = parse_sign(after_align);
240240
let (alternate_form, after_alternate_form) = parse_alternate_form(after_sign);
241-
let after_zero = parse_zero(after_alternate_form);
241+
let (zero, after_zero) = parse_zero(after_alternate_form);
242242
let (width, after_width) = parse_number(after_zero);
243243
let (grouping_option, after_grouping_option) = parse_grouping_option(after_width);
244244
let (precision, after_precision) = parse_precision(after_grouping_option);
245245
let (format_type, _) = parse_format_type(after_precision);
246246

247+
if zero && fill.is_none() {
248+
fill.replace('0');
249+
align = align.or(Some(FormatAlign::AfterSign));
250+
}
251+
247252
FormatSpec {
248253
preconversor,
249254
fill,

vm/src/obj/objstr.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1326,9 +1326,7 @@ fn try_update_quantity_from_tuple(
13261326
Ok(tuple_index)
13271327
}
13281328
}
1329-
None => {
1330-
Err(vm.new_type_error("not enough arguments for format string".to_string()))
1331-
}
1329+
None => Err(vm.new_type_error("not enough arguments for format string".to_string())),
13321330
}
13331331
}
13341332
_ => Ok(tuple_index),

vm/src/stdlib/ast.rs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -620,12 +620,8 @@ fn comprehension_to_ast(
620620

621621
fn string_to_ast(vm: &VirtualMachine, string: &ast::StringGroup) -> PyResult<AstNodeRef> {
622622
let string = match string {
623-
ast::StringGroup::Constant { value } => {
624-
node!(vm, Str, { s => vm.ctx.new_str(value.clone()) })
625-
}
626-
ast::StringGroup::FormattedValue { value, .. } => {
627-
node!(vm, FormattedValue, { value => expression_to_ast(vm, value)? })
628-
}
623+
ast::StringGroup::Constant { value } => node!(vm, Str, { s => vm.ctx.new_str(value.clone()) }),
624+
ast::StringGroup::FormattedValue { value, .. } => node!(vm, FormattedValue, { value => expression_to_ast(vm, value)? }),
629625
ast::StringGroup::Joined { values } => {
630626
let py_values = map_ast(string_to_ast, vm, &values)?;
631627
node!(vm, JoinedStr, { values => py_values })

vm/src/stdlib/unicodedata.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,7 @@ fn name(
5454
} else {
5555
match default {
5656
OptionalArg::Present(obj) => Ok(obj),
57-
OptionalArg::Missing => {
58-
Err(vm.new_value_error("character name not found!".to_string()))
59-
}
57+
OptionalArg::Missing => Err(vm.new_value_error("character name not found!".to_string())),
6058
}
6159
}
6260
}

wasm/lib/src/browser_module.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ fn browser_request_animation_frame(func: PyCallable, vm: &VirtualMachine) -> PyR
137137

138138
let closure = f.borrow_mut().take();
139139
drop(closure);
140-
}) as Box<Fn(f64)>));
140+
}) as Box<dyn Fn(f64)>));
141141

142142
let id = window()
143143
.request_animation_frame(&js_sys::Function::from(

0 commit comments

Comments
 (0)