Log message for revision 69658: - Fix #2155: Wrong parameters being passed to logger's error().
Changed: U Zope/branches/2.9/doc/CHANGES.txt U Zope/branches/2.9/lib/python/ZPublisher/BeforeTraverse.py A Zope/branches/2.9/lib/python/ZPublisher/tests/testBeforeTraverse.py -=- Modified: Zope/branches/2.9/doc/CHANGES.txt =================================================================== --- Zope/branches/2.9/doc/CHANGES.txt 2006-08-18 16:10:19 UTC (rev 69657) +++ Zope/branches/2.9/doc/CHANGES.txt 2006-08-18 16:34:06 UTC (rev 69658) @@ -16,6 +16,9 @@ - Usage of 'urljoin' in 'webdav.davcmds' could lead to wrongly constructed urls. + - Collector #2155: Fix wrong parameter being passed to + logger's error() method, with tests. + Zope 2.9.4 (2006/07/21) Bugs fixed Modified: Zope/branches/2.9/lib/python/ZPublisher/BeforeTraverse.py =================================================================== --- Zope/branches/2.9/lib/python/ZPublisher/BeforeTraverse.py 2006-08-18 16:10:19 UTC (rev 69657) +++ Zope/branches/2.9/lib/python/ZPublisher/BeforeTraverse.py 2006-08-18 16:34:06 UTC (rev 69658) @@ -13,10 +13,9 @@ __version__='$Revision: 1.12 $'[11:-2] """BeforeTraverse interface and helper classes""" -import logging +import logging from Acquisition import aq_base -import sys # Interface @@ -105,7 +104,7 @@ cob(container, request) except TypeError: self.logger.error('%s call %s failed.' % ( - `self._hookname`, `cob`), error=sys.exc_info()) + `self._hookname`, `cob`), exc_info=True) def add(self, cob): self._list.append(cob) @@ -151,6 +150,5 @@ # Only catch exceptions that are likely to be logic errors. # We shouldn't catch Redirects, Unauthorizeds, etc. since # the programmer may want to raise them deliberately. - import sys self.logger.error('Error while invoking hook: "%s"' - % self.name, error=sys.exc_info()) + % self.name, exc_info=True) Added: Zope/branches/2.9/lib/python/ZPublisher/tests/testBeforeTraverse.py =================================================================== --- Zope/branches/2.9/lib/python/ZPublisher/tests/testBeforeTraverse.py 2006-08-18 16:10:19 UTC (rev 69657) +++ Zope/branches/2.9/lib/python/ZPublisher/tests/testBeforeTraverse.py 2006-08-18 16:34:06 UTC (rev 69658) @@ -0,0 +1,153 @@ +import sys +import logging + +from Acquisition import Implicit +from ZPublisher import BeforeTraverse +from ZPublisher.BaseRequest import BaseRequest +from ZPublisher.HTTPResponse import HTTPResponse + +def makeBaseRequest(root): + response = HTTPResponse() + environment = { 'URL': '', + 'PARENTS': [root], + 'steps': [], + '_hacked_path': 0, + '_test_counter': 0, + 'response': response } + return BaseRequest(environment) + + +class DummyObjectBasic(Implicit): + """ Dummy class with docstring. + """ + pass + + +class BrokenHook: + + def __call__(self, *args): + print self.__class__.__name__, 'called' + raise TypeError, self.__class__.__name__ + +def testBeforeTraverse(self): + """ + Zope supports a 'before traverse' hook that is used for several + features, including 'Site Access Rules'. It is implemented using a + special API for registering hooks, and the hooks themselves are + called during traversal by ZPublisher. + + >>> root = DummyObjectBasic() + >>> request = makeBaseRequest(root) + + >>> container = DummyObjectBasic() + >>> root.container = container + + >>> obj = DummyObjectBasic() + >>> container.obj = obj + + Setup a broken hook as the before traverse hook for the + container. That will create a 'MultiHook' object: + + >>> BeforeTraverse.registerBeforeTraverse(container, BrokenHook(), + ... 'broken_hook') + + >>> container.__before_publishing_traverse__ + <ZPublisher.BeforeTraverse.MultiHook instance at ...> + + >>> container.__before_traverse__ + {(99, 'broken_hook'): <ZPublisher.tests.testBeforeTraverse.BrokenHook ...>} + + Setup logging so we can see the actual exception being logged: + + >>> logger = logging.getLogger('MultiHook') + >>> level = logger.level + >>> handlers = logger.handlers[:] + + >>> logger.addHandler(logging.StreamHandler(sys.stdout)) + >>> logger.setLevel(logging.ERROR) + + Now do the actual traversal: + + >>> _ = request.traverse('container/obj') + BrokenHook called + '__before_publishing_traverse__' call ... failed. + Traceback (most recent call last): + ... + TypeError: BrokenHook + + Unregister the borken hook: + + >>> _ = BeforeTraverse.unregisterBeforeTraverse(container, 'broken_hook') + + The list of 'before traverse' hooks is empty: + + >>> container.__before_traverse__ + {} + + But the 'MultiHook' is not removed: + + >>> container.__before_publishing_traverse__ + <ZPublisher.BeforeTraverse.MultiHook instance at ...> + + If you have an object in the same container that you want to call + during traversal you can register a 'NameCaller' as the hook + instead, and it will delegate to the callable by looking it up as + an attribute of the container: + + >>> container.broken_callable = BrokenHook() + >>> BeforeTraverse.registerBeforeTraverse(container, + ... BeforeTraverse.NameCaller('broken_callable'), + ... 'broken_callable') + + >>> container.__before_traverse__ + {(99, 'broken_callable'): <ZPublisher.BeforeTraverse.NameCaller ...>} + + Setup logging so we can see the actual exception being logged: + + >>> bt_logger = logging.getLogger('BeforeTraverse') + >>> bt_level = logger.level + >>> bt_handlers = logger.handlers[:] + + >>> bt_logger.addHandler(logging.StreamHandler(sys.stdout)) + >>> bt_logger.setLevel(logging.ERROR) + + Now do the actual traversal: + + >>> _ = request.traverse('container/obj') + BrokenHook called + Error while invoking hook: "broken_callable" + Traceback (most recent call last): + ... + TypeError: BrokenHook + + Unregister the borken hook: + + >>> _ = BeforeTraverse.unregisterBeforeTraverse(container, 'broken_callable') + + And restore the logger state: + + >>> bt_logger.setLevel(bt_level) + >>> bt_logger.handlers = handlers[:] + + The list of 'before traverse' hooks is empty: + + >>> container.__before_traverse__ + {} + + But the 'MultiHook' is not removed: + + >>> container.__before_publishing_traverse__ + <ZPublisher.BeforeTraverse.MultiHook instance at ...> + + Finally, restore the logger state: + + >>> logger.setLevel(level) + >>> logger.handlers = handlers[:] + + """ + pass + +from zope.testing import doctest + +def test_suite(): + return doctest.DocTestSuite(optionflags=doctest.ELLIPSIS) _______________________________________________ Zope-Checkins maillist - Zope-Checkins@zope.org http://mail.zope.org/mailman/listinfo/zope-checkins