[pygobject/bilelmoussaoui/dispose: 29/29] object: Allow overriding dispose implementation




commit d8473a16733377b74681b8a8e913b017cdc053d6
Author: Bilal Elmoussaoui <belmouss redhat com>
Date:   Tue Feb 15 15:02:54 2022 +0100

    object: Allow overriding dispose implementation
    
    In GTK4 people are expected to unparent their custom GtkWidget
    implementation
    in the object's dispose method which is the main motivation behind this
    patch

 gi/gimodule.c         | 36 ++++++++++++++++++++++++++++++++++++
 tests/test_gobject.py | 11 +++++++++++
 2 files changed, 47 insertions(+)
---
diff --git a/gi/gimodule.c b/gi/gimodule.c
index 766fd341..9066b9ee 100644
--- a/gi/gimodule.c
+++ b/gi/gimodule.c
@@ -937,6 +937,41 @@ pyg_object_set_property (GObject *object, guint property_id,
     PyGILState_Release(state);
 }
 
+static void
+pyg_object_dispose (GObject *object)
+{
+    PyObject *object_wrapper, *retval;
+    PyGILState_STATE state;
+    GObjectClass *parent_class = g_type_class_peek (g_type_parent (G_TYPE_FROM_CLASS (object)));
+
+    state = PyGILState_Ensure();
+
+    object_wrapper = g_object_get_qdata(object, pygobject_wrapper_key);
+
+    if (object_wrapper)
+      Py_INCREF (object_wrapper);
+    else
+      object_wrapper = pygobject_new(object);
+
+    if (object_wrapper == NULL) {
+       PyGILState_Release(state);
+       return;
+    }
+    retval = PyObject_CallMethod(object_wrapper, "do_dispose", NULL);
+    if (retval) {
+       Py_DECREF(retval);
+    } else {
+       PyErr_Print();
+    }
+    // Chain up the dispose call
+    if (parent_class->dispose) {
+        parent_class->dispose(object);
+    }
+    Py_DECREF(object_wrapper);
+
+    PyGILState_Release(state);
+}
+
 static void
 pyg_object_class_init(GObjectClass *class, PyObject *py_class)
 {
@@ -945,6 +980,7 @@ pyg_object_class_init(GObjectClass *class, PyObject *py_class)
 
     class->set_property = pyg_object_set_property;
     class->get_property = pyg_object_get_property;
+    class->dispose = pyg_object_dispose;
 
     /* install signals */
     /* we look this up in the instance dictionary, so we don't
diff --git a/tests/test_gobject.py b/tests/test_gobject.py
index fbc3bb79..19d850b8 100644
--- a/tests/test_gobject.py
+++ b/tests/test_gobject.py
@@ -775,6 +775,17 @@ class TestGValue(unittest.TestCase):
         value = GObject.Value(GObject.TYPE_OBJECT, obj)
         self.assertEqual(value.get_value(), obj)
 
+    def test_dispose_object(self):
+        class TestObject(GObject.Object):
+            def __init__(self):
+                self.child = "Some Child"
+            def do_dispose(self):
+                self.child = None
+        obj = TestObject()
+        obj.run_dispose()
+        self.assertEqual(obj.child, None)
+
+
     def test_value_array(self):
         value = GObject.Value(GObject.ValueArray)
         self.assertEqual(value.g_type, GObject.type_from_name('GValueArray'))


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