Package: unattended-upgrades
Version: 2.13
Severity: minor
Tags: patch

Dear Maintainer,

After upgrading unattended-upgrades from 2.12+nmu1 to 2.13 on Debian testing/unstable (forky/sid), the unattended-upgrades-shutdown daemon throws a PyGIDeprecationWarning in the system logs: "PyGIDeprecationWarning: GLib.unix_signal_add is deprecated; use GLibUnix.signal_add instead"

The attached DEP-3 patch migrates the code cleanly to GLibUnix.signal_add while safely maintaining fallback signature compliance (*args positional parameter swallowing) for setups running without python3-gi. Tested successfully on a live unit with SIGHUP handling.

Description: Fix GLib.unix_signal_add deprecation warning
Under newer PyGObject/GLib releases (such as those in Debian trixie/forky),
  calling GLib.unix_signal_add issues a PyGIDeprecationWarning because the
  function has been relocated to the platform-specific GLibUnix namespace.
  .
  This patch migrates the call to GLibUnix.signal_add. To maintain runtime
  fallback compatibility with environments lacking python3-gi (which relies
on native python signal.signal), the internal signal_handler signature has
  been modified to use *args, ensuring it safely handles both standard Unix
  frame arguments and GLib user_data contexts.
Author: Florian Neumeyer <[email protected]>
Forwarded: no
Last-Update: 2026-08-30
--- a/usr/share/unattended-upgrades/unattended-upgrade-shutdown	2026-07-06 18:39:18.000000000 +0200
+++ b/usr/share/unattended-upgrades/unattended-upgrade-shutdown	2026-08-30 22:13:58.934175646 +0200
@@ -38,8 +38,11 @@
 
 # for dbus signal handling
 try:
+    import gi
+    gi.require_version('GLib', '2.0')
+    gi.require_version('GLibUnix', '2.0')
     from dbus.mainloop.glib import DBusGMainLoop
-    from gi.repository import GLib
+    from gi.repository import GLib, GLibUnix
 except ImportError:
     pass
 
@@ -231,14 +234,21 @@
         """ delay shutdown and wait for PrepareForShutdown or other signals"""
 
         # set signal handlers
-        def signal_handler(signum, frame):
-            # type: (object) -> None
+        # Updated handler signature to safely swallow both (signum, frame) and (user_data)
+        def signal_handler(*args):
+            # type: (*object) -> bool | None
             logging.warning(
                 "SIGTERM or SIGHUP received, stopping unattended-upgrades "
                 "only if it is running")
             self.stop_signal_received.set()
             self.start_iterations()
 
+            # Only return GLib constants if GLib was successfully imported
+            try:
+                return GLib.SOURCE_REMOVE
+            except NameError:
+                return None
+
         # fall back to polling without GLib
         try:
             hasattr(GLib, "MainLoop")
@@ -247,8 +257,8 @@
             return
 
         for sig in (signal.SIGTERM, signal.SIGHUP):
-            GLib.unix_signal_add(GLib.PRIORITY_DEFAULT, sig,
-                                 signal_handler, None, None)
+            GLibUnix.signal_add(GLib.PRIORITY_DEFAULT, sig,
+                                 signal_handler, None)
         if self.options.wait_for_signal:
             def prepare_for_shutdown_handler(active):
                 """ Handle PrepareForShutdown() """

Reply via email to