Commit a1ea75b1 authored by Sidnei da Silva's avatar Sidnei da Silva

- Fix #2155: Wrong parameters being passed to logger's error().

parents 76fccc3c fc2f28d4
...@@ -29,6 +29,9 @@ Zope Changes ...@@ -29,6 +29,9 @@ Zope Changes
Bugs Fixed Bugs Fixed
- Collector #2155: Fix wrong parameter being passed to
logger's error() method, with tests.
- Collector #2157: Expose name of broken class in SystemError raised - Collector #2157: Expose name of broken class in SystemError raised
from '__getstate__' of a broken instance. from '__getstate__' of a broken instance.
......
...@@ -16,7 +16,6 @@ __version__='$Revision: 1.12 $'[11:-2] ...@@ -16,7 +16,6 @@ __version__='$Revision: 1.12 $'[11:-2]
from Acquisition import aq_base from Acquisition import aq_base
from logging import getLogger from logging import getLogger
import sys
# Interface # Interface
...@@ -106,7 +105,7 @@ class MultiHook: ...@@ -106,7 +105,7 @@ class MultiHook:
cob(container, request) cob(container, request)
except TypeError: except TypeError:
LOG.error('%s call %s failed.' % ( LOG.error('%s call %s failed.' % (
`self._hookname`, `cob`), exc_info=sys.exc_info()) `self._hookname`, `cob`), exc_info=True)
def add(self, cob): def add(self, cob):
self._list.append(cob) self._list.append(cob)
...@@ -151,6 +150,5 @@ class NameCaller: ...@@ -151,6 +150,5 @@ class NameCaller:
# Only catch exceptions that are likely to be logic errors. # Only catch exceptions that are likely to be logic errors.
# We shouldn't catch Redirects, Unauthorizeds, etc. since # We shouldn't catch Redirects, Unauthorizeds, etc. since
# the programmer may want to raise them deliberately. # the programmer may want to raise them deliberately.
LOG.error('BeforeTraverse: Error while invoking hook: "%s"' % self.name, LOG.error('BeforeTraverse: Error while invoking hook: "%s"' % self.name,
exc_info=sys.exc_info()) exc_info=True)
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('ZPublisher')
>>> 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 ...>}
Now do the actual traversal:
>>> _ = request.traverse('container/obj')
BrokenHook called
BeforeTraverse: Error while invoking hook: "broken_callable"
Traceback (most recent call last):
...
TypeError: BrokenHook
Unregister the borken hook:
>>> _ = BeforeTraverse.unregisterBeforeTraverse(container, 'broken_callable')
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)
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment