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

Brian Sutherland brian at vanguardistas.net
Mon Nov 30 04:05:59 EST 2009


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.

> 
> Hanno
> _______________________________________________
> Zope-Dev maillist  -  Zope-Dev at zope.org
> https://mail.zope.org/mailman/listinfo/zope-dev
> **  No cross posts or HTML encoding!  **
> (Related lists - 
>  https://mail.zope.org/mailman/listinfo/zope-announce
>  https://mail.zope.org/mailman/listinfo/zope )

-- 
Brian Sutherland


More information about the Zope-Dev mailing list