[pitivi: 20/28] Fix Signallable to not skip next handler when a handler disconnects itself while handling a signal



commit 4d5b01ed8248f6c88ce9bc23185aad18d5379861
Author: Alex BÄluÈ <alexandru balut gmail com>
Date:   Mon Jul 11 13:06:48 2011 +0200

    Fix Signallable to not skip next handler when a handler disconnects itself while handling a signal

 pitivi/signalinterface.py |    8 +++++++-
 tests/test_signallable.py |   40 ++++++++++++++++++++++++++++++++++++----
 2 files changed, 43 insertions(+), 5 deletions(-)
---
diff --git a/pitivi/signalinterface.py b/pitivi/signalinterface.py
index 9b895c4..9273277 100644
--- a/pitivi/signalinterface.py
+++ b/pitivi/signalinterface.py
@@ -111,7 +111,13 @@ class Signallable(object):
             # will concatenate the given args/kwargs with
             # the ones supplied in .connect()
             res = None
-            for sigid in self.handlers[signame]:
+            # Create a copy because if the handler being executed disconnects,
+            # the next handler will not be called.
+            signame_handlers = list(self.handlers[signame])
+            for sigid in signame_handlers:
+                if sigid not in self.handlers[signame]:
+                    # The handler has been disconnected in the meantime!
+                    continue
                 # cb: callable
                 cb, orar, kwar = self.ids[sigid]
                 ar = args[:] + orar
diff --git a/tests/test_signallable.py b/tests/test_signallable.py
index 39e29cf..6b8285a 100644
--- a/tests/test_signallable.py
+++ b/tests/test_signallable.py
@@ -6,8 +6,7 @@ class myobject(Signallable):
 
     __signals__ = {
         "signal-oneargs": ["firstarg"],
-        "signal-noargs": []
-        }
+        "signal-noargs": []}
 
     def emit_signal_one_args(self, firstarg):
         self.emit("signal-oneargs", firstarg)
@@ -19,8 +18,7 @@ class myobject(Signallable):
 class mysubobject(myobject):
 
     __signals__ = {
-        "subobject-noargs": None
-        }
+        "subobject-noargs": None}
 
     def emit_sub_signal_no_args(self):
         self.emit("subobject-noargs")
@@ -159,6 +157,40 @@ class TestSignalisation(unittest.TestCase):
 
         self.object.emit("signal-oneargs", 42)
 
+    def test_disconnect_while_handling(self):
+        # When the handler being called disconnects itself,
+        # the next handler must not be skipped.
+
+        def firstCb(unused_object):
+            self.object.disconnect_by_function(firstCb)
+
+        def secondCb(unused_object):
+            self.called = True
+
+        self.called = False
+        self.object.connect("signal-oneargs", firstCb)
+        self.object.connect("signal-oneargs", secondCb)
+        self.object.emit("signal-oneargs")
+        self.assertTrue(self.called)
+        del self.called
+
+    def test_disconnect_following_handler_while_handling(self):
+        # When the handler being called disconnects a following handler,
+        # the following handler must be skipped.
+
+        def firstCb(unused_object):
+            self.object.disconnect_by_function(secondCb)
+
+        def secondCb(unused_object):
+            self.called = True
+
+        self.called = False
+        self.object.connect("signal-oneargs", firstCb)
+        self.object.connect("signal-oneargs", secondCb)
+        self.object.emit("signal-oneargs")
+        self.assertFalse(self.called)
+        del self.called
+
     def test04_emit01(self):
         # signal: no arguments
         # connect: no arguments



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]