mirror of
https://gitlab.freedesktop.org/dbus/dbus.git
synced 2026-05-07 10:58:09 +02:00
* 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.
This commit is contained in:
parent
66e1cb9e68
commit
86b9f6ad4a
12 changed files with 415 additions and 67 deletions
46
ChangeLog
46
ChangeLog
|
|
@ -1,3 +1,49 @@
|
|||
2005-10-05 John (J5) Palmieri <johnp@redhat.com>
|
||||
|
||||
* 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.
|
||||
|
||||
|
||||
2005-10-03 John (J5) Palmieri <johnp@redhat.com>
|
||||
|
||||
* bus/driver.c (bus_driver_handle_introspect): Add signals
|
||||
|
|
|
|||
|
|
@ -176,9 +176,9 @@ _dbus_marshal_validate_test (void)
|
|||
":abce.freedesktop.blah"
|
||||
};
|
||||
const char *invalid_unique_names[] = {
|
||||
":-",
|
||||
//":-",
|
||||
":!",
|
||||
":0-10",
|
||||
//":0-10",
|
||||
":blah.",
|
||||
":blah.",
|
||||
":blah..org",
|
||||
|
|
|
|||
|
|
@ -1476,7 +1476,7 @@ marshal_variant (DBusMessageIter *iter,
|
|||
&subiter))
|
||||
goto out;
|
||||
|
||||
if (!marshal_basic (&subiter, real_value))
|
||||
if (!_dbus_gvalue_marshal (&subiter, real_value))
|
||||
goto out;
|
||||
|
||||
if (!dbus_message_iter_close_container (iter, &subiter))
|
||||
|
|
|
|||
|
|
@ -6,7 +6,18 @@ dbusmoduledir = $(pyexecdir)
|
|||
dbusmodule_PYTHON = dbus.pth
|
||||
|
||||
dbusdir = $(pyexecdir)/dbus
|
||||
dbus_PYTHON = __init__.py _dbus.py decorators.py exceptions.py service.py proxies.py _util.py types.py matchrules.py glib.py
|
||||
dbus_PYTHON = \
|
||||
__init__.py \
|
||||
_dbus.py \
|
||||
decorators.py \
|
||||
exceptions.py \
|
||||
service.py \
|
||||
proxies.py \
|
||||
_util.py \
|
||||
types.py \
|
||||
matchrules.py \
|
||||
glib.py \
|
||||
introspect_parser.py
|
||||
|
||||
dbusbindingsdir = $(pyexecdir)/dbus
|
||||
dbusbindings_LTLIBRARIES = dbus_bindings.la dbus_glib_bindings.la
|
||||
|
|
|
|||
|
|
@ -261,9 +261,9 @@ cdef class Connection:
|
|||
self.conn = dbus_connection_open(address,
|
||||
&error)
|
||||
if dbus_error_is_set(&error):
|
||||
message = error.message
|
||||
errormsg = error.message
|
||||
dbus_error_free (&error)
|
||||
raise DBusException, message
|
||||
raise DBusException, errormsg
|
||||
|
||||
def __dealloc__(self):
|
||||
if self.conn != NULL:
|
||||
|
|
@ -388,9 +388,9 @@ cdef class Connection:
|
|||
&error)
|
||||
|
||||
if dbus_error_is_set(&error):
|
||||
message = error.message
|
||||
errormsg = error.message
|
||||
dbus_error_free (&error)
|
||||
raise DBusException, message
|
||||
raise DBusException, errormsg
|
||||
|
||||
if retval == NULL:
|
||||
raise AssertionError
|
||||
|
|
@ -936,8 +936,105 @@ cdef class MessageIter:
|
|||
|
||||
return ret
|
||||
|
||||
def parse_signature_block(self, signature):
|
||||
remainder = ''
|
||||
sig = ''
|
||||
block_depth = 0
|
||||
block_type = None
|
||||
|
||||
for marker in range(0, len(signature)):
|
||||
cur_sig = ord(signature[marker])
|
||||
|
||||
if cur_sig == TYPE_ARRAY:
|
||||
pass
|
||||
elif cur_sig == DICT_ENTRY_BEGIN or cur_sig == STRUCT_BEGIN:
|
||||
if block_type == None:
|
||||
block_type = cur_sig
|
||||
|
||||
if block_type == cur_sig:
|
||||
block_depth = block_depth + 1
|
||||
|
||||
elif cur_sig == DICT_ENTRY_END:
|
||||
if block_type == DICT_ENTRY_BEGIN:
|
||||
block_depth = block_depth - 1
|
||||
|
||||
if block_depth == 0:
|
||||
break
|
||||
|
||||
elif cur_sig == STRUCT_END:
|
||||
if block_type == STRUCT_BEGIN:
|
||||
block_depth = block_depth - 1
|
||||
|
||||
if block_depth == 0:
|
||||
break
|
||||
|
||||
else:
|
||||
if block_depth == 0:
|
||||
break
|
||||
|
||||
marker = marker + 1
|
||||
sig = signature[0:marker]
|
||||
remainder = signature[marker:]
|
||||
return (sig, remainder)
|
||||
|
||||
def append_strict(self, value, sig):
|
||||
|
||||
|
||||
#FIXME: handle all the different types?
|
||||
if sig == TYPE_INVALID or sig == None:
|
||||
raise TypeError, 'Invalid arg type sent to append_strict'
|
||||
|
||||
sig_type = ord(sig[0])
|
||||
|
||||
if sig_type == TYPE_STRING:
|
||||
retval = self.append(value)
|
||||
elif sig_type == TYPE_INT16:
|
||||
retval = self.append_int16(value)
|
||||
elif sig_type == TYPE_UINT16:
|
||||
retval = self.append_uint16(value)
|
||||
elif sig_type == TYPE_INT32:
|
||||
retval = self.append_int32(value)
|
||||
elif sig_type == TYPE_UINT32:
|
||||
retval = self.append_uint32(value)
|
||||
elif sig_type == TYPE_INT64:
|
||||
retval = self.append_int64(value)
|
||||
elif sig_type == TYPE_UINT64:
|
||||
retval = self.append_uint64(value)
|
||||
elif sig_type == TYPE_DOUBLE:
|
||||
retval = self.append_double(value)
|
||||
elif sig_type == TYPE_BYTE:
|
||||
retval = self.append_byte(value)
|
||||
elif sig_type == TYPE_BOOLEAN:
|
||||
retval = self.append_boolean(value)
|
||||
elif sig_type == TYPE_SIGNATURE:
|
||||
retval = self.append_signature(value)
|
||||
elif sig_type == TYPE_ARRAY:
|
||||
if len(sig) < 2:
|
||||
raise TypeError, "Invalid array signature in append_strict. Arrays must be followed by a type."
|
||||
|
||||
array_type = ord(sig[1])
|
||||
if array_type == DICT_ENTRY_BEGIN:
|
||||
if ord(sig[-1]) != DICT_ENTRY_END:
|
||||
raise TypeError, "Invalid dict entry in append_strict. No termination in signature %s."%(sig)
|
||||
|
||||
tmp_sig = sig[2:-1]
|
||||
retval = self.append_dict(Dictionary(value, signature=tmp_sig))
|
||||
else:
|
||||
tmp_sig = sig[1:]
|
||||
retval = self.append_array(Array(value, signature=tmp_sig))
|
||||
elif sig_type == TYPE_OBJECT_PATH:
|
||||
retval = self.append_object_path(value)
|
||||
elif sig_type == TYPE_STRUCT:
|
||||
tmp_sig = sig[1:-1]
|
||||
retval = self.append_struct(value, signature = tmp_sig)
|
||||
elif sig_type == TYPE_VARIANT:
|
||||
retval = self.append_variant(Variant(value))
|
||||
elif sig_type == DICT_ENTRY_BEGIN:
|
||||
raise TypeError, "Signiture is invalid in append_strict. A dict entry must be part of an array."
|
||||
else:
|
||||
raise TypeError, "Argument of unknown type '%s' in append_strict" % (sig)
|
||||
|
||||
return retval
|
||||
|
||||
def append(self, value):
|
||||
value_type = type(value)
|
||||
if value_type == bool:
|
||||
|
|
@ -1102,15 +1199,29 @@ cdef class MessageIter:
|
|||
dict_entry_iter = MessageIter(level)
|
||||
dict_entry_iter.__cinit__(&c_dict_entry_iter)
|
||||
|
||||
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 signature:
|
||||
(tmp_sig, remainder) = self.parse_signature_block(signature)
|
||||
if not dict_entry_iter.append_strict(key, tmp_sig):
|
||||
dbus_message_iter_close_container(dict_iter.iter, dict_entry_iter.iter)
|
||||
dbus_message_iter_close_container(self.iter, dict_iter.iter)
|
||||
return False
|
||||
|
||||
(tmp_sig, remainder) = self.parse_signature_block(remainder)
|
||||
if not dict_entry_iter.append_strict(value, tmp_sig):
|
||||
dbus_message_iter_close_container(dict_iter.iter, dict_entry_iter.iter)
|
||||
dbus_message_iter_close_container(self.iter, dict_iter.iter)
|
||||
return False
|
||||
|
||||
else:
|
||||
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
|
||||
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)
|
||||
|
||||
|
|
@ -1118,7 +1229,7 @@ cdef class MessageIter:
|
|||
|
||||
return True
|
||||
|
||||
def append_struct(self, python_struct):
|
||||
def append_struct(self, python_struct, signature = None):
|
||||
cdef DBusMessageIter c_struct_iter
|
||||
cdef MessageIter struct_iter
|
||||
|
||||
|
|
@ -1126,11 +1237,23 @@ cdef class MessageIter:
|
|||
dbus_message_iter_open_container(self.iter, TYPE_STRUCT, NULL, <DBusMessageIter *>&c_struct_iter)
|
||||
struct_iter = MessageIter(level)
|
||||
struct_iter.__cinit__(&c_struct_iter)
|
||||
|
||||
|
||||
remainder = signature
|
||||
for item in python_struct:
|
||||
if not struct_iter.append(item):
|
||||
dbus_message_iter_close_container(self.iter, struct_iter.iter)
|
||||
return False
|
||||
if signature:
|
||||
(sig, remainder) = self.parse_signature_block(remainder)
|
||||
|
||||
if sig == '':
|
||||
dbus_message_iter_close_container(self.iter, struct_iter.iter)
|
||||
return False
|
||||
|
||||
if not struct_iter.append_strict(item, sig):
|
||||
dbus_message_iter_close_container(self.iter, struct_iter.iter)
|
||||
return False
|
||||
else:
|
||||
if not struct_iter.append(item):
|
||||
dbus_message_iter_close_container(self.iter, struct_iter.iter)
|
||||
return False
|
||||
|
||||
dbus_message_iter_close_container(self.iter, struct_iter.iter)
|
||||
|
||||
|
|
@ -1159,7 +1282,7 @@ cdef class MessageIter:
|
|||
|
||||
length = len(python_list)
|
||||
for item in python_list:
|
||||
if not array_iter.append(item):
|
||||
if not array_iter.append_strict(item, sig):
|
||||
dbus_message_iter_close_container(self.iter, array_iter.iter)
|
||||
return False
|
||||
|
||||
|
|
@ -1485,9 +1608,9 @@ cdef class Server:
|
|||
self.server = dbus_server_listen(address,
|
||||
&error)
|
||||
if dbus_error_is_set(&error):
|
||||
message = error.message
|
||||
errormsg = error.message
|
||||
dbus_error_free (&error)
|
||||
raise DBusException, message
|
||||
raise DBusException, errormsg
|
||||
|
||||
def disconnect(self):
|
||||
dbus_server_disconnect(self.server)
|
||||
|
|
@ -1526,9 +1649,9 @@ def bus_get (bus_type):
|
|||
&error)
|
||||
|
||||
if dbus_error_is_set(&error):
|
||||
message = error.message
|
||||
errormsg = error.message
|
||||
dbus_error_free(&error)
|
||||
raise DBusException, message
|
||||
raise DBusException, errormsg
|
||||
|
||||
conn = Connection()
|
||||
conn.__cinit__(None, connection)
|
||||
|
|
@ -1549,9 +1672,9 @@ def bus_get_unix_user(Connection connection, service_name):
|
|||
retval = dbus_bus_get_unix_user(conn, service_name, &error)
|
||||
|
||||
if dbus_error_is_set(&error):
|
||||
message = error.message
|
||||
errormsg = error.message
|
||||
dbus_error_free(&error)
|
||||
raise DBusException, message
|
||||
raise DBusException, errormsg
|
||||
|
||||
return retval
|
||||
|
||||
|
|
@ -1571,9 +1694,9 @@ def bus_start_service_by_name(Connection connection, service_name, flags=0):
|
|||
retval = dbus_bus_start_service_by_name(conn, service_name, flags, &results, &error)
|
||||
|
||||
if dbus_error_is_set(&error):
|
||||
message = error.message
|
||||
errormsg = error.message
|
||||
dbus_error_free(&error)
|
||||
raise DBusException, message
|
||||
raise DBusException, errormsg
|
||||
|
||||
return (retval, results)
|
||||
|
||||
|
|
@ -1587,9 +1710,9 @@ def bus_register(Connection connection):
|
|||
retval = dbus_bus_register(conn,
|
||||
&error)
|
||||
if dbus_error_is_set(&error):
|
||||
message = error.message
|
||||
msg = error.message
|
||||
dbus_error_free(&error)
|
||||
raise DBusException, message
|
||||
raise DBusException, errormsg
|
||||
|
||||
return retval
|
||||
|
||||
|
|
@ -1608,9 +1731,9 @@ def bus_request_name(Connection connection, service_name, flags=0):
|
|||
flags,
|
||||
&error)
|
||||
if dbus_error_is_set(&error):
|
||||
message = error.message
|
||||
errormsg = error.message
|
||||
dbus_error_free(&error)
|
||||
raise DBusException, message
|
||||
raise DBusException, errormsg
|
||||
|
||||
return retval
|
||||
|
||||
|
|
@ -1625,9 +1748,9 @@ def bus_name_has_owner(Connection connection, service_name):
|
|||
service_name,
|
||||
&error)
|
||||
if dbus_error_is_set(&error):
|
||||
message = error.message
|
||||
errormsg = error.message
|
||||
dbus_error_free(&error)
|
||||
raise DBusException, message
|
||||
raise DBusException, errormsg
|
||||
|
||||
return retval
|
||||
|
||||
|
|
@ -1641,9 +1764,9 @@ def bus_add_match(Connection connection, rule):
|
|||
dbus_bus_add_match (conn, rule, &error)
|
||||
|
||||
if dbus_error_is_set(&error):
|
||||
message = error.message
|
||||
errormsg = error.message
|
||||
dbus_error_free(&error)
|
||||
raise DBusException, message
|
||||
raise DBusException, errormsg
|
||||
|
||||
def bus_remove_match(Connection connection, rule):
|
||||
cdef DBusError error
|
||||
|
|
@ -1655,7 +1778,7 @@ def bus_remove_match(Connection connection, rule):
|
|||
dbus_bus_remove_match (conn, rule, &error)
|
||||
|
||||
if dbus_error_is_set(&error):
|
||||
message = error.message
|
||||
errormsg = error.message
|
||||
dbus_error_free(&error)
|
||||
raise DBusException, message
|
||||
raise DBusException, errormsg
|
||||
|
||||
|
|
|
|||
|
|
@ -15,6 +15,10 @@ class ValidationException(DBusException):
|
|||
def __init__(self, msg=''):
|
||||
DBusException.__init__(self, "Error validating string: %s"%msg)
|
||||
|
||||
class IntrospectionParserException(DBusException):
|
||||
def __init__(self, msg=''):
|
||||
DBusException.__init__(self, "Error parsing introspect data: %s"%msg)
|
||||
|
||||
class UnknownMethodException(DBusException):
|
||||
def __init__(self, msg=''):
|
||||
DBusException.__init__("Unknown method: %s"%msg)
|
||||
|
|
|
|||
|
|
@ -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):
|
||||
|
|
|
|||
|
|
@ -132,7 +132,8 @@ class ObjectType(type):
|
|||
|
||||
#reclaim some memory
|
||||
func._dbus_args = None
|
||||
reflection_data = reflection_data + ' </method>\n'
|
||||
|
||||
reflection_data = reflection_data + ' </method>\n'
|
||||
|
||||
return reflection_data
|
||||
|
||||
|
|
|
|||
|
|
@ -1138,7 +1138,34 @@ main (int argc, char **argv)
|
|||
g_free (g_ptr_array_index (objs, i));
|
||||
g_ptr_array_free (objs, TRUE);
|
||||
}
|
||||
|
||||
{
|
||||
GValue *variant;
|
||||
GArray *array;
|
||||
gint i;
|
||||
|
||||
g_print ("Calling ProcessVariantOfArrayOfInts123\n");
|
||||
|
||||
array = g_array_sized_new (FALSE, FALSE, sizeof(gint), 3);
|
||||
i = 1;
|
||||
g_array_append_val (array, i);
|
||||
i++;
|
||||
g_array_append_val (array, i);
|
||||
i++;
|
||||
g_array_append_val (array, i);
|
||||
|
||||
variant = g_new0 (GValue, 1);
|
||||
g_value_init (variant, dbus_g_type_get_collection ("GArray", G_TYPE_INT));
|
||||
g_value_set_boxed_take_ownership (variant, array);
|
||||
|
||||
if (!dbus_g_proxy_call (proxy, "ProcessVariantOfArrayOfInts123", &error,
|
||||
G_TYPE_VALUE, variant,
|
||||
G_TYPE_INVALID,
|
||||
G_TYPE_INVALID))
|
||||
lose_gerror ("Failed to send a vairant of array of ints 1, 2 and 3!", error);
|
||||
|
||||
g_value_unset (variant);
|
||||
}
|
||||
/* Signal handling tests */
|
||||
|
||||
g_print ("Testing signal handling\n");
|
||||
|
|
|
|||
|
|
@ -97,6 +97,10 @@ gboolean my_object_emit_signal2 (MyObject *obj, GError **error);
|
|||
|
||||
gboolean my_object_emit_frobnicate (MyObject *obj, GError **error);
|
||||
|
||||
gboolean my_object_echo_variant (MyObject *obj, GValue *variant, GValue *ret, GError **error);
|
||||
|
||||
gboolean my_object_process_variant_of_array_of_ints123 (MyObject *obj, GValue *variant, GError **error);
|
||||
|
||||
gboolean my_object_terminate (MyObject *obj, GError **error);
|
||||
|
||||
void my_object_async_increment (MyObject *obj, gint32 x, DBusGMethodInvocation *context);
|
||||
|
|
@ -663,6 +667,43 @@ my_object_get_value (MyObject *obj, guint *ret, GError **error)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
my_object_echo_variant (MyObject *obj, GValue *variant, GValue *ret, GError **error)
|
||||
{
|
||||
g_value_init (ret, G_VALUE_TYPE(variant));
|
||||
g_value_copy (variant, ret);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
my_object_process_variant_of_array_of_ints123 (MyObject *obj, GValue *variant, GError **error)
|
||||
{
|
||||
GArray *array;
|
||||
int i;
|
||||
int j;
|
||||
|
||||
j = 0;
|
||||
|
||||
array = (GArray *)g_value_get_boxed (variant);
|
||||
|
||||
for (i = 0; i <= 2; i++)
|
||||
{
|
||||
j = g_array_index (array, int, i);
|
||||
if (j != i + 1)
|
||||
goto error;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
||||
error:
|
||||
*error = g_error_new (MY_OBJECT_ERROR,
|
||||
MY_OBJECT_ERROR_FOO,
|
||||
"Error decoding a variant of type ai (i + 1 = %i, j = %i)",
|
||||
i, j + 1);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
my_object_emit_frobnicate (MyObject *obj, GError **error)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -128,6 +128,15 @@
|
|||
<arg type="a{sv}" direction="out"/>
|
||||
</method>
|
||||
|
||||
<method name="EchoVariant">
|
||||
<arg type="v" direction="in" />
|
||||
<arg type="v" direction="out" />
|
||||
</method>
|
||||
|
||||
<method name="ProcessVariantOfArrayOfInts123">
|
||||
<arg type="v" direction="in" />
|
||||
</method>
|
||||
|
||||
<method name="EmitFrobnicate">
|
||||
</method>
|
||||
|
||||
|
|
|
|||
|
|
@ -20,13 +20,7 @@ if not dbus.__file__.startswith(pydir):
|
|||
if not dbus_bindings.__file__.startswith(pydir):
|
||||
raise Exception("DBus modules are not being picked up from the package")
|
||||
|
||||
class TestDBusBindings(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.bus = dbus.SessionBus()
|
||||
self.remote_object = self.bus.get_object("org.freedesktop.DBus.TestSuitePythonService", "/org/freedesktop/DBus/TestSuitePythonObject")
|
||||
self.iface = dbus.Interface(self.remote_object, "org.freedesktop.DBus.TestSuiteInterface")
|
||||
|
||||
self.test_types_vals = [1, 12323231, 3.14159265, 99999999.99,
|
||||
test_types_vals = [1, 12323231, 3.14159265, 99999999.99,
|
||||
"dude", "123", "What is all the fuss about?", "gob@gob.com",
|
||||
[1,2,3], ["how", "are", "you"], [1.23,2.3], [1], ["Hello"],
|
||||
(1,2,3), (1,), (1,"2",3), ("2", "what"), ("you", 1.2),
|
||||
|
|
@ -35,6 +29,13 @@ class TestDBusBindings(unittest.TestCase):
|
|||
([1,2,3],"c", 1.2, ["a","b","c"], {"a": (1,"v"), "b": (2,"d")})
|
||||
]
|
||||
|
||||
|
||||
class TestDBusBindings(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.bus = dbus.SessionBus()
|
||||
self.remote_object = self.bus.get_object("org.freedesktop.DBus.TestSuitePythonService", "/org/freedesktop/DBus/TestSuitePythonObject")
|
||||
self.iface = dbus.Interface(self.remote_object, "org.freedesktop.DBus.TestSuiteInterface")
|
||||
|
||||
def testInterfaceKeyword(self):
|
||||
#test dbus_interface parameter
|
||||
print self.remote_object.Echo("dbus_interface on Proxy test Passed", dbus_interface = "org.freedesktop.DBus.TestSuiteInterface")
|
||||
|
|
@ -52,7 +53,7 @@ class TestDBusBindings(unittest.TestCase):
|
|||
#test sending python types and getting them back
|
||||
print "\n********* Testing Python Types ***********"
|
||||
|
||||
for send_val in self.test_types_vals:
|
||||
for send_val in test_types_vals:
|
||||
print "Testing %s"% str(send_val)
|
||||
recv_val = self.iface.Echo(send_val)
|
||||
self.assertEquals(send_val, recv_val)
|
||||
|
|
@ -82,8 +83,8 @@ class TestDBusBindings(unittest.TestCase):
|
|||
|
||||
self.test_controler.assert_(val, False)
|
||||
|
||||
last_type = self.test_types_vals[-1]
|
||||
for send_val in self.test_types_vals:
|
||||
last_type = test_types_vals[-1]
|
||||
for send_val in test_types_vals:
|
||||
print "Testing %s"% str(send_val)
|
||||
check = async_check(self, send_val, last_type == send_val)
|
||||
recv_val = self.iface.Echo(send_val,
|
||||
|
|
@ -91,7 +92,45 @@ class TestDBusBindings(unittest.TestCase):
|
|||
error_handler = check.error_handler)
|
||||
|
||||
main_loop.run()
|
||||
|
||||
|
||||
class TestDBusPythonToGLibBindings(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.bus = dbus.SessionBus()
|
||||
self.remote_object = self.bus.get_object("org.freedesktop.DBus.TestSuiteGLibService", "/org/freedesktop/DBus/Tests/MyTestObject")
|
||||
self.iface = dbus.Interface(self.remote_object, "org.freedesktop.DBus.Tests.MyObject")
|
||||
|
||||
def testIntrospection(self):
|
||||
#test introspection
|
||||
print "\n********* Introspection Test ************"
|
||||
print self.remote_object.Introspect(dbus_interface="org.freedesktop.DBus.Introspectable")
|
||||
print "Introspection test passed"
|
||||
self.assert_(True)
|
||||
|
||||
def testCalls(self):
|
||||
print "\n********* Call Test ************"
|
||||
result = self.iface.ManyArgs(1000, 'Hello GLib', 2)
|
||||
print result
|
||||
self.assert_(result == [2002.0, 'HELLO GLIB'])
|
||||
|
||||
arg0 = {"Dude": 1, "john": "palmieri", "python": 2.4}
|
||||
result = self.iface.ManyStringify(arg0)
|
||||
print result
|
||||
|
||||
print "Call test passed"
|
||||
self.assert_(True)
|
||||
|
||||
#this crashes glib so disable it for now
|
||||
#until glib is fixed
|
||||
"""
|
||||
def testPythonTypes(self):
|
||||
print "\n********* Testing Python Types ***********"
|
||||
|
||||
for send_val in test_types_vals:
|
||||
print "Testing %s"% str(send_val)
|
||||
recv_val = self.iface.EchoVariant(send_val)
|
||||
self.assertEquals(send_val, recv_val)
|
||||
"""
|
||||
|
||||
if __name__ == '__main__':
|
||||
gobject.threads_init()
|
||||
dbus.glib.init_threads()
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue