diff --git a/Lib/test/test_str.py b/Lib/test/test_str.py index 15cee0d3a44..455c98ac369 100644 --- a/Lib/test/test_str.py +++ b/Lib/test/test_str.py @@ -1469,7 +1469,6 @@ def test_format_huge_width(self): with self.assertRaises(ValueError): result = format(2.34, format_string) - @unittest.expectedFailure # TODO: RUSTPYTHON; IndexError: tuple index out of range def test_format_huge_item_number(self): format_string = "{{{}:.6f}}".format(sys.maxsize + 1) with self.assertRaises(ValueError): diff --git a/crates/common/src/format.rs b/crates/common/src/format.rs index 9b769a038e7..5575ead0d17 100644 --- a/crates/common/src/format.rs +++ b/crates/common/src/format.rs @@ -1102,6 +1102,7 @@ pub enum FormatParseError { EmptyAttribute, MissingRightBracket, InvalidCharacterAfterRightBracket, + TooManyDecimalDigits, } impl FromStr for FormatSpec { @@ -1185,7 +1186,19 @@ impl FieldName { let field_type = if first.is_empty() { FieldType::Auto } else if let Some(index) = parse_usize(&first) { + // Match CPython's get_integer: digits-only segment must fit in + // Py_ssize_t. Above that, raise ValueError at parse time. + if index > isize::MAX as usize { + return Err(FormatParseError::TooManyDecimalDigits); + } FieldType::Index(index) + } else if first + .as_str() + .ok() + .is_some_and(|s| s.bytes().all(|b| b.is_ascii_digit())) + { + // All-digit segment whose value overflows usize itself. + return Err(FormatParseError::TooManyDecimalDigits); } else { FieldType::Keyword(first) }; diff --git a/crates/vm/src/format.rs b/crates/vm/src/format.rs index e60b8ed9a4a..ec92330e170 100644 --- a/crates/vm/src/format.rs +++ b/crates/vm/src/format.rs @@ -114,6 +114,9 @@ impl ToPyException for FormatParseError { fn to_pyexception(&self, vm: &VirtualMachine) -> PyBaseExceptionRef { match self { Self::UnmatchedBracket => vm.new_value_error("expected '}' before end of string"), + Self::TooManyDecimalDigits => { + vm.new_value_error("Too many decimal digits in format string") + } _ => vm.new_value_error("Unexpected error parsing format string"), } }