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 /python/proxies.py | |
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
Diffstat (limited to 'python/proxies.py')
-rw-r--r-- | python/proxies.py | 97 |
1 files changed, 86 insertions, 11 deletions
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>'%( |