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), _______________________________________________ Zope-Checkins maillist - Zope-Checkins@zope.org http://mail.zope.org/mailman/listinfo/zope-checkins