[Zope-dev] improving the utility and adapter lookup APIs

Christian Theune ct at gocept.com
Thu Dec 3 01:44:54 EST 2009


On 11/30/2009 10:05 AM, Brian Sutherland wrote:
> On Wed, Nov 25, 2009 at 10:17:41PM +0100, Hanno Schlichting wrote:
>> On Wed, Nov 25, 2009 at 9:52 PM, Tres Seaver<tseaver at palladion.com>  wrote:
>>> Hmm, I may be missing something here, but if Foo implements IFoo, then
>>> the getAdapter lookup for it will short circuit, leading you into
>>> infinite recursion.  Except that it doesn't:
>>
>> [snip example]
>>
>>> which strikes me as wildly disjoint:  the IFoo behavior is "expected"
>>> (short-circuit the lookup if the object already provides the interface),
>>> while the getAdapter behavior is a puzzlement.
>>
>> This has been mentioned numerous times as one of those odd and
>> unexpected differences between the IFoo vs. get/queryAdapter semantic.
>> IIRC the only use-case I ever heard of for the getAdapter semantic,
>> was the possibility to override the behavior promised by the interface
>> with a different adapter without touching the class that implements
>> the interface directly.
>>
>> I think changing this falls into the category of: Small backwards
>> incompatibly that seem worthwhile to make the behavior consistent and
>> expected.
>
> I do agree that this behaviour is inconsistent with the common idea of
> adapters in the ZCA. So it doesn't have to be in the "main API" to the
> ZCA, i.e. the one people most heavily and frequently use.
>
> But, I'll argue that it should be still possible if you are willing to
> go outside the main API.
>
> My particular usecase is Location objects implementing IPublishTraverse
> without depending on the default traversal adapter:
>
>      class FakeContainerOfSomeKind(Location):
>
>          implements(IPublishTraverse)
>
>          def publishTraverse(self, request, name):
>              if name.isdigit() and do_i_contain(name):
>                  return get_the_object_i_contain(name)
>              # fallback to default traversal adapter without depending on it
>              traverser = getMultiAdapter((self, request), IPublishTraverse)
>              return traverser.publishTraverse(request, name)
>
> I wouldn't know how to implement the above code without either depending
> directly on the default traversal adapter or making an
> IDefaultPublishTraverse marker interface. Neither of those, in my
> opinion, is as elegant as the above.

That reminds me that I had the occasional wish to invoke the ZCA using 
some kind of chaining mechanism so that an adapter can ask for the next 
less specific adapter that would have been invoked if the former wasn't 
there. The use case is similar: delegate to a default.

Christian

-- 
Christian Theune · ct at gocept.com
gocept gmbh & co. kg · forsterstraße 29 · 06112 halle (saale) · germany
http://gocept.com · tel +49 345 1229889 0 · fax +49 345 1229889 1
Zope and Plone consulting and development



More information about the Zope-Dev mailing list