Skip to content

Commit 8cb2b82

Browse files
authored
Merge pull request RustPython#4386 from yt2b/fix_character_format
Fix character format
2 parents cb4bd51 + 24c2b88 commit 8cb2b82

File tree

2 files changed

+15
-1
lines changed

2 files changed

+15
-1
lines changed

extra_tests/snippets/builtin_format.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,3 +29,7 @@ def test_zero_padding():
2929
assert f'{4294967296:,}' == '4,294,967,296'
3030
assert 'F' == "{0:{base}}".format(15, base="X")
3131
assert f'{255:#X}' == "0XFF"
32+
assert f"{65:c}" == "A"
33+
assert f"{0x1f5a5:c}" == "🖥"
34+
assert_raises(ValueError, "{:+c}".format, 1, _msg="Sign not allowed with integer format specifier 'c'")
35+
assert_raises(ValueError, "{:#c}".format, 1, _msg="Alternate form (#) not allowed with integer format specifier 'c'")

vm/src/format.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -477,7 +477,17 @@ impl FormatSpec {
477477
},
478478
Some(FormatType::Number) => self.format_int_radix(magnitude, 10),
479479
Some(FormatType::String) => Err("Unknown format code 's' for object of type 'int'"),
480-
Some(FormatType::Character) => Err("Unknown format code 'c' for object of type 'int'"),
480+
Some(FormatType::Character) => match (self.sign, self.alternate_form) {
481+
(Some(_), _) => Err("Sign not allowed with integer format specifier 'c'"),
482+
(_, true) => {
483+
Err("Alternate form (#) not allowed with integer format specifier 'c'")
484+
}
485+
(_, _) => match num.to_u32() {
486+
Some(n) if n <= 0x10ffff => Ok(std::char::from_u32(n).unwrap().to_string()),
487+
// TODO: raise OverflowError
488+
Some(_) | None => Err("%c arg not in range(0x110000)"),
489+
},
490+
},
481491
Some(FormatType::GeneralFormatUpper) => {
482492
Err("Unknown format code 'G' for object of type 'int'")
483493
}

0 commit comments

Comments
 (0)