[pygobject] Add GLib.Variant.unpack()



commit ecb9f824c503c529d43e585b4cdb4c1c9ab14593
Author: Martin Pitt <martin pitt ubuntu com>
Date:   Tue Jan 18 10:48:03 2011 +0100

    Add GLib.Variant.unpack()
    
    This method decomposes a GLib.Variant into a native Python object, i. e. the
    counterpart of _VariantCreator. This makes it a lot nicer for application
    developers to use e. g. return values from gdbus calls.
    
    Add appropriate test case.

 gi/overrides/GLib.py    |   45 +++++++++++++++++++++++++++++++++++++++++++++
 tests/test_overrides.py |   33 ++++++++++++++++++++++++++++++++-
 2 files changed, 77 insertions(+), 1 deletions(-)
---
diff --git a/gi/overrides/GLib.py b/gi/overrides/GLib.py
index 13f34a4..4cfdf52 100644
--- a/gi/overrides/GLib.py
+++ b/gi/overrides/GLib.py
@@ -150,6 +150,51 @@ class Variant(GLib.Variant):
     def __repr__(self):
         return '<GLib.Variant(%s)>' % getattr(self, 'print')(True)
 
+    def unpack(self):
+        '''Decompose a GVariant into a native Python object.'''
+
+        LEAF_ACCESSORS = {
+            'b': self.get_boolean,
+            'y': self.get_byte,
+            'n': self.get_int16,
+            'q': self.get_uint16,
+            'i': self.get_int32,
+            'u': self.get_uint32,
+            'x': self.get_int64,
+            't': self.get_uint64,
+            'h': self.get_handle,
+            'd': self.get_double,
+            's': self.get_string,
+            'o': self.get_string, # object path
+            'g': self.get_string, # signature
+        }
+
+        # simple values
+        la = LEAF_ACCESSORS.get(self.get_type_string())
+        if la:
+            return la()
+
+        # tuple
+        if self.get_type_string().startswith('('):
+            res = [self.get_child_value(i).unpack() 
+                    for i in xrange(self.n_children())]
+            return tuple(res)
+
+        # dictionary
+        if self.get_type_string().startswith('a{'):
+            res = {}
+            for i in xrange(self.n_children()):
+                v = self.get_child_value(i)
+                res[v.get_child_value(0).unpack()] = v.get_child_value(1).unpack()
+            return res
+
+        # array
+        if self.get_type_string().startswith('a'):
+            return [self.get_child_value(i).unpack() 
+                    for i in xrange(self.n_children())]
+
+        raise NotImplementedError, 'unsupported GVariant type ' + self.get_type_string()
+
 @classmethod
 def new_tuple(cls, *elements):
     return variant_new_tuple(elements)
diff --git a/tests/test_overrides.py b/tests/test_overrides.py
index 1e0557b..bbcd1fc 100644
--- a/tests/test_overrides.py
+++ b/tests/test_overrides.py
@@ -16,7 +16,7 @@ import gi.types
 
 class TestGLib(unittest.TestCase):
 
-    def test_gvariant(self):
+    def test_gvariant_create(self):
         variant = GLib.Variant('i', 42)
         self.assertTrue(isinstance(variant, GLib.Variant))
         self.assertEquals(variant.get_int32(), 42)
@@ -38,6 +38,37 @@ class TestGLib(unittest.TestCase):
         self.assertEquals(variant.get_child_value(0).get_child_value(0).get_string(), 'key2')
         self.assertEquals(variant.get_child_value(0).get_child_value(1).get_int32(), 2)
 
+    def test_gvariant_unpack(self):
+        # simple values
+        res = GLib.Variant.new_int32(-42).unpack()
+        self.assertEqual(res, -42)
+
+        res = GLib.Variant.new_uint64(34359738368).unpack()
+        self.assertEqual(res, 34359738368)
+
+        res = GLib.Variant.new_boolean(True).unpack()
+        self.assertEqual(res, True)
+
+        res = GLib.Variant.new_object_path('/foo/Bar').unpack()
+        self.assertEqual(res, '/foo/Bar')
+
+        # tuple
+        res = GLib.Variant.new_tuple(GLib.Variant.new_int32(-1),
+                GLib.Variant.new_string('hello')).unpack()
+        self.assertEqual(res, (-1, 'hello'))
+
+        # array
+        vb = GLib.VariantBuilder()
+        vb.init(gi._gi.variant_type_from_string('ai'))
+        vb.add_value(GLib.Variant.new_int32(-1))
+        vb.add_value(GLib.Variant.new_int32(3))
+        res = vb.end().unpack()
+        self.assertEqual(res, [-1, 3])
+
+        # dictionary
+        res = GLib.Variant('a{si}', {'key1': 1, 'key2': 2}).unpack()
+        self.assertEqual(res, {'key1': 1, 'key2': 2})
+
 class TestPango(unittest.TestCase):
 
     def test_font_description(self):



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