[PEAK] Re: gf.when() doesn't honour Interfaces on instances (protocols.adviseObject)

Phillip J. Eby pje at telecommunity.com
Thu Dec 2 10:52:15 EST 2004

At 03:35 PM 12/2/04 +0100, Ulrich Eck wrote:
>it seems, the dispatch.when does some optimization that prevents it from
>being able to recognize that the PPObject implements the Interface
>needed to match the spec.
>am i doing something wrong?

Well, first off, your filters say "self is IPPStatePending", which should 
be "in", not "is".  Second, you can't use adviseObject() to add and remove 
interfaces like that, because PyProtocols wants to have a convergent 
interface state, and therefore never retracts interfaces in its default 
implementation.  If you need an object to change its interfaces on the fly 
you need to implement a custom __conform__ method and handle it internally 
to the object.

However, it would be simpler to define a 'state' attribute as part of a 
single workflow interface, and then dispatch on 'self.state==State1', 
'self.state==State2', and so on.

>is the behaviour intended?

It's a known issue with predicate-dispatch generic functions that they 
don't handle instance-specific adapters.  The problem is that to do it in 
an efficient manner, there really needs to be a way to ask the object for 
*all* the interfaces it knows it can adapt to, or at least to give it a 
list of interfaces that the generic function is looking for.

You can use an expression like 'IFoo(bar,None) is not None' to test that an 
instance adapts to a particular interface; you then have to adapt it again 
in your function body.  However, you will run into ambiguity problems if 
you have multiple interface targets for the function, because right now the 
dispatch machinery can't tell which adaptations imply each other.

So anyway, instance-specific adaptation is currently a big problem for 
predicate-dispatch generic functions; if you can't use a single-dispatch 
function, you may want to define an interface to which the parameter must 
first be adapted before even calling the generic function.

In your case, however, the more meaningful thing to do is to use a state 
attribute and dispatch on that.  Predicate functions can dispatch '==' 
tests with a single hash lookup, so it's even faster than any of the 
adaptation approaches for your example.

More information about the PEAK mailing list