summaryrefslogtreecommitdiffstats
path: root/python/service.py
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/service.py
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/service.py')
-rw-r--r--python/service.py43
1 files changed, 39 insertions, 4 deletions
diff --git a/python/service.py b/python/service.py
index 0cc2ed9f..ce251ed5 100644
--- a/python/service.py
+++ b/python/service.py
@@ -1,6 +1,7 @@
import dbus_bindings
import _dbus
+import operator
from exceptions import UnknownMethodException
from decorators import method
from decorators import signal
@@ -57,14 +58,48 @@ def _dispatch_dbus_method_call(target_methods, self, argument_list, message):
error_name = e.__class__.__name__
else:
error_name = e.__module__ + '.' + str(e.__class__.__name__)
- error_contents = str(e)
- reply = dbus_bindings.Error(message, error_name, error_contents)
+
+ error_contents = str(e)
+ reply = dbus_bindings.Error(message, error_name, error_contents)
else:
reply = dbus_bindings.MethodReturn(message)
- if retval != None:
+
+ # temporary - about to replace the method lookup code...
+ target_parent = target_method
+ target_name = str(target_method)
+
+ # do strict adding if an output signature was provided
+ if target_parent._dbus_out_signature != None:
+ # iterate signature into list of complete types
+ signature = tuple(dbus_bindings.Signature(target_parent._dbus_out_signature))
+
+ if retval == None:
+ if len(signature) != 0:
+ raise TypeError('%s returned nothing but output signature is %s' %
+ (target_name, target_parent._dbus_out_signature))
+ elif len(signature) == 1:
+ iter = reply.get_iter(append=True)
+ iter.append_strict(retval, signature[0])
+ elif len(signature) > 1:
+ if operator.isSequenceType(retval):
+ if len(signature) > len(retval):
+ raise TypeError('output signature %s is longer than the number of values returned by %s' %
+ (target_parent._dbus_out_signature, target_name))
+ elif len(retval) > len(signature):
+ raise TypeError('output signature %s is shorter than the number of values returned by %s' %
+ (target_parent._dbus_out_signature, target_name))
+ else:
+ iter = reply.get_iter(append=True)
+ for (value, sig) in zip(retval, signature):
+ iter.append_strict(value, sig)
+ else:
+ raise TypeError('output signature %s has multiple values but %s didn\'t return a sequence type' %
+ (target_parent._dbus_out_signature, target_name))
+
+ # try and guess the return type
+ elif retval != None:
iter = reply.get_iter(append=True)
iter.append(retval)
-
return reply
class ObjectType(type):