Mercurial > libervia-backend
diff src/bridge/bridge_constructor/dbus_core_template.py @ 468:c97640c90a94
D-Bus Bridge: use inspection to name attribute + fix asynchronous calls for dynamically added method, it now use deferred return value instead of callback/errback attributes
author | Goffi <goffi@goffi.org> |
---|---|
date | Fri, 30 Mar 2012 09:23:23 +0200 |
parents | cf005701624b |
children | db4c2b82bab6 |
line wrap: on
line diff
--- a/src/bridge/bridge_constructor/dbus_core_template.py Thu Mar 29 00:04:31 2012 +0200 +++ b/src/bridge/bridge_constructor/dbus_core_template.py Fri Mar 30 09:23:23 2012 +0200 @@ -24,6 +24,7 @@ import dbus import dbus.service import dbus.mainloop.glib +import inspect from logging import debug, info, error from twisted.internet.defer import Deferred @@ -82,7 +83,7 @@ if not isinstance(result, Deferred): error("Asynchronous method [%s] does not return a Deferred." % name) raise AsyncNotDeferred - result.addCallback(callback) + result.addCallback(lambda result: callback() if result==None else callback(result)) result.addErrback(lambda err:errback(GenericException(err))) else: if isinstance(result, Deferred): @@ -142,17 +143,32 @@ i+=1 return attr - def addMethod(self, name, int_suffix, in_sign, out_sign, async=False, doc={}): + def addMethod(self, name, int_suffix, in_sign, out_sign, method, async=False): """Dynamically add a method to Dbus Bridge""" - _attributes = self.__attributes(in_sign) + inspect_args = inspect.getargspec(method) + + _attributes = inspect_args.args + _defaults = list(inspect_args.defaults or []) + + if inspect.ismethod(method): + #if we have a method, we don't want the first argument (usually 'self') + del(_attributes[0]) if async: _attributes.extend(['callback','errback']) + _defaults.extend(['callback', 'errback']) attributes = ', '.join(_attributes) + + #now we create a second list with default values + for i in range(1, len(_defaults)+1): + _attributes[-i] = "%s = %s" % (_attributes[-i], repr(_defaults[-i])) - code = compile ('def '+name+' (self,'+attributes+'): return self.cb["'+name+'"]('+attributes+')', '<DBus bridge>','exec') - exec (code) + attributes_defaults = ', '.join(_attributes) + + code = compile ('def %(name)s (self,%(attributes_defaults)s): return self.cb["%(name)s"](%(attributes)s)' % + {'name':name, 'attributes_defaults':attributes_defaults, 'attributes':attributes}, '<DBus bridge>','exec') + exec (code) #FIXME: to the same thing in a cleaner way, without compile/exec method = locals()[name] async_callbacks = ('callback', 'errback') if async else None setattr(DbusObject, name, dbus.service.method( @@ -165,6 +181,7 @@ def addSignal(self, name, int_suffix, signature, doc={}): """Dynamically add a signal to Dbus Bridge""" attributes = ', '.join(self.__attributes(signature)) + #TODO: use doc parameter to name attributes #code = compile ('def '+name+' (self,'+attributes+'): debug ("'+name+' signal")', '<DBus bridge>','exec') #XXX: the debug is too annoying with xmllog code = compile ('def '+name+' (self,'+attributes+'): pass', '<DBus bridge>','exec') @@ -193,8 +210,9 @@ def addMethod(self, name, int_suffix, in_sign, out_sign, method, async=False, doc={}): """Dynamically add a method to Dbus Bridge""" + #FIXME: doc parameter is kept only temporary, the time to remove it from calls print ("Adding method [%s] to DBus bridge" % name) - self.dbus_bridge.addMethod(name, int_suffix, in_sign, out_sign, async, doc) + self.dbus_bridge.addMethod(name, int_suffix, in_sign, out_sign, method, async) self.register(name, method) def addSignal(self, name, int_suffix, signature, doc={}):