[Repoze-checkins] r1055 - in repoze.zope2/trunk: . repoze/zope2 repoze/zope2/tests

Chris McDonough chrism at agendaless.com
Tue May 27 02:34:00 EDT 2008


Author: Chris McDonough <chrism at agendaless.com>
Date: Tue May 27 02:33:59 2008
New Revision: 1055

Log:
  - Use view lookup as well as getattr in next_name to detect whether
    a browser default page actually exists in order to support Zope
    2.9 "Five.traversable" semantics: getattr alone doesn't work under
    2.9 to detect whether a default view exists or not.



Modified:
   repoze.zope2/trunk/CHANGES.txt
   repoze.zope2/trunk/repoze/zope2/tests/base.py
   repoze.zope2/trunk/repoze/zope2/tests/test_z2bob.py
   repoze.zope2/trunk/repoze/zope2/z2bob.py
   repoze.zope2/trunk/setup.py

Modified: repoze.zope2/trunk/CHANGES.txt
==============================================================================
--- repoze.zope2/trunk/CHANGES.txt	(original)
+++ repoze.zope2/trunk/CHANGES.txt	Tue May 27 02:33:59 2008
@@ -1,3 +1,10 @@
+0.4.1 (2008-05-27)
+
+  - Use view lookup as well as getattr in next_name to detect whether
+    a browser default page actually exists in order to support Zope
+    2.9 "Five.traversable" semantics: getattr alone doesn't work under
+    2.9 to detect whether a default view exists or not.
+
 0.4.0 (2008-05-21)
 
   - Raise an error Z2BobHelper's map_result method detects that it's

Modified: repoze.zope2/trunk/repoze/zope2/tests/base.py
==============================================================================
--- repoze.zope2/trunk/repoze/zope2/tests/base.py	(original)
+++ repoze.zope2/trunk/repoze/zope2/tests/base.py	Tue May 27 02:33:59 2008
@@ -24,6 +24,9 @@
     from zope.app.traversing.interfaces import TraversalError
     _BETTER_THAN_210 = False
 
+from zope.publisher.interfaces.browser import IBrowserRequest
+from zope.interface import implements
+
 class DummyResponse:
     unauth_called = False
     urls_reset = False
@@ -70,8 +73,10 @@
         self._wrote = True
         self.stdout.write(data)
 
+
 class DummyRequest:
     no_acquire_flag = False
+    implements(IBrowserRequest)
     def __init__(self, env):
         self.environ = env
         if not 'TraversalRequestNameStack' in self.environ:

Modified: repoze.zope2/trunk/repoze/zope2/tests/test_z2bob.py
==============================================================================
--- repoze.zope2/trunk/repoze/zope2/tests/test_z2bob.py	(original)
+++ repoze.zope2/trunk/repoze/zope2/tests/test_z2bob.py	Tue May 27 02:33:59 2008
@@ -341,6 +341,29 @@
         self.assertEqual(helper.browser_default_published, None)
         self.assertEqual(result, 'nondefault')
 
+    def test_next_name_trns_empty_browserdefault_returns_path_to_view(self):
+        published = DummyBrowserDefaultPublishedObject()
+        published.browserdefault = published
+        published.bd_path = ('nondefault',)
+        class DummyView:
+            def __init__(self, context, request):
+                pass
+        from zope.publisher.interfaces.browser import IBrowserRequest
+        from zope.interface import Interface
+        if _BETTER_THAN_210:
+            ztapi.provideAdapter((Interface, IBrowserRequest), Interface,
+                                 DummyView, 'nondefault')
+        else:
+            ztapi.provideView(None, IBrowserRequest, Interface,
+                              'nondefault', DummyView)
+        helper = self._makeOne()
+        parents = helper.request['PARENTS']
+        parents.append(published)
+        result = helper.next_name()
+        self.assertEqual(helper.browser_default, True)
+        self.assertEqual(helper.browser_default_published, None)
+        self.assertEqual(result, 'nondefault')
+
     def test_next_name_with_rvh_novhost(self):
         helper = self._makeOne()
         helper.request['TraversalRequestNameStack'] = ['bar', '_rvh:foo']

Modified: repoze.zope2/trunk/repoze/zope2/z2bob.py
==============================================================================
--- repoze.zope2/trunk/repoze/zope2/z2bob.py	(original)
+++ repoze.zope2/trunk/repoze/zope2/z2bob.py	Tue May 27 02:33:59 2008
@@ -27,6 +27,7 @@
 from paste import httpheaders
 
 from zope.component import queryMultiAdapter
+from zope.interface import Interface
 
 from zope.publisher.interfaces import IPublishTraverse
 from zope.publisher.interfaces.browser import IBrowserPublisher
@@ -250,6 +251,8 @@
             parents = self.request['PARENTS']
             published = parents[-1]
 
+            default_page = self.default_page
+
             adapter = self._getPublishTraverseView(IBrowserPublisher, published)
             default, path = adapter.browserDefault(self.request)
 
@@ -275,16 +278,21 @@
                 # BaseRequest.traverse pops names off the stack (from
                 # back to front).  Since this doesn't appear to make
                 # sense under ZPublisher "proper", we just ignore all
-                # but the last element of the returned path and
-                # reassign our default_page to that name.  Code that
-                # depended on returning more than two names and which
-                # worked around the reversed-order bug will lose,
-                # sorry.
+                # but the last element of the returned path and use it
+                # as the default_page.  Code that depended on
+                # returning more than two names and which worked
+                # around the reversed-order bug will lose, sorry.
                 self.browser_default = True
-                self.default_page = path[-1]
+                default_page = path[-1]
 
-            if getattr(published, self.default_page, None) not in _FALSETYPES:
-                return self.default_page
+            # we need to check if we actually have a default page in
+            # next_name because if we try to do it in traverse, if we
+            # don't actually *have* the default page (because we've
+            # already traversed it explicitly, for example), we'll be
+            # "stuck" redoing the before_traverse of the previous
+            # object and cleaning up the URL and such.
+            if self._hasDefaultPage(published, default_page):
+                return default_page
 
     def before_traverse(self, ob):
         # NB: we *must* build the PARENTS list in "reverse" order then
@@ -628,6 +636,19 @@
                 self.vroot_stack.reverse()
         return path
 
+    def _hasDefaultPage(self, published, name):
+        # getattr is usually used
+        if getattr(published, name, None) not in _FALSETYPES:
+            return True
+        # Zope 2.9's Five uses adapter lookup to find the default page
+        # ( see Products/Five/traversable.py(147)traverse() ).  In
+        # 2.10+, getattr takes over for that purpose, so this won't
+        # ever be called if the above if statement is true under 2.10+.
+        lookup = (published, self.request)
+        if queryMultiAdapter(lookup, Interface, name) is not None:
+            return True
+        return False
+
 lock = threading.Lock()
 db = None
 

Modified: repoze.zope2/trunk/setup.py
==============================================================================
--- repoze.zope2/trunk/setup.py	(original)
+++ repoze.zope2/trunk/setup.py	Tue May 27 02:33:59 2008
@@ -12,7 +12,7 @@
 #
 ##############################################################################
 
-__version__ = '0.4.0'
+__version__ = '0.4.1'
 
 from ez_setup import use_setuptools
 use_setuptools()


More information about the Repoze-checkins mailing list