Hi! While rebuilding the python related packages against the Python 3.15rc2 version we found that khal fails to build from source: https://debusine.debian.net/debian/r-python-python3.15/artifact/4856282/ In the log, there are several tests failing, apparently due to date parsing errors: =================================== FAILURES =================================== E assert not SystemExit(1) E + where SystemExit(1) = <Result SystemExit(1)>.exception tests/cli_test.py:1069: AssertionError ------------------------------ Captured log call ------------------------------- CRITICAL khal:cli.py:273 Could not parse "01.06. 15:00 01.06. 15:30". Please check your configuration or run `khal printformats` to see if this does match your configured [long](date|time|datetime)format. If you suspect a bug, please file an issue at https://github.com/pimutils/khal/issues/ E assert 'error parsing range' not in "calendar: two\nsummary: new event\ndatetime range: now\ntimezone [Europe/Berlin]: Europe/London\ndescription (or 'None'): None\n/tmp/pytest-of-sbuild/pytest-0/test_issue_10560/calendar2/61UPW4BTXJL113QXECJKRR1NC1CYWGVHPNPJ.ics\nevent saved\nEdit? do[n]e [s]ummary [d]escription da[t]etime range re[p]eat [l]ocation\n[c]ategories [a]larm [D]elete [u]rl: t\ndatetime range [01.06. 09:00 01.06. 10:00]: \nerror parsing range\nEdit? do[n]e [s]ummary [d]escription da[t]etime range re[p]eat [l]ocation\n[c]ategories [a]larm [D]elete [u]rl: n\n" E E 'error parsing range' is contained here: E calendar: two E summary: new event E datetime range: now E timezone [Europe/Berlin]: Europe/London E description (or 'None'): None E /tmp/pytest-of-sbuild/pytest-0/test_issue_10560/calendar2/61UPW4BTXJL113QXECJKRR1NC1CYWGVHPNPJ.ics E event saved E Edit? do[n]e [s]ummary [d]escription da[t]etime range re[p]eat [l]ocation E [c]ategories [a]larm [D]elete [u]rl: t E datetime range [01.06. 09:00 01.06. 10:00]: E error parsing range E Edit? do[n]e [s]ummary [d]escription da[t]etime range re[p]eat [l]ocation E [c]ategories [a]larm [D]elete [u]rl: n tests/cli_test.py:1092: AssertionError E AssertionError: assert b'BEGIN:VEVENT\r\nSUMMARY:16.08. \xc3\x84wes\xc3\xb6me Event\r\nDTSTART;VALUE=DATE:20140815\r\nDTEND;VALUE=DATE:20140816\r\nDTSTAMP:20140216T120000Z\r\nUID:E41JRQX2DB4P1AQZI86BAT7NHPBHPRIIHQKA\r\nEND:VEVENT\r\n' == b'BEGIN:VEVENT\r\nSUMMARY:\xc3\x84wes\xc3\xb6me Event\r\nDTSTART;VALUE=DATE:20140815\r\nDTEND;VALUE=DATE:20140817\r\nDTSTAMP:20140216T120000Z\r\nUID:E41JRQX2DB4P1AQZI86BAT7NHPBHPRIIHQKA\r\nEND:VEVENT\r\n' E E At index 22 diff: b'1' != b'\xc3' E E Full diff: E - (b'BEGIN:VEVENT\r\nSUMMARY:\xc3\x84wes\xc3\xb6me Event\r\nDTSTART;VALUE=DATE:20' E ? ------- E + (b'BEGIN:VEVENT\r\nSUMMARY:16.08. \xc3\x84wes\xc3\xb6me Event\r\nDTSTART;VALUE=' E ? +++++++ E - b'140815\r\nDTEND;VALUE=DATE:20140817\r\nDTSTAMP:20140216T120000Z\r\nUID:E41' E ? ^ ------- E + b'DATE:20140815\r\nDTEND;VALUE=DATE:20140816\r\nDTSTAMP:20140216T120000Z\r\n' E ? +++++++ ^ E - b'JRQX2DB4P1AQZI86BAT7NHPBHPRIIHQKA\r\nEND:VEVENT\r\n') E + b'UID:E41JRQX2DB4P1AQZI86BAT7NHPBHPRIIHQKA\r\nEND:VEVENT\r\n') E ? +++++++ tests/parse_datetime_test.py:468: AssertionError tests/parse_datetime_test.py:526: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/parse_datetime_test.py:47: in _construct_event info = eventinfofstr( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ info_string = '15.06. Äwesöme Event' locale = {'default_timezone': <DstTzInfo 'Europe/Berlin' LMT+0:53:00 STD>, 'local_timezone': <DstTzInfo 'Europe/Berlin' LMT+0:53:00 STD>, 'dateformat': '%d.%m.', 'longdateformat': '%d.%m.%Y', ...} default_event_duration = datetime.timedelta(seconds=3600) default_dayevent_duration = datetime.timedelta(days=1), adjust_reasonably = True def eventinfofstr( info_string: str, locale: LocaleConfiguration, default_event_duration: dt.timedelta, default_dayevent_duration: dt.timedelta, adjust_reasonably: bool = False, ) -> dict[str, Any]: """parses a string of the form START [END | DELTA] [TIMEZONE] [SUMMARY] [:: DESCRIPTION] into a dictionary with keys: dtstart, dtend, timezone, allday, summary, description """ description = None if " :: " in info_string: info_string, description = info_string.split(" :: ") parts = info_string.split(" ") summary = None start: dt.datetime | dt.date | None = None end: dt.datetime | dt.date | None = None tz: pytz.BaseTzInfo | None = None allday: bool = False for i in reversed(range(1, len(parts) + 1)): try: start, end, allday = guessrangefstr( " ".join(parts[0:i]), locale, default_timedelta_datetime=default_event_duration, default_timedelta_date=default_dayevent_duration, adjust_reasonably=adjust_reasonably, ) except (ValueError, DateTimeParseError): continue if start is not None and end is not None: try: # next element is a valid Olson db timezone string tz = pytz.timezone(parts[i]) i += 1 except (pytz.UnknownTimeZoneError, UnicodeDecodeError, IndexError): tz = None summary = " ".join(parts[i:]) break if start is None or end is None: f'Could not parse "{info_string}".\nPlease check your ' "configuration or run `khal printformats` to see if this does " "match your configured [long](date|time|datetime)format.\nIf you " "suspect a bug, please file an issue at " "https://github.com/pimutils/khal/issues/ " ) E khal.exceptions.DateTimeParseError: Could not parse "15.06. Äwesöme Event". E Please check your configuration or run `khal printformats` to see if this does match your configured [long](date|time|datetime)format. E If you suspect a bug, please file an issue at https://github.com/pimutils/khal/issues/ khal/parse_datetime.py:492: DateTimeParseError tests/parse_datetime_test.py:546: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/parse_datetime_test.py:47: in _construct_event info = eventinfofstr( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ info_string = '29.02. Äwesöme Event' locale = {'default_timezone': <DstTzInfo 'Europe/Berlin' LMT+0:53:00 STD>, 'local_timezone': <DstTzInfo 'Europe/Berlin' LMT+0:53:00 STD>, 'dateformat': '%d.%m.', 'longdateformat': '%d.%m.%Y', ...} default_event_duration = datetime.timedelta(seconds=3600) default_dayevent_duration = datetime.timedelta(days=1), adjust_reasonably = True def eventinfofstr( info_string: str, locale: LocaleConfiguration, default_event_duration: dt.timedelta, default_dayevent_duration: dt.timedelta, adjust_reasonably: bool = False, ) -> dict[str, Any]: """parses a string of the form START [END | DELTA] [TIMEZONE] [SUMMARY] [:: DESCRIPTION] into a dictionary with keys: dtstart, dtend, timezone, allday, summary, description """ description = None if " :: " in info_string: info_string, description = info_string.split(" :: ") parts = info_string.split(" ") summary = None start: dt.datetime | dt.date | None = None end: dt.datetime | dt.date | None = None tz: pytz.BaseTzInfo | None = None allday: bool = False for i in reversed(range(1, len(parts) + 1)): try: start, end, allday = guessrangefstr( " ".join(parts[0:i]), locale, default_timedelta_datetime=default_event_duration, default_timedelta_date=default_dayevent_duration, adjust_reasonably=adjust_reasonably, ) except (ValueError, DateTimeParseError): continue if start is not None and end is not None: try: # next element is a valid Olson db timezone string tz = pytz.timezone(parts[i]) i += 1 except (pytz.UnknownTimeZoneError, UnicodeDecodeError, IndexError): tz = None summary = " ".join(parts[i:]) break if start is None or end is None: f'Could not parse "{info_string}".\nPlease check your ' "configuration or run `khal printformats` to see if this does " "match your configured [long](date|time|datetime)format.\nIf you " "suspect a bug, please file an issue at " "https://github.com/pimutils/khal/issues/ " ) E khal.exceptions.DateTimeParseError: Could not parse "29.02. Äwesöme Event". E Please check your configuration or run `khal printformats` to see if this does match your configured [long](date|time|datetime)format. E If you suspect a bug, please file an issue at https://github.com/pimutils/khal/issues/ khal/parse_datetime.py:492: DateTimeParseError tests/parse_datetime_test.py:582: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/parse_datetime_test.py:47: in _construct_event info = eventinfofstr( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ info_string = '15.06. Äwesöme Event' locale = {'default_timezone': <DstTzInfo 'Europe/Berlin' LMT+0:53:00 STD>, 'local_timezone': <DstTzInfo 'Europe/Berlin' LMT+0:53:00 STD>, 'dateformat': '%d.%m.', 'longdateformat': '%d.%m.%Y', ...} default_event_duration = datetime.timedelta(seconds=3600) default_dayevent_duration = datetime.timedelta(days=1), adjust_reasonably = True def eventinfofstr( info_string: str, locale: LocaleConfiguration, default_event_duration: dt.timedelta, default_dayevent_duration: dt.timedelta, adjust_reasonably: bool = False, ) -> dict[str, Any]: """parses a string of the form START [END | DELTA] [TIMEZONE] [SUMMARY] [:: DESCRIPTION] into a dictionary with keys: dtstart, dtend, timezone, allday, summary, description """ description = None if " :: " in info_string: info_string, description = info_string.split(" :: ") parts = info_string.split(" ") summary = None start: dt.datetime | dt.date | None = None end: dt.datetime | dt.date | None = None tz: pytz.BaseTzInfo | None = None allday: bool = False for i in reversed(range(1, len(parts) + 1)): try: start, end, allday = guessrangefstr( " ".join(parts[0:i]), locale, default_timedelta_datetime=default_event_duration, default_timedelta_date=default_dayevent_duration, adjust_reasonably=adjust_reasonably, ) except (ValueError, DateTimeParseError): continue if start is not None and end is not None: try: # next element is a valid Olson db timezone string tz = pytz.timezone(parts[i]) i += 1 except (pytz.UnknownTimeZoneError, UnicodeDecodeError, IndexError): tz = None summary = " ".join(parts[i:]) break if start is None or end is None: f'Could not parse "{info_string}".\nPlease check your ' "configuration or run `khal printformats` to see if this does " "match your configured [long](date|time|datetime)format.\nIf you " "suspect a bug, please file an issue at " "https://github.com/pimutils/khal/issues/ " ) E khal.exceptions.DateTimeParseError: Could not parse "15.06. Äwesöme Event". E Please check your configuration or run `khal printformats` to see if this does match your configured [long](date|time|datetime)format. E If you suspect a bug, please file an issue at https://github.com/pimutils/khal/issues/ khal/parse_datetime.py:492: DateTimeParseError Please note that while we ran into this error during the rebuild against Python 3.15, that doesn't mean that the root cause for the failure is necessarily the new Python version. Setting the severity to important for now. Once Python 3.15 is released and later added to python3-defaults, this bug will become release critical.