Florent Guillaume wrote:
So here's a proposal: how about having the following order: - __bobo_traverse__ - unacquired attribute - zope 3 views - acquired attributes
Attached is the current diff I'm working with (for Zope 2.10). Please review the unit test (which pass as is), to check if you agree with the semantics. I've decided that if you traverse ".../foo/@@something", then only the zope 3 views will be consulted and never an attribute. I hope everyone agrees with that. The remaining important question is: if a *default* view is specified using the zope 3 mechanism, should we always treat it as a zope 3 view, and refuse to lookup an attribute with that name? Currently the traverse code is not completely coherent with respect to that, there's a NotFound in the tests I added which isn't coherent with the rest. So we should decide on one semantic. To explicit the question, if you have: <browser:defaultView name="myview" for=".IFoo"/> and the publisher decides it has to use the default view (when ".../foo/" is traversed), should it try to lookup "myview" as an attribute? Or should only the zope 3 view be looked up? I'd be inclined to not use attributes, after all that's zope 3 directives we're talking about. Florent -- Florent Guillaume, Nuxeo (Paris, France) Director of R&D +33 1 40 33 71 59 http://nuxeo.com fg@nuxeo.com Index: lib/python/ZPublisher/tests/testBaseRequest.py =================================================================== --- lib/python/ZPublisher/tests/testBaseRequest.py (revision 68718) +++ lib/python/ZPublisher/tests/testBaseRequest.py (working copy) @@ -3,8 +3,15 @@ from Acquisition import Implicit from ZPublisher.BaseRequest import BaseRequest from ZPublisher.HTTPResponse import HTTPResponse +from ZPublisher import NotFound +import zope.interface +import zope.testing.cleanup +import zope.traversing.namespace +from zope.app.testing import ztapi +from zope.publisher.interfaces.browser import IDefaultBrowserLayer + class DummyObjectBasic(Implicit): """Dummy class with docstring.""" @@ -166,7 +173,6 @@ def test_traverse_withBDEmpty(self): # Collector 1079 (infinite loop 2) - from ZPublisher import NotFound r = self.makeBaseRequest() self.f1.objWithBD._default_path = [''] self.failUnlessRaises(NotFound, r.traverse, 'folder/objWithBD') @@ -174,7 +180,6 @@ def test_traverse_withBBT_handles_AttributeError(self): # Test that if __bobo_traverse__ raises AttributeError # that we get a NotFound - from ZPublisher import NotFound r = self.makeBaseRequest() self.failUnlessRaises(NotFound, r.traverse, 'folder/objWithBBT/bbt_foo') @@ -194,7 +199,6 @@ # and __bobo_traverse__ # __bobo_traverse__ should raise an AttributeError, which will # raise a NotFound - from ZPublisher import NotFound r = self.makeBaseRequest() self.f1.objWithBDBBT._default_path = ['xxx'] r = self.makeBaseRequest() @@ -214,27 +218,22 @@ self.assertEqual(r.response.base, '') def test_traverse_attribute_without_docstring(self): - from ZPublisher import NotFound r = self.makeBaseRequest() self.assertRaises(NotFound, r.traverse, 'folder/objBasic/noview') def test_traverse_class_without_docstring(self): - from ZPublisher import NotFound r = self.makeBaseRequest() self.assertRaises(NotFound, r.traverse, 'folder/objWithoutDocstring') def test_traverse_attribute_of_class_without_docstring(self): - from ZPublisher import NotFound r = self.makeBaseRequest() self.assertRaises(NotFound, r.traverse, 'folder/objWithoutDocstring/view') def test_traverse_attribute_and_class_without_docstring(self): - from ZPublisher import NotFound r = self.makeBaseRequest() self.assertRaises(NotFound, r.traverse, 'folder/objWithoutDocstring/noview') def test_traverse_simple_type(self): - from ZPublisher import NotFound r = self.makeBaseRequest() self.assertRaises(NotFound, r.traverse, 'folder/simpleString') self.assertRaises(NotFound, r.traverse, 'folder/simpleList') @@ -242,14 +241,144 @@ self.assertRaises(NotFound, r.traverse, 'folder/simpleComplex') def test_traverse_set_type(self): - from ZPublisher import NotFound r = self.makeBaseRequest() self.assertRaises(NotFound, r.traverse, 'folder/simpleSet') self.assertRaises(NotFound, r.traverse, 'folder/simpleFrozenSet') +class IDummy(zope.interface.Interface): + """IDummy""" + +class DummyObjectBasicZ3(DummyObjectBasic): + zope.interface.implements(IDummy) + def __init__(self, name): + self.name = name + +class DummyObjectBasicZ3WithAttr(DummyObjectBasicZ3): + def meth(self): + """doc""" + return 'meth on %s' % self.name + def methonly(self): + """doc""" + return 'methonly on %s' % self.name + +class DummyView(Implicit): + def __init__(self, content, request): + self.content = content + self.request = request + def __call__(self): + return 'view on %s' % (self.content.name) + +class TestBaseRequestZope3Views(TestCase): + + def setUp(self): + zope.testing.cleanup.cleanUp() + self.root = DummyObjectBasic() + self.f1 = self.root._setObject('folder', DummyObjectBasicZ3('folder')) + self.f1._setObject('obj', DummyObjectBasicZ3('obj')) + self.f1._setObject('withattr', DummyObjectBasicZ3WithAttr('withattr')) + self.f2 = self.root._setObject('folder2', + DummyObjectBasicZ3WithAttr('folder2')) + self.f2._setObject('obj2', DummyObjectBasicZ3('obj2')) + self.f2._setObject('withattr2', DummyObjectBasicZ3WithAttr('withattr2')) + + # This is needed to make "zope 3" traversing work + zope.interface.classImplements(BaseRequest, IDefaultBrowserLayer) + + # Define our 'meth' view + ztapi.browserView(IDummy, 'meth', DummyView) + + # Bind @@ to the view namespace + ztapi.provideNamespaceHandler('view', zope.traversing.namespace.view) + + def tearDown(self): + zope.testing.cleanup.cleanUp() + + def makeBaseRequest(self): + response = HTTPResponse() + environment = { 'URL': '', + 'PARENTS': [self.root], + 'steps': [], + '_hacked_path': 0, + '_test_counter': 0, + 'response': response } + return BaseRequest(environment) + + def test_traverse_view(self): + """simple view""" + r = self.makeBaseRequest() + ob = r.traverse('folder/obj/meth') + self.assertEqual(ob(), 'view on obj') + ob = r.traverse('folder/obj/@@meth') + self.assertEqual(ob(), 'view on obj') + # using default view + ztapi.setDefaultViewName(IDummy, 'meth') + ob = r.traverse('folder/obj/') + self.assertEqual(ob(), 'view on obj') + ob = r.traverse('folder/obj') + self.assertEqual(ob(), 'view on obj') + + def test_traverse_view_attr_local(self): + """method on object used first""" + r = self.makeBaseRequest() + ob = r.traverse('folder/withattr/meth') + self.assertEqual(ob(), 'meth on withattr') + ob = r.traverse('folder/withattr/@@meth') + self.assertEqual(ob(), 'view on withattr') + # using default view + ztapi.setDefaultViewName(IDummy, 'meth') + ob = r.traverse('folder/withattr/') + self.assertEqual(ob(), 'meth on withattr') + ob = r.traverse('folder/withattr') + self.assertEqual(ob(), 'meth on withattr') + + def test_traverse_view_attr_above(self): + """view takes precedence over acquired attribute""" + r = self.makeBaseRequest() + ob = r.traverse('folder2/obj2/meth') + self.assertEqual(ob(), 'view on obj2') # used to be buggy (acquired) + ob = r.traverse('folder2/obj2/@@meth') + self.assertEqual(ob(), 'view on obj2') + # using default view + ztapi.setDefaultViewName(IDummy, 'meth') + ob = r.traverse('folder2/obj2/') + self.assertEqual(ob(), 'view on obj2') + ob = r.traverse('folder2/obj2') + self.assertEqual(ob(), 'view on obj2') + + def test_traverse_view_attr_local2(self): + """method with other method above""" + r = self.makeBaseRequest() + ob = r.traverse('folder2/withattr2/meth') + self.assertEqual(ob(), 'meth on withattr2') + ob = r.traverse('folder2/withattr2/@@meth') + self.assertEqual(ob(), 'view on withattr2') + # using default view + ztapi.setDefaultViewName(IDummy, 'meth') + ob = r.traverse('folder2/withattr2/') + self.assertEqual(ob(), 'meth on withattr2') + ob = r.traverse('folder2/withattr2') + self.assertEqual(ob(), 'meth on withattr2') + + def test_traverse_view_attr_acquired(self): + """normal acquired attribute without view""" + r = self.makeBaseRequest() + ob = r.traverse('folder2/obj2/methonly') + self.assertEqual(ob(), 'methonly on folder2') + self.assertRaises(NotFound, r.traverse, 'folder2/obj2/@@methonly') + # using default view + ztapi.setDefaultViewName(IDummy, 'methonly') + ob = r.traverse('folder2/obj2/') + self.assertEqual(ob(), 'methonly on folder2') + ob = r.traverse('folder2/obj2') + self.assertEqual(ob(), 'methonly on folder2') + + def test_suite(): - return TestSuite( ( makeSuite(TestBaseRequest), ) ) + return TestSuite(( + makeSuite(TestBaseRequest), + makeSuite(TestBaseRequestZope3Views), + )) if __name__ == '__main__': main(defaultTest='test_suite') Index: lib/python/ZPublisher/BaseRequest.py =================================================================== --- lib/python/ZPublisher/BaseRequest.py (revision 68718) +++ lib/python/ZPublisher/BaseRequest.py (working copy) @@ -17,6 +17,7 @@ from urllib import quote import xmlrpc from zExceptions import Forbidden, Unauthorized, NotFound +from Acquisition import aq_base from zope.interface import implements, providedBy, Interface from zope.component import queryMultiAdapter @@ -72,6 +73,7 @@ raise Forbidden("Object name begins with an underscore at: %s" % URL) try: + # 1. Try __bobo_traverse__ if hasattr(object,'__bobo_traverse__'): subobject=object.__bobo_traverse__(request, name) if type(subobject) is type(()) and len(subobject) > 1: @@ -81,24 +83,28 @@ object, subobject = subobject[-2:] else: try: + # 2. Try as attribute on base object + getattr(aq_base(object), name) subobject=getattr(object, name) except AttributeError: + # 2.5 Try as item subobject=object[name] - + except (AttributeError, KeyError, NotFound): - # Find a view even if it doesn't start with @@, but only - # If nothing else could be found + # 4. Try as view subobject = queryMultiAdapter((object, request), Interface, name) if subobject is not None: # OFS.Application.__bobo_traverse__ calls # REQUEST.RESPONSE.notFoundError which sets the HTTP # status code to 404 - request.RESPONSE.setStatus(200) + request.response.setStatus(200) # We don't need to do the docstring security check # for views, so lets skip it and return the object here. return subobject.__of__(object) - raise + # 5. Try as acquired attribute, may raise + subobject = getattr(object, name) + # Ensure that the object has a docstring, or that the parent # object has a pseudo-docstring for the object. Objects that # have an empty or missing docstring are not published.
Florent Guillaume wrote:
Florent Guillaume wrote:
So here's a proposal: how about having the following order: - __bobo_traverse__ - unacquired attribute - zope 3 views - acquired attributes
Attached is the current diff I'm working with (for Zope 2.10).
Hey, cool. You know, the real challenge is backporting this all the way to Five 1.2 to ensure compatibility between the current stable Zope 2 releases.
Please review the unit test (which pass as is), to check if you agree with the semantics.
The unit tests look good except for the default-view-for-attributes issue (see below). By the way, I recommend avoiding ztapi. It isn't officially deprecated, but we try to discourage its use wherever we can. I think it'll be deprecated soon.
I've decided that if you traverse ".../foo/@@something", then only the zope 3 views will be consulted and never an attribute. I hope everyone agrees with that.
Yup.
The remaining important question is: if a *default* view is specified using the zope 3 mechanism, should we always treat it as a zope 3 view, and refuse to lookup an attribute with that name?
Yep. browser:defaultView should only affect the view machinery. Philipp
On 18 Jun 2006, at 12:37, Philipp von Weitershausen wrote:
Florent Guillaume wrote:
Florent Guillaume wrote:
So here's a proposal: how about having the following order: - __bobo_traverse__ - unacquired attribute - zope 3 views - acquired attributes
Attached is the current diff I'm working with (for Zope 2.10).
Hey, cool. You know, the real challenge is backporting this all the way to Five 1.2 to ensure compatibility between the current stable Zope 2 releases.
I know, unfortunately :( I can't make any promise about that, 2.10/trunk is my priority here. But I think Lennart was working on the same thing on the Five side.
Please review the unit test (which pass as is), to check if you agree with the semantics.
The unit tests look good except for the default-view-for-attributes issue (see below).
By the way, I recommend avoiding ztapi. It isn't officially deprecated, but we try to discourage its use wherever we can. I think it'll be deprecated soon.
I've decided that if you traverse ".../foo/@@something", then only the zope 3 views will be consulted and never an attribute. I hope everyone agrees with that.
Yup.
The remaining important question is: if a *default* view is specified using the zope 3 mechanism, should we always treat it as a zope 3 view, and refuse to lookup an attribute with that name?
Yep. browser:defaultView should only affect the view machinery.
Ok. Florent -- Florent Guillaume, Nuxeo (Paris, France) Director of R&D +33 1 40 33 71 59 http://nuxeo.com fg@nuxeo.com
On 6/18/06, Philipp von Weitershausen <philipp@weitershausen.de> wrote:
The remaining important question is: if a *default* view is specified using the zope 3 mechanism, should we always treat it as a zope 3 view, and refuse to lookup an attribute with that name?
Yep. browser:defaultView should only affect the view machinery.
OK, that means that the test in Five.browser.tests.test_defaultview lin 94 iw wrong, as it explicitly tests that they CAN be attributes. ;) This tests whether an existing ``index_html`` method is still supported and called: >>> print http(r''' ... GET /test_folder_1_/testindex HTTP/1.1 ... ''') HTTP/1.1 200 OK ... Default index_html called
From Five.browser.tests.defaultview.zcml:
<browser:defaultView for="Products.Five.tests.testing.simplecontent.IIndexSimpleContent" name="index_html" /> If you want to have non-views as browser default, we still need to use __browser_default__, then. The option is to allow attributes, and specify the browserdefault with @@ to force it to be a view. -- Lennart Regebro, Nuxeo http://www.nuxeo.com/ CPS Content Management http://www.cps-project.org/
On 18 Jun 2006, at 20:15, Lennart Regebro wrote:
If you want to have non-views as browser default, we still need to use __browser_default__, then.
The option is to allow attributes, and specify the browserdefault with @@ to force it to be a view.
But that wouldn't be compatible with what would happen in pure zope 3, where a default view of '@@foo' would mean the same as ++view+ +@@foo or @@@@foo, unless I'm mistaken. Florent -- Florent Guillaume, Nuxeo (Paris, France) Director of R&D +33 1 40 33 71 59 http://nuxeo.com fg@nuxeo.com
On 6/18/06, Florent Guillaume <fg@nuxeo.com> wrote:
On 18 Jun 2006, at 20:15, Lennart Regebro wrote:
If you want to have non-views as browser default, we still need to use __browser_default__, then.
The option is to allow attributes, and specify the browserdefault with @@ to force it to be a view.
But that wouldn't be compatible with what would happen in pure zope 3, where a default view of '@@foo' would mean the same as ++view+ +@@foo or @@@@foo, unless I'm mistaken.
I'm not saying it's a GOOD option. :-) Anyway, after we decide on this I can merge the branch to 2.10/trunk. -- Lennart Regebro, Nuxeo http://www.nuxeo.com/ CPS Content Management http://www.cps-project.org/
Lennart Regebro wrote:
On 6/18/06, Philipp von Weitershausen <philipp@weitershausen.de> wrote:
The remaining important question is: if a *default* view is specified using the zope 3 mechanism, should we always treat it as a zope 3 view, and refuse to lookup an attribute with that name?
Yep. browser:defaultView should only affect the view machinery.
OK, that means that the test in Five.browser.tests.test_defaultview lin 94 iw wrong, as it explicitly tests that they CAN be attributes. ;)
This tests whether an existing ``index_html`` method is still supported and called:
>>> print http(r''' ... GET /test_folder_1_/testindex HTTP/1.1 ... ''') HTTP/1.1 200 OK ... Default index_html called
From Five.browser.tests.defaultview.zcml:
<browser:defaultView for="Products.Five.tests.testing.simplecontent.IIndexSimpleContent" name="index_html" />
If you want to have non-views as browser default, we still need to use __browser_default__, then.
Hmm, perhaps browser:defaultView isn't such a bad idea then... :). Actually, I don't have much of an opinion, to be honest. I just thought that it would make sense that browser:defaultView only modified the behaviour of Zope 3 views. The fact that it also modifies the behaviour of the general traversal machinery in Zope 2 sounds like a blessing if we get to avoid __browser_default__ this way; if it turns out to be a curse for other people, then perhaps we need a five:defaultPublishedName or something...
The option is to allow attributes, and specify the browserdefault with @@ to force it to be a view.
Hmm. <browser:defaultView ... name="@@index.html" />??? That doesn't sound right. Philipp
On 6/19/06, Philipp von Weitershausen <philipp@weitershausen.de> wrote:
Hmm, perhaps browser:defaultView isn't such a bad idea then... :). Actually, I don't have much of an opinion, to be honest. I just thought that it would make sense that browser:defaultView only modified the behaviour of Zope 3 views. The fact that it also modifies the behaviour of the general traversal machinery in Zope 2 sounds like a blessing if we get to avoid __browser_default__ this way; if it turns out to be a curse for other people, then perhaps we need a five:defaultPublishedName or something...
Well, or we don't do anything, and let people who refuse to use views continue to use __browser_default__. :-) We do have the non-five adapter for this, it can stay for ever.
The option is to allow attributes, and specify the browserdefault with @@ to force it to be a view.
Hmm. <browser:defaultView ... name="@@index.html" />??? That doesn't sound right.
Good, then all seems to agree on that. -- Lennart Regebro, Nuxeo http://www.nuxeo.com/ CPS Content Management http://www.cps-project.org/
Philipp von Weitershausen wrote:
Lennart Regebro wrote:
On 6/18/06, Philipp von Weitershausen <philipp@weitershausen.de> wrote:
The remaining important question is: if a *default* view is specified using the zope 3 mechanism, should we always treat it as a zope 3 view, and refuse to lookup an attribute with that name? Yep. browser:defaultView should only affect the view machinery. OK, that means that the test in Five.browser.tests.test_defaultview lin 94 iw wrong, as it explicitly tests that they CAN be attributes. ;)
This tests whether an existing ``index_html`` method is still supported and called:
>>> print http(r''' ... GET /test_folder_1_/testindex HTTP/1.1 ... ''') HTTP/1.1 200 OK ... Default index_html called
From Five.browser.tests.defaultview.zcml:
<browser:defaultView for="Products.Five.tests.testing.simplecontent.IIndexSimpleContent" name="index_html" />
If you want to have non-views as browser default, we still need to use __browser_default__, then.
Hmm, perhaps browser:defaultView isn't such a bad idea then... :). Actually, I don't have much of an opinion, to be honest. I just thought that it would make sense that browser:defaultView only modified the behaviour of Zope 3 views. The fact that it also modifies the behaviour of the general traversal machinery in Zope 2 sounds like a blessing if we get to avoid __browser_default__ this way; if it turns out to be a curse for other people, then perhaps we need a five:defaultPublishedName or something...
+1 on an alternative spelling, like five:defaultPublishedName or even five:defaultView if that's not too error-prone. Florent
The option is to allow attributes, and specify the browserdefault with @@ to force it to be a view.
Hmm. <browser:defaultView ... name="@@index.html" />??? That doesn't sound right.
Philipp
-- Florent Guillaume, Nuxeo (Paris, France) Director of R&D +33 1 40 33 71 59 http://nuxeo.com fg@nuxeo.com
Florent Guillaume wrote:
Philipp von Weitershausen wrote:
Lennart Regebro wrote:
On 6/18/06, Philipp von Weitershausen <philipp@weitershausen.de> wrote:
The remaining important question is: if a *default* view is specified using the zope 3 mechanism, should we always treat it as a zope 3 view, and refuse to lookup an attribute with that name? Yep. browser:defaultView should only affect the view machinery. OK, that means that the test in Five.browser.tests.test_defaultview lin 94 iw wrong, as it explicitly tests that they CAN be attributes. ;)
This tests whether an existing ``index_html`` method is still supported and called:
>>> print http(r''' ... GET /test_folder_1_/testindex HTTP/1.1 ... ''') HTTP/1.1 200 OK ... Default index_html called
From Five.browser.tests.defaultview.zcml:
<browser:defaultView for="Products.Five.tests.testing.simplecontent.IIndexSimpleContent" name="index_html" />
If you want to have non-views as browser default, we still need to use __browser_default__, then.
Hmm, perhaps browser:defaultView isn't such a bad idea then... :). Actually, I don't have much of an opinion, to be honest. I just thought that it would make sense that browser:defaultView only modified the behaviour of Zope 3 views. The fact that it also modifies the behaviour of the general traversal machinery in Zope 2 sounds like a blessing if we get to avoid __browser_default__ this way; if it turns out to be a curse for other people, then perhaps we need a five:defaultPublishedName or something...
+1 on an alternative spelling, like five:defaultPublishedName or even five:defaultView if that's not too error-prone.
Yeah, but does anyone really need it? I was just thinking out loud above. Perhaps I shouldn't have :) Philipp
Philipp von Weitershausen wrote:
Florent Guillaume wrote:
Florent Guillaume wrote:
So here's a proposal: how about having the following order: - __bobo_traverse__ - unacquired attribute - zope 3 views - acquired attributes Attached is the current diff I'm working with (for Zope 2.10).
Hey, cool. You know, the real challenge is backporting this all the way to Five 1.2 to ensure compatibility between the current stable Zope 2 releases.
We've actually noticed Five 1.2.4 is not compatible with Five 1.2 in some way to do with mysterious 'index.html' bits appearing after URLs where we thought they shouldn't. We haven't tracked this down and we might not for a while (we just switched back to Five 1.2..), just wanted to let you know Five 1.2 has some compatibility issues.. Regards, Martijn
On 20 Jun 2006, at 13:23, Martijn Faassen wrote:
Philipp von Weitershausen wrote:
Florent Guillaume wrote:
Florent Guillaume wrote:
So here's a proposal: how about having the following order: - __bobo_traverse__ - unacquired attribute - zope 3 views - acquired attributes Attached is the current diff I'm working with (for Zope 2.10). Hey, cool. You know, the real challenge is backporting this all the way to Five 1.2 to ensure compatibility between the current stable Zope 2 releases.
We've actually noticed Five 1.2.4 is not compatible with Five 1.2 in some way to do with mysterious 'index.html' bits appearing after URLs where we thought they shouldn't. We haven't tracked this down and we might not for a while (we just switched back to Five 1.2..), just wanted to let you know Five 1.2 has some compatibility issues..
I was looking at the publisher, and it hacks the URL to explicitely add the default view to it when a default view is used. That might explain it. You're saying Zope 2.10 doesn't do that? I thought it did too. Florent -- Florent Guillaume, Nuxeo (Paris, France) Director of R&D +33 1 40 33 71 59 http://nuxeo.com fg@nuxeo.com
Florent Guillaume wrote:
On 20 Jun 2006, at 13:23, Martijn Faassen wrote: [snip]
We've actually noticed Five 1.2.4 is not compatible with Five 1.2 in some way to do with mysterious 'index.html' bits appearing after URLs where we thought they shouldn't. We haven't tracked this down and we might not for a while (we just switched back to Five 1.2..), just wanted to let you know Five 1.2 has some compatibility issues..
I was looking at the publisher, and it hacks the URL to explicitely add the default view to it when a default view is used. That might explain it. You're saying Zope 2.10 doesn't do that? I thought it did too.
I'm just comparing Zope 2.8 + Five 1.2 with Zope 2.8 + Five 1.2.4. I have no idea what Zope 2.10 does. It broke a lot of stuff for us, so we switched back until we can figure out what's going on when we upgrade that piece of code to a newer version of Zope. Regards, Martijn
On 6/20/06, Martijn Faassen <faassen@infrae.com> wrote:
It broke a lot of stuff for us, so we switched back until we can figure out what's going on when we upgrade that piece of code to a newer version of Zope.
There is more tests in Five 1.5, adding them to older version of Five should be easy. Making them not break may be more complicated. ;) -- Lennart Regebro, Nuxeo http://www.nuxeo.com/ CPS Content Management http://www.cps-project.org/
On 6/20/06, Florent Guillaume <fg@nuxeo.com> wrote:
I was looking at the publisher, and it hacks the URL to explicitely add the default view to it when a default view is used. That might explain it. You're saying Zope 2.10 doesn't do that? I thought it did too.
Well, it adds index_html, not index.html. And it's not visible, just traversed. -- Lennart Regebro, Nuxeo http://www.nuxeo.com/ CPS Content Management http://www.cps-project.org/
Martijn Faassen wrote:
Philipp von Weitershausen wrote:
Florent Guillaume wrote:
Florent Guillaume wrote:
So here's a proposal: how about having the following order: - __bobo_traverse__ - unacquired attribute - zope 3 views - acquired attributes Attached is the current diff I'm working with (for Zope 2.10).
Hey, cool. You know, the real challenge is backporting this all the way to Five 1.2 to ensure compatibility between the current stable Zope 2 releases.
We've actually noticed Five 1.2.4 is not compatible with Five 1.2 in some way to do with mysterious 'index.html' bits appearing after URLs where we thought they shouldn't. We haven't tracked this down and we might not for a while (we just switched back to Five 1.2..), just wanted to let you know Five 1.2 has some compatibility issues..
I wasn't aware of this issue. Please file a collector entry so it won't get lost :). Note that it'd be great if you can find out which particular version of Five 1.2.x introduced the problem. And as always, a unit test that demonstrates the problem reproducibly would be superb. Philipp
Philipp von Weitershausen wrote:
Martijn Faassen wrote:
Philipp von Weitershausen wrote:
Florent Guillaume wrote:
Florent Guillaume wrote:
So here's a proposal: how about having the following order: - __bobo_traverse__ - unacquired attribute - zope 3 views - acquired attributes Attached is the current diff I'm working with (for Zope 2.10). Hey, cool. You know, the real challenge is backporting this all the way to Five 1.2 to ensure compatibility between the current stable Zope 2 releases. We've actually noticed Five 1.2.4 is not compatible with Five 1.2 in some way to do with mysterious 'index.html' bits appearing after URLs where we thought they shouldn't. We haven't tracked this down and we might not for a while (we just switched back to Five 1.2..), just wanted to let you know Five 1.2 has some compatibility issues..
I wasn't aware of this issue. Please file a collector entry so it won't get lost :).
Honestly we haven't had any time to figure this out, so I wouldn't even know what to write in a collector issue. We'll figure it out eventually but for now we'll just stick with Five 1.2. Regards, Martijn
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Philipp von Weitershausen wrote:
Martijn Faassen wrote:
Philipp von Weitershausen wrote:
Florent Guillaume wrote:
Florent Guillaume wrote:
So here's a proposal: how about having the following order: - __bobo_traverse__ - unacquired attribute - zope 3 views - acquired attributes Attached is the current diff I'm working with (for Zope 2.10). Hey, cool. You know, the real challenge is backporting this all the way to Five 1.2 to ensure compatibility between the current stable Zope 2 releases. We've actually noticed Five 1.2.4 is not compatible with Five 1.2 in some way to do with mysterious 'index.html' bits appearing after URLs where we thought they shouldn't. We haven't tracked this down and we might not for a while (we just switched back to Five 1.2..), just wanted to let you know Five 1.2 has some compatibility issues..
I wasn't aware of this issue. Please file a collector entry so it won't get lost :).
Note that it'd be great if you can find out which particular version of Five 1.2.x introduced the problem. And as always, a unit test that demonstrates the problem reproducibly would be superb.
I'll bet a beer that Martijn's breakage is related to the change added to the semantics of traversal lookup, which broke stuff for me between 2.9.1 and 2.9.2. Tres. - -- =================================================================== Tres Seaver +1 202-558-7113 tseaver@palladion.com Palladion Software "Excellence by Design" http://palladion.com -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.2.2 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org iD8DBQFEmWdk+gerLs4ltQ4RAgPSAJwLdIUhcMsr9ai1U2Ucyj/nrX65ngCgj8Hh /cfrL8nWU9BsIAPv6BiPFHE= =1COo -----END PGP SIGNATURE-----
Florent Guillaume wrote at 2006-6-18 02:05 +0200:
... if hasattr(object,'__bobo_traverse__'): subobject=object.__bobo_traverse__(request, name)
If you are working on it, then you should implement a means that "__bobo_traverse__" can tell the caller that it should use the normal default. This feature makes lots of "__bobo_traverse__" implementations much saner. A prominent example is the Archetypes' one. In our private Zope version, I have used an exception ("UseTraversalDefault") for this purpose. -- Dieter
Dieter Maurer wrote:
Florent Guillaume wrote at 2006-6-18 02:05 +0200:
... if hasattr(object,'__bobo_traverse__'): subobject=object.__bobo_traverse__(request, name)
If you are working on it, then you should implement a means that "__bobo_traverse__" can tell the caller that it should use the normal default.
This feature makes lots of "__bobo_traverse__" implementations much saner. A prominent example is the Archetypes' one.
In our private Zope version, I have used an exception ("UseTraversalDefault") for this purpose.
I think that __bobo_traverse__ can raise AttributeError currently to indicate that it has failed to look up an attribute and that traversal should try other options. Apart from being a more explicit spelling, what advantage would UseTraversalDefault have? Philipp
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Philipp von Weitershausen wrote:
Dieter Maurer wrote:
Florent Guillaume wrote at 2006-6-18 02:05 +0200:
... if hasattr(object,'__bobo_traverse__'): subobject=object.__bobo_traverse__(request, name) If you are working on it, then you should implement a means that "__bobo_traverse__" can tell the caller that it should use the normal default.
This feature makes lots of "__bobo_traverse__" implementations much saner. A prominent example is the Archetypes' one.
In our private Zope version, I have used an exception ("UseTraversalDefault") for this purpose.
I think that __bobo_traverse__ can raise AttributeError currently to indicate that it has failed to look up an attribute and that traversal should try other options. Apart from being a more explicit spelling, what advantage would UseTraversalDefault have?
The contract for '__bobo_traverse__' is actually insane on this point, becuase it has to serve two "masters": - In publishing traversal, an AttributeErrror raised from '__bobo_traverse__' has the semantics you describe. - In '{un,}restrictedTraverse', an AtttributeError causes the whole traversal process to abort, returning the 'default' value (if passed), or raising. Fixing this incompatibility without breaking applications which may be unknowingling dependent on it is going to be hard. Tres. - -- =================================================================== Tres Seaver +1 202-558-7113 tseaver@palladion.com Palladion Software "Excellence by Design" http://palladion.com -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.2.2 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org iD8DBQFEmpB2+gerLs4ltQ4RAtc9AKDIxupDiJI57PA2+Vsx/HNDHBlMWgCgosXm BCH//4dbeBOKt/C6ESsEvG0= =4DH2 -----END PGP SIGNATURE-----
On 22 Jun 2006, at 14:43, Tres Seaver wrote:
Philipp von Weitershausen wrote:
Dieter Maurer wrote:
Florent Guillaume wrote at 2006-6-18 02:05 +0200:
... if hasattr(object,'__bobo_traverse__'): subobject=object.__bobo_traverse__(request, name) If you are working on it, then you should implement a means that "__bobo_traverse__" can tell the caller that it should use the normal default.
This feature makes lots of "__bobo_traverse__" implementations much saner. A prominent example is the Archetypes' one.
In our private Zope version, I have used an exception ("UseTraversalDefault") for this purpose.
I think that __bobo_traverse__ can raise AttributeError currently to indicate that it has failed to look up an attribute and that traversal should try other options. Apart from being a more explicit spelling, what advantage would UseTraversalDefault have?
The contract for '__bobo_traverse__' is actually insane on this point, becuase it has to serve two "masters":
- In publishing traversal, an AttributeErrror raised from '__bobo_traverse__' has the semantics you describe.
- In '{un,}restrictedTraverse', an AtttributeError causes the whole traversal process to abort, returning the 'default' value (if passed), or raising.
Fixing this incompatibility without breaking applications which may be unknowingling dependent on it is going to be hard.
Which is one of the reasons why abandoning it and moving on to Zope 3 traversal is the only sane way to proceed :) Abandon = deprecate, yes :) Florent -- Florent Guillaume, Nuxeo (Paris, France) Director of R&D +33 1 40 33 71 59 http://nuxeo.com fg@nuxeo.com
Florent Guillaume wrote at 2006-6-22 14:50 +0200:
...
Fixing this incompatibility without breaking applications which may be unknowingling dependent on it is going to be hard.
Which is one of the reasons why abandoning it and moving on to Zope 3 traversal is the only sane way to proceed :)
Abandon = deprecate, yes :)
Congratulations: up to know one of the proposals with the highest rate of breakage :-( Hopefully, it will happen only after a very long time... -- Dieter
Philipp von Weitershausen wrote at 2006-6-22 09:03 +0200:
Dieter Maurer wrote: ...
If you are working on it, then you should implement a means that "__bobo_traverse__" can tell the caller that it should use the normal default. ... In our private Zope version, I have used an exception ("UseTraversalDefault") for this purpose.
I think that __bobo_traverse__ can raise AttributeError currently to indicate that it has failed to look up an attribute and that traversal should try other options. Apart from being a more explicit spelling, what advantage would UseTraversalDefault have?
First of all, I had expected that you were in favour of "explicit is better than implicit" (usually, I am not). In this case, you should be happy with a "more explicit spelling" ;-) I do not know the current code in Zope 2.10, but earlier it looked like: if hasattr(object,'__bobo_traverse__'): try: subobject=object.__bobo_traverse__(request,entry_name) ... except (AttributeError, KeyError): if debug_mode: return response.debugError( "Cannot locate object at: %s" % URL) else: return response.notFoundError(URL) With this code, you were only partially right: "__bobo_traverse__" could indeed raise an "AttributeError" to do something special -- but not to get the default traversal but to get a "NotFound" or a "DebugError" exception. That's quite different from what I proposed ;-) Should you prefer the implicit use of "AttributeError" over a more explicit use (the "UseTraversalDefault" was only some possibility; I am happy, if you find something better -- but equally explicit) to get the default traversal, I would not be completely unhappy but think: not optimal but better than nothing ;-) -- Dieter
Dieter Maurer wrote:
Philipp von Weitershausen wrote at 2006-6-22 09:03 +0200:
Dieter Maurer wrote: ...
If you are working on it, then you should implement a means that "__bobo_traverse__" can tell the caller that it should use the normal default. ... In our private Zope version, I have used an exception ("UseTraversalDefault") for this purpose. I think that __bobo_traverse__ can raise AttributeError currently to indicate that it has failed to look up an attribute and that traversal should try other options. Apart from being a more explicit spelling, what advantage would UseTraversalDefault have?
First of all, I had expected that you were in favour of "explicit is better than implicit" (usually, I am not). In this case, you should be happy with a "more explicit spelling" ;-)
Don't get me wrong, I am :).
I do not know the current code in Zope 2.10, but earlier it looked like:
if hasattr(object,'__bobo_traverse__'):
Btw, I think this should be a gettattr() call here, hasattr eats exceptions.
try: subobject=object.__bobo_traverse__(request,entry_name) ... except (AttributeError, KeyError): if debug_mode: return response.debugError( "Cannot locate object at: %s" % URL) else: return response.notFoundError(URL)
With this code, you were only partially right:
Right, I stand corrected. I have no problem with a more explicit spelling; I didn't even have one in the first place, was just wondering what advantage UseTraversalDefault would have (see my original inquiry above). We just need to be careful about BBB, as Tres pointed out. The whole __bobo_traverse__ mess makes me wonder whether it's worth to improve at all. After all, with IPublishTraverse adapters being a first class citizen now in ZPublisher, we could, well, leave __bobo_traverse__ as it is, deprecate it and let it rod till eternity? Philipp
participants (6)
-
Dieter Maurer -
Florent Guillaume -
Lennart Regebro -
Martijn Faassen -
Philipp von Weitershausen -
Tres Seaver