[Zope-Checkins]
SVN: Zope/branches/philikon-aq/lib/python/ZPublisher/
Fix a bug in the traversal code regarding
IBrowserPublisher.browserDefault.
Philipp von Weitershausen
philikon at philikon.de
Sun Jul 29 10:57:39 EDT 2007
Log message for revision 78460:
Fix a bug in the traversal code regarding IBrowserPublisher.browserDefault.
browserDefault implementations that were returning object_thats_not_self, ()
didnt' work.
Changed:
U Zope/branches/philikon-aq/lib/python/ZPublisher/BaseRequest.py
U Zope/branches/philikon-aq/lib/python/ZPublisher/tests/testBaseRequest.py
-=-
Modified: Zope/branches/philikon-aq/lib/python/ZPublisher/BaseRequest.py
===================================================================
--- Zope/branches/philikon-aq/lib/python/ZPublisher/BaseRequest.py 2007-07-29 12:05:30 UTC (rev 78459)
+++ Zope/branches/philikon-aq/lib/python/ZPublisher/BaseRequest.py 2007-07-29 14:57:38 UTC (rev 78460)
@@ -427,7 +427,7 @@
else:
# If we have reached the end of the path, we look to see
# if we can find IBrowserPublisher.browserDefault. If so,
- # we call it to let the object tell us how to publish it
+ # we call it to let the object tell us how to publish it.
# BrowserDefault returns the object to be published
# (usually self) and a sequence of names to traverse to
# find the method to be published.
@@ -440,7 +440,8 @@
not hasattr(object,'__bobo_traverse__')):
if object.aq_parent is not object.aq_inner.aq_parent:
from webdav.NullResource import NullResource
- object = NullResource(parents[-2], object.getId(), self).__of__(parents[-2])
+ object = NullResource(parents[-2], object.getId(),
+ self).__of__(parents[-2])
if IBrowserPublisher.providedBy(object):
adapter = object
@@ -451,10 +452,9 @@
# Zope2 doesn't set up its own adapters in a lot
# of cases so we will just use a default adapter.
adapter = DefaultPublishTraverse(object, self)
-
- newobject, default_path = adapter.browserDefault(self)
- if default_path or newobject is not object:
- object = newobject
+
+ object, default_path = adapter.browserDefault(self)
+ if default_path:
request._hacked_path=1
if len(default_path) > 1:
path = list(default_path)
Modified: Zope/branches/philikon-aq/lib/python/ZPublisher/tests/testBaseRequest.py
===================================================================
--- Zope/branches/philikon-aq/lib/python/ZPublisher/tests/testBaseRequest.py 2007-07-29 12:05:30 UTC (rev 78459)
+++ Zope/branches/philikon-aq/lib/python/ZPublisher/tests/testBaseRequest.py 2007-07-29 14:57:38 UTC (rev 78460)
@@ -264,11 +264,11 @@
import zope.component
import zope.testing.cleanup
import zope.traversing.namespace
+import zope.publisher.browser
from zope.publisher.browser import IBrowserRequest
from zope.publisher.browser import IDefaultBrowserLayer
from zope.traversing.interfaces import ITraversable
-
class IDummy(zope.interface.Interface):
"""IDummy"""
@@ -292,6 +292,33 @@
def __call__(self):
return 'view on %s' % (self.content.name)
+class DummyPage(zope.publisher.browser.BrowserPage):
+
+ # BrowserPage is an IBrowserPublisher with a browserDefault that
+ # returns self, () so that __call__ is invoked by the publisher.
+
+ def __call__(self):
+ return 'Test page'
+
+class DummyPage2(zope.publisher.browser.BrowserPage):
+
+ def browserDefault(self, request):
+ # intentionally return something that's not self
+ return DummyPage(self.context, request), ()
+
+ # __call__ remains unimplemented, baseclass raises NotImplementedError
+
+class DummyPage3(zope.publisher.browser.BrowserPage):
+
+ def browserDefault(self, request):
+ # intentionally return a method here
+ return self.foo, ()
+
+ def foo(self):
+ return 'Test page'
+
+ # __call__ remains unimplemented, baseclass raises NotImplementedError
+
class TestBaseRequestZope3Views(TestCase):
def setUp(self):
@@ -309,9 +336,15 @@
# The request needs to implement the proper interface
zope.interface.classImplements(BaseRequest, IDefaultBrowserLayer)
- # Define our 'meth' view
- gsm.registerAdapter(DummyView, (IDummy, IDefaultBrowserLayer), None,
- 'meth')
+ # Define the views
+ gsm.registerAdapter(DummyView, (IDummy, IDefaultBrowserLayer),
+ zope.interface.Interface, 'meth')
+ gsm.registerAdapter(DummyPage, (IDummy, IDefaultBrowserLayer),
+ zope.interface.Interface, 'page')
+ gsm.registerAdapter(DummyPage2, (IDummy, IDefaultBrowserLayer),
+ zope.interface.Interface, 'page2')
+ gsm.registerAdapter(DummyPage3, (IDummy, IDefaultBrowserLayer),
+ zope.interface.Interface, 'page3')
# Bind the 'view' namespace (for @@ traversal)
gsm.registerAdapter(zope.traversing.namespace.view,
@@ -407,6 +440,16 @@
r.traverse('folder/obj/++view++meth')
self.assertEqual(r['URL'], '/folder/obj/++view++meth')
+ def test_browserDefault(self):
+ # Test that browserDefault returning self, () works
+ r = self.makeBaseRequest()
+ ob = r.traverse('folder/obj/page')
+ self.assertEqual(ob(), 'Test page')
+
+ r = self.makeBaseRequest()
+ ob = r.traverse('folder/obj/page2')
+ self.assertEqual(ob(), 'Test page')
+
def test_suite():
return TestSuite( ( makeSuite(TestBaseRequest),
makeSuite(TestBaseRequestZope3Views),
More information about the Zope-Checkins
mailing list