[pygobject] Add override for GLib.Variant.split_signature()



commit c39f4555ebd703651eca6f978ed9870655b737f0
Author: Martin Pitt <martin pitt ubuntu com>
Date:   Fri Aug 12 22:55:02 2011 +0200

    Add override for GLib.Variant.split_signature()
    
    This is useful for e. g. iterating over method parameters which are passed as a
    single Variant. In particular we will need it for automatically generating
    introspection XML for exported DBus server objects.

 gi/overrides/GLib.py    |   50 +++++++++++++++++++++++++++++++++++++++++++++++
 tests/test_overrides.py |   22 ++++++++++++++++++++
 2 files changed, 72 insertions(+), 0 deletions(-)
---
diff --git a/gi/overrides/GLib.py b/gi/overrides/GLib.py
index e42f854..f3abe28 100644
--- a/gi/overrides/GLib.py
+++ b/gi/overrides/GLib.py
@@ -221,6 +221,56 @@ class Variant(GLib.Variant):
 
         raise NotImplementedError('unsupported GVariant type ' + self.get_type_string())
 
+    @classmethod
+    def split_signature(klass, signature):
+        '''Return a list of the element signatures of the topmost signature tuple.
+
+        If the signature is not a tuple, it returns one element with the entire
+        signature. If the signature is an empty tuple, the result is [].
+        
+        This is useful for e. g. iterating over method parameters which are
+        passed as a single Variant.
+        '''
+        if signature == '()':
+            return []
+
+        if not signature.startswith('('):
+            return [signature]
+
+        result = []
+        head = ''
+        tail = signature[1:-1] # eat the surrounding ( )
+        while tail:
+            c = tail[0]
+            head += c
+            tail = tail[1:]
+
+            if c in ('m', 'a'):
+                # prefixes, keep collecting
+                continue
+            if c in ('(', '{'):
+                # consume until corresponding )/}
+                level = 1
+                up = c
+                if up == '(':
+                    down = ')'
+                else:
+                    down = '}'
+                while level > 0:
+                    c = tail[0]
+                    head += c
+                    tail = tail[1:]
+                    if c == up:
+                        level += 1
+                    elif c == down:
+                        level -= 1
+
+            # otherwise we have a simple type
+            result.append(head)
+            head = ''
+
+        return result
+
     #
     # Pythonic iterators
     #
diff --git a/tests/test_overrides.py b/tests/test_overrides.py
index 14114b7..427f4d1 100644
--- a/tests/test_overrides.py
+++ b/tests/test_overrides.py
@@ -325,6 +325,28 @@ class TestGLib(unittest.TestCase):
         # string iteration
         self.assertEqual([x for x in v], ['h', 'e', 'l', 'l', 'o'])
 
+    def test_variant_split_signature(self):
+        self.assertEqual(GLib.Variant.split_signature('()'), [])
+
+        self.assertEqual(GLib.Variant.split_signature('s'), ['s'])
+
+        self.assertEqual(GLib.Variant.split_signature('as'), ['as'])
+
+        self.assertEqual(GLib.Variant.split_signature('(s)'), ['s'])
+
+        self.assertEqual(GLib.Variant.split_signature('(iso)'), ['i', 's', 'o'])
+
+        self.assertEqual(GLib.Variant.split_signature('(s(ss)i(ii))'), 
+                ['s', '(ss)', 'i', '(ii)'])
+
+        self.assertEqual(GLib.Variant.split_signature('(as)'), ['as'])
+
+        self.assertEqual(GLib.Variant.split_signature('(s(ss)iaiaasa(ii))'), 
+                ['s', '(ss)', 'i', 'ai', 'aas', 'a(ii)'])
+
+        self.assertEqual(GLib.Variant.split_signature('(a{iv}(ii)((ss)a{s(ss)}))'), 
+                ['a{iv}', '(ii)', '((ss)a{s(ss)})'])
+
 class TestPango(unittest.TestCase):
 
     def test_default_font_description(self):



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