dbus-python-in-C initial implementation available

Simon McVittie simon.mcvittie at collabora.co.uk
Wed Sep 27 07:54:17 PDT 2006

I've pushed the C reimplementation of dbus-python into the git repo at
<http://people.freedesktop.org/~smcv/git/dbus-python/.git/>. All
comments welcome!

In particular: J5, would you be happy to release this or something based
on it as dbus-python 0.8?

API docs in <http://people.freedesktop.org/~smcv/temp/dbus-python.epydoc/>
as before.

API changes in dbus-python-in-c

* Byte is a subtype of str rather than of int, which better matches
  Python's conventions for dealing with byte streams. Its constructor
  accepts either single-byte strings or integers in the range 0 to 255.
  It overrides __int__, but unfortunately int() special-cases strings,
  so int(Byte(1)) raises ValueError and int(Byte('1')) gives 1 rather
  than the expected ord('1').

* In method parameters, method returns from proxy methods, etc.,
  integers arrive as instances of dbus.Int32 etc., bytes arrive as
  Byte, and so on, rather than everything being converted to an
  appropriate built-in Python type. This means you can tell exactly
  what arguments went over the bus, and their types.

* Variants arrive as method parameters, returns from proxy methods, etc.
  as Variant objects. This is a bit of a big change, but makes things
  completely unambiguous. To unwrap variants like the old Pyrex
  implementation did, you can write::

      while isinstance(myparam, dbus.Variant):
          myparam = myparam.object

  This should also work (and do nothing) under the Pyrex implementation.

* The D-Bus integer types (dbus.Int32, etc.) are properly range-checked.

* Variants are now immutable "value objects".

* Variants are somewhat more useful: they can be cast using int(),
  str(), long(), float(), you can iterate over them with iter() if they
  contain an iterable, you can compare them with ``==`` and ``!=``,
  and you can hash them if the underlying object supports it.

* Array constructor takes arguments (iterable[, signature])
  rather than (iterable[, type][, signature]); ditto Variant, Dict

* Proxy methods with multiple return values return a tuple rather than
  a list.

* Calling a proxy method with reply ignored, or with async
  handlers, returns None

* The Boolean, String, Double and Struct types are now aliases for the
  built-in bool, unicode, float and tuple types. Their use is vaguely

* ConnectionError no longer exists (it was never raised)

* dbus_bindings is now called _dbus_bindings, and is considerably
  different internally:

  * connections are private at the libdbus level: shared connections
    are only shared among Python code

  * The MessageIter stuff is now done in C: there's a much simpler
    Python API, ``Message.append(...)`` where positional arguments are
    the things to be appended, and the keyword argument ``signature``
    controls how objects are interpreted

  * The signature-guessing algorithm used if there is no proper
    signature is exposed as a static method,

  * Bus is a subclass of Connection rather than being a wrapper object
    which has-a Connection

  * Some relatively internal methods have been renamed starting with
    an underscore - most Python code shouldn't need to use them, and
    they expose the full complexity of Messages etc.

  * The timeouts in _send_with_reply and in _send_with_reply_and_block
    are in (possibly fractional) seconds, as is conventional in Python

  * The specialized Message subclasses have names ending with Message


I've tried to work out who wrote what from the CVS and git history, and
put proper copyright notices on things, after noticing that my C code
had the first copyright notices in the whole source tree!

Did Seth Nickell write dbus-python independently, or is it owned by an

J5, I assume your bits of it are owned by Red Hat?

Still to be done

* Address some of the points raised previously regarding the
  high-level API:

  * Exporting an object as an entire subtree

  * Proxy[INTERFACE].Method() as seen in Telepathy

  * Replace the magic that happens when you import dbus.glib with something
    more explicit (probably in a module called dbus.gobject, deprecating

  * Provide a dbus.gobject.Object which is a subclass of
    dbus.service.Object and GObject, i.e. whose metaclass subclasses their
    metaclasses, to make it easy to export objects from pygtk apps

  * Make non-glib mainloops work (preferably Twisted-compatibly)

  * Migrate dbus.service to dbus.export or something, which is
    incidentally a great time to make backwards-incompatible changes,

  * Change dbus.export.Object to take a Connection rather than a BusName
    as constructor parameter - this removes the requirement that every
    app that exports any object has a well-known name

  * Perhaps stop using the _block() libdbus functions in favour of
    recursively entering the main loop (which means filters and
    callbacks run as expected, and apps calling each other's methods
    synchronously stop deadlocking)

* Port existing dbus-python uses (Avahi, HAL, Telepathy, smart-notifier,
  service-discovery-applet, gnome-osd, listen are the ones I'm aware of)
  to the new API

* Run cross-tests against Java (I need to find a working i386 first, though)


More information about the dbus mailing list