Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package python-khal for openSUSE:Factory 
checked in at 2026-08-22 21:35:38
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-khal (Old)
 and      /work/SRC/openSUSE:Factory/.python-khal.new.1258 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-khal"

Sat Aug 22 21:35:38 2026 rev:10 rq:1373022 version:0.14.1

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-khal/python-khal.changes  2026-03-30 
18:32:16.845520085 +0200
+++ /work/SRC/openSUSE:Factory/.python-khal.new.1258/python-khal.changes        
2026-08-22 21:37:46.538720427 +0200
@@ -1,0 +2,8 @@
+Sat Aug 22 09:11:37 UTC 2026 - Dirk Müller <[email protected]>
+
+- update to 0.14.1:
+  * FIX add timezone when assigning start/end time
+  * FIX crash on urwid >= 4.0.5
+  * NEW add alarms-list output formats
+
+-------------------------------------------------------------------

Old:
----
  khal-0.14.0.tar.gz

New:
----
  khal-0.14.1.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-khal.spec ++++++
--- /var/tmp/diff_new_pack.olRC46/_old  2026-08-22 21:37:47.112740946 +0200
+++ /var/tmp/diff_new_pack.olRC46/_new  2026-08-22 21:37:47.113740982 +0200
@@ -18,7 +18,7 @@
 
 %{?sle15_python_module_pythons}
 Name:           python-khal
-Version:        0.14.0
+Version:        0.14.1
 Release:        0
 Summary:        CLI calendar with CalDAV support
 License:        MIT

++++++ khal-0.14.0.tar.gz -> khal-0.14.1.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/khal-0.14.0/CHANGELOG.rst 
new/khal-0.14.1/CHANGELOG.rst
--- old/khal-0.14.0/CHANGELOG.rst       2026-03-24 17:05:07.000000000 +0100
+++ new/khal-0.14.1/CHANGELOG.rst       2026-08-21 08:25:24.936279000 +0200
@@ -7,6 +7,13 @@
 may want to subscribe to `GitHub's tag feed
 <https://github.com/geier/khal/tags.atom>`_.
 
+0.14.1
+======
+2026-08-21
+* FIX add timezone when assigning start/end time
+* FIX crash on urwid >= 4.0.5
+* NEW add alarms-list output formats
+
 0.14.0
 ======
 2026-03-24
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/khal-0.14.0/PKG-INFO new/khal-0.14.1/PKG-INFO
--- old/khal-0.14.0/PKG-INFO    2026-03-24 17:05:08.431989200 +0100
+++ new/khal-0.14.1/PKG-INFO    2026-08-21 08:25:26.511973100 +0200
@@ -1,6 +1,6 @@
 Metadata-Version: 2.4
 Name: khal
-Version: 0.14.0
+Version: 0.14.1
 Summary: Standards based terminal calendar
 Author-email: khal contributors <[email protected]>
 License-Expression: MIT
@@ -61,7 +61,7 @@
 *Khal* is a standards based CLI and terminal calendar program, able to 
synchronize
 with CalDAV_ servers through vdirsyncer_.
 
-.. image:: http://lostpackets.de/images/khal.png
+.. image:: https://lostpackets.de/images/khal.png
 
 Features
 --------
@@ -86,16 +86,16 @@
 
 .. _vdir: https://vdirsyncer.readthedocs.org/en/stable/vdir.html
 .. _vdirsyncer: https://github.com/pimutils/vdirsyncer
-.. _CalDAV: http://en.wikipedia.org/wiki/CalDAV
+.. _CalDAV: https://en.wikipedia.org/wiki/CalDAV
 .. _github: https://github.com/pimutils/khal/
-.. __: 
http://en.wikipedia.org/wiki/Comparison_of_CalDAV_and_CardDAV_implementations
+.. __: 
https://en.wikipedia.org/wiki/Comparison_of_CalDAV_and_CardDAV_implementations
 
 
 Documentation
 -------------
 For khal's documentation have a look at readthedocs_.
 
-.. _readthedocs: http://khal.readthedocs.org/
+.. _readthedocs: https://khal.readthedocs.org/
 
 Installation
 ------------
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/khal-0.14.0/README.rst new/khal-0.14.1/README.rst
--- old/khal-0.14.0/README.rst  2026-03-24 17:05:07.000000000 +0100
+++ new/khal-0.14.1/README.rst  2026-08-21 08:25:24.936279000 +0200
@@ -12,7 +12,7 @@
 *Khal* is a standards based CLI and terminal calendar program, able to 
synchronize
 with CalDAV_ servers through vdirsyncer_.
 
-.. image:: http://lostpackets.de/images/khal.png
+.. image:: https://lostpackets.de/images/khal.png
 
 Features
 --------
@@ -37,16 +37,16 @@
 
 .. _vdir: https://vdirsyncer.readthedocs.org/en/stable/vdir.html
 .. _vdirsyncer: https://github.com/pimutils/vdirsyncer
-.. _CalDAV: http://en.wikipedia.org/wiki/CalDAV
+.. _CalDAV: https://en.wikipedia.org/wiki/CalDAV
 .. _github: https://github.com/pimutils/khal/
-.. __: 
http://en.wikipedia.org/wiki/Comparison_of_CalDAV_and_CardDAV_implementations
+.. __: 
https://en.wikipedia.org/wiki/Comparison_of_CalDAV_and_CardDAV_implementations
 
 
 Documentation
 -------------
 For khal's documentation have a look at readthedocs_.
 
-.. _readthedocs: http://khal.readthedocs.org/
+.. _readthedocs: https://khal.readthedocs.org/
 
 Installation
 ------------
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/khal-0.14.0/doc/source/conf.py 
new/khal-0.14.1/doc/source/conf.py
--- old/khal-0.14.0/doc/source/conf.py  2026-03-24 17:05:07.000000000 +0100
+++ new/khal-0.14.1/doc/source/conf.py  2026-08-21 08:25:24.937338400 +0200
@@ -17,7 +17,7 @@
 
 try:
     # Available from configobj 5.1.0
-    import configobj.validate as validate
+    from configobj import validate
 except ModuleNotFoundError:
     import validate
 
@@ -38,7 +38,7 @@
 def write_section(specsection, secname, key, comment, output):
     # why is _parse_check a "private" method? seems to be rather useful...
     # we don't need fun_kwargs
-    fun_name, fun_args, fun_kwargs, default = 
validator._parse_check(specsection)
+    fun_name, fun_args, _fun_kwargs, default = 
validator._parse_check(specsection)
     output.write(f"\n.. _{secname}-{key}:")
     output.write("\n")
     output.write(f"\n.. object:: {key}\n")
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/khal-0.14.0/doc/source/usage.rst 
new/khal-0.14.1/doc/source/usage.rst
--- old/khal-0.14.0/doc/source/usage.rst        2026-03-24 17:05:07.000000000 
+0100
+++ new/khal-0.14.1/doc/source/usage.rst        2026-08-21 08:25:24.938294600 
+0200
@@ -115,6 +115,9 @@
    alarm-symbol
         An alarm symbol (alarm clock) if the event has at least one alarm.
 
+   alarms-list
+        A comma-separated list of alarms for the event (e.g., `alarm1@-15m, 
getready@-1h`).
+
    location
         The event location.
 
@@ -222,7 +225,7 @@
            end-date-long, end-time, start-full, start-long-full,
            start-date-full, start-date-long-full, start-time-full,
            end-full, end-long-full, end-date-full, end-date-long-full,
-           end-time-full, repeat-symbol, location, calendar,
+           end-time-full, repeat-symbol, alarms-list, location, calendar,
            calendar-color, start-style, to-style, end-style,
            start-end-time-style, end-necessary, end-necessary-long,
            status, cancelled, organizer, url, duration, duration-full,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/khal-0.14.0/khal/controllers.py 
new/khal-0.14.1/khal/controllers.py
--- old/khal-0.14.0/khal/controllers.py 2026-03-24 17:05:07.000000000 +0100
+++ new/khal-0.14.1/khal/controllers.py 2026-08-21 08:25:24.939682500 +0200
@@ -163,7 +163,7 @@
         start = dt.datetime(*dt.date.today().timetuple()[:3])
         end = start + default_timedelta_date
     else:
-        start, end, allday = parse_datetime.guessrangefstr(
+        start, end, _allday = parse_datetime.guessrangefstr(
             daterange,
             locale,
             default_timedelta_date=default_timedelta_date,
@@ -580,6 +580,9 @@
             value = prompt("datetime range", default=current)
             try:
                 start, end, allday = 
parse_datetime.guessrangefstr(ansi.sub("", value), locale)
+                if not allday:
+                    start = locale["local_timezone"].localize(start)
+                    end = locale["local_timezone"].localize(end)
                 event.update_start_end(start, end)
                 edited = True
             except Exception:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/khal-0.14.0/khal/exceptions.py 
new/khal-0.14.1/khal/exceptions.py
--- old/khal-0.14.0/khal/exceptions.py  2026-03-24 17:05:07.000000000 +0100
+++ new/khal-0.14.1/khal/exceptions.py  2026-08-21 08:25:24.939682500 +0200
@@ -23,14 +23,10 @@
 class Error(Exception):
     """base class for all of khal's Exceptions"""
 
-    pass
-
 
 class FatalError(Error):
     """execution cannot continue"""
 
-    pass
-
 
 class DateTimeParseError(FatalError):
     pass
@@ -43,14 +39,10 @@
 class UnsupportedFeatureError(Error):
     """something Failed but we know why"""
 
-    pass
-
 
 class UnsupportedRecurrence(Error):
     """raised if the RRULE is not understood by dateutil.rrule"""
 
-    pass
-
 
 class InvalidDate(Error):
     pass
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/khal-0.14.0/khal/icalendar.py 
new/khal-0.14.1/khal/icalendar.py
--- old/khal-0.14.0/khal/icalendar.py   2026-03-24 17:05:07.000000000 +0100
+++ new/khal-0.14.1/khal/icalendar.py   2026-08-21 08:25:24.940310000 +0200
@@ -79,7 +79,7 @@
         try:
             ics = ics_from_list(events, tzs, random_uid, default_timezone)
         except Exception as exception:
-            logger.warn(f"Error when trying to import the event {uid}")
+            logger.warning(f"Error when trying to import the event {uid}")
             saved_exception = exception
         else:
             out.append(ics)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/khal-0.14.0/khal/khalendar/backend.py 
new/khal-0.14.1/khal/khalendar/backend.py
--- old/khal-0.14.0/khal/khalendar/backend.py   2026-03-24 17:05:07.000000000 
+0100
+++ new/khal-0.14.1/khal/khalendar/backend.py   2026-08-21 08:25:24.940524600 
+0200
@@ -98,7 +98,7 @@
         self._at_once = True
         try:
             yield self
-        except:
+        except Exception:
             raise
         else:
             self.conn.commit()
@@ -277,7 +277,7 @@
         self.deletelike(href + "%", calendar=calendar)
         ical = cal_from_ics(vevent_str)
         vcard = ical.walk()[0]
-        for key in vcard.keys():
+        for key in vcard:
             if key in ["BDAY", "X-ANNIVERSARY", "ANNIVERSARY"] or 
key.endswith("X-ABDATE"):
                 date = vcard[key]
                 uuid = vcard.get("UID")
@@ -589,7 +589,7 @@
         """returns the ical string matching href and calendar"""
         assert calendar is not None
         sql_s = "SELECT item, etag FROM events WHERE href = ? AND calendar = 
?;"
-        item, etag = self.sql_ex(sql_s, (href, calendar))[0]
+        item, _etag = self.sql_ex(sql_s, (href, calendar))[0]
         return item
 
     def get_with_etag(self, href: str, calendar: str) -> tuple[str, str]:
@@ -694,11 +694,11 @@
         return "anniversary"
     elif key.endswith("X-ABDATE"):
         desc_key = key[:-8] + "X-ABLABEL"
-        if desc_key in vcard.keys():
+        if desc_key in vcard:
             return vcard[desc_key]
         else:
             desc_key = key[:-8] + "X-ABLabel"
-            if desc_key in vcard.keys():
+            if desc_key in vcard:
                 return vcard[desc_key]
             else:
                 return "custom event from vcard"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/khal-0.14.0/khal/khalendar/event.py 
new/khal-0.14.1/khal/khalendar/event.py
--- old/khal-0.14.0/khal/khalendar/event.py     2026-03-24 17:05:07.000000000 
+0100
+++ new/khal-0.14.1/khal/khalendar/event.py     2026-08-21 08:25:24.940524600 
+0200
@@ -26,6 +26,7 @@
 import logging
 import os
 from collections.abc import Callable
+from typing import Any
 
 import icalendar
 import icalendar.cal
@@ -151,7 +152,7 @@
                 vevents["PROTO"] = event
 
         if ref is None:
-            ref = "PROTO" if ref in vevents.keys() else list(vevents.keys())[0]
+            ref = "PROTO" if ref in vevents else list(vevents.keys())[0]
         try:
             if type(vevents[ref]["DTSTART"].dt) is not 
type(vevents[ref]["DTEND"].dt):
                 raise ValueError("DTSTART and DTEND should be of the same type 
(datetime or date)")
@@ -612,7 +613,7 @@
         """
         env = env or {}
 
-        attributes = {}
+        attributes: dict[str, Any] = {}
         if isinstance(relative_to, tuple):
             relative_to_start, relative_to_end = relative_to
         else:
@@ -734,6 +735,14 @@
         attributes["repeat-symbol"] = self._recur_str
         attributes["repeat-pattern"] = self.recurpattern
         attributes["alarm-symbol"] = self._alarm_str
+        attributes["alarms-list"] = [
+            {
+                "delta": alarm[0].total_seconds(),
+                "description": str(alarm[1]),
+                "delta-formatted": timedelta2str(alarm[0]),
+            }
+            for alarm in self.alarms
+        ]
         attributes["status-symbol"] = self._status_str
         attributes["partstat-symbol"] = self._partstat_str
         attributes["title"] = self.summary
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/khal-0.14.0/khal/parse_datetime.py 
new/khal-0.14.1/khal/parse_datetime.py
--- old/khal-0.14.0/khal/parse_datetime.py      2026-03-24 17:05:07.000000000 
+0100
+++ new/khal-0.14.1/khal/parse_datetime.py      2026-08-21 08:25:24.940524600 
+0200
@@ -92,8 +92,8 @@
     for _ in range(parts):
         item = dtime_list.pop(0)
         if " " in item:
-            logger.warn("detected a space in datetime specification, this can 
lead to errors.")
-            logger.warn("Make sure not to quote your datetime specification.")
+            logger.warning("detected a space in datetime specification, this 
can lead to errors.")
+            logger.warning("Make sure not to quote your datetime 
specification.")
 
     if infer_year:
         dtstart = dt.datetime(*(default_day.timetuple()[:1] + 
dtstart_struct[1:5]))
@@ -242,8 +242,7 @@
         (datetimefwords, "", False, False),
     ]:
         # if a `short` format contains a year, treat it as a `long` format
-        if infer_year and "97" in dt.datetime(1997, 10, 11).strftime(dtformat):
-            infer_year = False
+        infer_year = infer_year and "97" not in dt.datetime(1997, 10, 
11).strftime(dtformat)
         try:
             dtstart = fun(dtime_list, dtformat, infer_year=infer_year)
         except (ValueError, DateTimeParseError):
@@ -389,7 +388,7 @@
                     end = start + delta
                 except (ValueError, DateTimeParseError):
                     split = endstr.split(" ")
-                    end, end_allday = guessdatetimefstr(
+                    end, _end_allday = guessdatetimefstr(
                         split, locale, default_day=start.date(), 
in_future=False
                     )
                     if len(split) != 0:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/khal-0.14.0/khal/settings/exceptions.py 
new/khal-0.14.1/khal/settings/exceptions.py
--- old/khal-0.14.0/khal/settings/exceptions.py 2026-03-24 17:05:07.000000000 
+0100
+++ new/khal-0.14.1/khal/settings/exceptions.py 2026-08-21 08:25:24.941382000 
+0200
@@ -25,8 +25,6 @@
 class InvalidSettingsError(Error):
     """Invalid Settings detected"""
 
-    pass
-
 
 class CannotParseConfigFileError(InvalidSettingsError):
     pass
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/khal-0.14.0/khal/settings/utils.py 
new/khal-0.14.1/khal/settings/utils.py
--- old/khal-0.14.0/khal/settings/utils.py      2026-03-24 17:05:07.000000000 
+0100
+++ new/khal-0.14.1/khal/settings/utils.py      2026-08-21 08:25:24.941382000 
+0200
@@ -71,7 +71,7 @@
         raise VdtValueError(f"Invalid timedelta: {string}")
 
 
-def weeknumber_option(option: str) -> Literal["left", "right"] | 
Literal[False]:
+def weeknumber_option(option: str) -> Literal["left", "right", False]:
     """checks if *option* is a valid value
 
     :param option: the option the user set in the config file
@@ -133,7 +133,7 @@
     # 5) an HTML-style color code
     if (
         color in ["", "auto"]
-        or color in COLORS.keys()
+        or color in COLORS
         or (color.isdigit() and int(color) >= 0 and int(color) <= 255)
         or (
             color.startswith("#")
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/khal-0.14.0/khal/ui/__init__.py 
new/khal-0.14.1/khal/ui/__init__.py
--- old/khal-0.14.0/khal/ui/__init__.py 2026-03-24 17:05:07.000000000 +0100
+++ new/khal-0.14.1/khal/ui/__init__.py 2026-08-21 08:25:24.941382000 +0200
@@ -1303,17 +1303,17 @@
         colors = {}
         # Colorcube
         colorlevels = (0x00, 0x5F, 0x87, 0xAF, 0xD7, 0xFF)
-        for r in range(0, 6):
-            for g in range(0, 6):
-                for b in range(0, 6):
+        for r in range(6):
+            for g in range(6):
+                for b in range(6):
                     colors[r * 36 + g * 6 + b + 16] = (
                         colorlevels[r],
                         colorlevels[g],
                         colorlevels[b],
                     )
         # Grayscale
-        graylevels = [0x08 + 10 * i for i in range(0, 24)]
-        for c in range(0, 24):
+        graylevels = [0x08 + 10 * i for i in range(24)]
+        for c in range(24):
             colors[232 + c] = (graylevels[c],) * 3
         # Parse the HTML-style color into the variables r, g, b.
         if len(color) == 4:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/khal-0.14.0/khal/ui/base.py 
new/khal-0.14.1/khal/ui/base.py
--- old/khal-0.14.0/khal/ui/base.py     2026-03-24 17:05:07.000000000 +0100
+++ new/khal-0.14.1/khal/ui/base.py     2026-08-21 08:25:24.942063800 +0200
@@ -201,7 +201,7 @@
         this callback is called with the given data (if any) before
         the previous pane gets redrawn.
         """
-        old_pane, cb = self._track.pop()
+        _old_pane, cb = self._track.pop()
         if cb:
             cb(data)
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/khal-0.14.0/khal/ui/calendarwidget.py 
new/khal-0.14.1/khal/ui/calendarwidget.py
--- old/khal-0.14.0/khal/ui/calendarwidget.py   2026-03-24 17:05:07.000000000 
+0100
+++ new/khal-0.14.1/khal/ui/calendarwidget.py   2026-08-21 08:25:24.942063800 
+0200
@@ -266,7 +266,7 @@
         return super().render(size, focus)
 
     def mouse_event(self, *args):
-        size, event, button, col, row, focus = args
+        _size, event, button, _col, _row, _focus = args
 
         if event == "mouse press" and button == 1:
             
self.focus.focus.set_styles(self.focus.get_styles(self.body.focus_date, False))
@@ -451,8 +451,8 @@
 
     def reset_styles_range(self, min_date: dt.date, max_date: dt.date) -> None:
         """reset styles for all (displayed) dates between min_date and 
max_date"""
-        minr, minc = self.get_date_pos(max(min_date, self.earliest_date))
-        maxr, maxc = self.get_date_pos(min(max_date, self.latest_date))
+        minr, _minc = self.get_date_pos(max(min_date, self.earliest_date))
+        maxr, _maxc = self.get_date_pos(min(max_date, self.latest_date))
         focus_pos = self.focus, self[self.focus].focus_col
 
         for row in range(minr, maxr + 1):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/khal-0.14.0/khal/ui/widgets.py 
new/khal-0.14.1/khal/ui/widgets.py
--- old/khal-0.14.0/khal/ui/widgets.py  2026-03-24 17:05:07.000000000 +0100
+++ new/khal-0.14.1/khal/ui/widgets.py  2026-08-21 08:25:24.942325400 +0200
@@ -305,7 +305,7 @@
 
     def _first_selectable(self):
         """return sequence number of self.contents last selectable item"""
-        for j in range(0, len(self._contents)):
+        for j in range(len(self._contents)):
             if self._contents[j][0].selectable():
                 return j
         return False
@@ -373,7 +373,7 @@
 
     def _first_selectable(self):
         """return sequence number of self._contents last selectable item"""
-        for j in range(0, len(self.body)):
+        for j in range(len(self.body)):
             if self.body[j].selectable():
                 return j
         return False
@@ -643,8 +643,8 @@
             focus_item=1,
         )
 
-        urwid.WidgetDecoration.__init__(self, widget)
         urwid.WidgetWrap.__init__(self, self._all)
+        self._original_widget = widget
 
     def render(self, size, focus):
         inner = self._all.contents[1][0]
@@ -696,7 +696,7 @@
         )
 
         urwid.WidgetWrap.__init__(self, self._all)
-        urwid.WidgetDecoration.__init__(self, widget)
+        self._original_widget = widget
 
     def render(self, size, focus):
         if focus:
@@ -715,7 +715,7 @@
         topline = urwid.AttrMap(urwid.Divider("━"), "frame")
         self._all = urwid.Pile([("flow", topline), widget], focus_item=1)
         urwid.WidgetWrap.__init__(self, self._all)
-        urwid.WidgetDecoration.__init__(self, widget)
+        self._original_widget = widget
 
     def render(self, size, focus):
         if focus:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/khal-0.14.0/khal/utils.py 
new/khal-0.14.1/khal/utils.py
--- old/khal-0.14.0/khal/utils.py       2026-03-24 17:05:07.000000000 +0100
+++ new/khal-0.14.1/khal/utils.py       2026-08-21 08:25:24.942325400 +0200
@@ -197,6 +197,12 @@
             if "calendar-color" in row:
                 row["calendar-color"] = get_color(row["calendar-color"])
 
+            if "alarms-list" in row and isinstance(row["alarms-list"], list):
+                row["alarms-list"] = ", ".join(
+                    alarm["description"] + "@" + alarm["delta-formatted"]
+                    for alarm in row["alarms-list"]
+                )
+
             s = format_string.format(**row)
 
             if colors:
@@ -245,6 +251,7 @@
     "end-necessary-long",
     "repeat-symbol",
     "repeat-pattern",
+    "alarms-list",
     "title",
     "organizer",
     "description",
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/khal-0.14.0/khal/version.py 
new/khal-0.14.1/khal/version.py
--- old/khal-0.14.0/khal/version.py     2026-03-24 17:05:08.000000000 +0100
+++ new/khal-0.14.1/khal/version.py     2026-08-21 08:25:26.381694800 +0200
@@ -28,7 +28,7 @@
 commit_id: COMMIT_ID
 __commit_id__: COMMIT_ID
 
-__version__ = version = '0.14.0'
-__version_tuple__ = version_tuple = (0, 14, 0)
+__version__ = version = '0.14.1'
+__version_tuple__ = version_tuple = (0, 14, 1)
 
-__commit_id__ = commit_id = 'gd1b48422c'
+__commit_id__ = commit_id = 'ge8642d7c9'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/khal-0.14.0/khal.egg-info/PKG-INFO 
new/khal-0.14.1/khal.egg-info/PKG-INFO
--- old/khal-0.14.0/khal.egg-info/PKG-INFO      2026-03-24 17:05:08.000000000 
+0100
+++ new/khal-0.14.1/khal.egg-info/PKG-INFO      2026-08-21 08:25:26.421289200 
+0200
@@ -1,6 +1,6 @@
 Metadata-Version: 2.4
 Name: khal
-Version: 0.14.0
+Version: 0.14.1
 Summary: Standards based terminal calendar
 Author-email: khal contributors <[email protected]>
 License-Expression: MIT
@@ -61,7 +61,7 @@
 *Khal* is a standards based CLI and terminal calendar program, able to 
synchronize
 with CalDAV_ servers through vdirsyncer_.
 
-.. image:: http://lostpackets.de/images/khal.png
+.. image:: https://lostpackets.de/images/khal.png
 
 Features
 --------
@@ -86,16 +86,16 @@
 
 .. _vdir: https://vdirsyncer.readthedocs.org/en/stable/vdir.html
 .. _vdirsyncer: https://github.com/pimutils/vdirsyncer
-.. _CalDAV: http://en.wikipedia.org/wiki/CalDAV
+.. _CalDAV: https://en.wikipedia.org/wiki/CalDAV
 .. _github: https://github.com/pimutils/khal/
-.. __: 
http://en.wikipedia.org/wiki/Comparison_of_CalDAV_and_CardDAV_implementations
+.. __: 
https://en.wikipedia.org/wiki/Comparison_of_CalDAV_and_CardDAV_implementations
 
 
 Documentation
 -------------
 For khal's documentation have a look at readthedocs_.
 
-.. _readthedocs: http://khal.readthedocs.org/
+.. _readthedocs: https://khal.readthedocs.org/
 
 Installation
 ------------
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/khal-0.14.0/pyproject.toml 
new/khal-0.14.1/pyproject.toml
--- old/khal-0.14.0/pyproject.toml      2026-03-24 17:05:07.000000000 +0100
+++ new/khal-0.14.1/pyproject.toml      2026-08-21 08:25:24.942752000 +0200
@@ -63,6 +63,12 @@
 khal = "khal.cli:main_khal"
 ikhal = "khal.cli:main_ikhal"
 
+[tool.pytest.ini_options]
+filterwarnings = [
+  # hypothesis triggers warnings while walking modules inside urwid.
+  
"ignore:.*urwid\\.(lcd_display|html_fragment|web_display|monitored_list|listbox|treetools)
 is moved to.*:DeprecationWarning",
+]
+
 [build-system]
 requires = ["setuptools>=77", "setuptools_scm>=8"]
 build-backend = "setuptools.build_meta"
@@ -92,6 +98,3 @@
 exclude_lines = [
     "if TYPE_CHECKING:",
 ]
-
-[tool.mypy]
-ignore_missing_imports = true
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/khal-0.14.0/tests/cli_test.py 
new/khal-0.14.1/tests/cli_test.py
--- old/khal-0.14.0/tests/cli_test.py   2026-03-24 17:05:07.000000000 +0100
+++ new/khal-0.14.1/tests/cli_test.py   2026-08-21 08:25:24.942902600 +0200
@@ -215,7 +215,7 @@
             result = runner.invoke(main_khal, command.split())
             assert not result.exception
 
-        result = runner.invoke(main_khal, "list now".split())
+        result = runner.invoke(main_khal, ["list", "now"])
         assert (
             result.output
             == """Today, 01.06.2015
@@ -232,7 +232,7 @@
 """
         )
         assert not result.exception
-        result = runner.invoke(main_khal, "list now --notstarted".split())
+        result = runner.invoke(main_khal, ["list", "now", "--notstarted"])
         assert (
             result.output
             == """Today, 01.06.2015
@@ -246,7 +246,7 @@
         )
         assert not result.exception
 
-        result = runner.invoke(main_khal, "list now --once".split())
+        result = runner.invoke(main_khal, ["list", "now", "--once"])
         assert (
             result.output
             == """Today, 01.06.2015
@@ -260,7 +260,7 @@
         )
         assert not result.exception
 
-        result = runner.invoke(main_khal, "list now --once 
--notstarted".split())
+        result = runner.invoke(main_khal, ["list", "now", "--once", 
"--notstarted"])
         assert (
             result.output
             == """Today, 01.06.2015
@@ -346,9 +346,9 @@
 
 def test_invalid_calendar(runner):
     runner = runner(days=2)
-    result = runner.invoke(main_khal, ["new"] + "-a one 18:00 myevent".split())
+    result = runner.invoke(main_khal, ["new"] + ["-a", "one", "18:00", 
"myevent"])
     assert not result.exception
-    result = runner.invoke(main_khal, ["new"] + "-a inexistent 18:00 
myevent".split())
+    result = runner.invoke(main_khal, ["new"] + ["-a", "inexistent", "18:00", 
"myevent"])
     assert result.exception
     assert result.exit_code == 2
     assert "Unknown calendar " in result.output
@@ -527,6 +527,32 @@
     assert result.output.startswith(expected)
 
 
+def test_list_alarms(runner):
+    runner = runner(days=2)
+    now = dt.datetime.now().strftime("%d.%m.%Y")
+    runner.invoke(main_khal, f"new {now} 18:00 myevent --alarms 
-15m,1h".split())
+    args = ["list", "--format", "{alarms-list}", "--day-format", ""]
+    result = runner.invoke(main_khal, args)
+    assert not result.exception
+    assert result.output.strip() == "@15m, @-1h"
+
+
+def test_list_alarms_json(runner):
+    runner = runner()
+    now = dt.datetime.now().strftime("%d.%m.%Y")
+    runner.invoke(main_khal, f"new {now} 18:00 myevent --alarms 
15m,1h".split())
+    args = ["list", "--json", "alarms-list"]
+    result = runner.invoke(main_khal, args)
+    expected = '[{"alarms-list": [\
+{"delta": -900.0, "description": "", "delta-formatted": "-15m"}, \
+{"delta": -3600.0, "description": "", "delta-formatted": "-1h"}\
+]}]'
+    print(result.output)
+    print(expected)
+    assert not result.exception
+    assert result.output.startswith(expected)
+
+
 def test_search(runner):
     runner = runner(days=2)
     now = dt.datetime.now().strftime("%d.%m.%Y")
@@ -560,7 +586,7 @@
 
 def test_no_default_new(runner):
     runner = runner(default_calendar=False)
-    result = runner.invoke(main_khal, "new 18:00 beer".split())
+    result = runner.invoke(main_khal, ["new", "18:00", "beer"])
     assert (
         "Error: Invalid value: No default calendar is configured, please 
provide one explicitly."
     ) in result.output
@@ -578,7 +604,7 @@
 
 def test_import(runner, monkeypatch):
     runner = runner()
-    result = runner.invoke(main_khal, "import -a one -a two import 
file.ics".split())
+    result = runner.invoke(main_khal, ["import", "-a", "one", "-a", "two", 
"import", "file.ics"])
     assert result.exception
     assert result.exit_code == 2
     assert 'Can\'t use "--include-calendar" / "-a" more than once' in 
result.output
@@ -992,7 +1018,7 @@
 def test_new(runner):
     runner = runner(print_new="path")
 
-    result = runner.invoke(main_khal, "new 13.03.2016 3d Visit".split())
+    result = runner.invoke(main_khal, ["new", "13.03.2016", "3d", "Visit"])
     assert not result.exception
     assert result.output.endswith(".ics\n")
     assert result.output.startswith(str(runner.tmpdir))
@@ -1033,7 +1059,7 @@
 def test_new_interactive(runner):
     runner = runner(print_new="path")
 
-    result = runner.invoke(main_khal, "new -i".split(), "Another event\n13:00 
17:00\n\nNone\nn\n")
+    result = runner.invoke(main_khal, ["new", "-i"], "Another event\n13:00 
17:00\n\nNone\nn\n")
     assert not result.exception
     assert result.exit_code == 0
 
@@ -1053,7 +1079,7 @@
 
     result = runner.invoke(
         main_khal,
-        "new -i 15:00 15:30".split(),
+        ["new", "-i", "15:00", "15:30"],
         "?\ninvalid\ntwo\n"
         "Unicce Name\n"
         "\n"
@@ -1079,7 +1105,7 @@
 
     result = runner.invoke(
         main_khal,
-        "new -i".split(),
+        ["new", "-i"],
         "two\n"
         "new event\n"
         "now\n"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/khal-0.14.0/tests/controller_test.py 
new/khal-0.14.1/tests/controller_test.py
--- old/khal-0.14.0/tests/controller_test.py    2026-03-24 17:05:07.000000000 
+0100
+++ new/khal-0.14.1/tests/controller_test.py    2026-08-21 08:25:24.943333000 
+0200
@@ -39,7 +39,7 @@
 
 class TestGetAgenda:
     def test_new_event(self, coll_vdirs):
-        coll, vdirs = coll_vdirs
+        coll, _vdirs = coll_vdirs
         event = coll.create_event_from_ics(event_today, utils.cal1)
         coll.insert(event)
         assert ["                 a meeting :: short description\x1b[0m"] == 
khal_list(
@@ -47,7 +47,7 @@
         )
 
     def test_new_event_day_format(self, coll_vdirs):
-        coll, vdirs = coll_vdirs
+        coll, _vdirs = coll_vdirs
         event = coll.create_event_from_ics(event_today, utils.cal1)
         coll.insert(event)
         assert [
@@ -61,7 +61,7 @@
             event_today = event_allday_template.format(
                 today.strftime("%Y%m%d"), tomorrow.strftime("%Y%m%d")
             )
-            coll, vdirs = coll_vdirs
+            coll, _vdirs = coll_vdirs
             event = coll.create_event_from_ics(event_today, utils.cal1)
             coll.insert(event)
             out = khal_list(coll, conf=conf, agenda_format=event_format, 
datepoint=[])
@@ -72,14 +72,14 @@
 
     def test_agenda_fail(self, coll_vdirs):
         with freeze_time("2016-04-10 12:33"):
-            coll, vdirs = coll_vdirs
+            coll, _vdirs = coll_vdirs
             with pytest.raises(exceptions.FatalError):
                 khal_list(coll, conf=conf, agenda_format=event_format, 
datepoint=["xyz"])
             with pytest.raises(exceptions.FatalError):
                 khal_list(coll, conf=conf, agenda_format=event_format, 
datepoint=["today"])
 
     def test_empty_recurrence(self, coll_vdirs):
-        coll, vidrs = coll_vdirs
+        coll, _vidrs = coll_vdirs
         coll.insert(
             coll.create_event_from_ics(
                 dedent(
@@ -106,7 +106,7 @@
 
 class TestImport:
     def test_import(self, coll_vdirs):
-        coll, vdirs = coll_vdirs
+        coll, _vdirs = coll_vdirs
         view = {"event_format": "{title}"}
         conf = {"locale": utils.LOCALE_BERLIN, "view": view}
         import_ics(coll, conf, _get_text("event_rrule_recuid"), batch=True)
@@ -132,7 +132,7 @@
         """
         Test importing events with mixed tz-aware and tz-naive datetimes.
         """
-        coll, vdirs = coll_vdirs
+        coll, _vdirs = coll_vdirs
         view = {"event_format": "{title}"}
         import_ics(
             coll,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/khal-0.14.0/tests/event_test.py 
new/khal-0.14.1/tests/event_test.py
--- old/khal-0.14.0/tests/event_test.py 2026-03-24 17:05:07.000000000 +0100
+++ new/khal-0.14.1/tests/event_test.py 2026-08-21 08:25:24.943333000 +0200
@@ -596,6 +596,28 @@
     assert event.alarms == [(dt.timedelta(-1, 82800), vText("new event"))]
 
 
+def test_event_alarm_list():
+    """test the content of `alarms-list` attribute"""
+    event = Event.fromString(_get_text("event_dt_simple"), **EVENT_KWARGS)
+    assert event.alarms == []
+    event.update_alarms(
+        [(dt.timedelta(minutes=30), "alarm 1"), (-dt.timedelta(hours=1, 
minutes=30), "alarm 2")]
+    )
+    attributes = event.attributes(dt.date.today())
+    assert attributes["alarms-list"] == [
+        {"delta": 1800.0, "description": "alarm 1", "delta-formatted": "30m"},
+        {"delta": -5400.0, "description": "alarm 2", "delta-formatted": "-1h 
-30m"},
+    ]
+
+
+def test_event_no_alarms_list():
+    """test that `alarms-list` is empty for an event with no alarms"""
+    event = Event.fromString(_get_text("event_dt_simple"), **EVENT_KWARGS)
+    assert event.alarms == []
+    attributes = event.attributes(dt.date.today())
+    assert attributes["alarms-list"] == []
+
+
 def test_event_attendees():
     event = Event.fromString(_get_text("event_dt_simple"), **EVENT_KWARGS)
     assert event.attendees == ""
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/khal-0.14.0/tests/khalendar_test.py 
new/khal-0.14.1/tests/khalendar_test.py
--- old/khal-0.14.0/tests/khalendar_test.py     2026-03-24 17:05:07.000000000 
+0100
+++ new/khal-0.14.1/tests/khalendar_test.py     2026-08-21 08:25:24.945348300 
+0200
@@ -71,7 +71,7 @@
         assert len(list(vdirs[cal1].list())) == 1
 
     def test_sanity(self, coll_vdirs):
-        coll, vdirs = coll_vdirs
+        coll, _vdirs = coll_vdirs
         mtimes = {}
         for _ in range(100):
             for cal in coll._calendars:
@@ -115,7 +115,7 @@
 
 class TestVdirsyncerCompat:
     def test_list(self, coll_vdirs):
-        coll, vdirs = coll_vdirs
+        coll, _vdirs = coll_vdirs
         event = Event.fromString(_get_text("event_d"), calendar=cal1, 
locale=LOCALE_BERLIN)
         assert event.etag is None
         assert event.href is None
@@ -164,7 +164,7 @@
         assert coll.writable_names == ["home"]
 
     def test_empty(self, coll_vdirs):
-        coll, vdirs = coll_vdirs
+        coll, _vdirs = coll_vdirs
         start = dt.datetime.combine(today, dt.time.min)
         end = dt.datetime.combine(today, dt.time.max)
         assert list(coll.get_floating(start, end)) == []
@@ -225,7 +225,7 @@
 
     def test_get(self, coll_vdirs):
         """test getting an event by its href"""
-        coll, vdirs = coll_vdirs
+        coll, _vdirs = coll_vdirs
         event = Event.fromString(
             _get_text("event_dt_simple"),
             href="xyz.ics",
@@ -242,7 +242,7 @@
 
     def test_change(self, coll_vdirs):
         """moving an event from one calendar to another"""
-        coll, vdirs = coll_vdirs
+        coll, _vdirs = coll_vdirs
         event = Event.fromString(_get_text("event_dt_simple"), calendar=cal1, 
locale=LOCALE_BERLIN)
         coll.insert(event, cal1)
         event = list(coll.get_events_on(aday))[0]
@@ -255,7 +255,7 @@
 
     def test_update_event(self, coll_vdirs):
         """updating one event"""
-        coll, vdirs = coll_vdirs
+        coll, _vdirs = coll_vdirs
         event = Event.fromString(_get_text("event_dt_simple"), calendar=cal1, 
locale=LOCALE_BERLIN)
         coll.insert(event, cal1)
         events = coll.get_events_on(aday)
@@ -270,7 +270,7 @@
         assert events[0].summary == "really simple event"
 
     def test_newevent(self, coll_vdirs):
-        coll, vdirs = coll_vdirs
+        coll, _vdirs = coll_vdirs
         bday = dt.datetime.combine(aday, dt.time.min)
         anend = bday + dt.timedelta(hours=1)
         event = icalendar_helpers.new_vevent(
@@ -284,7 +284,7 @@
         assert event.allday is False
 
     def test_modify_readonly_calendar(self, coll_vdirs):
-        coll, vdirs = coll_vdirs
+        coll, _vdirs = coll_vdirs
         coll._calendars[cal1]["readonly"] = True
         coll._calendars[cal3]["readonly"] = True
         event = Event.fromString(_get_text("event_dt_simple"), calendar=cal1, 
locale=LOCALE_BERLIN)
@@ -296,7 +296,7 @@
             coll.delete("href", "eteg", cal1)
 
     def test_search(self, coll_vdirs):
-        coll, vdirs = coll_vdirs
+        coll, _vdirs = coll_vdirs
         assert len(list(coll.search("Event"))) == 0
         event = Event.fromString(_get_text("event_dt_simple"), calendar=cal1, 
locale=LOCALE_BERLIN)
         coll.insert(event, cal1)
@@ -311,7 +311,7 @@
     def test_search_recurrence_id_only(self, coll_vdirs):
         """test searching for recurring events which only have a recuid event,
         and no master"""
-        coll, vdirs = coll_vdirs
+        coll, _vdirs = coll_vdirs
         assert len(list(coll.search("Event"))) == 0
         event = Event.fromString(
             _get_text("event_dt_recuid_no_master"), calendar=cal1, 
locale=LOCALE_BERLIN
@@ -322,7 +322,7 @@
     def test_search_recurrence_id_only_multi(self, coll_vdirs):
         """test searching for recurring events which only have a recuid event,
         and no master"""
-        coll, vdirs = coll_vdirs
+        coll, _vdirs = coll_vdirs
         assert len(list(coll.search("Event"))) == 0
         event = Event.fromString(
             _get_text("event_dt_multi_recuid_no_master"), calendar=cal1, 
locale=LOCALE_BERLIN
@@ -386,7 +386,7 @@
     def test_invalid_timezones(self, coll_vdirs):
         """testing if we can delete any of two events in two different
         calendars with the same filename"""
-        coll, vdirs = coll_vdirs
+        coll, _vdirs = coll_vdirs
         event = Event.fromString(_get_text("invalid_tzoffset"), calendar=cal1, 
locale=LOCALE_BERLIN)
         coll.insert(event, cal1)
         events = sorted(coll.search("Event"))
@@ -515,7 +515,7 @@
 def test_only_update_old_event(coll_vdirs, monkeypatch, sleep_time):
     coll, vdirs = coll_vdirs
 
-    href_one, etag_one = vdirs[cal1].upload(
+    _href_one, _etag_one = vdirs[cal1].upload(
         coll.create_event_from_ics(
             dedent("""
     BEGIN:VEVENT
@@ -531,7 +531,7 @@
 
     sleep(sleep_time)  # Make sure we get a new etag for meeting-two
 
-    href_two, etag_two = vdirs[cal1].upload(
+    _href_two, _etag_two = vdirs[cal1].upload(
         coll.create_event_from_ics(
             dedent("""
     BEGIN:VEVENT
@@ -559,7 +559,7 @@
 
     monkeypatch.setattr(coll, "_update_vevent", _update_vevent)
 
-    href_three, etag_three = vdirs[cal1].upload(
+    href_three, _etag_three = vdirs[cal1].upload(
         coll.create_event_from_ics(
             dedent("""
     BEGIN:VEVENT
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/khal-0.14.0/tests/parse_datetime_test.py 
new/khal-0.14.1/tests/parse_datetime_test.py
--- old/khal-0.14.0/tests/parse_datetime_test.py        2026-03-24 
17:05:07.000000000 +0100
+++ new/khal-0.14.1/tests/parse_datetime_test.py        2026-08-21 
08:25:24.945348300 +0200
@@ -144,31 +144,31 @@
     @freeze_time("2016-9-19T8:00")
     def test_tomorrow(self):
         assert (dt.datetime(2016, 9, 20, 16), False) == guessdatetimefstr(
-            "tomorrow 16:00 16:00".split(), locale=LOCALE_BERLIN
+            ["tomorrow", "16:00", "16:00"], locale=LOCALE_BERLIN
         )
 
     @freeze_time("2016-9-19T8:00")
     def test_time_tomorrow(self):
         assert (dt.datetime(2016, 9, 20, 16), False) == guessdatetimefstr(
-            "16:00".split(), locale=LOCALE_BERLIN, default_day=dt.date(2016, 
9, 20)
+            ["16:00"], locale=LOCALE_BERLIN, default_day=dt.date(2016, 9, 20)
         )
 
     @freeze_time("2016-9-19T8:00")
     def test_time_yesterday(self):
         assert (dt.datetime(2016, 9, 18, 16), False) == guessdatetimefstr(
-            "Yesterday 16:00".split(), locale=LOCALE_BERLIN, 
default_day=dt.datetime.today()
+            ["Yesterday", "16:00"], locale=LOCALE_BERLIN, 
default_day=dt.datetime.today()
         )
 
     @freeze_time("2016-9-19")
     def test_time_weekday(self):
         assert (dt.datetime(2016, 9, 23, 16), False) == guessdatetimefstr(
-            "Friday 16:00".split(), locale=LOCALE_BERLIN, 
default_day=dt.datetime.today()
+            ["Friday", "16:00"], locale=LOCALE_BERLIN, 
default_day=dt.datetime.today()
         )
 
     @freeze_time("2016-9-19 17:53")
     def test_time_now(self):
         assert (dt.datetime(2016, 9, 19, 17, 53), False) == guessdatetimefstr(
-            "now".split(), locale=LOCALE_BERLIN, 
default_day=dt.datetime.today()
+            ["now"], locale=LOCALE_BERLIN, default_day=dt.datetime.today()
         )
 
     @freeze_time("2016-12-30 17:53")
@@ -182,10 +182,10 @@
             "longdatetimeformat": "",
         }
         assert (dt.datetime(2017, 1, 1), True) == guessdatetimefstr(
-            "2017-1-1".split(), locale=locale, default_day=dt.datetime.today()
+            ["2017-1-1"], locale=locale, default_day=dt.datetime.today()
         )
         assert (dt.datetime(2017, 1, 1, 16, 30), False) == guessdatetimefstr(
-            "2017-1-1 16:30".split(), locale=locale, 
default_day=dt.datetime.today()
+            ["2017-1-1", "16:30"], locale=locale, 
default_day=dt.datetime.today()
         )
 
     @freeze_time("2016-12-30 17:53")
@@ -200,10 +200,10 @@
             "longdatetimeformat": "%Y-%m-%d %H:%M",
         }
         assert (dt.datetime(2017, 1, 1), True) == guessdatetimefstr(
-            "2017-1-1".split(), locale=locale, default_day=dt.datetime.today()
+            ["2017-1-1"], locale=locale, default_day=dt.datetime.today()
         )
         assert (dt.datetime(2017, 1, 1, 16, 30), False) == guessdatetimefstr(
-            "2017-1-1 16:30".split(), locale=locale, 
default_day=dt.datetime.today()
+            ["2017-1-1", "16:30"], locale=locale, 
default_day=dt.datetime.today()
         )
 
 
@@ -539,9 +539,8 @@
 
 def test_leap_year():
     for data_list, vevent in test_set_leap_year:
-        with freeze_time("1999-1-1"):
-            with pytest.raises(DateTimeParseError):
-                event = _construct_event(data_list.split(), 
locale=LOCALE_BERLIN)
+        with freeze_time("1999-1-1"), pytest.raises(DateTimeParseError):
+            event = _construct_event(data_list.split(), locale=LOCALE_BERLIN)
         with freeze_time("2016-1-1 20:21:22"):
             event = _construct_event(data_list.split(), locale=LOCALE_BERLIN)
             assert _replace_uid(event).to_ical() == vevent
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/khal-0.14.0/tests/ui/test_widgets.py 
new/khal-0.14.1/tests/ui/test_widgets.py
--- old/khal-0.14.0/tests/ui/test_widgets.py    2026-03-24 17:05:07.000000000 
+0100
+++ new/khal-0.14.1/tests/ui/test_widgets.py    2026-08-21 08:25:24.946356000 
+0200
@@ -1,4 +1,12 @@
-from khal.ui.widgets import delete_last_word
+import pytest
+import urwid
+
+from khal.ui.widgets import (
+    FocusLineBoxColor,
+    FocusLineBoxTop,
+    FocusLineBoxWidth,
+    delete_last_word,
+)
 
 
 def test_delete_last_word():
@@ -27,3 +35,12 @@
 
     for org, short, number in tests:
         assert delete_last_word(org, number) == short
+
+
[email protected]("cls", [FocusLineBoxColor, FocusLineBoxTop, 
FocusLineBoxWidth])
+def test_focus_line_box(cls):
+    inner = urwid.Filler(urwid.Text("test"))
+    box = cls(inner)
+    assert box.original_widget is inner
+    box.render((20, 10), focus=False)
+    box.render((20, 10), focus=True)

Reply via email to