Cleaning up the Python D-Bus Bindings
John (J5) Palmieri
johnp at redhat.com
Tue Apr 5 15:16:17 PDT 2005
The time has come to clean up the Python D-Bus bindings. Ray Strode and
I sat down today and discussed where we would like to see the bindings
go. Right now they are starting grow some bit rot having been one of the
first useful bindings to come out for D-Bus. Some of the things
discussed was starting from the premise of creating simple clean
bindings that fit into the Python way of doing things. This means
stripping away a lot of the low level D-Bus API-isms and concentrating
on the higher level interface being easy and intuitive to use for the
core functionality of D-Bus which is creating and using IPC services.
Where low level functionality is needed we will need to find a way to
fit it into the higher level API.
What does this mean for the end user? The API is changing and I won’t
hesitate to break backwards compatibility. Hopefully the API will be
changing for the better and this will be the final API for 1.0. Below is
a rough outline of what I want to implement and how the API’s will be
changing. Any constructive input would be greatly appreciated.
* Introspection
* Invoking Methods (reading introspection data from a
service)
* Use introspection data to construct proxy
objects on object creation (i.e.
RemoteService.get_object())
* use parameter signatures to marshal
objects
* do not block for introspection data
* When blocking methods are called, block
until introspection data is received
then call blocking method
* Async methods are queued and called when
introspection completes
* On failure to obtain introspection data
(timeout, object does not support
org.freedesktop.DBus.Introspectable,
etc.) pending methods are executed using
the old way
* Exporting Introspection Data
* every registered object gains the
org.freedesktop.DBus.Introspectable interface
* use inspect.getargspec() on list of exported
methods to get the parameter count
* all parameters will be exported as
varients
* Should we provide a way to add
hints so that we can do type
checking or make it easier to
use from C? My gut says no but
perhaps add this if some sort of
static type checking enters
python.
* proposed standard annotation to the introspection format
* org.freedesktop.DBus.Doc for document strings.
It is easy enough for us to get from Python
(method.__doc__) and allows users of the python
bindings to call __doc__ on a proxy object’s
methods and get documentation
* registering signals
* Signals should be registered with dbus.Object so
that they can be exported in the introspection
data.
* Parameter format needs to be passed when
registering
* Method calls
* methods are called with their arguments listed first and
may contain a number of optional keywords
* method(arg1, arg2, ..., callback=None,
error_callback=None, interface=None)
* callback keyword
* when set to None method is
blocking
* catch errors using
try/except blocks
* when set to a python function or
method callback is called when
the pending call returns
* callback signature
depend on the number of
arguments sent in the
return method.
* there are no
extra parameters
sent into a
callback.
* to construct a
callback that
has a variable
number of return
values use the
*args construct
(in general you
should not use
this too much)
* error_callback keyword
* callback signature is def
error_cb(exception): where
exception is a python exception
generated from the D-Bus error
* for async calls if this is set
to a function or method it will
be called on any D-Bus error
* For blocking calls this will
throw an error if set
* interface keyword
* using this one can override the
default interface and call a
method on another interface
* Signals
* Signal callbacks will be dropping the Sender object
* sender just exposes API details like the message
and signal name
* signal callbacks will look exactly like async method
callbacks
* do we need an signal_error callback also?
* Interfaces
* objects initialized with an interface will consider that
interface the default interface
* object =
service.get_object("/org/designfu/SomeObject",
"org.designfu.SampleInterface")
* org.designfu.SampleInterface becomes the
default interface
* methods can override the default interface
* object.Introspect(interface=”org.freedesktop.DBus.Introspectable”)
* the Interface wrapper object acts just like an object
but casts the wrapped object to another interface for
all methods
* introspect_interface = Interface(object,
“org.freedesktop.DBus.Introspectable”)
* introspect_interface.Introspect()
* when constructing the proxy object methods are all name
spaced in a dictionary by their interface from the
introspected data
* proxy_dict =
{“org.freedesktop.DBus.Introspectable.Introspect”, self.__generated_bindings_introspect, “org.designfu.SampleServiceInterface.HelloWorld”, self.HelloWorld}
* What is going to go
* Messages, PendingCalls, Iters, etc. will no
longer be exposed to the user (or at least moved
into the low level bindings with warning that
anyone using them will be flamed)
* Nomenclature (such as service) will change to
reflect the current naming in the D-Bus spec
* The low level bindings will be stripped of
methods not used by the higher level bindings.
Let me know what you think.
--
John (J5) Palmieri
Associate Software Engineer
Desktop Group
Red Hat, Inc.
Blog: http://martianrock.com
More information about the dbus
mailing list