Log message for revision 66212: Merge philikon-fix-lookup-priorities branch and prepare for release.
Changed: U Products.Five/branches/1.0/CHANGES.txt U Products.Five/branches/1.0/fiveconfigure.py U Products.Five/branches/1.0/tests/test_five.py U Products.Five/branches/1.0/traversable.py U Products.Five/branches/1.0/version.txt -=- Modified: Products.Five/branches/1.0/CHANGES.txt =================================================================== --- Products.Five/branches/1.0/CHANGES.txt 2006-03-26 22:31:56 UTC (rev 66211) +++ Products.Five/branches/1.0/CHANGES.txt 2006-03-26 22:37:14 UTC (rev 66212) @@ -2,14 +2,24 @@ Five Changes ============ -Five 1.0.3 (...) -================ +Five 1.0.3 (2006-03-26) +======================= -* Added missing fix from newer versions of Five where the _context wasn't - getting cleaned up properly in zcml.py. Without this fix, adapter lookups - wouldn't work in any test after the first test that used load_zcml in the - same test fixture (essentially adapter lookups were dead). +Bugfixes +-------- +* Fixed look-up order during Five traversal. It is now as follows: + + 1. If an object has __bobo_traverse__, use it. + + 2. Otherwise do attribute look-up or, if that doesn't work, key item + lookup. + + 3. If neither __bobo_traverse__ nor attribute/key look-up work, it + tries to find a Zope 3-style view. + +* Properly clean up ZCML context in Five.zcml. + * Fixed bug that broke WebDAV access for five:defaultViewable objects. The __browser_default__ now modifies only GET and POST requests. @@ -20,7 +30,8 @@ instead of the ZopeTwoPageTemplateFile. This seem to cause access problems in some very obscure situations, and is now fixed. -* FivePageTemplate is now deprecated and will be removed in Five 1.1. +* FivePageTemplate is now deprecated and removed in more recent + versions of Five. * Some parts of add.pt and edit.pt were not being translated. Modified: Products.Five/branches/1.0/fiveconfigure.py =================================================================== --- Products.Five/branches/1.0/fiveconfigure.py 2006-03-26 22:31:56 UTC (rev 66211) +++ Products.Five/branches/1.0/fiveconfigure.py 2006-03-26 22:37:14 UTC (rev 66212) @@ -28,10 +28,10 @@ from zope.interface import classImplements from zope.configuration import xmlconfig from zope.app.component.interface import provideInterface -from viewable import Viewable -from traversable import Traversable -from bridge import fromZ2Interface -from browserconfigure import page +from Products.Five.viewable import Viewable +from Products.Five.traversable import Traversable +from Products.Five.bridge import fromZ2Interface +from Products.Five.browserconfigure import page debug_mode = App.config.getConfiguration().debug_mode @@ -54,7 +54,7 @@ # in the control panel. However, all attempts to do so has failed from my # side. //regebro exc = sys.exc_info() - LOG('Five', ERROR, 'Could not import Product %s' % name, error=exc) + LOG('Five', ERROR, 'Could not import Product %s' % product.__name__, error=exc) def loadProducts(_context): products = findProducts() @@ -118,14 +118,11 @@ isFiveMethod(class_.__bobo_traverse__)): return - if hasattr(class_, '__bobo_traverse__'): - if not isFiveMethod(class_.__bobo_traverse__): - # if there's an existing bobo_traverse hook already, use that - # as the traversal fallback method - setattr(class_, '__fallback_traverse__', class_.__bobo_traverse__) - if not hasattr(class_, '__fallback_traverse__'): - setattr(class_, '__fallback_traverse__', - Traversable.__fallback_traverse__.im_func) + if (hasattr(class_, '__bobo_traverse__') and + not isFiveMethod(class_.__bobo_traverse__)): + # if there's an existing bobo_traverse hook already, use that + # as the traversal fallback method + setattr(class_, '__fallback_traverse__', class_.__bobo_traverse__) setattr(class_, '__bobo_traverse__', Traversable.__bobo_traverse__.im_func) Modified: Products.Five/branches/1.0/tests/test_five.py =================================================================== --- Products.Five/branches/1.0/tests/test_five.py 2006-03-26 22:31:56 UTC (rev 66211) +++ Products.Five/branches/1.0/tests/test_five.py 2006-03-26 22:37:14 UTC (rev 66212) @@ -333,9 +333,11 @@ response = self.publish('/test_folder_1_/fancy/something-else') self.assertEquals('something-else', response.getBody()) - # check if z3-based view lookup works + # even though we have a zope 3 view registered as 'fancy', it + # doesn't kick in, the existing bobo_traverse takes over + # everything response = self.publish('/test_folder_1_/fancy/fancy') - self.assertEquals("Fancy, fancy", response.getBody()) + self.assertEquals("fancy", response.getBody()) def test_publish_image_resource(self): url = '/test_folder_1_/testoid/++resource++pattern.png' Modified: Products.Five/branches/1.0/traversable.py =================================================================== --- Products.Five/branches/1.0/traversable.py 2006-03-26 22:31:56 UTC (rev 66211) +++ Products.Five/branches/1.0/traversable.py 2006-03-26 22:37:14 UTC (rev 66212) @@ -15,7 +15,6 @@ $Id$ """ -from zExceptions import NotFound from zope.exceptions import NotFoundError from zope.component import getView, ComponentLookupError from zope.interface import implements @@ -24,12 +23,11 @@ from zope.app.traversing.adapters import DefaultTraversable from zope.app.traversing.adapters import traversePathElement -from AccessControl import getSecurityManager -from Products.Five.security import newInteraction +import Products.Five.security +from zExceptions import NotFound +from ZPublisher import xmlrpc -_marker = object - -class FakeRequest: +class FakeRequest(dict): implements(IBrowserRequest) def getPresentationSkin(self): @@ -38,22 +36,14 @@ def has_key(self, key): return False + def getURL(self): + return "http://codespeak.net/z3/five" + class Traversable: """A mixin to make an object traversable using an ITraverser adapter. """ __five_traversable__ = True - def __fallback_traverse__(self, REQUEST, name): - """Method hook for fallback traversal - - This method is called by __bobo_traverse___ when Zope3-style - ITraverser traversal fails. - - Just raise a AttributeError to indicate traversal has failed - and let Zope do it's job. - """ - raise AttributeError, name - def __bobo_traverse__(self, REQUEST, name): """Hook for Zope 2 traversal @@ -61,28 +51,60 @@ It allows us to trick it into faking the Zope 3 traversal system by using an ITraverser adapter. """ + # We are trying to be compatible with Zope 2 and 3 traversal + # behaviour as much as possible. Therefore the first part of + # this method is based on BaseRequest.traverse's behaviour: + # 1. If an object has __bobo_traverse__, use it. + # 2. Otherwise do attribute look-up or, if that doesn't work, + # key item lookup. + + if hasattr(self, '__fallback_traverse__'): + try: + return self.__fallback_traverse__(REQUEST, name) + except (AttributeError, KeyError): + pass + else: + try: + return getattr(self, name) + except AttributeError: + pass + + try: + return self[name] + except (KeyError, IndexError, TypeError, AttributeError): + pass + + # This is the part Five adds: + # 3. If neither __bobo_traverse__ nor attribute/key look-up + # work, we try to find a Zope 3-style view. + + # For that we need to make sure we have a good request + # (sometimes __bobo_traverse__ gets a stub request) if not IBrowserRequest.providedBy(REQUEST): # Try to get the REQUEST by acquisition REQUEST = getattr(self, 'REQUEST', None) if not IBrowserRequest.providedBy(REQUEST): REQUEST = FakeRequest() - # con Zope 3 into using Zope 2's checkPermission - newInteraction() + + # Con Zope 3 into using Zope 2's checkPermission + Products.Five.security.newInteraction() + + # Use the ITraverser adapter (which in turn uses ITraversable + # adapters) to traverse to a view. Note that we're mixing + # object-graph and object-publishing traversal here, but Zope + # 2 has no way to tell us when to use which... + # TODO Perhaps we can decide on object-graph vs. + # object-publishing traversal depending on whether REQUEST is + # a stub or not? try: return ITraverser(self).traverse( path=[name], request=REQUEST).__of__(self) except (ComponentLookupError, NotFoundError, AttributeError, KeyError, NotFound): pass - try: - return getattr(self, name) - except AttributeError: - pass - try: - return self[name] - except (AttributeError, KeyError): - pass - return self.__fallback_traverse__(REQUEST, name) + + raise AttributeError, name + __bobo_traverse__.__five_method__ = True @@ -95,7 +117,7 @@ REQUEST = getattr(context, 'REQUEST', None) if not IBrowserRequest.providedBy(REQUEST): REQUEST = FakeRequest() - # Try to lookup a view first + # Try to lookup a view try: return getView(context, name, REQUEST) except ComponentLookupError: Modified: Products.Five/branches/1.0/version.txt =================================================================== --- Products.Five/branches/1.0/version.txt 2006-03-26 22:31:56 UTC (rev 66211) +++ Products.Five/branches/1.0/version.txt 2006-03-26 22:37:14 UTC (rev 66212) @@ -1 +1 @@ -Five 1.0.2 +Five 1.0.3 _______________________________________________ Zope-Checkins maillist - Zope-Checkins@zope.org http://mail.zope.org/mailman/listinfo/zope-checkins