[Zope-Checkins] SVN: Products.Five/branches/1.0/ Merge
philikon-fix-lookup-priorities branch and prepare for release.
Philipp von Weitershausen
philikon at philikon.de
Sun Mar 26 17:37:15 EST 2006
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
More information about the Zope-Checkins
mailing list