summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Pitt <martin.pitt@ubuntu.com>2011-08-12 22:55:02 +0200
committerMartin Pitt <martin.pitt@ubuntu.com>2011-08-16 10:40:26 +0200
commitc39f4555ebd703651eca6f978ed9870655b737f0 (patch)
treea81a3fb383e4859c84dbd7675709f0bf03c41f0f
parent735f98d83c1c19df7457aa32a378e8c80cf2831f (diff)
downloadpygobject-c39f4555ebd703651eca6f978ed9870655b737f0.tar.gz
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.
-rw-r--r--gi/overrides/GLib.py50
-rw-r--r--tests/test_overrides.py22
2 files changed, 72 insertions, 0 deletions
diff --git a/gi/overrides/GLib.py b/gi/overrides/GLib.py
index e42f854a..f3abe28c 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 14114b77..427f4d12 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):