[Zope-Checkins]
SVN: Zope/branches/ajung-death-to-unicode-errors/lib/python/Products/PageTemplates/
- implemented some unicode encoding conflict resolvers
Andreas Jung
andreas at andreas-jung.com
Sun Jan 7 05:25:22 EST 2007
Log message for revision 71752:
- implemented some unicode encoding conflict resolvers
- configuration through ZCML
- additional useful logging
Changed:
U Zope/branches/ajung-death-to-unicode-errors/lib/python/Products/PageTemplates/Expressions.py
U Zope/branches/ajung-death-to-unicode-errors/lib/python/Products/PageTemplates/configure.zcml
U Zope/branches/ajung-death-to-unicode-errors/lib/python/Products/PageTemplates/interfaces.py
U Zope/branches/ajung-death-to-unicode-errors/lib/python/Products/PageTemplates/unicodeconflictresolver.py
-=-
Modified: Zope/branches/ajung-death-to-unicode-errors/lib/python/Products/PageTemplates/Expressions.py
===================================================================
--- Zope/branches/ajung-death-to-unicode-errors/lib/python/Products/PageTemplates/Expressions.py 2007-01-07 01:31:25 UTC (rev 71751)
+++ Zope/branches/ajung-death-to-unicode-errors/lib/python/Products/PageTemplates/Expressions.py 2007-01-07 10:25:20 UTC (rev 71752)
@@ -18,8 +18,9 @@
$Id$
"""
-import sys
+import logging
+from zope.component import getUtility
from zope.interface import implements
from zope.tales.tales import Context, Iterator
from zope.tales.expressions import PathExpr, StringExpr, NotExpr
@@ -34,13 +35,17 @@
from MultiMapping import MultiMapping
from Acquisition import aq_base
from zExceptions import NotFound, Unauthorized
+
from Products.Five.browser.providerexpression import Z2ProviderExpression
from Products.PageTemplates import ZRPythonExpr
from Products.PageTemplates.DeferExpr import LazyExpr
from Products.PageTemplates.GlobalTranslationService import getGlobalTranslationService
+from Products.PageTemplates.interfaces import IUnicodeEncodingConflictResolver
SecureModuleImporter = ZRPythonExpr._SecureModuleImporter()
+LOG = logging.getLogger('Expressions')
+
# BBB 2005/05/01 -- remove after 12 months
import zope.deprecation
from zope.deprecation import deprecate
@@ -183,9 +188,9 @@
"""
text = self.evaluate(expr)
-# print expr, repr(text), text.__class__
if text is self.getDefault() or text is None:
+ # XXX: should be unicode???
return text
if isinstance(text, unicode):
@@ -193,26 +198,20 @@
return text
elif isinstance(text, str):
- # waahhh...a standard string
- # trying to be somewhat smart...this must be
- # replaced with some kind of configurable
- # UnicodeEncodingConflictResolver (what a name)
+ # bahh...non-unicode string..we need to convert it to unicode
+ resolver = getUtility(IUnicodeEncodingConflictResolver)
try:
- return unicode(text)
-
- except UnicodeDecodeError:
- # check for management_page_charset property, default to Python's
- # default encoding
-
- encoding = getattr(self.contexts['context'], 'management_page_charset', sys.getdefaultencoding())
-
- try:
- return unicode(text, encoding)
- except UnicodeDecodeError:
- # errors='replace' sucks...it's fine for now
- return unicode(text, encoding, 'replace')
-
+ return resolver.resolve(self.contexts['context'], text, expr)
+ except UnicodeDecodeError,e:
+ LOG.error("""UnicodeDecodeError detected for expression "%s"\n"""
+ """Resolver class: %s\n"""
+ """Exception text: %s\n"""
+ """Template: %s\n"""
+ """Rendered text: %r""" % \
+ (expr, resolver.__class__, e,
+ self.contexts['template'].absolute_url(1), text))
+ raise
else:
# This is a weird culprit ...calling unicode() on non-string
Modified: Zope/branches/ajung-death-to-unicode-errors/lib/python/Products/PageTemplates/configure.zcml
===================================================================
--- Zope/branches/ajung-death-to-unicode-errors/lib/python/Products/PageTemplates/configure.zcml 2007-01-07 01:31:25 UTC (rev 71751)
+++ Zope/branches/ajung-death-to-unicode-errors/lib/python/Products/PageTemplates/configure.zcml 2007-01-07 10:25:20 UTC (rev 71752)
@@ -1,11 +1,8 @@
-<configure xmlns="http://namespaces.zope.org/zope"
- xmlns:browser="http://namespaces.zope.org/browser"
- xmlns:five="http://namespaces.zope.org/five">
+<configure xmlns="http://namespaces.zope.org/zope">
-
<utility
- provides="zope.component.interfaces.IFactory"
- component="Products.PageTemplates.unicodeconflictresolver.UnicodeEncodingResolverFactory"
+ provides="Products.PageTemplates.interfaces.IUnicodeEncodingConflictResolver"
+ component="Products.PageTemplates.unicodeconflictresolver.DefaultUnicodeEncodingConflictResolver"
/>
</configure>
Modified: Zope/branches/ajung-death-to-unicode-errors/lib/python/Products/PageTemplates/interfaces.py
===================================================================
--- Zope/branches/ajung-death-to-unicode-errors/lib/python/Products/PageTemplates/interfaces.py 2007-01-07 01:31:25 UTC (rev 71751)
+++ Zope/branches/ajung-death-to-unicode-errors/lib/python/Products/PageTemplates/interfaces.py 2007-01-07 10:25:20 UTC (rev 71752)
@@ -1,12 +1,30 @@
+##############################################################################
+#
+# 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
+#
+##############################################################################
-
from zope.interface import Interface
class IUnicodeEncodingConflictResolver(Interface):
+ """ A utility that tries to convert a non-unicode string into
+ a Python unicode by implementing some policy in order
+ to figure out a possible encoding - either through the
+ calling context, the location or the system environment
+ """
- def resolve(context, text):
+ def resolve(context, text, expression):
""" Returns 'text' as unicode string.
- 'context' is the current context object
+ 'context' is the current context object.
+ 'expression' is the original expression (can be used for
+ logging purposes)
"""
Modified: Zope/branches/ajung-death-to-unicode-errors/lib/python/Products/PageTemplates/unicodeconflictresolver.py
===================================================================
--- Zope/branches/ajung-death-to-unicode-errors/lib/python/Products/PageTemplates/unicodeconflictresolver.py 2007-01-07 01:31:25 UTC (rev 71751)
+++ Zope/branches/ajung-death-to-unicode-errors/lib/python/Products/PageTemplates/unicodeconflictresolver.py 2007-01-07 10:25:20 UTC (rev 71752)
@@ -1,37 +1,56 @@
-###########################################################################
-# TextIndexNG V 3
-# The next generation TextIndex for Zope
+##############################################################################
#
-# This software is governed by a license. See
-# LICENSE.txt for the terms of this license.
-###########################################################################
+# 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
+#
+##############################################################################
+import sys
+from zope.interface import implements
+from Products.PageTemplates.interfaces import IUnicodeEncodingConflictResolver
+default_encoding = sys.getdefaultencoding()
-from zope.component.interfaces import IFactory
-from zope.interface import implements, implementedBy
+class DefaultUnicodeEncodingConflictResolver:
+ """ This resolver implements the old-style behavior and will
+ raise an exception in case of the string 'text' can't be converted
+ propertly to unicode.
+ """
-from Products.PageTemplates.interfaces import IUnicodeEncodingConflictResolver
+ implements(IUnicodeEncodingConflictResolver)
-class UnicodeEncodingResolver:
+ def resolve(self, context, text, expression):
+ return unicode(text)
+DefaultUnicodeEncodingConflictResolver = DefaultUnicodeEncodingConflictResolver()
+
+
+class Z2UnicodeEncodingConflictResolver:
+ """ This resolver tries to lookup the encoding from the
+ 'management_page_charset' property and defaults to
+ sys.getdefaultencoding().
+ """
+
implements(IUnicodeEncodingConflictResolver)
- def __init__(self, context, text):
- self.context = context
- self.text = text
+ def __init__(self, mode='strict'):
+ self.mode = mode
- def resolve(self, context, text):
- return unicode(self.text, errors='replace')
+ def resolve(self, context, text, expression):
-class UnicodeEncodingResolverFactory:
-
- implements(IFactory)
+ try:
+ return unicode(text)
+ except UnicodeDecodeError:
+ encoding = getattr(context, 'managment_page_charset', default_encoding)
+ return unicode(text, encoding, self.mode)
- def __call__(self, context, text):
- return UnicodeEncodingResolver(context, text)
- def getInterfaces(self):
- return implementedBy(UnicodeEncodingResolverFactory)
-
-UnicodeEncodingResolverFactory = UnicodeEncodingResolverFactory()
+StrictUnicodeEncodingConflictResolver = Z2UnicodeEncodingConflictResolver('strict')
+ReplacingUnicodeEncodingConflictResolver = Z2UnicodeEncodingConflictResolver('replace')
+IgnoringUnicodeEncodingConflictResolver = Z2UnicodeEncodingConflictResolver('ignore')
More information about the Zope-Checkins
mailing list