-
Notifications
You must be signed in to change notification settings - Fork 223
Open
Description
Describe the bug
When editing an event, Khal will crash if the EXDATE values are date only.
If applicable: Stack Trace
Traceback (most recent call last):
File "/usr/lib/python3/dist-packages/khal/ui/__init__.py", line 1494, in start_pane
loop.run()
~~~~~~~~^^
File "/usr/lib/python3/dist-packages/urwid/event_loop/main_loop.py", line 337, in run
self._run()
~~~~~~~~~^^
File "/usr/lib/python3/dist-packages/urwid/event_loop/main_loop.py", line 439, in _run
self.event_loop.run()
~~~~~~~~~~~~~~~~~~~^^
File "/usr/lib/python3/dist-packages/urwid/event_loop/select_loop.py", line 182, in run
self._loop()
~~~~~~~~~~^^
File "/usr/lib/python3/dist-packages/urwid/event_loop/select_loop.py", line 229, in _loop
record.data()
~~~~~~~~~~~^^
File "/usr/lib/python3/dist-packages/urwid/display/_posix_raw_display.py", line 285, in wrapper
return self.parse_input(event_loop, callback, self.get_available_raw_input())
~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3/dist-packages/urwid/display/_raw_display_base.py", line 488, in parse_input
callback(decoded_codes, raw_codes)
~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3/dist-packages/urwid/event_loop/main_loop.py", line 466, in _update
self.process_input(keys)
~~~~~~~~~~~~~~~~~~^^^^^^
File "/usr/lib/python3/dist-packages/urwid/event_loop/main_loop.py", line 566, in process_input
handled_key = self._topmost_widget.keypress(self.screen_size, key)
File "/usr/lib/python3/dist-packages/urwid/widget/popup.py", line 143, in keypress
return self._current_widget.keypress(size, key)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^
File "/usr/lib/python3/dist-packages/urwid/widget/frame.py", line 526, in keypress
return self.body.keypress((maxcol, remaining), key)
~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3/dist-packages/khal/ui/__init__.py", line 1158, in keypress
return super().keypress(size, key)
~~~~~~~~~~~~~~~~^^^^^^^^^^^
File "/usr/lib/python3/dist-packages/khal/ui/base.py", line 121, in keypress
return super().keypress(size, key)
~~~~~~~~~~~~~~~~^^^^^^^^^^^
File "/usr/lib/python3/dist-packages/urwid/widget/widget.py", line 729, in keypress
return get_delegate(self).keypress(size, key)
~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^
File "/usr/lib/python3/dist-packages/khal/ui/widgets.py", line 317, in keypress
key = super().keypress(size, key)
File "/usr/lib/python3/dist-packages/urwid/widget/columns.py", line 1216, in keypress
key = w.keypress(size_args[i], key)
File "/usr/lib/python3/dist-packages/urwid/widget/widget.py", line 729, in keypress
return get_delegate(self).keypress(size, key)
~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^
File "/usr/lib/python3/dist-packages/urwid/widget/widget.py", line 729, in keypress
return get_delegate(self).keypress(size, key)
~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^
File "/usr/lib/python3/dist-packages/khal/ui/__init__.py", line 947, in keypress
self.edit(self.focus_event.event, external_edit=True)
~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3/dist-packages/khal/ui/__init__.py", line 769, in edit
self.pane.collection.update(new_event)
~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^
File "/usr/lib/python3/dist-packages/khal/khalendar/khalendar.py", line 182, in update
self._backend.update(event.raw, event.href, event.etag, calendar=event.calendar)
~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3/dist-packages/khal/khalendar/backend.py", line 246, in update
self._update_impl(vevent, href, calendar)
~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3/dist-packages/khal/khalendar/backend.py", line 367, in _update_impl
dtstartend = expand_vevent(vevent, href)
File "/usr/lib/python3/dist-packages/khal/icalendar.py", line 340, in expand
for date in get_dates(vevent, 'EXDATE') or ():
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3/dist-packages/khal/icalendar.py", line 253, in sanitize_datetime
date = events_tz.localize(date)
File "/usr/lib/python3/dist-packages/pytz/tzinfo.py", line 320, in localize
if dt.tzinfo is not None:
^^^^^^^^^
AttributeError: 'datetime.date' object has no attribute 'tzinfo'
To Reproduce
- In
khal interactive, create a recurring event.
e.g.:
BEGIN:VCALENDAR
BEGIN:VEVENT
UID:event_rrule_exdate_timezone_date
SUMMARY:Monthly Report
RRULE:FREQ=MONTHLY;BYDAY=+4SA;UNTIL=20301231T060000Z
DTSTART;TZID=Europe/Berlin:20240629T070000
DTEND;TZID=Europe/Berlin:20240629T120000
END:VEVENT
END:VCALENDAR- Use the
external_editfunction (meta E) to edit the iCalendar data. - Set some exception date values (in the
EXDATEproperty) for the recurrence set.
e.g.:
BEGIN:VCALENDAR
BEGIN:VEVENT
UID:event_rrule_exdate_timezone_date
SUMMARY:Monthly Report
RRULE:FREQ=MONTHLY;BYDAY=+4SA;UNTIL=20301231T060000Z
DTSTART;TZID=Europe/Berlin:20240629T070000
DTEND;TZID=Europe/Berlin:20240629T120000
EXDATE;TZID=Europe/Berlin:20241227,20251227,20261226,20271225,20281223,20291229,20301228
END:VEVENT
END:VCALENDAR- Save the file and return to Khal.
- Khal will crash with the above stack trace.
Expected behavior
Because the EXDATE property contains date-only values (not datetime), this still meets the iCalendar specification.
The expected behaviour is to remove any instances from the recurrence set, whose start date matches those date-only values.
OS, version, khal version and how you installed it:
$ cat /etc/debian_version
13.1
$ dpkg --list khal
[…]
ii khal 1:0.11.4-1 all Standards based CLI and terminal calendar program
$ khal --version
khal, version 0.11.4
$ python3 --version
Python 3.13.5
- Your khal config file
[calendars]
[[private]]
path = /home/bignose/.local/share/khal/calendars/private
type = calendar
[locale]
timeformat = %H:%M
dateformat = %Y-%m-%d
longdateformat = %Y-%m-%d
datetimeformat = %Y-%m-%d %H:%M
longdatetimeformat = %Y-%m-%d %H:%M
[default]
default_calendar = privateAdditional context
The iCalendar data parses correctly using the Python icalendar library. It crashed Khal only when attempting to render a recurring event from that data.
Metadata
Metadata
Assignees
Labels
No labels