dbus-python issues (was: D-Bus is killing me)

Simon McVittie simon.mcvittie at collabora.co.uk
Sun Dec 17 13:38:36 PST 2006


On Sun, 17 Dec 2006 at 17:26:02 +0000, Mystilleef wrote:
> 1). Doesn't like Python 2.5 and I don't know why.

The current version of dbus-python is, as you say, idiosyncratic. I've
rewritten most of it and will hopefully release version 0.80 soon -
0.80 release candidate 2 was previously announced on this list, and
seems to work.

> Exception exceptions.AttributeError: "'exceptions.TypeError' object
> has no attribute '__module__'" in
> 'dbus_bindings._GIL_safe_cmessage_function_handler' ignored

You're right, that's obscure. I believe this is an incompatibility
between Python 2.5 and (the code generated by) Pyrex, a preprocessor used
to write dbus-python. The upcoming version 0.80 doesn't use Pyrex, which
should make many issues go away.

I believe this issue has been reported on this list before. I'd argue that
removing the __module__ attribute is backwards compatibility breakage in
Python 2.5 and should probably be fixed there...

> The entertaining thing about D-Bus's error messages is that you never
> whether the problem stems from D-Bus or the application using it.

If it looks like

    DBusException: TypeError: blah blah blah

(i.e. a DBusException for which the message is some other exception)
then it's an exception at the other end being passed back to you. I
agree this could be made substantially clearer; perhaps DBusException
should get a subclass RemoteException or something for this purpose.

> My application won't run as root because of D-Bus. I get this cryptic
> error message everytime I attempt to run it as root:
...
> dbus_bindings.DBusException: Did not receive a reply. Possible causes
> include: the remote application did not send a reply, the message bus
                                                        ^^^^^^^^^^^^^^^
> security policy blocked the reply, the reply timeout expired, or the
  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> network connection was broken.

If dbus-python doesn't receive any reply at all, there is no way for it to
distinguish between any of these possible causes of not receiving a
reply, which is why the message has to be so vague... in this case, the
message-bus security policy in question is "only the same user whose bus
it is can receive messages".

> 3). D-Bus Isn't re-entrant.

D-Bus is (or can be) re-entrant, but there is a common situation in which
libdbus and dbus-python behave in a non-re-entrant way. The short version is,
if you want re-entrancy, make your calls asynchronous: that is, instead of

	try:
		foo, bar = proxy.DoStuff(1, 2, 3)
	except Exception, e:
		print "failed to do stuff: %s" % e

use:

	def on_reply(foo, bar):
		"""do something with foo and bar"""
	def on_error(e):
		print "failed to do stuff: %s" % e
	proxy.DoStuff(1, 2, 3, reply_handler=on_reply, error_handler=on_error)

The long version is that there are two ways we could implement
blocking calls. The first, which is currently used (and matches the
behaviour of libdbus), is to bypass the main loop and just queue
up incoming messages until the reply arrives. If the service tries to
call a method on the client before it'll return a reply, you have a
deadlock, which I understand is what you're complaining about?

The second possibility is to re-enter the main loop recursively - that
would make it re-entrant, but at the cost of causing potentially
startling behaviour (if you call a blocking method, you might not be
expecting callbacks for D-Bus signals and asynchronous method-call replies
to be called while you're still blocking on that method!)

Also, the interaction with threads could be ... interesting (if you block
on a method in one thread while the main loop runs in another, currently it'd
work; but if blocking methods in a thread invoked the main loop in that
thread, I expect pain to ensue).

Regards,
	Simon


More information about the dbus mailing list