[pygobject] Move various signal methods from static bindings to gi and python



commit b31d8a952cd57dc92b06a381e054199660a2d570
Author: Simon Feltman <sfeltman src gnome org>
Date:   Thu Jan 31 02:35:36 2013 -0800

    Move various signal methods from static bindings to gi and python
    
    Move disconnect, handler_is_connected, handler_block, handler_unblock,
    and stop_emission from static to gi python overrides.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=692918

 gi/_gobject/pygobject.c |   90 -----------------------------------------------
 gi/overrides/GObject.py |   44 ++++++++++++++++-------
 tests/test_signal.py    |   19 ++++++----
 3 files changed, 42 insertions(+), 111 deletions(-)
---
diff --git a/gi/_gobject/pygobject.c b/gi/_gobject/pygobject.c
index 36d0874..a23d469 100644
--- a/gi/_gobject/pygobject.c
+++ b/gi/_gobject/pygobject.c
@@ -1833,62 +1833,6 @@ pygobject_connect_object_after(PyGObject *self, PyObject *args)
 }
 
 static PyObject *
-pygobject_disconnect(PyGObject *self, PyObject *args)
-{
-    gulong handler_id;
-
-    if (!PyArg_ParseTuple(args, "k:GObject.disconnect", &handler_id))
-	return NULL;
-    
-    CHECK_GOBJECT(self);
-    
-    g_signal_handler_disconnect(self->obj, handler_id);
-    Py_INCREF(Py_None);
-    return Py_None;
-}
-
-static PyObject *
-pygobject_handler_is_connected(PyGObject *self, PyObject *args)
-{
-    gulong handler_id;
-
-    if (!PyArg_ParseTuple(args, "k:GObject.handler_is_connected", &handler_id))
-	return NULL;
-
-    
-    CHECK_GOBJECT(self);
-    
-    return PyBool_FromLong(g_signal_handler_is_connected(self->obj, handler_id));
-}
-
-static PyObject *
-pygobject_handler_block(PyGObject *self, PyObject *args)
-{
-    gulong handler_id;
-
-    if (!PyArg_ParseTuple(args, "k:GObject.handler_block", &handler_id))
-	return NULL;
-
-    CHECK_GOBJECT(self);
-
-    g_signal_handler_block(self->obj, handler_id);
-    Py_INCREF(Py_None);
-    return Py_None;
-}
-
-static PyObject *
-pygobject_handler_unblock(PyGObject *self, PyObject *args)
-{
-    gulong handler_id;
-
-    if (!PyArg_ParseTuple(args, "k:GObject.handler_unblock", &handler_id))
-	return NULL;
-    g_signal_handler_unblock(self->obj, handler_id);
-    Py_INCREF(Py_None);
-    return Py_None;
-}
-
-static PyObject *
 pygobject_emit(PyGObject *self, PyObject *args)
 {
     guint signal_id, i, j;
@@ -1980,33 +1924,6 @@ pygobject_emit(PyGObject *self, PyObject *args)
 }
 
 static PyObject *
-pygobject_stop_emission(PyGObject *self, PyObject *args)
-{
-    gchar *signal;
-    guint signal_id;
-    GQuark detail;
-    PyObject *repr = NULL;
-
-    if (!PyArg_ParseTuple(args, "s:GObject.stop_emission", &signal))
-	return NULL;
-    
-    CHECK_GOBJECT(self);
-    
-    if (!g_signal_parse_name(signal, G_OBJECT_TYPE(self->obj),
-			     &signal_id, &detail, TRUE)) {
-	repr = PyObject_Repr((PyObject*)self);
-	PyErr_Format(PyExc_TypeError, "%s: unknown signal name: %s",
-		     PYGLIB_PyUnicode_AsString(repr),
-		     signal);
-	Py_DECREF(repr);
-	return NULL;
-    }
-    g_signal_stop_emission(self->obj, signal_id, detail);
-    Py_INCREF(Py_None);
-    return Py_None;
-}
-
-static PyObject *
 pygobject_chain_from_overridden(PyGObject *self, PyObject *args)
 {
     GSignalInvocationHint *ihint;
@@ -2238,17 +2155,10 @@ static PyMethodDef pygobject_methods[] = {
     { "connect_after", (PyCFunction)pygobject_connect_after, METH_VARARGS },
     { "connect_object", (PyCFunction)pygobject_connect_object, METH_VARARGS },
     { "connect_object_after", (PyCFunction)pygobject_connect_object_after, METH_VARARGS },
-    { "disconnect", (PyCFunction)pygobject_disconnect, METH_VARARGS },
     { "disconnect_by_func", (PyCFunction)pygobject_disconnect_by_func, METH_VARARGS },
-    { "handler_disconnect", (PyCFunction)pygobject_disconnect, METH_VARARGS },
-    { "handler_is_connected", (PyCFunction)pygobject_handler_is_connected, METH_VARARGS },
-    { "handler_block", (PyCFunction)pygobject_handler_block, METH_VARARGS },
-    { "handler_unblock", (PyCFunction)pygobject_handler_unblock,METH_VARARGS },
     { "handler_block_by_func", (PyCFunction)pygobject_handler_block_by_func, METH_VARARGS },
     { "handler_unblock_by_func", (PyCFunction)pygobject_handler_unblock_by_func, METH_VARARGS },
     { "emit", (PyCFunction)pygobject_emit, METH_VARARGS },
-    { "stop_emission", (PyCFunction)pygobject_stop_emission, METH_VARARGS },
-    { "emit_stop_by_name", (PyCFunction)pygobject_stop_emission,METH_VARARGS },
     { "chain", (PyCFunction)pygobject_chain_from_overridden,METH_VARARGS },
     { "weak_ref", (PyCFunction)pygobject_weak_ref, METH_VARARGS },
     { "__copy__", (PyCFunction)pygobject_copy, METH_NOARGS },
diff --git a/gi/overrides/GObject.py b/gi/overrides/GObject.py
index 458db55..2176d84 100644
--- a/gi/overrides/GObject.py
+++ b/gi/overrides/GObject.py
@@ -22,12 +22,14 @@
 # USA
 
 import sys
+import warnings
 from collections import namedtuple
 
 import gi.overrides
 import gi.module
 from gi.overrides import override
 from gi.repository import GLib
+from gi import PyGIDeprecationWarning
 
 from gi._gobject import _gobject
 from gi._gobject import propertyhelper
@@ -424,7 +426,7 @@ class _HandlerBlockManager(object):
         pass
 
     def __exit__(self, exc_type, exc_value, traceback):
-        _gobject.GObject.handler_unblock(self.obj, self.handler_id)
+        self.obj.handler_unblock(self.handler_id)
 
 
 class _FreezeNotifyManager(object):
@@ -489,15 +491,10 @@ class Object(GObjectModule.Object):
     connect_after = _gobject.GObject.connect_after
     connect_object = _gobject.GObject.connect_object
     connect_object_after = _gobject.GObject.connect_object_after
-    disconnect = _gobject.GObject.disconnect
     disconnect_by_func = _gobject.GObject.disconnect_by_func
-    handler_disconnect = _gobject.GObject.handler_disconnect
-    handler_is_connected = _gobject.GObject.handler_is_connected
     handler_block_by_func = _gobject.GObject.handler_block_by_func
     handler_unblock_by_func = _gobject.GObject.handler_unblock_by_func
     emit = _gobject.GObject.emit
-    emit_stop_by_name = _gobject.GObject.emit_stop_by_name
-    stop_emission = _gobject.GObject.stop_emission
     chain = _gobject.GObject.chain
     weak_ref = _gobject.GObject.weak_ref
     __copy__ = _gobject.GObject.__copy__
@@ -512,15 +509,12 @@ class Object(GObjectModule.Object):
         >>> with obj.handler_block(id):
         >>>    pass
         """
-
-        # Note Object.handler_block is a static method specific to pygobject and not
-        # found in introspection. We need to continue using the static method
-        # until we figure out a technique to call the global signal_handler_block.
-        # But this requires a gpointer to the Object which we currently don't have
-        # access to in python.
-        _gobject.GObject.handler_block(self, handler_id)
+        GObjectModule.signal_handler_block(self.__gpointer__, handler_id)
         return _HandlerBlockManager(self, handler_id)
 
+    def handler_unblock(self, handler_id):
+        GObjectModule.signal_handler_unblock(self.__gpointer__, handler_id)
+
     def freeze_notify(self):
         """Freezes the object's property-changed notification queue.
 
@@ -536,6 +530,30 @@ class Object(GObjectModule.Object):
         super(Object, self).freeze_notify()
         return _FreezeNotifyManager(self)
 
+    def handler_disconnect(self, handler_id):
+        GObjectModule.signal_handler_disconnect(self.__gpointer__, handler_id)
+
+    def handler_is_connected(self, handler_id):
+        return bool(GObjectModule.signal_handler_is_connected(self.__gpointer__, handler_id))
+
+    def stop_emission_by_name(self, detailed_signal):
+        GObjectModule.signal_stop_emission_by_name(self.__gpointer__, detailed_signal)
+
+    #
+    # Aliases
+    #
+    disconnect = handler_disconnect
+
+    #
+    # Deprecated Methods
+    #
+    def stop_emission(self, detailed_signal):
+        """Deprecated, please use stop_emission_by_name."""
+        warnings.warn(self.stop_emission.__doc__, PyGIDeprecationWarning, stacklevel=2)
+        return self.stop_emission_by_name(detailed_signal)
+
+    emit_stop_by_name = stop_emission
+
 
 Object = override(Object)
 GObject = Object
diff --git a/tests/test_signal.py b/tests/test_signal.py
index 7c1ade8..afa9926 100644
--- a/tests/test_signal.py
+++ b/tests/test_signal.py
@@ -261,25 +261,28 @@ class TestClosures(unittest.TestCase):
     def setUp(self):
         self.count = 0
         self.emission_stopped = False
-        self.emission_error = None
+        self.emission_error = False
 
     def _callback(self, e):
         self.count += 1
 
     def _callback_stop_emission(self, obj, prop, stop_it):
         if stop_it:
-            obj.stop_emission('notify::prop')
+            obj.stop_emission_by_name('notify::prop')
             self.emission_stopped = True
         else:
             self.count += 1
 
     def _callback_invalid_stop_emission_name(self, obj, prop):
-        # Note we log the error and test it later because it occurs within
-        # a closure which don't bubble through the binding layer.
+        # We expect a GLib warning but there currently is no way to test that
+        # This can at least make sure we don't crash
+        old_mask = GLib.log_set_always_fatal(GLib.LogLevelFlags.LEVEL_CRITICAL |
+                                             GLib.LogLevelFlags.LEVEL_ERROR)
         try:
-            obj.stop_emission('notasignal::baddetail')
-        except TypeError as exc:
-            self.emission_error = exc
+            obj.stop_emission_by_name('notasignal::baddetail')
+        finally:
+            GLib.log_set_always_fatal(old_mask)
+            self.emission_error = True
 
     def test_disconnect_by_func(self):
         e = E()
@@ -315,7 +318,7 @@ class TestClosures(unittest.TestCase):
 
         e.connect('notify::prop', self._callback_invalid_stop_emission_name)
         e.set_property('prop', 1234)
-        self.assertTrue(isinstance(self.emission_error, TypeError))
+        self.assertTrue(self.emission_error)
 
     def test_handler_block(self):
         e = E()



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