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