diff options
| author | Seth Nickell <seth@gnome.org> | 2004-05-30 05:30:09 +0000 | 
|---|---|---|
| committer | Seth Nickell <seth@gnome.org> | 2004-05-30 05:30:09 +0000 | 
| commit | 26c937cb302506c0f4dd96e2a1dd98535f167696 (patch) | |
| tree | 8e02bc49599319c3aa62855b68da6ce5b6780f9b | |
| parent | 2e8a06bb8fa49b5b2163450654819fd26593cee4 (diff) | |
2004-05-30  Seth Nickell  <seth@gnome.org>
	* python/dbus_bindings.pyx.in:
	Add support for ObjectPath type.
	* python/dbus.py:
	Refactor message handling code to a common function.
	* python/tests/test-client.py:
	* python/tests/test-server.py:
	Add tests that check to make sure values of all types
	can be echoed from a service w/o mangling.
| -rw-r--r-- | ChangeLog | 16 | ||||
| -rw-r--r-- | python/dbus.py | 58 | ||||
| -rw-r--r-- | python/dbus_bindings.pyx.in | 66 | ||||
| -rw-r--r-- | python/tests/test-client.py | 28 | ||||
| -rw-r--r-- | python/tests/test-server.py | 17 | 
5 files changed, 142 insertions, 43 deletions
| @@ -1,3 +1,19 @@ +2004-05-30  Seth Nickell  <seth@gnome.org> + +	* python/dbus_bindings.pyx.in: + +	Add support for ObjectPath type. + +	* python/dbus.py: + +	Refactor message handling code to a common function. +	 +	* python/tests/test-client.py: +	* python/tests/test-server.py: + +	Add tests that check to make sure values of all types +	can be echoed from a service w/o mangling. +	  2004-05-29  Seth Nickell  <seth@gnome.org>  	* python/dbus.py: diff --git a/python/dbus.py b/python/dbus.py index 2c405c73..797b1969 100644 --- a/python/dbus.py +++ b/python/dbus.py @@ -215,6 +215,28 @@ class Service:          """Get the name of this service"""          return self._service_name +def _dispatch_dbus_method_call(target_method, argument_list, message): +    """Calls method_to_call using argument_list, but handles +    exceptions, etc, and generates a reply to the DBus Message message +    """ +    try: +        retval = target_method(*argument_list) +    except Exception, e: +        if e.__module__ == '__main__': +            # FIXME: is it right to use .__name__ here? +            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) +    else: +        reply = dbus_bindings.MethodReturn(message) +        if retval != None: +            iter = reply.get_iter() +            iter.append(retval) + +    return reply +  class Object:      """A base class for exporting your own Objects across the Bus. @@ -246,22 +268,8 @@ class Object:          target_method = self._method_name_to_method[target_method_name]          args = message.get_args_list() -        try: -            retval = target_method(*args) -        except Exception, e: -            if e.__module__ == '__main__': -                # FIXME: is it right to use .__name__ here? -                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) -        else: -            reply = dbus_bindings.MethodReturn(message) -            if retval != None: -                iter = reply.get_iter() -                iter.append(retval) -                 +        reply = _dispatch_dbus_method_call(target_method, args, message) +                  self._connection.send(reply)      def _build_method_dictionary(self, methods): @@ -304,22 +312,8 @@ class ObjectTree:          target_method_name = message.get_member()                  args = message.get_args_list() -        try: -            retval = self.object_method_called(target_object_path, target_method_name, args) -        except Exception, e: -            if e.__module__ == '__main__': -                # FIXME: is it right to use .__name__ here? -                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) -        else: -            reply = dbus_bindings.MethodReturn(message) -            if retval != None: -                iter = reply.get_iter() -                iter.append(retval) -                 +        reply = _dispatch_dbus_method_call(target_method, args, message) +          self._connection.send(reply)  class RemoteService: diff --git a/python/dbus_bindings.pyx.in b/python/dbus_bindings.pyx.in index 16df6fef..c8d0b6c5 100644 --- a/python/dbus_bindings.pyx.in +++ b/python/dbus_bindings.pyx.in @@ -61,6 +61,10 @@ class DBusException(Exception):  class ConnectionError(Exception):      pass +class ObjectPath(str): +    def __init__(self, value): +        str.__init__(value) +  #forward delcerations  cdef class Connection @@ -476,12 +480,16 @@ cdef class MessageIter:              if array_type == TYPE_STRING:                  retval = self.get_string_array() -            elif array_type == TYPE_BOOLEAN: -                retval = self.get_boolean_array() +            elif array_type == TYPE_OBJECT_PATH: +                retval = self.get_object_path_array() +            elif array_type == TYPE_BYTE: +                retval = self.get_byte_array()              else:                  raise TypeError, "Unknown array type %d in MessageIter" % (array_type)          elif arg_type == TYPE_DICT:              retval = self.get_dict() +        elif arg_type == TYPE_OBJECT_PATH: +            retval = self.get_object_path()          else:              raise TypeError, 'Unknown arg type %d in MessageIter' % (arg_type) @@ -507,16 +515,15 @@ cdef class MessageIter:          self.iter = old_iter          return dict -     +      def get_arg_type(self):          return dbus_message_iter_get_arg_type(self.iter)      def get_array_type(self):          return dbus_message_iter_get_array_type(self.iter) -    #FIXME: implement get_byte -    #def get_byte(self): -    #    return dbus_message_iter_get_byte(self.iter) +    def get_byte(self): +        return chr(dbus_message_iter_get_byte(self.iter))      def get_boolean(self):          return dbus_message_iter_get_boolean(self.iter) @@ -533,11 +540,14 @@ cdef class MessageIter:      def get_string(self):          return dbus_message_iter_get_string(self.iter) +    def get_object_path(self): +        object_path_string = dbus_message_iter_get_object_path(self.iter) +        return ObjectPath(object_path_string) +          def get_dict_key(self):          return dbus_message_iter_get_dict_key(self.iter) -    # FIXME: implement dbus_message_iter_get_named -    #                  dbus_message_iter_init_array_iterator +    # FIXME: implement dbus_message_iter_init_array_iterator      def get_byte_array(self):          cdef int len @@ -563,6 +573,16 @@ cdef class MessageIter:              list.append(retval[i])          return list +    def get_object_path_array(self): +        cdef int len +        cdef char **retval +         +        dbus_message_iter_get_object_path_array(self.iter, &retval, <int*>&len) +        list = [] +        for i from 0 <= i < len: +            list.append(ObjectPath(retval[i])) +        return list     +      # dbus_message_append_iter_init included in class Message      #FIXME: handle all the different types? @@ -578,13 +598,17 @@ cdef class MessageIter:          elif value_type == str:              retval = self.append_string(value)          elif value_type == list: -            if (len(list) == 1): +            if (len(list) == 0):                  raise TypeError, "Empty list"              list_type = type(list[0])              if list_type == str:                  self.append_string_array(list) +            elif isinstance(list[0], ObjectPath): +                self.append_object_path_array(list)              else:                  raise TypeError, "List of unknown type '%s'" % (list_type) +        elif isinstance(value, ObjectPath): +            retval = self.append_object_path(value)          else:              raise TypeError, "Argument of unknown type '%s'" % (value_type) @@ -597,7 +621,9 @@ cdef class MessageIter:          return dbus_message_iter_append_boolean(self.iter, value)      def append_byte(self, value): -        return dbus_message_iter_append_byte(self.iter, value) +        if type(value) != str or len(value) != 1: +            raise TypeError +        return dbus_message_iter_append_byte(self.iter, ord(value))      def append_int32(self, value):          return dbus_message_iter_append_int32(self.iter, value) @@ -616,6 +642,9 @@ cdef class MessageIter:      def append_dict_key(self, value):          return dbus_message_iter_append_dict_key(self.iter, value) +    def append_object_path(self, value): +        return dbus_message_iter_append_object_path(self.iter, str(value)) +      # FIXME: append_array, append_dict_array, append_boolean_array, append_int32_array, append_uint32_array, append_double_array      def append_byte_array(self, list): @@ -629,6 +658,19 @@ cdef class MessageIter:                  raise TypeError              value[i] = ord(item)          return dbus_message_iter_append_byte_array(self.iter, value, length) + +    def append_object_path_array(self, list): +        cdef char **value +        cdef int length +        length = len(list) +        value = <char**>malloc(length) +        for i from 0 <= i < length: +            item = list[i] +            if not isinstance(item, ObjectPath): +                raise TypeError +            value[i] = str(item) + +        return dbus_message_iter_append_object_path_array(self,iter, value, length)      def append_string_array(self, list):          cdef char **value @@ -642,7 +684,6 @@ cdef class MessageIter:              value[i] = item          return dbus_message_iter_append_string_array(self.iter, value, length) -      (MESSAGE_TYPE_INVALID, MESSAGE_TYPE_METHOD_CALL, MESSAGE_TYPE_METHOD_RETURN, MESSAGE_TYPE_ERROR, MESSAGE_TYPE_SIGNAL) = range(5)  (TYPE_INVALID, TYPE_NIL, TYPE_BYTE, TYPE_BOOLEAN, TYPE_INT32, TYPE_UINT32, TYPE_INT64, TYPE_UINT64, TYPE_DOUBLE, TYPE_STRING, TYPE_CUSTOM, TYPE_ARRAY, TYPE_DICT, TYPE_OBJECT_PATH) = (0, ord('v'), ord('y'), ord('b'), ord('i'), ord('u'), ord('x'), ord('t'), ord('d'), ord('s'), ord('c'), ord('a'), ord('m'), ord('o'))  (HANDLER_RESULT_HANDLED, HANDLER_RESULT_NOT_YET_HANDLED, HANDLER_RESULT_NEED_MEMORY) = range(3) @@ -726,6 +767,9 @@ cdef class Message:              elif type == TYPE_STRING:                  str = iter.get_string()                  arg = 'string:%s\n' % (str) +            elif type == TYPE_OBJECT_PATH: +                path = iter.get_object_path() +                arg = 'object_path:%s\n' % (path)              elif type == TYPE_INT32:                  num = iter.get_int32()                  arg = 'int32:%d\n' % (num) diff --git a/python/tests/test-client.py b/python/tests/test-client.py new file mode 100644 index 00000000..d12ee2aa --- /dev/null +++ b/python/tests/test-client.py @@ -0,0 +1,28 @@ +import dbus +import dbus_bindings + + +def TestEcho(value, should_be_equal = True): +    global remote_object +    echoed = remote_object.Echo(value) +    if type(echoed) != type(value): +        raise Exception ("Sending %s, expected echo of type %s, but got %s" % (value, type(value), type(echoed))) + +    if echoed.__class__ != value.__class__: +        raise Exception ("Sending %s, expected echo to be of class %s, but got %s" % (value, value.__class__, echoed.__class__)) + +    if should_be_equal: +        if echoed != value: +            raise Exception("Sending %s, expected echo to be the same, but was %s" % (value, echoed)) + +session_bus = dbus.SessionBus() + +remote_service = session_bus.get_service("org.designfu.Test") +remote_object = remote_service.get_object("/TestObject", "org.designfu.Test") + +TestEcho(chr(120)) +TestEcho(10) +TestEcho(39.5) +TestEcho("HelloWorld") +TestEcho(dbus_bindings.ObjectPath("/test/path")) + diff --git a/python/tests/test-server.py b/python/tests/test-server.py new file mode 100644 index 00000000..2af685bc --- /dev/null +++ b/python/tests/test-server.py @@ -0,0 +1,17 @@ +import dbus +import gtk + +class TestObject(dbus.Object): +    def __init__(self, service): +        method_list = [ self.Echo ] +        dbus.Object.__init__(self, "/TestObject", method_list, service) + +    def Echo(self, variable): +        return variable +             +session_bus = dbus.SessionBus() + +local_service = dbus.Service("org.designfu.Test", bus=session_bus) +local_object = TestObject(local_service) + +gtk.main() | 
