summaryrefslogtreecommitdiffstats
path: root/python/dbus_bindings.pyx
diff options
context:
space:
mode:
authorRobert McQueen <robot101@debian.org>2005-10-29 19:13:17 +0000
committerRobert McQueen <robot101@debian.org>2005-10-29 19:13:17 +0000
commit20bcbaf21f4e94c48d6348a4ba8013d20f9e4d36 (patch)
treecf690b655da24bcd25d678bdd178d42064934258 /python/dbus_bindings.pyx
parent2d74492ba2c61a41d9d22a8872806a8184acef16 (diff)
2005-10-29 Robert McQueen <robot101@debian.org>
* python/decorators.py: Add optional arguments to the method and signal decorators to allow you to specify the signature of arguments and return values. Preserve the doc strings of signal functions in the decorated version, for pydoc and friends. * python/dbus_bindings.pyx, python/proxies.py: Replace the parse_signature_block function with an iterable dbus.Signature() type. Fix a bug in MessageIter.append_strict where you could append anything by claiming it was a string. * python/service.py: Use the out_signature decoration on methods to marshal return values, meaning you no longer require dbus.Array() or dbus.Dictionary() to indicate the type when returning empty arrays or dictionaries. Fix a bug where exceptions which are defined in __main__ are not turned into error replies. * test/python/test-client.py, test/python/test-service.py: Add test for correct marshalling of return values according to out_signature. Fix a bug in the async call test where the error_handler is missing a self argument.
Diffstat (limited to 'python/dbus_bindings.pyx')
-rw-r--r--python/dbus_bindings.pyx119
1 files changed, 72 insertions, 47 deletions
diff --git a/python/dbus_bindings.pyx b/python/dbus_bindings.pyx
index 4bf0893c..fe6e7777 100644
--- a/python/dbus_bindings.pyx
+++ b/python/dbus_bindings.pyx
@@ -77,9 +77,74 @@ class ByteArray(str):
def __init__(self, value):
str.__init__(self, value)
+class SignatureIter(object):
+ def __init__(self, string):
+ object.__init__(self)
+ self.remaining = string
+
+ def next(self):
+ if self.remaining == '':
+ raise StopIteration
+
+ signature = self.remaining
+ block_depth = 0
+ block_type = None
+ end = len(signature)
+
+ for marker in range(0, end):
+ cur_sig = ord(signature[marker])
+
+ if cur_sig == TYPE_ARRAY:
+ pass
+ elif cur_sig == DICT_ENTRY_BEGIN or cur_sig == STRUCT_BEGIN:
+ if block_type == None:
+ block_type = cur_sig
+
+ if block_type == cur_sig:
+ block_depth = block_depth + 1
+
+ elif cur_sig == DICT_ENTRY_END:
+ if block_type == DICT_ENTRY_BEGIN:
+ block_depth = block_depth - 1
+
+ if block_depth == 0:
+ end = marker
+ break
+
+ elif cur_sig == STRUCT_END:
+ if block_type == STRUCT_BEGIN:
+ block_depth = block_depth - 1
+
+ if block_depth == 0:
+ end = marker
+ break
+
+ else:
+ if block_depth == 0:
+ end = marker
+ break
+
+ end = end + 1
+ self.remaining = signature[end:]
+ return Signature(signature[0:end])
+
class Signature(str):
+ """An iterable method signature. Iterating gives the signature of each
+ argument in turn."""
def __init__(self, value):
- str.__init__(self, value)
+ return str.__init__(self, value)
+
+ def __iter__(self):
+ return SignatureIter(self)
+
+class VariantSignature(object):
+ """A fake method signature which when iterated, is an endless stream
+ of variants (handy with zip()). It has no string representation."""
+ def __iter__(self):
+ return self
+
+ def next(self):
+ return 'v'
class Byte(int):
def __init__(self, value):
@@ -937,47 +1002,6 @@ cdef class MessageIter:
return ret
- def parse_signature_block(self, signature):
- remainder = ''
- sig = ''
- block_depth = 0
- block_type = None
-
- for marker in range(0, len(signature)):
- cur_sig = ord(signature[marker])
-
- if cur_sig == TYPE_ARRAY:
- pass
- elif cur_sig == DICT_ENTRY_BEGIN or cur_sig == STRUCT_BEGIN:
- if block_type == None:
- block_type = cur_sig
-
- if block_type == cur_sig:
- block_depth = block_depth + 1
-
- elif cur_sig == DICT_ENTRY_END:
- if block_type == DICT_ENTRY_BEGIN:
- block_depth = block_depth - 1
-
- if block_depth == 0:
- break
-
- elif cur_sig == STRUCT_END:
- if block_type == STRUCT_BEGIN:
- block_depth = block_depth - 1
-
- if block_depth == 0:
- break
-
- else:
- if block_depth == 0:
- break
-
- marker = marker + 1
- sig = signature[0:marker]
- remainder = signature[marker:]
- return (sig, remainder)
-
def append_strict(self, value, sig):
if sig == TYPE_INVALID or sig == None:
@@ -986,7 +1010,7 @@ cdef class MessageIter:
sig_type = ord(sig[0])
if sig_type == TYPE_STRING:
- retval = self.append(value)
+ retval = self.append_string(value)
elif sig_type == TYPE_INT16:
retval = self.append_int16(value)
elif sig_type == TYPE_UINT16:
@@ -1201,13 +1225,14 @@ cdef class MessageIter:
dict_entry_iter.__cinit__(&c_dict_entry_iter)
if signature:
- (tmp_sig, remainder) = self.parse_signature_block(signature)
+ signature_iter = iter(Signature(signature))
+ tmp_sig = signature_iter.next()
if not dict_entry_iter.append_strict(key, tmp_sig):
dbus_message_iter_close_container(dict_iter.iter, dict_entry_iter.iter)
dbus_message_iter_close_container(self.iter, dict_iter.iter)
return False
- (tmp_sig, remainder) = self.parse_signature_block(remainder)
+ tmp_sig = signature_iter.next()
if not dict_entry_iter.append_strict(value, tmp_sig):
dbus_message_iter_close_container(dict_iter.iter, dict_entry_iter.iter)
dbus_message_iter_close_container(self.iter, dict_iter.iter)
@@ -1239,10 +1264,10 @@ cdef class MessageIter:
struct_iter = MessageIter(level)
struct_iter.__cinit__(&c_struct_iter)
- remainder = signature
+ signature_iter = iter(Signature(signature))
for item in python_struct:
if signature:
- (sig, remainder) = self.parse_signature_block(remainder)
+ sig = signature_iter.next()
if sig == '':
dbus_message_iter_close_container(self.iter, struct_iter.iter)