[pygobject] refactor: Move builder connection utilities outside of Builder class



commit ba8380d093d6f84eabcf18c02b248aae8ffc3cf5
Author: Simon Feltman <sfeltman src gnome org>
Date:   Tue May 27 19:24:20 2014 -0700

    refactor: Move builder connection utilities outside of Builder class
    
    Move _extract_handler_and_args and _builder_connect_callback into module
    scope for re-use by GTK+ Composite Templates.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=701843

 gi/overrides/Gtk.py         |   83 +++++++++++++++++++++++--------------------
 tests/test_overrides_gtk.py |    8 ++--
 2 files changed, 48 insertions(+), 43 deletions(-)
---
diff --git a/gi/overrides/Gtk.py b/gi/overrides/Gtk.py
index 561bdf0..05ef403 100644
--- a/gi/overrides/Gtk.py
+++ b/gi/overrides/Gtk.py
@@ -72,6 +72,49 @@ def _construct_target_list(targets):
 __all__.append('_construct_target_list')
 
 
+def _extract_handler_and_args(obj_or_map, handler_name):
+    handler = None
+    if isinstance(obj_or_map, collections.Mapping):
+        handler = obj_or_map.get(handler_name, None)
+    else:
+        handler = getattr(obj_or_map, handler_name, None)
+
+    if handler is None:
+        raise AttributeError('Handler %s not found' % handler_name)
+
+    args = ()
+    if isinstance(handler, collections.Sequence):
+        if len(handler) == 0:
+            raise TypeError("Handler %s tuple can not be empty" % handler)
+        args = handler[1:]
+        handler = handler[0]
+
+    elif not _callable(handler):
+        raise TypeError('Handler %s is not a method, function or tuple' % handler)
+
+    return handler, args
+
+
+# Exposed for unit-testing.
+__all__.append('_extract_handler_and_args')
+
+
+def _builder_connect_callback(builder, gobj, signal_name, handler_name, connect_obj, flags, obj_or_map):
+    handler, args = _extract_handler_and_args(obj_or_map, handler_name)
+
+    after = flags & GObject.ConnectFlags.AFTER
+    if connect_obj is not None:
+        if after:
+            gobj.connect_object_after(signal_name, handler, connect_obj, *args)
+        else:
+            gobj.connect_object(signal_name, handler, connect_obj, *args)
+    else:
+        if after:
+            gobj.connect_after(signal_name, handler, *args)
+        else:
+            gobj.connect(signal_name, handler, *args)
+
+
 class Widget(Gtk.Widget):
 
     translate_coordinates = strip_boolean_result(Gtk.Widget.translate_coordinates)
@@ -396,29 +439,6 @@ __all__.append('MenuItem')
 
 
 class Builder(Gtk.Builder):
-    @staticmethod
-    def _extract_handler_and_args(obj_or_map, handler_name):
-        handler = None
-        if isinstance(obj_or_map, collections.Mapping):
-            handler = obj_or_map.get(handler_name, None)
-        else:
-            handler = getattr(obj_or_map, handler_name, None)
-
-        if handler is None:
-            raise AttributeError('Handler %s not found' % handler_name)
-
-        args = ()
-        if isinstance(handler, collections.Sequence):
-            if len(handler) == 0:
-                raise TypeError("Handler %s tuple can not be empty" % handler)
-            args = handler[1:]
-            handler = handler[0]
-
-        elif not _callable(handler):
-            raise TypeError('Handler %s is not a method, function or tuple' % handler)
-
-        return handler, args
-
     def connect_signals(self, obj_or_map):
         """Connect signals specified by this builder to a name, handler mapping.
 
@@ -431,22 +451,7 @@ class Builder(Gtk.Builder):
 
             builder.connect_signals({'on_clicked': (on_clicked, arg1, arg2)})
         """
-        def _full_callback(builder, gobj, signal_name, handler_name, connect_obj, flags, obj_or_map):
-            handler, args = self._extract_handler_and_args(obj_or_map, handler_name)
-
-            after = flags & GObject.ConnectFlags.AFTER
-            if connect_obj is not None:
-                if after:
-                    gobj.connect_object_after(signal_name, handler, connect_obj, *args)
-                else:
-                    gobj.connect_object(signal_name, handler, connect_obj, *args)
-            else:
-                if after:
-                    gobj.connect_after(signal_name, handler, *args)
-                else:
-                    gobj.connect(signal_name, handler, *args)
-
-        self.connect_signals_full(_full_callback, obj_or_map)
+        self.connect_signals_full(_builder_connect_callback, obj_or_map)
 
     def add_from_string(self, buffer):
         if not isinstance(buffer, _basestring):
diff --git a/tests/test_overrides_gtk.py b/tests/test_overrides_gtk.py
index d339adf..fac78b2 100644
--- a/tests/test_overrides_gtk.py
+++ b/tests/test_overrides_gtk.py
@@ -711,28 +711,28 @@ class TestBuilder(unittest.TestCase):
         obj = Obj()
         obj.foo = lambda: None
 
-        handler, args = Gtk.Builder._extract_handler_and_args(obj, 'foo')
+        handler, args = Gtk._extract_handler_and_args(obj, 'foo')
         self.assertEqual(handler, obj.foo)
         self.assertEqual(len(args), 0)
 
     def test_extract_handler_and_args_dict(self):
         obj = {'foo': lambda: None}
 
-        handler, args = Gtk.Builder._extract_handler_and_args(obj, 'foo')
+        handler, args = Gtk._extract_handler_and_args(obj, 'foo')
         self.assertEqual(handler, obj['foo'])
         self.assertEqual(len(args), 0)
 
     def test_extract_handler_and_args_with_seq(self):
         obj = {'foo': (lambda: None, 1, 2)}
 
-        handler, args = Gtk.Builder._extract_handler_and_args(obj, 'foo')
+        handler, args = Gtk._extract_handler_and_args(obj, 'foo')
         self.assertEqual(handler, obj['foo'][0])
         self.assertSequenceEqual(args, [1, 2])
 
     def test_extract_handler_and_args_no_handler_error(self):
         obj = dict(foo=lambda: None)
         self.assertRaises(AttributeError,
-                          Gtk.Builder._extract_handler_and_args,
+                          Gtk._extract_handler_and_args,
                           obj, 'not_a_handler')
 
     def test_builder_with_handler_and_args(self):


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