diff options
author | Martin Pitt <martin.pitt@ubuntu.com> | 2011-08-12 22:55:02 +0200 |
---|---|---|
committer | Martin Pitt <martin.pitt@ubuntu.com> | 2011-08-16 10:40:26 +0200 |
commit | c39f4555ebd703651eca6f978ed9870655b737f0 (patch) | |
tree | a81a3fb383e4859c84dbd7675709f0bf03c41f0f | |
parent | 735f98d83c1c19df7457aa32a378e8c80cf2831f (diff) | |
download | pygobject-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.py | 50 | ||||
-rw-r--r-- | 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 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): |