summaryrefslogtreecommitdiffstats
path: root/python/proxies.py
diff options
context:
space:
mode:
authorJohn (J5) Palmieri <johnp@redhat.com>2005-10-05 20:43:46 +0000
committerJohn (J5) Palmieri <johnp@redhat.com>2005-10-05 20:43:46 +0000
commit86b9f6ad4a6f466e24b5e4c1c320029041c50e3b (patch)
tree83aeb914e341f5e5b29b9a2ba3382caac251d26b /python/proxies.py
parent66e1cb9e68ba37980f7a90c396950be1587cdcd7 (diff)
* glib/dbus-gvalue.c (marshal_variant): call _dbus_gvalue_marshal
instead of marshal basic so we can handle recursive types in a variant * test/glib/test-dbus-glib.c: Add test for marshaling recurive types in variants * test/glib/test-service-glib.c, test-service-glib.xml (my_object_echo_variant [EchoVariant], my_object_process_variant_of_array_of_ints123 [ProcessVariantOfArrayOfInts123]): Add two test methods * python/introspect_parser.py: New module for parsing introspect data. * python/dbus_bindings.pyx: (various places): when throwing errors fix to use errormsg instead of message local variable because Pyrex can get confused with other message variables (initial patch by Robert McQueen <robert.mcqueen at collabora.co.uk>) (MessageIter::parse_signature_block): new method for getting the next block in a signiture. (MessageIter::append_strict): new method for appending values strictly using the passed in signature instead of guessing at the type (MessageItter:: append_dict, append_struct, append_array): use signatures to marshal children if the signature is available * python/exceptions.py (IntrospectionParserException): new exception * python/proxies.py (ProxyMethod::__call__): Marshal args with introspected signatures if available, else we fall back to the old way of doing things. (ProxyObject::_introspect_reply_handler ): parse introspection data * python/service.py (ObjectType::_reflect_on_method): Properly terminate <method> if there are no args in the reflection data * test/python/test-client.py: add tests for talking with the GLib test server. This gives us better coverage for introspection since python to python will always generate arguments as variants. It also allows us to test the robustness of the GLib bindings and interlanguage communications.
Diffstat (limited to 'python/proxies.py')
-rw-r--r--python/proxies.py75
1 files changed, 61 insertions, 14 deletions
diff --git a/python/proxies.py b/python/proxies.py
index f41a8de1..ee2a3f7e 100644
--- a/python/proxies.py
+++ b/python/proxies.py
@@ -1,5 +1,7 @@
import dbus_bindings
-from exceptions import MissingReplyHandlerException, MissingErrorHandlerException
+import introspect_parser
+import sys
+from exceptions import MissingReplyHandlerException, MissingErrorHandlerException, IntrospectionParserException
class DeferedMethod:
"""A DeferedMethod
@@ -19,12 +21,13 @@ class ProxyMethod:
method produce messages that travel over the Bus and are routed
to a specific named Service.
"""
- def __init__(self, connection, named_service, object_path, dbus_interface, method_name):
+ def __init__(self, connection, named_service, object_path, dbus_interface, method_name, introspect_sig):
self._connection = connection
self._named_service = named_service
self._object_path = object_path
self._method_name = method_name
self._dbus_interface = dbus_interface
+ self._introspect_sig = introspect_sig
def __call__(self, *args, **keywords):
dbus_interface = self._dbus_interface
@@ -54,8 +57,14 @@ class ProxyMethod:
# Add the arguments to the function
iter = message.get_iter(True)
+
+ remainder = self._introspect_sig
for arg in args:
- iter.append(arg)
+ if self._introspect_sig:
+ (sig, remainder) = iter.parse_signature_block(remainder)
+ iter.append_strict(arg, sig)
+ else:
+ iter.append(arg)
if reply_handler:
result = self._connection.send_with_reply_handlers(message, timeout, reply_handler, error_handler)
@@ -87,16 +96,18 @@ class ProxyObject:
#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):
+ def __init__(self, bus, named_service, object_path, introspect=True):
self._bus = bus
self._named_service = named_service
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 = []
-
+ #dictionary mapping method names to their input signatures
+ self._introspect_method_map = {}
+
if not introspect:
self._introspect_state = self.INTROSPECT_STATE_DONT_INTROSPECT
else:
@@ -118,23 +129,47 @@ class ProxyObject:
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)
+ self._introspect_reply_handler,
+ self._introspect_error_handler)
return result
-
+
+
+
+
def _introspect_reply_handler(self, data):
- self._introspect_state = self.INTROSPECT_STATE_INTROSPECT_DONE
+ try:
+ self._introspect_method_map = introspect_parser.process_introspection_data(data)
+ except IntrospectionParserException, e:
+ self._introspect_error_handler(e)
+ return
+ self._introspect_state = self.INTROSPECT_STATE_INTROSPECT_DONE
+
+ #TODO: we should actually call these even if introspection fails
for call in self._pending_introspect_queue:
(member, iface, args, keywords) = call
+
+ introspect_sig = None
+
+ tmp_iface = ''
+ if iface:
+ tmp_iface = iface + '.'
+
+ key = tmp_iface + '.' + member
+ if self._introspect_method_map.has_key (key):
+ introspect_sig = self._introspect_method_map[key]
+
+
call_object = self.ProxyMethodClass(self._bus.get_connection(),
- self._named_service,
- self._object_path, iface, member)
+ self._named_service,
+ self._object_path, iface, member,
+ introspect_sig)
call_object(args, keywords)
def _introspect_error_handler(self, error):
self._introspect_state = self.INTROSPECT_STATE_DONT_INTROSPECT
+ sys.stderr.write(str(error))
def __getattr__(self, member, **keywords):
if member == '__call__':
@@ -142,6 +177,8 @@ class ProxyObject:
elif member.startswith('__') and member.endswith('__'):
raise AttributeError(member)
else:
+ introspect_sig = None
+
iface = None
if keywords.has_key('dbus_interface'):
iface = keywords['dbus_interface']
@@ -163,10 +200,20 @@ class ProxyObject:
ret = self.DeferedMethodClass()
return ret
-
+
+ if self._introspect_state == self.INTROSPECT_STATE_INTROSPECT_DONE:
+ tmp_iface = ''
+ if iface:
+ tmp_iface = iface + '.'
+
+ key = tmp_iface + member
+ if self._introspect_method_map.has_key (key):
+ introspect_sig = self._introspect_method_map[key]
+
ret = self.ProxyMethodClass(self._bus.get_connection(),
self._named_service,
- self._object_path, iface, member)
+ self._object_path, iface, member,
+ introspect_sig)
return ret
def __repr__(self):