Interfaces, Errors, and Python bindings (oh my)
Seth Nickell
seth@gnome.org
25 Sep 2003 03:04:53 -0700
So the good news is the Python bindings now provide support for both
using and exporting services (and objects)... both taking only a few
lines of code. wheee! I'm interested in people's general feedback for
the API, which can be found on the dbus-object-names branch in
python/dbus.py. There are also simple examples of a client and a
service.
Its not clear to me when the appropriate point to ask for an "interface"
is. I think glib-dbus is doing this differently, but that changes from
day to day *grin*. For the Python API, a short snippet looks like:
bus = dbus.Bus()
remote_service = bus.get_service("org.designfu.SampleService")
remote_object = remote_service.get_object("/SomeObject",
"org.designfu.SampleInterface")
hello_reply = remote_object.HelloWorld("Hello from example-client.py!")
Notice that I'm asking people to provide an interface at the point that
they retrieve an object: you ask for an object resolved against a
particular interface. This seems reasonable if you think of interfaces
as being like Bonobo Interfaces. AFAICT, we have neither a dbus-wide
mechanism like IDL for defining interfaces (I think its good that we
don't have this), nor do we have a standard like OAF queries for saying
"fetch me an object implementing this interface".
1) I think intuitively what we are calling "interfaces" are mostly just
"namespaces for methods". If that is true, maybe we should be calling
them "method_namespace" rather than "interface"? Right now the apparent
similarity between service names and interface names, combined with the
role of interface names not being entirely obvious... makes it a
somewhat confusing API. Thinking of namespaces for method names seems
clearer, at least to me. you conceptually call
ObjectInstance."org.whatever.interface.Method"().
A long time ago, Havoc wrote:
> Diverging from DCOP a bit, I would like to suggest that paths are
> more tightly namespaced. something like:
>
> /com.trolltech/qt/foo
> or
> /org.abiword/foo
>
> or perhaps even:
>
> /com/trolltech/qt
2) Why? I was confused out of my mind by having three apparently similar
but actually entirely disconnected "namespaces". Also, I expect many
services to provide a single object. It would be nice to not have to
always look that up but expect it to be "/" (or in that case, maybe even
make the "/" optional and have the equivalent of functions... you just
directly call the service instead of worrying about objects and
methods).
3) Error handling... so the clean way this works is that people writing
Services in Python trap their own exceptions in methods they provide to
the DBus and then raise a dbus.Error. I trap the dbus.Error, and
generate an appropriate error reply. The big question is: What should
happen if they screw up and *don't* trap a particular exception?
Technically it is pretty simple for me to convert any-old Python
exception into some sort of DBus Error message, but they will have names
like "exceptions.KeyError": i.e. they would often be python specific
internal details. Maybe it is better to provide clients with shitty
error messages rather than none at all though?
-Seth