Tres Seaver wrote: > -----BEGIN PGP SIGNED MESSAGE----- > Hash: SHA1 > > Martin Aspeli wrote: > >> There's currently a funny inconsistency in Zope's Traversable class. If >> you have a URL like http://localhost:8080/path/to/@@aview/foo, and >> @@aview implements IPublishTraverse (and, I presume, if there's a custom >> IPublishTraverse adapter for any other path component), URL traversal >> will work fine, but calling to.restrictedTraverse('@@aview/foo') or some >> variant thereof will fail, because (un)restrictedTraverse() does not >> respect custom IPublishTraverse adapters. > > 'restrictedTraverse' is not (and never has been) the same as URL > traversal. For instance: > > - - URL traversal does no security checking until it finds the published > object. > > - - URL traveresal manages the '__before_publishing_traverse__' hooks. > > > If you want your adapter to be respected by *both*, it needs to > implement the appropriate interfaces for both. > >> I can kind of see why it's done like this since it's called >> I*Publish*Traverse, but it is a pain. >> >> Note that namespace traversal (like ++skin++) works fine with >> restrictedTraverse(). >> >> I don't think it'd be hard to implement this, but: >> >> - is this a bug? > > No. > >> - is there a reason not to do this? > > - -1 to adding any more majyk to the over-complicated Z3-style traversal > dance inside Zope2, especially as it would involve a bunch of subtle > behavior changes which would be hard to explain. > > For maximum portability across Z2 / Z3 / BFG, you could just do the same > thing and implement __getitem__ on any object you want to be traversable > by either the publisher or APIs like (un)restrictedTraverse, and forego > the over-complicated component-laden traversal dance. ;)
Minimal example demonstrating this with a view in zope2: >>> from zope.component import getSiteManager >>> from Testing.makerequest import makerequest >>> from zope.publisher.browser import IBrowserView >>> from Acquisition import Explicit >>> from zope.component import getSiteManager >>> app = makerequest(app) >>> smgr = getSiteManager() >>> class Foo(Explicit): ... def __init__(self, context, request): ... self.context, self.request = context, request ... def __getitem__(self, key): ... return int(key) ... >>> smgr.registerAdapter(Foo, (None, IRequest), IBrowserView, name='foo') >>> app.unrestrictedTraverse('@@foo/12345') 12345 Laurence _______________________________________________ Zope-Dev maillist - Zope-Dev@zope.org http://mail.zope.org/mailman/listinfo/zope-dev ** No cross posts or HTML encoding! ** (Related lists - http://mail.zope.org/mailman/listinfo/zope-announce http://mail.zope.org/mailman/listinfo/zope )