[pygobject] GVariant overrides: Support empty tuple arrays
- From: Martin Pitt <martinpitt src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [pygobject] GVariant overrides: Support empty tuple arrays
- Date: Thu, 27 Sep 2012 06:20:50 +0000 (UTC)
commit bfd9c8fac1ea240b29fbcd4185dc1702539c1e96
Author: Martin Pitt <martinpitt gnome org>
Date: Thu Sep 27 08:18:34 2012 +0200
GVariant overrides: Support empty tuple arrays
Implement the "empty value" branch in _create_tuple(), so that _create_array()
can call it for parsing the element type for an empty array.
This fixes creating variants such as GLib.Variant('a(ii)', []).
https://bugzilla.gnome.org/show_bug.cgi?id=684928
gi/overrides/GLib.py | 30 +++++++++++++++++++++++-------
tests/test_overrides_glib.py | 31 +++++++++++++++++++++++++++++++
2 files changed, 54 insertions(+), 7 deletions(-)
---
diff --git a/gi/overrides/GLib.py b/gi/overrides/GLib.py
index c41f523..b6f2ce2e 100644
--- a/gi/overrides/GLib.py
+++ b/gi/overrides/GLib.py
@@ -85,11 +85,23 @@ class _VariantCreator(object):
'''Handle the case where the outermost type of format is a tuple.'''
format = format[1:] # eat the '('
- builder = GLib.VariantBuilder.new(variant_type_from_string('r'))
- if args is not None:
+ if args is None:
+ # empty value: we need to call _create() to parse the subtype
+ rest_format = format
+ while rest_format:
+ if rest_format.startswith(')'):
+ break
+ rest_format = self._create(rest_format, None)[1]
+ else:
+ raise TypeError('tuple type string not closed with )')
+
+ rest_format = rest_format[1:] # eat the )
+ return (None, rest_format, None)
+ else:
if not args or not isinstance(args[0], tuple):
raise TypeError('expected tuple argument')
+ builder = GLib.VariantBuilder.new(variant_type_from_string('r'))
for i in range(len(args[0])):
if format.startswith(')'):
raise TypeError('too many arguments for tuple signature')
@@ -97,7 +109,11 @@ class _VariantCreator(object):
(v, format, _) = self._create(format, args[0][i:])
builder.add_value(v)
args = args[1:]
- return (builder.end(), format[1:], args)
+ if not format.startswith(')'):
+ raise TypeError('tuple type string not closed with )')
+
+ rest_format = format[1:] # eat the )
+ return (builder.end(), rest_format, args)
def _create_dict(self, format, args):
'''Handle the case where the outermost type of format is a dict.'''
@@ -109,8 +125,8 @@ class _VariantCreator(object):
rest_format = self._create(format[2:], None)[1]
rest_format = self._create(rest_format, None)[1]
if not rest_format.startswith('}'):
- raise ValueError('dictionary type string not closed with }')
- rest_format = rest_format[1:] # eat the}
+ raise TypeError('dictionary type string not closed with }')
+ rest_format = rest_format[1:] # eat the }
element_type = format[:len(format) - len(rest_format)]
builder = GLib.VariantBuilder.new(variant_type_from_string(element_type))
else:
@@ -120,8 +136,8 @@ class _VariantCreator(object):
(val_v, rest_format, _) = self._create(rest_format, [v])
if not rest_format.startswith('}'):
- raise ValueError('dictionary type string not closed with }')
- rest_format = rest_format[1:] # eat the}
+ raise TypeError('dictionary type string not closed with }')
+ rest_format = rest_format[1:] # eat the }
entry = GLib.VariantBuilder.new(variant_type_from_string('{?*}'))
entry.add_value(key_v)
diff --git a/tests/test_overrides_glib.py b/tests/test_overrides_glib.py
index 4c77011..3799454 100644
--- a/tests/test_overrides_glib.py
+++ b/tests/test_overrides_glib.py
@@ -151,6 +151,30 @@ class TestGVariant(unittest.TestCase):
self.assertEqual(variant.get_child_value(0).n_children(), 1)
self.assertEqual(variant.get_child_value(0).get_child_value(0).get_string(), 'hello')
+ variant = GLib.Variant('a(ii)', [])
+ self.assertEqual(variant.get_type_string(), 'a(ii)')
+ self.assertEqual(variant.n_children(), 0)
+
+ variant = GLib.Variant('a(ii)', [(5, 6)])
+ self.assertEqual(variant.get_type_string(), 'a(ii)')
+ self.assertEqual(variant.n_children(), 1)
+ self.assertEqual(variant.get_child_value(0).n_children(), 2)
+ self.assertEqual(variant.get_child_value(0).get_child_value(0).get_int32(), 5)
+ self.assertEqual(variant.get_child_value(0).get_child_value(1).get_int32(), 6)
+
+ variant = GLib.Variant('(a(ii))', ([],))
+ self.assertEqual(variant.get_type_string(), '(a(ii))')
+ self.assertEqual(variant.n_children(), 1)
+ self.assertEqual(variant.get_child_value(0).n_children(), 0)
+
+ variant = GLib.Variant('(a(ii))', ([(5, 6)],))
+ self.assertEqual(variant.get_type_string(), '(a(ii))')
+ self.assertEqual(variant.n_children(), 1)
+ self.assertEqual(variant.get_child_value(0).n_children(), 1)
+ self.assertEqual(variant.get_child_value(0).get_child_value(0).n_children(), 2)
+ self.assertEqual(variant.get_child_value(0).get_child_value(0).get_child_value(0).get_int32(), 5)
+ self.assertEqual(variant.get_child_value(0).get_child_value(0).get_child_value(1).get_int32(), 6)
+
obj = {'a1': (1, True), 'a2': (2, False)}
variant = GLib.Variant('a{s(ib)}', obj)
self.assertEqual(variant.get_type_string(), 'a{s(ib)}')
@@ -204,6 +228,13 @@ class TestGVariant(unittest.TestCase):
# unimplemented data type
self.assertRaises(NotImplementedError, GLib.Variant, 'Q', 1)
+ # invalid types
+ self.assertRaises(TypeError, GLib.Variant, '(ii', (42, 3))
+ self.assertRaises(TypeError, GLib.Variant, '(ii))', (42, 3))
+ self.assertRaises(TypeError, GLib.Variant, 'a{si', {})
+ self.assertRaises(TypeError, GLib.Variant, 'a{si}}', {})
+ self.assertRaises(TypeError, GLib.Variant, 'a{iii}', {})
+
def test_unpack(self):
# simple values
res = GLib.Variant.new_int32(-42).unpack()
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]