[pygobject] [gi] pass raw GValues instead of trying to marshal them



commit 9e4ce7dc0f03ea407654c4af028122f57cbc4c5e
Author: John (J5) Palmieri <johnp redhat com>
Date:   Mon Feb 21 16:14:20 2011 -0500

    [gi] pass raw GValues instead of trying to marshal them
    
    * Right now GValues are transparent to the user but this leave us no
       way to describe fundimental types other than those supported directly
       by python (e.g. int, str, etc)
     * If an interface is expecting a uint or other GValue type a user can now use
       the raw GValue interfaces and expect paramaters that take GValues to
       marshal them correctly e.g.:
           value = GObject.Value()
           value.int(GObject.TYPE_UINT)
           value.set_uint(1234)
     * The objective here is to not for users to use this API but for overrides
       to be able to utilize them.  For instance in the TreeModel API we can
       get the expected type for a column and them create a GValue with the correct
       type so that he underlying python object is marshalled correctly.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=642914

 gi/pygi-argument.c |   24 ++++++++++++++++++------
 tests/test_gi.py   |    9 ++++++++-
 2 files changed, 26 insertions(+), 7 deletions(-)
---
diff --git a/gi/pygi-argument.c b/gi/pygi-argument.c
index 9816738..dc9c289 100644
--- a/gi/pygi-argument.c
+++ b/gi/pygi-argument.c
@@ -1009,13 +1009,25 @@ array_success:
                         g_warn_if_fail (transfer == GI_TRANSFER_NOTHING);
 
                         value = g_slice_new0 (GValue);
-                        g_value_init (value, object_type);
 
-                        retval = pyg_value_from_pyobject (value, object);
-                        if (retval < 0) {
-                            g_slice_free (GValue, value);
-                            PyErr_SetString (PyExc_RuntimeError, "PyObject conversion to GValue failed");
-                            break;
+                        /* if already a gvalue, copy, else marshal into gvalue */
+                        if (object_type == G_TYPE_VALUE) {
+                            /* src GValue's lifecycle is handled by Python
+                             * so we have to copy it into the destination's
+                             * GValue which is freed during the cleanup of
+                             * invoke.
+                             */
+                            GValue *src = (GValue *)((PyGObject *) object)->obj;
+                            g_value_init (value, G_VALUE_TYPE (src));
+                            g_value_copy(src, value);
+                        } else {
+                            g_value_init (value, object_type);
+                            retval = pyg_value_from_pyobject (value, object);
+                            if (retval < 0) {
+                                g_slice_free (GValue, value);
+                                PyErr_SetString (PyExc_RuntimeError, "PyObject conversion to GValue failed");
+                                break;
+                            }
                         }
 
                         arg.v_pointer = value;
diff --git a/tests/test_gi.py b/tests/test_gi.py
index c12863b..843c3b6 100644
--- a/tests/test_gi.py
+++ b/tests/test_gi.py
@@ -925,13 +925,20 @@ class TestGValue(unittest.TestCase):
 
     def test_gvalue_in(self):
         GIMarshallingTests.gvalue_in(42)
+        value = GObject.Value()
+        value.init(GObject.TYPE_INT)
+        value.set_int(42)
+        GIMarshallingTests.gvalue_in(value)
 
     def test_gvalue_out(self):
         self.assertEquals(42, GIMarshallingTests.gvalue_out())
 
     def test_gvalue_inout(self):
         self.assertEquals('42', GIMarshallingTests.gvalue_inout(42))
-
+        value = GObject.Value()
+        value.init(GObject.TYPE_INT)
+        value.set_int(42)
+        self.assertEquals('42', GIMarshallingTests.gvalue_inout(value))
 
 class TestGClosure(unittest.TestCase):
 



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