diff options
| author | John (J5) Palmieri <johnp@redhat.com> | 2005-08-16 22:54:04 +0000 | 
|---|---|---|
| committer | John (J5) Palmieri <johnp@redhat.com> | 2005-08-16 22:54:04 +0000 | 
| commit | ce84a7761a567f5afaca03d0fb5c0378f293da80 (patch) | |
| tree | 7f00e7193fb6e6f07df88fa70650174916231820 | |
| parent | 9746c7a97871508c7298a8cad88dc7daff1c2bb3 (diff) | |
	* python/__init__.py: Version updated (0, 43, 0)
	* python/dbus_bindings.pyx:
	- Fixed type objects to have self passed into __init__
	- Added the Variant type
	- Add the ability to specify types or signatures for Array, Variant and Dictionary
	- (Connection::send_with_reply_handlers): return a PendingCall object
	- (_pending_call_notification): handle the case when an error is returned
	without an error message in the body
	- (MessageIter::get_boolean): return True or False instead of an integer
	- (MessageIter::python_value_to_dbus_sig): add direct checking of types and
	add checks for objects with embeded signatures or types (Array, Variant and
	Dictionary)
	- (MessageIter::append_byte): handle case when the value is a dbus.Byte
	- (MessageIter::append_dict): handle embeded types or signatures
	- (MessageIter::append_array): handle embeded types or signatures
	- (MessageIter::append_variant): new method
	* python/proxies.py:
	- (DeferedMethod): New. Dummy executable object used when queuing calls blocking on
	introspection data
	- (ProxyMethod::__call__): add the timeout keyword for specifying longer or
	shorter timeouts for method calls
	- (ProxyObject): Add first pass at an introspection state machine
	- (ProxyObject::__init__): Add introspect keyword for turing off an on
	introspection.
	- (ProxyObject::_Introspect): Internal Introspect call that bypasses the usual
	mechanisms for sending messages.  This is to avoid a deadlock where the Intospect
	call would be queued waiting for the Introspect call to finish ;-)
	- (ProxyObject::_introspect_reply_handler): New.  This method is called when
	introspection returns with no error
	- (ProxyObject::_introspect_error_handler): New.  This method is called when
	introspection encounters an error
	- (ProxyObject::__getattr__): Code to handle different introspection states.
	Queue async calls or block blocking calls if we are introspecting.  Pass through
	as normal if we are not or are done with introspecting.
	* python/service.py: Import signal and method from decorators.py
	* python/types.py: Add Variant type
| -rw-r--r-- | ChangeLog | 43 | ||||
| -rw-r--r-- | python/__init__.py | 2 | ||||
| -rw-r--r-- | python/_dbus.py | 5 | ||||
| -rw-r--r-- | python/dbus_bindings.pyx | 223 | ||||
| -rw-r--r-- | python/examples/example-client.py | 1 | ||||
| -rw-r--r-- | python/examples/list-system-services.py | 4 | ||||
| -rw-r--r-- | python/proxies.py | 97 | ||||
| -rw-r--r-- | python/service.py | 2 | ||||
| -rw-r--r-- | python/types.py | 1 | 
9 files changed, 312 insertions, 66 deletions
@@ -1,3 +1,46 @@ +2005-08-16  John (J5) Palmieri  <johnp@redhat.com> + +	* python/__init__.py: Version updated (0, 43, 0) +	 +	* python/dbus_bindings.pyx:  +	- Fixed type objects to have self passed into __init__ +	- Added the Variant type +	- Add the ability to specify types or signatures for Array, Variant and Dictionary +	- (Connection::send_with_reply_handlers): return a PendingCall object +	- (_pending_call_notification): handle the case when an error is returned  +	without an error message in the body +	- (MessageIter::get_boolean): return True or False instead of an integer +	- (MessageIter::python_value_to_dbus_sig): add direct checking of types and +	add checks for objects with embeded signatures or types (Array, Variant and  +	Dictionary) +	- (MessageIter::append_byte): handle case when the value is a dbus.Byte +	- (MessageIter::append_dict): handle embeded types or signatures +	- (MessageIter::append_array): handle embeded types or signatures +	- (MessageIter::append_variant): new method +	 +	* python/proxies.py: +	- (DeferedMethod): New. Dummy executable object used when queuing calls blocking on +	introspection data +	- (ProxyMethod::__call__): add the timeout keyword for specifying longer or +	shorter timeouts for method calls +	- (ProxyObject): Add first pass at an introspection state machine +	- (ProxyObject::__init__): Add introspect keyword for turing off an on  +	introspection.  +	- (ProxyObject::_Introspect): Internal Introspect call that bypasses the usual +	mechanisms for sending messages.  This is to avoid a deadlock where the Intospect +	call would be queued waiting for the Introspect call to finish ;-) +	- (ProxyObject::_introspect_reply_handler): New.  This method is called when +	introspection returns with no error +	- (ProxyObject::_introspect_error_handler): New.  This method is called when +	introspection encounters an error +	- (ProxyObject::__getattr__): Code to handle different introspection states. +	Queue async calls or block blocking calls if we are introspecting.  Pass through +	as normal if we are not or are done with introspecting. +	 +	* python/service.py: Import signal and method from decorators.py + +	* python/types.py: Add Variant type +  2005-08-16  Colin Walters  <walters@verbum.org>  	* glib/dbus-gobject.c (dbus_set_g_error): Don't lose if the diff --git a/python/__init__.py b/python/__init__.py index 945ef67e..a1ff407a 100644 --- a/python/__init__.py +++ b/python/__init__.py @@ -1,5 +1,5 @@  from _dbus import *  from types import * -version = (0, 42, 0) +version = (0, 43, 0)  _dbus_main_loop_setup_function = None diff --git a/python/_dbus.py b/python/_dbus.py index f0c7b069..6074be16 100644 --- a/python/_dbus.py +++ b/python/_dbus.py @@ -196,8 +196,9 @@ class Interface:          if member == '__call__':              return object.__call__          else: -            return self._obj.__getattr__(member, dbus_interface=_dbus_interface) -     +            ret = self._obj.__getattr__(member, dbus_interface=_dbus_interface) +            return ret +      def __repr__(self):          return '<Interface %r implementing %r at %x>'%(          self._obj, self._dbus_interface, id(self)) diff --git a/python/dbus_bindings.pyx b/python/dbus_bindings.pyx index 608ef544..a083f504 100644 --- a/python/dbus_bindings.pyx +++ b/python/dbus_bindings.pyx @@ -74,53 +74,53 @@ class ConnectionError(Exception):  class ObjectPath(str):      def __init__(self, value): -        str.__init__(value) +        str.__init__(self, value)  class ByteArray(str):      def __init__(self, value): -        str.__init__(value) +        str.__init__(self, value)  class Signature(str):      def __init__(self, value): -        str.__init__(value) +        str.__init__(self, value)  class Byte(int):      def __init__(self, value): -        int.__init__(value) +        int.__init__(self, value)  class Boolean(int):      def __init__(self, value): -        int.__init__(value) +        int.__init__(self, value)  class Int16(int):      def __init__(self, value): -        int.__init__(value) +        int.__init__(self, value)  class UInt16(int):      def __init__(self, value):          if value < 0:              raise TypeError('Unsigned integers must not have a negitive value')  -        int.__init__(value) +        int.__init__(self, value)  class Int32(int):      def __init__(self, value): -        int.__init__(value) +        int.__init__(self, value)  class UInt32(long):      def __init__(self, value):          if value < 0:              raise TypeError('Unsigned integers must not have a negitive value')  -        long.__init__(value) +        long.__init__(self, value)  class Int64(long):      def __init__(self, value): -        long.__init__(value) +        long.__init__(self, value)  class UInt64(long):      def __init__(self, value):          if value < 0:              raise TypeError('Unsigned integers must not have a negitive value')  -        long.__init__(value) +        long.__init__(self, value)  class Double(float):      def __init__(self, value): @@ -128,19 +128,49 @@ class Double(float):  class String(str):      def __init__(self, value): -        str.__init__(value) +        str.__init__(self, value)  class Array(list): -    def __init__(self, value): -        list.__init__(value) +    def __init__(self, value, type=None, signature=None): +        if signature and type: +            raise TypeError('Can not mix type and signature arguments in a D-BUS Array') +     +        self.type = type +        self.signature = signature +        list.__init__(self, value) + +class Variant: +    def __init__(self, value, type=None, signature=None): +        self.value = value +        if signature and type: +            raise TypeError('Can not mix type and signature arguments in a D-BUS Variant') + +        self.type = type +        self.signature = signature + +    def __repr__(self): +        return repr(self.value) + +    def __str__(self): +        return str(self.value)  class Struct(tuple):      def __init__(self, value): -        tuple.__init__(value) +        tuple.__init__(self, value)  class Dictionary(dict): -    def __init__(self, value): -        dict.__init__(value) +    def __init__(self, value, key_type=None, value_type=None, signature=None): +        if key_type and not value_type: +             raise TypeError('When specifying a key_type you must also have a value_type in a D-BUS Dictionary') +        elif value_type and not key_type: +             raise TypeError('When specifying a value_type you must also have a key_type in a D-BUS Dictionary') +        elif key_type and signature: +              raise TypeError('Can not mix type arguments with signature arguments in a D-BUS Dictionary') +               +        self.key_type = key_type +        self.value_type = value_type +        self.signature = signature +        dict.__init__(self, value)  #forward delcerations  cdef class Message @@ -190,7 +220,7 @@ cdef DBusHandlerResult cmessage_function_handler (DBusConnection *connection,          return retval      finally:          PyGILState_Release(gil) -	 +  cdef class Connection:      def __init__(self, address=None, Connection _conn=None):          cdef DBusConnection *c_conn @@ -297,7 +327,7 @@ cdef class Connection:          except Exception, e:              error_handler(e) -        return retval +        return (retval, pending_call)      def send_with_reply(self, Message message, timeout_milliseconds):          cdef dbus_bool_t retval @@ -470,7 +500,10 @@ cdef void _pending_call_notification(DBusPendingCall *pending_call, void *user_d          reply_handler(*args)      elif type == MESSAGE_TYPE_ERROR:          args = message.get_args_list() -        error_handler(DBusException(args[0])) +        if len(args) > 0: +            error_handler(DBusException(args[0])) +        else: +            error_handler(DBusException(""))      else:          error_handler(DBusException('Unexpected Message Type: ' + message.type_to_name(type))) @@ -628,7 +661,11 @@ cdef class MessageIter:      def get_boolean(self):          cdef dbus_bool_t c_val          dbus_message_iter_get_basic(self.iter, <dbus_bool_t *>&c_val) -        return c_val + +        if c_val: +            return True +        else: +            return False       def get_signature(self):          signature_string = self.get_string() @@ -637,6 +674,7 @@ cdef class MessageIter:      def get_int16(self):          cdef dbus_int16_t c_val          dbus_message_iter_get_basic(self.iter, <dbus_int16_t *>&c_val) +          return c_val      def get_uint16(self): @@ -672,6 +710,7 @@ cdef class MessageIter:      def get_string(self):          cdef char *c_str          dbus_message_iter_get_basic(self.iter, <char **>&c_str) +          return c_str      def get_object_path(self): @@ -797,60 +836,78 @@ cdef class MessageIter:          elif ptype == list:              ret = str(chr(TYPE_ARRAY))              ret = ret + self.python_value_to_dbus_sig(value[0], level) -        elif isinstance(value, ObjectPath): +        elif isinstance(value, ObjectPath) or value == ObjectPath: +              ret = TYPE_OBJECT_PATH              ret = str(chr(ret)) -        elif isinstance(ByteArray): +        elif isinstance(value, ByteArray) or value == ByteArray:              ret = str(chr(TYPE_ARRAY)) + str(chr(TYPE_BYTE)) -        elif isinstance(Signature): +        elif isinstance(value, Signature) or value == Signature:              ret = TYPE_SIGNATURE              ret = str(chr(ret)) -        elif isinstance(value, Byte): +        elif isinstance(value, Byte) or value == Byte:              ret = TYPE_BYTE              ret = str(chr(ret)) -        elif isinstance(value, Boolean): +        elif isinstance(value, Boolean) or value == Boolean:              ret = TYPE_BOOL              ret = str(chr(ret)) -        elif isinstance(value, Int16): +        elif isinstance(value, Int16) or value == Int16:              ret = TYPE_INT16              ret = str(chr(ret)) -        elif isinstance(value, UInt16): +        elif isinstance(value, UInt16) or value == UInt16:              ret = TYPE_UINT16              ret = str(chr(ret)) -        elif isinstance(value, Int32): +        elif isinstance(value, Int32) or value == Int32:              ret = TYPE_INT32              ret = str(chr(ret)) -        elif isinstance(value, UInt32): +        elif isinstance(value, UInt32) or value == UInt32:              ret = TYPE_UINT32              ret = str(chr(ret)) -        elif isinstance(value, Int64): +        elif isinstance(value, Int64) or value == Int64:              ret = TYPE_INT64              ret = str(chr(ret)) -        elif isinstance(value, UInt64): +        elif isinstance(value, UInt64) or value == UInt64:              ret = TYPE_UINT64              ret = str(chr(ret)) -        elif isinstance(value, Double): +        elif isinstance(value, Double) or value == Double:              ret = TYPE_DOUBLE              ret = str(chr(ret)) -        elif isinstance(value, String): +        elif isinstance(value, String) or value == String:              ret = TYPE_STRING              ret = str(chr(ret))          elif isinstance(value, Array):              ret = str(chr(TYPE_ARRAY)) -            ret = ret + self.python_value_to_dbus_sig(value[0], level) -        elif isinstance(value, Struct): +            if value.type == None: +                if value.signature: +                    ret = ret + value.signature +                else: +                    ret = ret + self.python_value_to_dbus_sig(value[0], level) +            else: +                ret = ret + self.python_value_to_dbus_sig(value.type, level) + +        elif isinstance(value, Struct) or value == Struct:              ret = str(chr(STRUCT_BEGIN))              for item in value:                  ret = ret + self.python_value_to_dbus_sig(item, level)              ret = ret + str(chr(STRUCT_END))          elif isinstance(value, Dictionary): -            dict_list = value.items() -            key, value = dict_list[0] -              ret = str(chr(TYPE_ARRAY)) + str(chr(DICT_ENTRY_BEGIN)) -            ret = ret + self.python_value_to_dbus_sig(key, level) -            ret = ret + self.python_value_to_dbus_sig(value, level) +             +            if value.key_type and value.value_type: +                ret = ret + self.python_value_to_dbus_sig(value.key_type, level) +                ret = ret + self.python_value_to_dbus_sig(value.value_type, level) +            elif value.signature: +                ret = ret + value.signature +            else: +                dict_list = value.items() + +                key, val = dict_list[0] +                ret = ret + self.python_value_to_dbus_sig(key, level) +                ret = ret + self.python_value_to_dbus_sig(val, level) +                              ret = ret + str(chr(DICT_ENTRY_END)) +        elif isinstance(value, Variant) or value == Variant: +            ret = ret + str(chr(TYPE_VARIANT))          else:              raise TypeError, "Argument of unknown type '%s'" % (ptype) @@ -910,6 +967,8 @@ cdef class MessageIter:              retval = self.append_struct(value)          elif isinstance(value, Dictionary):              retval = self.append_dict(value) +        elif isinstance(value, Variant): +            retval = self.append_variant(value)          else:              raise TypeError, "Argument of unknown type '%s'" % (value_type) @@ -922,10 +981,13 @@ cdef class MessageIter:      def append_byte(self, value):          cdef char b -        if type(value) != str or len(value) != 1: +        if type(value) == str and len(value) == 1: +                b = ord(value) +        elif type(value) == Byte: +                b = value +        else:              raise TypeError -        b = ord(value)          return dbus_message_iter_append_basic(self.iter, TYPE_BYTE, <char *>&b)      def append_int16(self, value): @@ -985,12 +1047,27 @@ cdef class MessageIter:          level = self.level + 1 -        dict_list = python_dict.items() -        key, value = dict_list[0] +        key = None +        value = None          sig = str(chr(DICT_ENTRY_BEGIN)) -        sig = sig + self.python_value_to_dbus_sig(key) -        sig = sig + self.python_value_to_dbus_sig(value) + +        if isinstance(python_dict, Dictionary): +            key = python_dict.key_type +            value = python_dict.value_type +            signature = python_dict.signature + +        dict_list = python_dict.items() + +        if signature: +            sig = sig + signature +        else:  +            if not (key and value): +                key, value = dict_list[0] + +            sig = sig + self.python_value_to_dbus_sig(key) +            sig = sig + self.python_value_to_dbus_sig(value) +          sig = sig + str(chr(DICT_ENTRY_END))          dbus_message_iter_open_container(self.iter, TYPE_ARRAY, sig, <DBusMessageIter *>&c_dict_iter) @@ -1002,13 +1079,22 @@ cdef class MessageIter:              dict_entry_iter = MessageIter(level)              dict_entry_iter.__cinit__(&c_dict_entry_iter) -            dict_entry_iter.append(key) -            dict_entry_iter.append(value) +            if not dict_entry_iter.append(key): +                dbus_message_iter_close_container(dict_iter.iter, dict_entry_iter.iter) +                dbus_message_iter_close_container(self.iter, dict_iter.iter) +                return False +                 +            if not dict_entry_iter.append(value): +                dbus_message_iter_close_container(dict_iter.iter, dict_entry_iter.iter) +                dbus_message_iter_close_container(self.iter, dict_iter.iter) +                return False              dbus_message_iter_close_container(dict_iter.iter, dict_entry_iter.iter)          dbus_message_iter_close_container(self.iter, dict_iter.iter) +        return True +      def append_struct(self, python_struct):          cdef DBusMessageIter c_struct_iter          cdef MessageIter struct_iter @@ -1025,12 +1111,24 @@ cdef class MessageIter:          dbus_message_iter_close_container(self.iter, struct_iter.iter) +        return True +      def append_array(self, python_list):          cdef DBusMessageIter c_array_iter          cdef MessageIter array_iter          level = self.level + 1 -        sig = self.python_value_to_dbus_sig(python_list[0]) + +        sig = None +        if isinstance(python_list, Array): +            if python_list.type: +                sig = self.python_value_to_dbus_sig(python_list.type) +            elif python_list.signature: +                sig = python_list.signature +            else: +                sig = self.python_value_to_dbus_sig(python_list[0]) +        else: +            sig = self.python_value_to_dbus_sig(python_list[0])          dbus_message_iter_open_container(self.iter, TYPE_ARRAY, sig, <DBusMessageIter *>&c_array_iter)          array_iter = MessageIter(level) @@ -1046,6 +1144,31 @@ cdef class MessageIter:          return True +    def append_variant(self, value): +        cdef DBusMessageIter c_variant_iter +        cdef MessageIter variant_iter + +        level = self.level + 1 +     +        if value.signature: +            sig = value.signature +        elif value.type: +            sig = self.python_value_to_dbus_sig(value.type) +        else: +            sig = self.python_value_to_dbus_sig(value.value) +     +        dbus_message_iter_open_container(self.iter, TYPE_VARIANT, sig, <DBusMessageIter *>&c_variant_iter) +         +        variant_iter = MessageIter(level) +        variant_iter.__cinit__(&c_variant_iter) + +        if not variant_iter.append(value.value): +            dbus_message_iter_close_container(self.iter, variant_iter.iter) +            return False + +        dbus_message_iter_close_container(self.iter, variant_iter.iter) +        return True +      def __str__(self):          cdef DBusMessageIter c_array_iter          cdef MessageIter array_iter diff --git a/python/examples/example-client.py b/python/examples/example-client.py index 7439e6bd..3d170bd4 100644 --- a/python/examples/example-client.py +++ b/python/examples/example-client.py @@ -19,3 +19,4 @@ print str(hello_reply_tuple)  print str(hello_reply_dict)  print remote_object.Introspect(dbus_interface="org.freedesktop.DBus.Introspectable") + diff --git a/python/examples/list-system-services.py b/python/examples/list-system-services.py index d4280551..4cad8717 100644 --- a/python/examples/list-system-services.py +++ b/python/examples/list-system-services.py @@ -2,6 +2,7 @@  """Lists services on the system bus  """ +  import dbus  # Get a connection to the SYSTEM bus @@ -18,5 +19,4 @@ dbus_iface = dbus.Interface(dbus_object, 'org.freedesktop.DBus')  # One of the member functions in the org.freedesktop.DBus interface  # is ListServices(), which provides a list of all the other services  # registered on this bus. Call it, and print the list. -system_service_list = dbus_object.ListNames() -print str(system_service_list) +print dbus_object.ListNames() diff --git a/python/proxies.py b/python/proxies.py index 95c98a9c..c7dc02be 100644 --- a/python/proxies.py +++ b/python/proxies.py @@ -1,6 +1,17 @@  import dbus_bindings  from exceptions import MissingReplyHandlerException, MissingErrorHandlerException +class DeferedMethod: +    """A DeferedMethod +     +    This is returned instead of ProxyMethod when we are defering DBus calls +    while waiting for introspection data to be returned +     +    This class can be used for debugging purposes +    """ +    def __call__(self, *args, **keywords): +        return None +  class ProxyMethod:      """A proxy Method. @@ -17,15 +28,19 @@ class ProxyMethod:      def __call__(self, *args, **keywords):          dbus_interface = self._dbus_interface -        if (keywords.has_key('dbus_interface')): +        if keywords.has_key('dbus_interface'):              dbus_interface = keywords['dbus_interface'] +        timeout = -1 +        if keywords.has_key('timeout'): +            timeout = keywords['timeout'] +          reply_handler = None -        if (keywords.has_key('reply_handler')): +        if keywords.has_key('reply_handler'):              reply_handler = keywords['reply_handler']          error_handler = None -        if (keywords.has_key('error_handler')): +        if keywords.has_key('error_handler'):              error_handler = keywords['error_handler']                      if not(reply_handler and error_handler): @@ -43,10 +58,10 @@ class ProxyMethod:              iter.append(arg)          if reply_handler: -            result = self._connection.send_with_reply_handlers(message, -1, reply_handler, error_handler) -            args_tuple = (result,) +            result = self._connection.send_with_reply_handlers(message, timeout, reply_handler, error_handler) +            args_tuple = result          else: -            reply_message = self._connection.send_with_reply_and_block(message, -1) +            reply_message = self._connection.send_with_reply_and_block(message, timeout)              args_tuple = reply_message.get_args_list()          if len(args_tuple) == 0: @@ -64,11 +79,31 @@ class ProxyObject:      have member functions, and can be called like normal Python objects.      """      ProxyMethodClass = ProxyMethod +    DeferedMethodClass = DeferedMethod -    def __init__(self, bus, named_service, object_path): -        self._bus          = bus +    INTROSPECT_STATE_DONT_INTROSPECT = 0 +    INTROSPECT_STATE_INTROSPECT_IN_PROGRESS = 1 +    INTROSPECT_STATE_INTROSPECT_DONE = 2 + +    #TODO: default introspect to False right now because it is not done yet +    #      make sure to default to True later +    def __init__(self, bus, named_service, object_path, introspect=False): +        self._bus           = bus          self._named_service = named_service -        self._object_path  = object_path +        self._object_path   = object_path +         +        #PendingCall object for Introspect call +        self._pending_introspect = None +        #queue of async calls waiting on the Introspect to return  +        self._pending_introspect_queue = [] +  +        if not introspect: +            self._introspect_state = self.INTROSPECT_STATE_DONT_INTROSPECT +        else: +            self._introspect_state = self.INTROSPECT_STATE_INTROSPECT_IN_PROGRESS +             +            (result, self._pending_introspect) = self._Introspect() +                  def connect_to_signal(self, signal_name, handler_function, dbus_interface=None):          self._bus.add_signal_receiver(handler_function, @@ -77,7 +112,28 @@ class ProxyObject:                                        named_service=self._named_service,                                        path=self._object_path) +    def _Introspect(self): +        message = dbus_bindings.MethodCall(self._object_path, 'org.freedesktop.DBus.Introspectable', 'Introspect') +        message.set_destination(self._named_service) +         +        result = self._bus.get_connection().send_with_reply_handlers(message, -1,  +                                                                                           self._introspect_reply_handler,  +                                                                                           self._introspect_error_handler) +        return result    +             +    def _introspect_reply_handler(self, data): +        self._introspect_state = self.INTROSPECT_STATE_INTROSPECT_DONE +         +        for call in self._pending_introspect_queue: +            (member, iface, args, keywords) = call +            call_object = self.ProxyMethodClass(self._bus.get_connection(), +                                                                       self._named_service, +                                                                       self._object_path, iface, member) +                                                                        +            call_object(args, keywords) +    def _introspect_error_handler(self, error): +        self._introspect_state = self.INTROSPECT_STATE_DONT_INTROSPECT      def __getattr__(self, member, **keywords):          if member == '__call__': @@ -86,12 +142,31 @@ class ProxyObject:              raise AttributeError(member)          else:              iface = None -            if (keywords.has_key('dbus_interface')): +            if keywords.has_key('dbus_interface'):                  iface = keywords['dbus_interface'] -            return self.ProxyMethodClass(self._bus.get_connection(), +            if self._introspect_state == self.INTROSPECT_STATE_INTROSPECT_IN_PROGRESS: +                reply_handler = None +                if keywords.has_key('reply_handler'): +                    reply_handler = keywords['reply_handler'] + +                error_handler = None +                if keywords.has_key('error_handler'): +                    error_handler = keywords['error_handler'] + +                if not reply_handler: +                    self._pending_introspect.block() +                else: +                    call = (memeber, iface, args, keywords) +                    self._pending_introspect_queue.append(call) +                     +                    ret = self.DeferedMethodClass() +                    return ret +                    +            ret = self.ProxyMethodClass(self._bus.get_connection(),                                  self._named_service,                                  self._object_path, iface, member) +            return ret      def __repr__(self):          return '<ProxyObject wrapping %s %s %s at %x>'%(  diff --git a/python/service.py b/python/service.py index edaef63f..bfe8fa5f 100644 --- a/python/service.py +++ b/python/service.py @@ -2,6 +2,8 @@  import dbus_bindings   import _dbus  from exceptions import UnknownMethodException +from decorators import method +from decorators import signal  class BusName:      """A base class for exporting your own Named Services across the Bus diff --git a/python/types.py b/python/types.py index 1a01d8e4..f3d348c6 100644 --- a/python/types.py +++ b/python/types.py @@ -16,3 +16,4 @@ String = dbus_bindings.String  Array = dbus_bindings.Array  Struct = dbus_bindings.Struct  Dictionary = dbus_bindings.Dictionary +Variant = dbus_bindings.Variant  | 
