From f6c747480053c623ffb65d08d287f6a2aae8613b Mon Sep 17 00:00:00 2001
From: Paul McCarthy <pauldmccarthy@gmail.com>
Date: Wed, 26 Feb 2025 16:26:44 +0000
Subject: [PATCH] BF: Notifier.notify() could raise an exception if a callback
 function was GC'd

---
 fsl/utils/notifier.py | 20 +++++++++++++-------
 1 file changed, 13 insertions(+), 7 deletions(-)

diff --git a/fsl/utils/notifier.py b/fsl/utils/notifier.py
index bb039e636..6a46df394 100644
--- a/fsl/utils/notifier.py
+++ b/fsl/utils/notifier.py
@@ -66,7 +66,12 @@ class _Listener:
         positional arguments - see :meth:`Notifier.register` for details.
         """
 
-        func    = self.callback
+        func = self.callback
+
+        # the function may have been GC'd
+        if func is None:
+            return False
+
         spec    = inspect.signature(func)
         posargs = 0
         varargs = False
@@ -377,9 +382,6 @@ class Notifier:
             callback = listener.callback
             name     = listener.name
 
-            if listener.expectsArguments: args = (self, topic, value)
-            else:                         args = ()
-
             # The callback, or the owner of the
             # callback function may have been
             # gc'd - remove it if this is the case.
@@ -387,12 +389,16 @@ class Notifier:
                 log.debug('Listener %s has been gc\'d - '
                           'removing from list', name)
                 self.__listeners[listener.topic].pop(name)
+                continue
 
-            elif not listener.enabled:
+            if not listener.enabled:
                 continue
 
-            elif listener.runOnIdle: idle.idle(callback, *args)
-            else:                    callback(           *args)
+            if listener.expectsArguments: args = (self, topic, value)
+            else:                         args = ()
+
+            if listener.runOnIdle: idle.idle(callback, *args)
+            else:                  callback(           *args)
 
 
     def __getListeners(self, topic):
-- 
GitLab