Repository: python-babel/babel (python)

Issue:
`parse_time` raises when a format doesn't contain seconds
## Overview Description

`parse_time` raises a `ValueError` when the given time format doesn't contain seconds e.g. `H:mm`.

## Steps to Reproduce

```python
>>> from babel.dates import parse_time
>>> parse_time('9:30', 'cs_CZ', 'short')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/dev/babel/babel/dates.py", line 1292, in parse_time
    sec_idx = format_str.index('s')
              ^^^^^^^^^^^^^^^^^^^^^
ValueError: substring not found
```

This happens because the `parse_time` function expects the format to have seconds, but some locales do not have those.
For example this is the CLDR definition for the `short` format in Czech:

```xml
<timeFormatLength type="short">
	<timeFormat>
		<pattern>H:mm</pattern>
		<datetimeSkeleton>Hmm</datetimeSkeleton>
	</timeFormat>
</timeFormatLength>
```

I think the obvious fix is to make the seconds optional and default to zero.


Pull request:
Make seconds optional in `parse_time` time formats
This addresses the crash by making the seconds optional. If the time format only contains house and minutes, seconds are assumed to be zero.

closes #1129 

Patch:
diff --git a/babel/dates.py b/babel/dates.py
index 30321b7..2f1b116 100644
--- a/babel/dates.py
+++ b/babel/dates.py
@@ -17,6 +17,7 @@
 
 from __future__ import annotations
 
+import math
 import re
 import warnings
 from functools import lru_cache
@@ -1281,7 +1282,9 @@ def parse_time(
     if hour_idx < 0:
         hour_idx = format_str.index('k')
     min_idx = format_str.index('m')
-    sec_idx = format_str.index('s')
+    # format might not contain seconds
+    if (sec_idx := format_str.find('s')) < 0:
+        sec_idx = math.inf
 
     indexes = sorted([(hour_idx, 'H'), (min_idx, 'M'), (sec_idx, 'S')])
     indexes = {item[1]: idx for idx, item in enumerate(indexes)}


Test patch:
diff --git a/tests/test_dates.py b/tests/test_dates.py
index 549929b..fef68ae 100644
--- a/tests/test_dates.py
+++ b/tests/test_dates.py
@@ -679,6 +679,14 @@ def test_parse_time(input, expected):
     assert dates.parse_time(input, locale='en_US') == expected
 
 
+def test_parse_time_no_seconds_in_format():
+    # parse time using a time format which does not include seconds
+    locale = 'cs_CZ'
+    fmt = 'short'
+    assert dates.get_time_format(format=fmt, locale=locale).pattern == 'H:mm'
+    assert dates.parse_time('9:30', locale=locale, format=fmt) == time(9, 30)
+
+
 def test_parse_time_alternate_characters(monkeypatch):
     # 'K' can be used as an alternative to 'H'
     def get_time_format(*args, **kwargs):