Another thing I really like about python is the fact that the Gnome community has a wealth of brain power on the subject. I got a lot of good feedback from James and Johan and have been able to whip up a test case to brainstorm on how I am going to implement the methods and signal piece of the bindings. If anyone has any comments on ways I could do this stuff better please chime in. Here is the prototype:

class meta(type):
    def __init__(cls, name, bases, dct):
        print 'Init is called: ' + str(cls) + str(name) + str(bases) + str(dct)

        method_list = []
        for func in dct.values():
	    try:
	        method_name = func._dbus_method_name()
	        method_list.append(method_name)
            except:
                pass 

	print method_list
        super(meta, cls).__init__(name, bases, dct)

def method(func):
    def decorator(self, *args):
        func(self, *args)

    def _dbus_method_name():
        return func.__name__

    decorator._dbus_method_name = _dbus_method_name
    return decorator

class bar:
    __metaclass__ = meta

    @method
    def my_method(self):
       print 'my_method'

x = bar()
x.my_method()

Ok so my main concerns is using the try/except block at top. While this works, is it cleaner to check for the _dbus_method_name member or is relying on the exception acceptibly pythonic? I could also just make it a property of the decorator object thereby avoiding the method call.

Perhaps I should explain what we are looking at here. I have created a method decorator that is used to tag methods as being exported. In that decorator I add a method that I can call on later to make a list of exported methods. At the top is a metaclass whoes purpose is to check all the decorators in classes that inherit from this metaclass. Upon the class bar being realized and its __metaclass__ being set to meta, the metaclass’ __init__ method gets called (__new__ gets called first but I don’t use it here). bar’s member dictionarty gets passed to init which we iterate over the values of. Upon finding an object with the member _dbus_method_name we add that to the list of exported methods. If this were the real bindings we would then attach this this as an attribute of the class which would then be used to bind the methods on the bus when the class is instantiated. The advantage here is that we don’t need to introspect every time an object is created but only when the class is first realized.

In the actual bindings I will be putting together a hash that points the interface and method objects so that we can have methods that overide each other. The code will also construct the dbus xml introspection format so that we can support the Introspectable interface. All of this will be hiddent to the user with the exception of having to use the @dbus.method and @dbus.signal decorators. It really is a nice solution.

As far as the backend structure goes I will be creating a dbus.MetaObject class which dbus.Object will use as its metaclass. The dbus.Object itself will use the decorators to implement DBus’ standard interfaces. Inheritting from dbus.Object will work almost the same way it does now except that one would use the decorators instead of the list in the constructor to export methods. I’m still debating if I should create class decorators for specifying classpaths or just leave it as is where we pass them into the constructor of dbus.Object. I don’t want to go overboard and make everything into a decorator even if I think they are pretty cool.

[read this post in: ar de es fr it ja ko pt ru zh-CN ]