[Zope-Checkins] SVN: Zope/branches/2.9/ - Fix #2155: Wrong parameters being passed to logger's error().

Sidnei da Silva sidnei at enfoldsystems.com
Fri Aug 18 12:34:07 EDT 2006


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)



More information about the Zope-Checkins mailing list