diff --git a/arrow/parser.py b/arrow/parser.py index fc3774b09..d0d7abce2 100644 --- a/arrow/parser.py +++ b/arrow/parser.py @@ -422,12 +422,21 @@ def parse( parts: _Parts = {} for token in fmt_tokens: value: Union[Tuple[str, str, str], str] - if token == "Do": - value = match.group("value") - elif token == "W": - value = (match.group("year"), match.group("week"), match.group("day")) - else: - value = match.group(token) + try: + if token == "Do": + value = match.group("value") + elif token == "W": + value = ( + match.group("year"), + match.group("week"), + match.group("day"), + ) + else: + value = match.group(token) + except IndexError: + raise ParserMatchError( + f"Failed to match {fmt!r} when parsing {datetime_string!r}." + ) if value is None: raise ParserMatchError( diff --git a/tests/test_parser.py b/tests/test_parser.py index 7038d880f..9a7facf1d 100644 --- a/tests/test_parser.py +++ b/tests/test_parser.py @@ -529,6 +529,14 @@ def test_parse_with_leading_and_trailing_whitespace(self): assert self.parser.parse(" 2016 ", "YYYY") == datetime(2016, 1, 1) + def test_parse_Do_indexerror_becomes_parser_match_error(self): + """Regression for #1191: On locales whose ordinal_day_re does not expose + a named 'value' capture group (e.g. GermanLocale), match.group('value') + previously raised a bare IndexError. It must raise ParserMatchError.""" + de_parser = DateTimeParser(locale="de") + with pytest.raises(ParserMatchError): + de_parser.parse("1", "Do") + assert self.parser.parse( " 2016-05-16 04:05:06.789120 ", "YYYY-MM-DD hh:mm:ss.S" ) == datetime(2016, 5, 16, 4, 5, 6, 789120)