[pygobject] Override GValue.set/get_boxed with static C marshaler



commit dd43a1e19440dbe025451d2e4e07a6074086498d
Author: Simon Feltman <sfeltman src gnome org>
Date:   Sat Jul 6 14:16:36 2013 -0700

    Override GValue.set/get_boxed with static C marshaler
    
    Override boxed type get/set methods on GValue to use the static C
    GValue marshaler. This works around the inability of the introspection
    version of these methods to know what the held GValue type is.
    With this, all boxed types will now marshal properly with GValues as
    their storage.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=688081

 gi/_gobject/gobjectmodule.c |   38 ++++++++++++++++++++++++++++++++++++++
 gi/overrides/GObject.py     |    9 +++++++++
 2 files changed, 47 insertions(+), 0 deletions(-)
---
diff --git a/gi/_gobject/gobjectmodule.c b/gi/_gobject/gobjectmodule.c
index 736cd8c..ac37904 100644
--- a/gi/_gobject/gobjectmodule.c
+++ b/gi/_gobject/gobjectmodule.c
@@ -1658,6 +1658,40 @@ pyg__install_metaclass(PyObject *dummy, PyTypeObject *metaclass)
     return Py_None;
 }
 
+static PyObject *
+pyg__gvalue_get(PyObject *module, PyObject *pygvalue)
+{
+    if (!pyg_boxed_check (pygvalue, G_TYPE_VALUE)) {
+        PyErr_SetString (PyExc_TypeError, "Expected GValue argument.");
+        return NULL;
+    }
+
+    return pyg_value_as_pyobject (pyg_boxed_get(pygvalue, GValue),
+                                  /*copy_boxed=*/ TRUE);
+}
+
+static PyObject *
+pyg__gvalue_set(PyObject *module, PyObject *args)
+{
+    PyObject *pygvalue;
+    PyObject *pyobject;
+
+    if (!PyArg_ParseTuple (args, "OO:_gobject._gvalue_set",
+                           &pygvalue, &pyobject))
+        return NULL;
+
+    if (!pyg_boxed_check (pygvalue, G_TYPE_VALUE)) {
+        PyErr_SetString (PyExc_TypeError, "Expected GValue argument.");
+        return NULL;
+    }
+
+    if (pyg_value_from_pyobject_with_error (pyg_boxed_get (pygvalue, GValue),
+                                            pyobject) == -1)
+        return NULL;
+
+    Py_RETURN_NONE;
+}
+
 static PyMethodDef _gobject_functions[] = {
     { "type_name", pyg_type_name, METH_VARARGS },
     { "type_from_name", pyg_type_from_name, METH_VARARGS },
@@ -1676,6 +1710,10 @@ static PyMethodDef _gobject_functions[] = {
       (PyCFunction)pyg_add_emission_hook, METH_VARARGS },
     { "_install_metaclass",
       (PyCFunction)pyg__install_metaclass, METH_O },
+    { "_gvalue_get",
+      (PyCFunction)pyg__gvalue_get, METH_O },
+    { "_gvalue_set",
+      (PyCFunction)pyg__gvalue_set, METH_VARARGS },
 
     { NULL, NULL, 0 }
 };
diff --git a/gi/overrides/GObject.py b/gi/overrides/GObject.py
index aa9974e..044c36e 100644
--- a/gi/overrides/GObject.py
+++ b/gi/overrides/GObject.py
@@ -219,6 +219,15 @@ class Value(GObjectModule.Value):
         if self._free_on_dealloc and self.g_type != TYPE_INVALID:
             self.unset()
 
+    def set_boxed(self, boxed):
+        # Workaround the introspection marshalers inability to know
+        # these methods should be marshaling boxed types. This is because
+        # the type information is stored on the GValue.
+        _gobject._gvalue_set(self, boxed)
+
+    def get_boxed(self):
+        return _gobject._gvalue_get(self)
+
     def set_value(self, py_value):
         gtype = self.g_type
 


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