[Zope3-checkins] SVN: Zope3/branches/3.2/ cleaned up redundant code from two different attempts to fix issue 599:

Yvo Schubbe y.2006_ at wcm-solutions.de
Sun Oct 1 16:55:49 EDT 2006


Log message for revision 70466:
  cleaned up redundant code from two different attempts to fix issue 599:
  
  - removed elif clause that bypassed view lookup
  - improved i18n Message handling of the error view
  - moved error view tests to error.txt
  - some related cleanup
  
  (Just want to make sure this goes into the 3.2.2 release. I'll forward port this tomorrow to 3.3 and trunk.)

Changed:
  U   Zope3/branches/3.2/doc/CHANGES.txt
  U   Zope3/branches/3.2/src/zope/formlib/configure.zcml
  U   Zope3/branches/3.2/src/zope/formlib/errors.py
  U   Zope3/branches/3.2/src/zope/formlib/errors.txt
  U   Zope3/branches/3.2/src/zope/formlib/form.py
  U   Zope3/branches/3.2/src/zope/formlib/tests.py

-=-
Modified: Zope3/branches/3.2/doc/CHANGES.txt
===================================================================
--- Zope3/branches/3.2/doc/CHANGES.txt	2006-10-01 17:47:37 UTC (rev 70465)
+++ Zope3/branches/3.2/doc/CHANGES.txt	2006-10-01 20:55:48 UTC (rev 70466)
@@ -10,14 +10,11 @@
 
     Bug fixes
 
+      - Improved fix for issue 599: Made sure i18n Message based Invalid
+        exceptions are handled correctly.
+
       - Fixed a bug in getImageInfo which could cause an
         UnboundLocalError under certain conditions.
-    
-      - Fix invariant error handling in formlib. The exception Invalid raised
-        in interface invariants where end in a component lookup error because
-        this exception didn't get converted to a usefull error message.
-        Now the error_views method in formlib can handle strings and i18n 
-        Message based Invalid exceptions.
 
       - Fixed issue 691: make formlib javascript to display help texts more
         robust. It can now also display the helptext correctly if a complex

Modified: Zope3/branches/3.2/src/zope/formlib/configure.zcml
===================================================================
--- Zope3/branches/3.2/src/zope/formlib/configure.zcml	2006-10-01 17:47:37 UTC (rev 70465)
+++ Zope3/branches/3.2/src/zope/formlib/configure.zcml	2006-10-01 20:55:48 UTC (rev 70466)
@@ -18,10 +18,7 @@
       />
 
   <!-- Error view for 'Invalid' -->
-  <view
-      type="zope.publisher.interfaces.browser.IBrowserRequest"
-      for="zope.interface.exceptions.Invalid"
-      provides="zope.app.form.browser.interfaces.IWidgetInputErrorView"
+  <adapter
       factory=".errors.InvalidErrorView"
       permission="zope.Public"
       />

Modified: Zope3/branches/3.2/src/zope/formlib/errors.py
===================================================================
--- Zope3/branches/3.2/src/zope/formlib/errors.py	2006-10-01 17:47:37 UTC (rev 70465)
+++ Zope3/branches/3.2/src/zope/formlib/errors.py	2006-10-01 20:55:48 UTC (rev 70466)
@@ -18,18 +18,23 @@
 
 from cgi import escape
 
+from zope.component import adapts
 from zope.interface import implements
+from zope.interface import Invalid
+from zope.i18n import Message
 from zope.i18n import translate
 
-from zope.app.form.interfaces import IWidgetInputError
 from zope.app.form.browser.interfaces import IWidgetInputErrorView
+from zope.publisher.interfaces.browser import IBrowserRequest
 
+
 class InvalidErrorView(object):
+
     """Display a validation error as a snippet of text."""
+
     implements(IWidgetInputErrorView)
+    adapts(Invalid, IBrowserRequest)
 
-    __used_for__ = IWidgetInputError
-
     def __init__(self, context, request):
         self.context = context
         self.request = request
@@ -42,7 +47,7 @@
         >>> InvalidErrorView(error, None).snippet()
         u'<span class="error">You made an error!</span>'
         """
-        message = str(self.context)
-        translated = translate(message, context=self.request, default=message)
-        return u'<span class="error">%s</span>' % escape(translated)
-
+        msg = self.context.args[0]
+        if isinstance(msg, Message):
+            msg = translate(msg, context=self.request)
+        return u'<span class="error">%s</span>' % escape(msg)

Modified: Zope3/branches/3.2/src/zope/formlib/errors.txt
===================================================================
--- Zope3/branches/3.2/src/zope/formlib/errors.txt	2006-10-01 17:47:37 UTC (rev 70465)
+++ Zope3/branches/3.2/src/zope/formlib/errors.txt	2006-10-01 20:55:48 UTC (rev 70466)
@@ -21,3 +21,51 @@
     >>> message
     u'<span class="error">You are wrong!</span>'
 
+Interface invariant methods raise zope.interface.Invalid exception. Test if
+this exception gets handled by the error_views.
+
+    >>> myError = Invalid('My error message')
+    >>> from zope.formlib import form
+    >>> mybase = form.FormBase(None, TestRequest())
+    >>> mybase.errors = (myError,)
+    >>> save = mybase.error_views()
+    >>> save.next()
+    u'<span class="error">My error message</span>'
+
+Now we need to set up the translation framework:
+
+    >>> from zope import component, interface
+    >>> from zope.i18n.interfaces import INegotiator
+    >>> class Negotiator:
+    ...     interface.implements(INegotiator)
+    ...     def getLanguage(*ignored): return 'test'
+    >>> component.provideUtility(Negotiator())
+    >>> from zope.i18n.testmessagecatalog import TestMessageFallbackDomain
+    >>> component.provideUtility(TestMessageFallbackDomain)
+
+And yes, we can even handle an i18n message in an Invalid exception:
+
+    >>> from zope.i18nmessageid import MessageFactory
+    >>> _ = MessageFactory('my.domain')
+    >>> myError = Invalid(_('My i18n error message'))
+    >>> mybase = form.FormBase(None, TestRequest())
+    >>> mybase.errors = (myError,)
+    >>> save = mybase.error_views()
+    >>> save.next()
+    u'<span class="error">[[my.domain][My i18n error message]]</span>'
+
+Displaying widget input errors
+==============================
+
+WidgetInputError exceptions also work with i18n messages:
+
+    >>> from zope.app.form.interfaces import WidgetInputError
+    >>> myError = WidgetInputError(
+    ...     field_name='summary',
+    ...     widget_title=_(u'Summary'),
+    ...     errors=_(u'Foo'))
+    >>> mybase = form.FormBase(None, TestRequest())
+    >>> mybase.errors = (myError,)
+    >>> save = mybase.error_views()
+    >>> save.next()
+    u'[[my.domain][Summary]]: <span class="error">[[my.domain][Foo]]</span>'

Modified: Zope3/branches/3.2/src/zope/formlib/form.py
===================================================================
--- Zope3/branches/3.2/src/zope/formlib/form.py	2006-10-01 17:47:37 UTC (rev 70465)
+++ Zope3/branches/3.2/src/zope/formlib/form.py	2006-10-01 20:55:48 UTC (rev 70466)
@@ -761,14 +761,6 @@
         for error in self.errors:
             if isinstance(error, basestring):
                 yield error
-            elif isinstance(error, interface.Invalid):
-                # convert invariants Invalid exception into usefull error
-                # message strings rather then end in component lookup error
-                msg = error.args[0]
-                if isinstance(msg, zope.i18n.Message):
-                    msg = zope.i18n.translate(msg, context=self.request, 
-                        default=msg)
-                yield u'<span class="error">%s</span>' % msg
             else:
                 view = component.getMultiAdapter(
                     (error, self.request),
@@ -781,6 +773,7 @@
                 else:
                     yield view.snippet()
 
+
 def haveInputWidgets(form, action):
     for input, widget in form.widgets.__iter_input_and_widget__():
         if input:

Modified: Zope3/branches/3.2/src/zope/formlib/tests.py
===================================================================
--- Zope3/branches/3.2/src/zope/formlib/tests.py	2006-10-01 17:47:37 UTC (rev 70465)
+++ Zope3/branches/3.2/src/zope/formlib/tests.py	2006-10-01 20:55:48 UTC (rev 70466)
@@ -233,35 +233,6 @@
 
 """
 
-
-def test_error_views_i18n():
-    """\
-
-    >>> from zope.i18n.simpletranslationdomain import SimpleTranslationDomain
-    >>> from zope.i18n.interfaces import ITranslationDomain
-    >>> messageDic = {('ja', u'Summary'): u'MatomeYaken'}
-    >>> sd = SimpleTranslationDomain('KansaiBen.domain', messageDic)
-    >>> component.provideUtility(provides=ITranslationDomain,
-    ...                          component=sd,
-    ...                          name='KansaiBen.domain')
-    >>> from zope.i18n.negotiator import negotiator
-    >>> component.provideUtility(negotiator)
-    >>> _ = zope.i18nmessageid.MessageFactory('KansaiBen.domain')
-    >>> myError = zope.app.form.interfaces.WidgetInputError(
-    ...     field_name='summary',
-    ...     widget_title=_(u'Summary'))
-    >>> from zope.publisher.browser import TestRequest
-    >>> req = TestRequest()
-    >>> req._environ['HTTP_ACCEPT_LANGUAGE'] = 'ja; q=1.0'
-    >>> mybase = form.FormBase(None, req)
-    >>> mybase.errors = (myError,)
-    >>> save = mybase.error_views()
-    >>> save.next()
-    u'MatomeYaken: <span class="error"></span>'
-    
-"""
-
-
 def test_error_handling():
     """\
 
@@ -313,49 +284,6 @@
     
 """
 
-
-def test_invariants():
-    """\
-
-Let's also test the invariant error handling. Interface invariant methods 
-raise zope.schem.Invalid exception. Test if this exception get handled by the 
-error_views.
-
-    >>> from zope.interface import Invalid
-    >>> myError = Invalid('My error message')
-    >>> from zope.publisher.browser import TestRequest
-    >>> req = TestRequest()
-    >>> mybase = form.FormBase(None, req)
-    >>> mybase.errors = (myError,)
-    >>> save = mybase.error_views()
-    >>> save.next()
-    u'<span class="error">My error message</span>'
-
-And yes, we can even handle a i18n message in a Invalid exception:
-
-    >>> from zope.i18n.simpletranslationdomain import SimpleTranslationDomain
-    >>> from zope.i18n.interfaces import ITranslationDomain
-    >>> messageDic = {('ja', u'My i18n error message'): u'Mein Fehler'}
-    >>> sd = SimpleTranslationDomain('foobar.domain', messageDic)
-    >>> component.provideUtility(provides=ITranslationDomain,
-    ...                          component=sd,
-    ...                          name='foobar.domain')
-    >>> from zope.i18n.negotiator import negotiator
-    >>> component.provideUtility(negotiator)
-    >>> _ = zope.i18nmessageid.MessageFactory('foobar.domain')
-    >>> myError = Invalid(_('My i18n error message'))
-    >>> from zope.publisher.browser import TestRequest
-    >>> req = TestRequest()
-    >>> req._environ['HTTP_ACCEPT_LANGUAGE'] = 'ja; q=1.0'
-    >>> mybase = form.FormBase(None, req)
-    >>> mybase.errors = (myError,)
-    >>> save = mybase.error_views()
-    >>> save.next()
-    u'<span class="error">Mein Fehler</span>'
-
-"""
-
-
 def test_form_template_i18n():
     """\
 Let's try to check that the formlib templates handle i18n correctly.



More information about the Zope3-Checkins mailing list