[pygobject] Change boxed type checking in marshaling to use __gtype__ attribute



commit 19c1a2dfb91a83a6fb0ca76b9c95c42a49a3736e
Author: Simon Feltman <sfeltman src gnome org>
Date:   Sun Sep 1 20:44:26 2013 -0700

    Change boxed type checking in marshaling to use __gtype__ attribute
    
    Replace usage of pyg_boxed_check(pyboxed) with g_type_is_a and
    pyg_type_from_object. This has the effect of using the __gtype__
    attribute stashed on object class instead of the PyGBoxed
    internally held gtype. This fixes type descrepencies for objects
    marshaled into overridden signal class closures and passed back
    to functions taking an alias their type.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=707140

 gi/pygi-marshal-from-py.c   |    8 +++++++-
 tests/test_overrides_gtk.py |   34 ++++++++++++++++++++++++++++++++++
 2 files changed, 41 insertions(+), 1 deletions(-)
---
diff --git a/gi/pygi-marshal-from-py.c b/gi/pygi-marshal-from-py.c
index a48479b..82d94a0 100644
--- a/gi/pygi-marshal-from-py.c
+++ b/gi/pygi-marshal-from-py.c
@@ -1827,7 +1827,13 @@ _pygi_marshal_from_py_interface_struct (PyObject *py_arg,
     }
 
     if (g_type_is_a (g_type, G_TYPE_BOXED)) {
-        if (pyg_boxed_check (py_arg, g_type)) {
+        /* Use pyg_type_from_object to pull the stashed __gtype__ attribute
+         * off of the input argument instead of checking PyGBoxed.gtype
+         * with pyg_boxed_check. This is needed to work around type discrepancies
+         * in cases with aliased (typedef) types. e.g. GtkAllocation, GdkRectangle.
+         * See: https://bugzilla.gnomethere are .org/show_bug.cgi?id=707140
+         */
+        if (g_type_is_a (pyg_type_from_object (py_arg), g_type)) {
             arg->v_pointer = pyg_boxed_get (py_arg, void);
             if (transfer == GI_TRANSFER_EVERYTHING) {
                 arg->v_pointer = g_boxed_copy (g_type, arg->v_pointer);
diff --git a/tests/test_overrides_gtk.py b/tests/test_overrides_gtk.py
index f9d21c2..fbe51ec 100644
--- a/tests/test_overrides_gtk.py
+++ b/tests/test_overrides_gtk.py
@@ -590,6 +590,40 @@ class TestGtk(unittest.TestCase):
 
 
 @unittest.skipUnless(Gtk, 'Gtk not available')
+class TestSignals(unittest.TestCase):
+    class WindowWithSizeAllocOverride(Gtk.ScrolledWindow):
+        __gsignals__ = {'size-allocate': 'override'}
+
+        def __init__(self):
+            Gtk.ScrolledWindow.__init__(self)
+            self._alloc_called = False
+            self._alloc_value = None
+            self._alloc_error = None
+
+        def do_size_allocate(self, alloc):
+            self._alloc_called = True
+            self._alloc_value = alloc
+
+            try:
+                Gtk.ScrolledWindow.do_size_allocate(self, alloc)
+            except Exception as e:
+                self._alloc_error = e
+
+    def test_class_closure_override_with_aliased_type(self):
+        win = self.WindowWithSizeAllocOverride()
+        rect = Gdk.Rectangle()
+        rect.width = 100
+        rect.height = 100
+
+        with realized(win):
+            win.show()
+            win.size_allocate(rect)
+            self.assertTrue(win._alloc_called)
+            self.assertIsInstance(win._alloc_value, Gdk.Rectangle)
+            self.assertTrue(win._alloc_error is None, win._alloc_error)
+
+
+ unittest skipUnless(Gtk, 'Gtk not available')
 class TestBuilder(unittest.TestCase):
     class SignalTest(GObject.GObject):
         __gtype_name__ = "GIOverrideSignalTest"


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