[PEAK] dispatch.add_assignment_advisor

Phillip J. Eby pje at telecommunity.com
Fri Dec 3 15:35:04 EST 2004

At 09:19 PM 12/3/04 +0100, Thomas Heller wrote:
>[Repost - the first one is still in the list-admin's queue because I
>wasn't subscribed, sorry for that]
>Only for fun, I'm experimenting with dispatch.add_assignment_advisor and
>sick decorators.

They don't look sick to me, they look quite healthy and useful, although I 
personally prefer to put them in [] so that they're more visibly magical.  :)

>The cool thing is that it also works with Python 2.3, and that it also
>is able to decorate classes (much more convenient than metaclasses,
>especially for multiple inheritence, where very soon metaclass conficts
>Unfortunately, the experiment didn't go as smooth as I first expected.
>Consider this code (cominterface and commethod are 'decorators' which
>call add_assignment_advisor (the correct term would probably be 'which
>add an assignment advisor):
>cominterface(uuid = "{00000000-0000-0000-C000-000000000046}")
>class IUnknown(object):
>     commethod(index=1,
>               restype = HRESULT,
>               argtypes = [POINTER(GUID), POINTER(c_void_p)])
>     def QueryInterface(self, interface):
>         "Query for another interface"
>     commethod(index=2, restype=c_long)
>     def AddRef(self):
>         "Increase the reference count"
>     commethod(index=1, restype=c_long)
>     def Release(self):
>         "Decrease the reference count"
>The problem is that the IUnknown methods are created first, and the
>commethod decorator is called.
>After that, the IUnknown type itself is created, and I expected that the
>cominterface decorator would be called - but it isn't.

I would have expected that too, but I haven't really tested assignment 
advisors with classes, because we already had class advisors for that.

>Any idea how to make this work as expected?

Use 'protocols.advice.addClassAdvisor' instead, and move the 'cominterface' 
call inside the class body.  Note, however, that addClassAdvisor has a 
different callback signature; the callback accepts one argument (the 
incoming class) and must return the desired output class.

More information about the PEAK mailing list