[pygobject] gi: Add support for more property types



commit 8c517de2d278bdef641c72b8f2919a3924290ec1
Author: Tomeu Vizoso <tomeu vizoso collabora co uk>
Date:   Fri Aug 20 14:54:35 2010 +0200

    gi: Add support for more property types
    
    https://bugzilla.gnome.org/show_bug.cgi?id=627494

 gi/pygi-property.c       |  156 +++++++++++++++++++++++++++++++++++-----------
 tests/test_everything.py |   34 ++++++++++
 2 files changed, 154 insertions(+), 36 deletions(-)
---
diff --git a/gi/pygi-property.c b/gi/pygi-property.c
index d9732c6..7b6a508 100644
--- a/gi/pygi-property.c
+++ b/gi/pygi-property.c
@@ -115,30 +115,87 @@ pygi_get_property_value_real (PyGObject *instance,
     type_info = g_property_info_get_type (property_info);
     transfer = g_property_info_get_ownership_transfer (property_info);
 
-    // FIXME: Lots of types still unhandled
-    if (g_type_info_is_pointer (type_info)) {
-        arg.v_pointer = g_value_peek_pointer (&value);
-    } else {
-        GITypeTag type_tag = g_type_info_get_tag (type_info);
-        switch (type_tag) {
-            case GI_TYPE_TAG_INT32:
-                arg.v_int = g_value_get_int (&value);
-                break;
-            case GI_TYPE_TAG_UINT32:
-                arg.v_uint = g_value_get_uint (&value);
-                break;
-            case GI_TYPE_TAG_BOOLEAN:
-                arg.v_boolean = g_value_get_boolean (&value);
-                break;
-            case GI_TYPE_TAG_INTERFACE:
-                arg.v_pointer = g_value_get_object (&value);
-                break;
-            default:
-                PyErr_Format (PyExc_NotImplementedError,
-                              "Retrieving properties of type %s is not implemented",
-                              g_type_tag_to_string (g_type_info_get_tag (type_info)));
-                goto out;
+    GITypeTag type_tag = g_type_info_get_tag (type_info);
+    switch (type_tag) {
+        case GI_TYPE_TAG_BOOLEAN:
+            arg.v_boolean = g_value_get_boolean (&value);
+            break;
+        case GI_TYPE_TAG_INT8:
+        case GI_TYPE_TAG_INT16:
+        case GI_TYPE_TAG_INT32:
+        case GI_TYPE_TAG_INT64:
+            arg.v_int = g_value_get_int (&value);
+            break;
+        case GI_TYPE_TAG_UINT8:
+        case GI_TYPE_TAG_UINT16:
+        case GI_TYPE_TAG_UINT32:
+        case GI_TYPE_TAG_UINT64:
+            arg.v_uint = g_value_get_uint (&value);
+            break;
+        case GI_TYPE_TAG_FLOAT:
+            arg.v_float = g_value_get_float (&value);
+            break;
+        case GI_TYPE_TAG_DOUBLE:
+            arg.v_double = g_value_get_double (&value);
+            break;
+        case GI_TYPE_TAG_GTYPE:
+            arg.v_size = g_value_get_uint (&value);
+            break;
+        case GI_TYPE_TAG_UTF8:
+        case GI_TYPE_TAG_FILENAME:
+            arg.v_string = g_value_dup_string (&value);
+            break;
+        case GI_TYPE_TAG_INTERFACE:
+        {
+            GIBaseInfo *info;
+            GIInfoType info_type;
+            GType type;
+
+            info = g_type_info_get_interface (type_info);
+            type = g_registered_type_info_get_g_type (info);
+            info_type = g_base_info_get_type (info);
+
+            switch (info_type) {
+                case GI_INFO_TYPE_ENUM:
+                    arg.v_int32 = g_value_get_enum (&value);
+                    break;
+                case GI_INFO_TYPE_INTERFACE:
+                case GI_INFO_TYPE_OBJECT:
+                    arg.v_pointer = g_value_get_object (&value);
+                    break;
+                case GI_INFO_TYPE_BOXED:
+                case GI_INFO_TYPE_STRUCT:
+                case GI_INFO_TYPE_UNION:
+
+                    if (g_type_is_a (type, G_TYPE_BOXED)) {
+                        arg.v_pointer = g_value_get_boxed (&value);
+                    } else if (g_type_is_a (type, G_TYPE_POINTER)) {
+                        arg.v_pointer = g_value_get_pointer (&value);
+                    } else {
+                        PyErr_Format (PyExc_NotImplementedError,
+                                      "Retrieving properties of type '%s' is not implemented",
+                                      g_type_name (type));
+                    }
+                    break;
+                default:
+                    PyErr_Format (PyExc_NotImplementedError,
+                                  "Retrieving properties of type '%s' is not implemented",
+                                  g_type_name (type));
+                    goto out;
+            }
+            break;
         }
+        case GI_TYPE_TAG_GHASH:
+            arg.v_pointer = g_value_get_boxed (&value);
+            break;
+        case GI_TYPE_TAG_GLIST:
+            arg.v_pointer = g_value_get_pointer (&value);
+            break;
+        default:
+            PyErr_Format (PyExc_NotImplementedError,
+                          "Retrieving properties of type %s is not implemented",
+                          g_type_tag_to_string (g_type_info_get_tag (type_info)));
+            goto out;
     }
 
     py_value = _pygi_argument_to_object (&arg, type_info, transfer);
@@ -198,10 +255,10 @@ pygi_set_property_value_real (PyGObject *instance,
         {
             GIBaseInfo *info;
             GIInfoType info_type;
+            GType type;
 
             info = g_type_info_get_interface (type_info);
-            g_assert (info != NULL);
-
+            type = g_registered_type_info_get_g_type (info);
             info_type = g_base_info_get_type (info);
 
             switch (info_type) {
@@ -212,32 +269,59 @@ pygi_set_property_value_real (PyGObject *instance,
                 case GI_INFO_TYPE_OBJECT:
                     g_value_set_object (&value, arg.v_pointer);
                     break;
+                case GI_INFO_TYPE_BOXED:
+                case GI_INFO_TYPE_STRUCT:
+                case GI_INFO_TYPE_UNION:
+                    if (g_type_is_a (type, G_TYPE_BOXED)) {
+                        g_value_set_boxed (&value, arg.v_pointer);
+                    } else {
+                        PyErr_Format (PyExc_NotImplementedError,
+                                      "Setting properties of type '%s' is not implemented",
+                                      g_type_name (type));
+                    }
+                    break;
                 default:
                     PyErr_Format (PyExc_NotImplementedError,
                                   "Setting properties of type '%s' is not implemented",
-                                  g_info_type_to_string (info_type));
+                                  g_type_name (type));
                     goto out;
             }
             break;
         }
-        case GI_TYPE_TAG_GHASH:
-            g_value_set_boxed (&value, arg.v_pointer);
-            break;
-        case GI_TYPE_TAG_GLIST:
-            g_value_set_pointer (&value, arg.v_pointer);
+        case GI_TYPE_TAG_BOOLEAN:
+            g_value_set_boolean (&value, arg.v_boolean);
             break;
+        case GI_TYPE_TAG_INT8:
+        case GI_TYPE_TAG_INT16:
         case GI_TYPE_TAG_INT32:
-            g_value_set_int (&value, arg.v_int32);
+        case GI_TYPE_TAG_INT64:
+            g_value_set_int (&value, arg.v_int);
             break;
+        case GI_TYPE_TAG_UINT8:
+        case GI_TYPE_TAG_UINT16:
         case GI_TYPE_TAG_UINT32:
-            g_value_set_uint (&value, arg.v_uint32);
-            break;
-        case GI_TYPE_TAG_BOOLEAN:
-            g_value_set_boolean (&value, arg.v_boolean);
+        case GI_TYPE_TAG_UINT64:
+            g_value_set_uint (&value, arg.v_uint);
             break;
         case GI_TYPE_TAG_FLOAT:
             g_value_set_float (&value, arg.v_float);
             break;
+        case GI_TYPE_TAG_DOUBLE:
+            g_value_set_double (&value, arg.v_double);
+            break;
+        case GI_TYPE_TAG_GTYPE:
+            g_value_set_uint (&value, arg.v_size);
+            break;
+        case GI_TYPE_TAG_UTF8:
+        case GI_TYPE_TAG_FILENAME:
+            g_value_set_string (&value, arg.v_string);
+            break;
+        case GI_TYPE_TAG_GHASH:
+            g_value_set_boxed (&value, arg.v_pointer);
+            break;
+        case GI_TYPE_TAG_GLIST:
+            g_value_set_pointer (&value, arg.v_pointer);
+            break;
         default:
             PyErr_Format (PyExc_NotImplementedError,
                           "Setting properties of type %s is not implemented",
diff --git a/tests/test_everything.py b/tests/test_everything.py
index 5d8c12b..ade139f 100644
--- a/tests/test_everything.py
+++ b/tests/test_everything.py
@@ -311,6 +311,29 @@ class TestCallbacks(unittest.TestCase):
 
 class TestProperties(unittest.TestCase):
 
+    def test_basic(self):
+        object_ = Everything.TestObj()
+
+        self.assertEquals(object_.props.int, 0)
+        object_.props.int = 42
+        self.assertTrue(isinstance(object_.props.int, int))
+        self.assertEquals(object_.props.int, 42)
+
+        self.assertEquals(object_.props.float, 0.0)
+        object_.props.float = 42.42
+        self.assertTrue(isinstance(object_.props.float, float))
+        self.assertAlmostEquals(object_.props.float, 42.42, places=5)
+
+        self.assertEquals(object_.props.double, 0.0)
+        object_.props.double = 42.42
+        self.assertTrue(isinstance(object_.props.double, float))
+        self.assertAlmostEquals(object_.props.double, 42.42, places=5)
+
+        self.assertEquals(object_.props.string, None)
+        object_.props.string = 'mec'
+        self.assertTrue(isinstance(object_.props.string, str))
+        self.assertEquals(object_.props.string, 'mec')
+
     def test_hash_table(self):
         object_ = Everything.TestObj()
         self.assertEquals(object_.props.hash_table, None)
@@ -326,3 +349,14 @@ class TestProperties(unittest.TestCase):
         object_.props.list = ['1', '2', '3']
         self.assertTrue(isinstance(object_.props.list, list))
         self.assertEquals(object_.props.list, ['1', '2', '3'])
+
+    def test_boxed(self):
+        object_ = Everything.TestObj()
+        self.assertEquals(object_.props.boxed, None)
+
+        boxed = Everything.TestBoxed()
+        boxed.some_int8 = 42
+        object_.props.boxed = boxed
+
+        self.assertTrue(isinstance(object_.props.boxed, Everything.TestBoxed))
+        self.assertEquals(object_.props.boxed.some_int8, 42)



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