Commit ecb9f824 authored by Martin Pitt's avatar Martin Pitt

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.
parent 31c73dee
......@@ -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)
......
......@@ -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):
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment