[pygobject] Add accumulator and accu_data arguments to GObject.Signal decorator



commit c32793dafbd52eab87b14ca064b47f5a4fb9000b
Author: Simon Feltman <sfeltman src gnome org>
Date:   Mon Aug 5 14:40:38 2013 -0700

    Add accumulator and accu_data arguments to GObject.Signal decorator
    
    Update __init__, __call__, and copy methods to accept and pass
    accumulators and associated user data through them. Update
    accumulator unittests to use Signal decorators for testing accumulator
    pass throughs. Verified the __gsignals__ dictionary accepts None
    as valid values for accumulator and accu_data so specialization
    for these arguments is not necessary.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=705533

 gi/_gobject/signalhelper.py |   17 ++++++++++----
 tests/test_signal.py        |   52 +++++++++++++++++++++++-------------------
 2 files changed, 40 insertions(+), 29 deletions(-)
---
diff --git a/gi/_gobject/signalhelper.py b/gi/_gobject/signalhelper.py
index 703b78c..b630158 100644
--- a/gi/_gobject/signalhelper.py
+++ b/gi/_gobject/signalhelper.py
@@ -110,7 +110,7 @@ class Signal(str):
         return str.__new__(cls, name)
 
     def __init__(self, name='', func=None, flags=_gobject.SIGNAL_RUN_FIRST,
-                 return_type=None, arg_types=None, doc=''):
+                 return_type=None, arg_types=None, doc='', accumulator=None, accu_data=None):
         """
         @param  name: name of signal or closure method when used as direct decorator.
         @type   name: string or callable
@@ -124,6 +124,11 @@ class Signal(str):
         @type   arg_types: None
         @param  doc: documentation of signal object
         @type   doc: string
+        @param  accumulator: accumulator method with the signature:
+                func(ihint, return_accu, handler_return, accu_data) -> boolean
+        @type   accumulator: function
+        @param  accu_data: user data passed to the accumulator
+        @type   accu_data: object
         """
         if func and not name:
             name = func.__name__
@@ -145,6 +150,8 @@ class Signal(str):
         self.return_type = return_type
         self.arg_types = arg_types
         self.__doc__ = doc
+        self.accumulator = accumulator
+        self.accu_data = accu_data
 
     def __get__(self, instance, owner=None):
         """Returns a BoundSignal when accessed on an object instance."""
@@ -170,7 +177,7 @@ class Signal(str):
             # Return a new value of this type since it is based on an immutable string.
             return type(self)(name=name, func=obj, flags=self.flags,
                               return_type=self.return_type, arg_types=self.arg_types,
-                              doc=self.__doc__)
+                              doc=self.__doc__, accumulator=self.accumulator, accu_data=self.accu_data)
 
     def copy(self, newName=None):
         """Returns a renamed copy of the Signal."""
@@ -178,11 +185,11 @@ class Signal(str):
             newName = self.name
         return type(self)(name=newName, func=self.func, flags=self.flags,
                           return_type=self.return_type, arg_types=self.arg_types,
-                          doc=self.__doc__)
+                          doc=self.__doc__, accumulator=self.accumulator, accu_data=self.accu_data)
 
     def get_signal_args(self):
-        """Returns a tuple of: (flags, return_type, arg_types)"""
-        return (self.flags, self.return_type, self.arg_types)
+        """Returns a tuple of: (flags, return_type, arg_types, accumulator, accu_data)"""
+        return (self.flags, self.return_type, self.arg_types, self.accumulator, self.accu_data)
 
 
 class SignalOverride(Signal):
diff --git a/tests/test_signal.py b/tests/test_signal.py
index c19fbe5..ec13896 100644
--- a/tests/test_signal.py
+++ b/tests/test_signal.py
@@ -116,48 +116,52 @@ def my_accumulator(ihint, return_accu, handler_return, user_data):
 
 
 class Foo(GObject.GObject):
-    __gsignals__ = {
-        'my-acc-signal': (GObject.SignalFlags.RUN_LAST, GObject.TYPE_INT,
-                          (), my_accumulator, "accum data"),
-        'my-other-acc-signal': (GObject.SignalFlags.RUN_LAST, GObject.TYPE_BOOLEAN,
-                                (), GObject.signal_accumulator_true_handled),
-        'my-acc-first-wins': (GObject.SignalFlags.RUN_LAST, GObject.TYPE_BOOLEAN,
-                              (), GObject.signal_accumulator_first_wins)
-        }
+    my_acc_signal = GObject.Signal(return_type=GObject.TYPE_INT,
+                                   flags=GObject.SignalFlags.RUN_LAST,
+                                   accumulator=my_accumulator,
+                                   accu_data="accum data")
+
+    my_other_acc_signal = GObject.Signal(return_type=GObject.TYPE_BOOLEAN,
+                                         flags=GObject.SignalFlags.RUN_LAST,
+                                         accumulator=GObject.signal_accumulator_true_handled)
+
+    my_acc_first_wins = GObject.Signal(return_type=GObject.TYPE_BOOLEAN,
+                                       flags=GObject.SignalFlags.RUN_LAST,
+                                       accumulator=GObject.signal_accumulator_first_wins)
 
 
 class TestAccumulator(unittest.TestCase):
 
     def test_accumulator(self):
         inst = Foo()
-        inst.connect("my-acc-signal", lambda obj: 1)
-        inst.connect("my-acc-signal", lambda obj: 2)
+        inst.my_acc_signal.connect(lambda obj: 1)
+        inst.my_acc_signal.connect(lambda obj: 2)
         ## the value returned in the following handler will not be
         ## considered, because at this point the accumulator already
         ## reached its limit.
-        inst.connect("my-acc-signal", lambda obj: 3)
-        retval = inst.emit("my-acc-signal")
+        inst.my_acc_signal.connect(lambda obj: 3)
+        retval = inst.my_acc_signal.emit()
         self.assertEqual(retval, 3)
 
     def test_accumulator_true_handled(self):
         inst = Foo()
-        inst.connect("my-other-acc-signal", self._true_handler1)
-        inst.connect("my-other-acc-signal", self._true_handler2)
+        inst.my_other_acc_signal.connect(self._true_handler1)
+        inst.my_other_acc_signal.connect(self._true_handler2)
         ## the following handler will not be called because handler2
         ## returns True, so it should stop the emission.
-        inst.connect("my-other-acc-signal", self._true_handler3)
+        inst.my_other_acc_signal.connect(self._true_handler3)
         self.__true_val = None
-        inst.emit("my-other-acc-signal")
+        inst.my_other_acc_signal.emit()
         self.assertEqual(self.__true_val, 2)
 
     def test_accumulator_first_wins(self):
         # First signal hit will always win
         inst = Foo()
-        inst.connect("my-acc-first-wins", self._true_handler3)
-        inst.connect("my-acc-first-wins", self._true_handler1)
-        inst.connect("my-acc-first-wins", self._true_handler2)
+        inst.my_acc_first_wins.connect(self._true_handler3)
+        inst.my_acc_first_wins.connect(self._true_handler1)
+        inst.my_acc_first_wins.connect(self._true_handler2)
         self.__true_val = None
-        inst.emit("my-acc-first-wins")
+        inst.my_acc_first_wins.emit()
         self.assertEqual(self.__true_val, 3)
 
     def _true_handler1(self, obj):
@@ -717,11 +721,11 @@ class TestSignalDecorator(unittest.TestCase):
 
     def test_get_signal_args(self):
         self.assertEqual(self.Decorated.pushed.get_signal_args(),
-                         (GObject.SignalFlags.RUN_FIRST, None, tuple()))
+                         (GObject.SignalFlags.RUN_FIRST, None, tuple(), None, None))
         self.assertEqual(self.Decorated.pulled.get_signal_args(),
-                         (GObject.SignalFlags.RUN_LAST, None, tuple()))
+                         (GObject.SignalFlags.RUN_LAST, None, tuple(), None, None))
         self.assertEqual(self.Decorated.stomped.get_signal_args(),
-                         (GObject.SignalFlags.RUN_FIRST, None, (int,)))
+                         (GObject.SignalFlags.RUN_FIRST, None, (int,), None, None))
 
     def test_closures_called(self):
         decorated = self.Decorated()
@@ -917,7 +921,7 @@ class TestPython3Signals(unittest.TestCase):
                          (str, (int, float)))
 
         self.assertEqual(self.AnnotatedClass.sig2_with_return.get_signal_args(),
-                         (GObject.SignalFlags.RUN_LAST, str, (int, float)))
+                         (GObject.SignalFlags.RUN_LAST, str, (int, float), None, None))
         self.assertEqual(self.AnnotatedClass.sig2_with_return.arg_types,
                          (int, float))
         self.assertEqual(self.AnnotatedClass.sig2_with_return.return_type,


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