[pygobject] [gi] Accept only a single object in GLib.Variant constructor



commit 27e3a6276ff5f2cdc03ddf69ee80d44c3bf2c094
Author: Martin Pitt <martin pitt ubuntu com>
Date:   Wed Jan 26 18:39:17 2011 +0100

    [gi] Accept only a single object in GLib.Variant constructor
    
    We previously allowed flat arguments for tuple signatures, e. g.
    
      GLib.Variant('(ii)', 1, 2)
    
    However, that's not how GVariant is supposed to work. Remove the special case
    to handle flat argument lists, and only accept a single value, i. e.
    
      GLib.Variant('(ii)', (1, 2))
    
    Note that this breaks the current API, but as it is not used widely yet, let's
    better fix it now.
    
    Thanks to Ryan Lortie for pointing this out!

 gi/overrides/GLib.py    |   25 ++++++++++---------------
 tests/test_overrides.py |   32 +++++++++++++-------------------
 2 files changed, 23 insertions(+), 34 deletions(-)
---
diff --git a/gi/overrides/GLib.py b/gi/overrides/GLib.py
index 2cca7f7..3ef0483 100644
--- a/gi/overrides/GLib.py
+++ b/gi/overrides/GLib.py
@@ -93,25 +93,22 @@ class _VariantCreator(object):
         raise NotImplementedError('cannot handle GVariant type ' + format)
 
     def _create_tuple(self, format, args):
-        '''Handle the case where the outermost type of format is a tuple.
+        '''Handle the case where the outermost type of format is a tuple.'''
 
-        Tuples might come in as actual tuples in args, or as a flat list, so
-        this needs to handle both cases.
-        '''
         format = format[1:] # eat the '('
         builder = GLib.VariantBuilder()
         builder.init(variant_type_from_string('r'))
-        if args is not None and args and type(args[0]) == type(()):
-            # tuple in args
+        if args is not None:
+            if not args or type(args[0]) != type(()):
+                raise TypeError, 'expected tuple argument'
+
             for i in xrange(len(args[0])):
+                if format.startswith(')'):
+                    raise TypeError, 'too many arguments for tuple signature'
+
                 (v, format, _) = self._create(format, args[0][i:])
                 builder.add_value(v)
             args = args[1:]
-        else:
-            # flat list
-            while format[0] != ')':
-                (v, format, args) = self._create(format, args)
-                builder.add_value(v)
         return (builder.end(), format[1:], args)
 
     def _create_dict(self, format, args):
@@ -168,13 +165,11 @@ class _VariantCreator(object):
         return (builder.end(), rest_format, args)
 
 class Variant(GLib.Variant):
-    def __new__(cls, format_string, *args):
+    def __new__(cls, format_string, value):
         creator = _VariantCreator()
-        (v, rest_format, restargs) = creator._create(format_string, list(args))
+        (v, rest_format, _) = creator._create(format_string, [value])
         if rest_format:
             raise TypeError('invalid remaining format string: "%s"' % rest_format)
-        if restargs:
-            raise TypeError('too many arguments for format string: "%s"' % str(restargs))
         return v
 
     def __repr__(self):
diff --git a/tests/test_overrides.py b/tests/test_overrides.py
index 41a24b5..ec0fda4 100644
--- a/tests/test_overrides.py
+++ b/tests/test_overrides.py
@@ -48,21 +48,18 @@ class TestGLib(unittest.TestCase):
 
         # tuples
 
-        variant = GLib.Variant('()')
+        variant = GLib.Variant('()', ())
         self.assertEqual(variant.get_type_string(), '()')
         self.assertEquals(variant.n_children(), 0)
 
-        # canonical arguments
-        variant = GLib.Variant('(ss)', ('mec', 'mac'))
-        self.assertEqual(variant.get_type_string(), '(ss)')
+        variant = GLib.Variant('(i)', (3,))
+        self.assertEqual(variant.get_type_string(), '(i)')
         self.assertTrue(isinstance(variant, GLib.Variant))
+        self.assertEquals(variant.n_children(), 1)
         self.assertTrue(isinstance(variant.get_child_value(0), GLib.Variant))
-        self.assertTrue(isinstance(variant.get_child_value(1), GLib.Variant))
-        self.assertEquals(variant.get_child_value(0).get_string(), 'mec')
-        self.assertEquals(variant.get_child_value(1).get_string(), 'mac')
+        self.assertEquals(variant.get_child_value(0).get_int32(), 3)
 
-        # flat arguments
-        variant = GLib.Variant('(ss)', 'mec', 'mac')
+        variant = GLib.Variant('(ss)', ('mec', 'mac'))
         self.assertEqual(variant.get_type_string(), '(ss)')
         self.assertTrue(isinstance(variant, GLib.Variant))
         self.assertTrue(isinstance(variant.get_child_value(0), GLib.Variant))
@@ -70,16 +67,11 @@ class TestGLib(unittest.TestCase):
         self.assertEquals(variant.get_child_value(0).get_string(), 'mec')
         self.assertEquals(variant.get_child_value(1).get_string(), 'mac')
 
-        # nested tuples (canonical)
+        # nested tuples
         variant = GLib.Variant('((si)(ub))', (('hello', -1), (42, True)))
         self.assertEqual(variant.get_type_string(), '((si)(ub))')
         self.assertEqual(variant.unpack(), (('hello', -1), (42L, True)))
 
-        # nested tuples (flat)
-        variant = GLib.Variant('((si)(ub))', 'hello', -1, 42, True)
-        self.assertEqual(variant.get_type_string(), '((si)(ub))')
-        self.assertEqual(variant.unpack(), (('hello', -1), (42L, True)))
-
         # dictionaries
 
         variant = GLib.Variant('a{si}', {})
@@ -158,18 +150,18 @@ class TestGLib(unittest.TestCase):
         # complex types
         #
 
-        variant = GLib.Variant('(as)', [])
+        variant = GLib.Variant('(as)', ([],))
         self.assertEqual(variant.get_type_string(), '(as)')
         self.assertEquals(variant.n_children(), 1)
         self.assertEquals(variant.get_child_value(0).n_children(), 0)
 
-        variant = GLib.Variant('(as)', [''])
+        variant = GLib.Variant('(as)', ([''],))
         self.assertEqual(variant.get_type_string(), '(as)')
         self.assertEquals(variant.n_children(), 1)
         self.assertEquals(variant.get_child_value(0).n_children(), 1)
         self.assertEquals(variant.get_child_value(0).get_child_value(0).get_string(), '')
 
-        variant = GLib.Variant('(as)', ['hello'])
+        variant = GLib.Variant('(as)', (['hello'],))
         self.assertEqual(variant.get_type_string(), '(as)')
         self.assertEquals(variant.n_children(), 1)
         self.assertEquals(variant.get_child_value(0).n_children(), 1)
@@ -197,13 +189,15 @@ class TestGLib(unittest.TestCase):
     def test_gvariant_create_errors(self):
         # excess arguments
         self.assertRaises(TypeError, GLib.Variant, 'i', 42, 3)
+        self.assertRaises(TypeError, GLib.Variant, '(i)', (42, 3))
 
         # not enough arguments
-        self.assertRaises(TypeError, GLib.Variant, '(ii)', 42)
+        self.assertRaises(TypeError, GLib.Variant, '(ii)', (42,))
 
         # data type mismatch
         self.assertRaises(TypeError, GLib.Variant, 'i', 'hello')
         self.assertRaises(TypeError, GLib.Variant, 's', 42)
+        self.assertRaises(TypeError, GLib.Variant, '(ss)', 'mec', 'mac')
 
         # unimplemented data type
         self.assertRaises(NotImplementedError, GLib.Variant, 'Q', 1)



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