[Checkins] SVN: Zope3/branches/3.2/src/zope/documenttemplate/ Backported fix from 3.3 branch r70129.

Yusei Tahara yusei at domen.cx
Thu Sep 28 11:19:59 EDT 2006


Log message for revision 70423:
  Backported fix from 3.3 branch r70129.
  

Changed:
  U   Zope3/branches/3.2/src/zope/documenttemplate/pdocumenttemplate.py
  U   Zope3/branches/3.2/src/zope/documenttemplate/tests/testdt_var.py
  A   Zope3/branches/3.2/src/zope/documenttemplate/ustr.py

-=-
Modified: Zope3/branches/3.2/src/zope/documenttemplate/pdocumenttemplate.py
===================================================================
--- Zope3/branches/3.2/src/zope/documenttemplate/pdocumenttemplate.py	2006-09-28 15:19:49 UTC (rev 70422)
+++ Zope3/branches/3.2/src/zope/documenttemplate/pdocumenttemplate.py	2006-09-28 15:19:58 UTC (rev 70423)
@@ -18,6 +18,7 @@
 from types import StringTypes, TupleType, ClassType
 ClassTypes = [ClassType]
 
+from zope.documenttemplate.ustr import ustr
 
 def safe_callable(ob):
     # Works with ExtensionClasses and Acquisition.
@@ -280,7 +281,7 @@
                     section = md[section]
                 else:
                     section = section(md)
-                section = str(section)
+                section = ustr(section)
             else:
                 # if
                 cache = {}

Modified: Zope3/branches/3.2/src/zope/documenttemplate/tests/testdt_var.py
===================================================================
--- Zope3/branches/3.2/src/zope/documenttemplate/tests/testdt_var.py	2006-09-28 15:19:49 UTC (rev 70422)
+++ Zope3/branches/3.2/src/zope/documenttemplate/tests/testdt_var.py	2006-09-28 15:19:58 UTC (rev 70423)
@@ -121,6 +121,29 @@
         self.assertEqual(res2, expected2)
 
 
+    def testNonAsciiUnicode(self):
+
+        html = self.doc_class(
+            u"""
+            English  : Hello world!
+            Japanese : <dtml-var japanese>
+            Chinese  : <dtml-var chinese>
+            Korea    : <dtml-var korean>
+            """)
+
+        expected = (
+            u"""
+            English  : Hello world!
+            Japanese : \u3053\u3093\u306b\u3061\u306f \u4e16\u754c!
+            Chinese  : \u4f60\u597d\uff0c\u4e16\u754c\uff01
+            Korea    : \uc548\ub155, \uc138\uc0c1!
+            """)
+
+        self.assertEqual(html(japanese=u'\u3053\u3093\u306b\u3061\u306f \u4e16\u754c!',
+                              chinese=u'\u4f60\u597d\uff0c\u4e16\u754c\uff01',
+                              korean=u'\uc548\ub155, \uc138\uc0c1!'),
+                         expected)
+
 def test_suite():
     suite = unittest.TestSuite()
     suite.addTest(unittest.makeSuite(TestDT_Var))

Added: Zope3/branches/3.2/src/zope/documenttemplate/ustr.py
===================================================================
--- Zope3/branches/3.2/src/zope/documenttemplate/ustr.py	2006-09-28 15:19:49 UTC (rev 70422)
+++ Zope3/branches/3.2/src/zope/documenttemplate/ustr.py	2006-09-28 15:19:58 UTC (rev 70423)
@@ -0,0 +1,62 @@
+##############################################################################
+#
+# Copyright (c) 2002 Zope Corporation and Contributors. All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""ustr function.
+
+$Id: ustr.py 67722 2006-04-28 15:10:48Z philikon $
+"""
+
+nasty_exception_str = Exception.__str__.im_func
+
+def ustr(v):
+    """Convert any object to a plain string or unicode string,
+    minimising the chance of raising a UnicodeError. This
+    even works with uncooperative objects like Exceptions
+    """
+    if isinstance(v, basestring):
+        return v
+    else:
+        fn = getattr(v,'__str__',None)
+        if fn is not None:
+            # An object that wants to present its own string representation,
+            # but we dont know what type of string. We cant use any built-in
+            # function like str() or unicode() to retrieve it because
+            # they all constrain the type which potentially raises an exception.
+            # To avoid exceptions we have to call __str__ direct.
+            if getattr(fn,'im_func',None)==nasty_exception_str:
+                # Exception objects have been optimised into C, and their
+                # __str__ function fails when given a unicode object.
+                # Unfortunately this scenario is all too common when
+                # migrating to unicode, because of code which does:
+                # raise ValueError(something_I_wasnt_expecting_to_be_unicode)
+                return _exception_str(v)
+            else:
+                # Trust the object to do this right
+                v = fn()
+                if isinstance(v, basestring):
+                    return v
+                else:
+                    raise ValueError('__str__ returned wrong type')
+        # Drop through for non-instance types, and instances that
+        # do not define a special __str__
+        return str(v)
+
+
+def _exception_str(exc):
+    if hasattr(exc, 'args'):
+        if not exc.args:
+            return ''
+        elif len(exc.args) == 1:
+            return ustr(exc.args[0])
+        else:
+            return str(exc.args)
+    return str(exc)



More information about the Checkins mailing list