Author: chrisz
Date: 2009-03-12 10:59:49 -0600 (Thu, 12 Mar 2009)
New Revision: 3805

Modified:
   FormEncode/trunk/formencode/validators.py
Log:
Allow None (with the meaning "do not decode/encode" as input or output decoding 
for UnicodeString. This is useful if you're sending output to a templating 
engine which usually expect unicode objects instead of encoded strings.

Modified: FormEncode/trunk/formencode/validators.py
===================================================================
--- FormEncode/trunk/formencode/validators.py   2009-03-09 18:15:44 UTC (rev 
3804)
+++ FormEncode/trunk/formencode/validators.py   2009-03-12 16:59:49 UTC (rev 
3805)
@@ -1154,10 +1154,16 @@
         'badEncoding' : _("Invalid data or incorrect encoding"),
     }
 
-    def __init__(self, inputEncoding=None, outputEncoding=None, **kw):
+    def __init__(self, inputEncoding=NoDefault, outputEncoding=NoDefault, 
**kw):
         String.__init__(self, **kw)
-        self.inputEncoding = inputEncoding or self.encoding
-        self.outputEncoding = outputEncoding or self.encoding
+        if inputEncoding is NoDefault:
+            self.inputEncoding = self.encoding
+        else:
+            self.inputEncoding = inputEncoding
+        if outputEncoding is NoDefault:
+            self.outputEncoding = self.encoding
+        else:
+            self.outputEncoding = outputEncoding
 
     def _to_python(self, value, state):
         if not value:
@@ -1170,12 +1176,15 @@
                 return value
             else:
                 value = str(value)
-        try:
-            return unicode(value, self.inputEncoding)
-        except UnicodeDecodeError:
-            raise Invalid(self.message('badEncoding', state), value, state)
-        except TypeError:
-            raise Invalid(self.message('badType', state, type=type(value), 
value=value), value, state)
+        if self.inputEncoding:
+            try:
+                value = unicode(value, self.inputEncoding)
+            except UnicodeDecodeError:
+                raise Invalid(self.message('badEncoding', state), value, state)
+            except TypeError:
+                raise Invalid(self.message('badType', state, type=type(value),
+                    value=value), value, state)
+        return value
 
     def _from_python(self, value, state):
         if not isinstance(value, unicode):
@@ -1183,7 +1192,7 @@
                 value = unicode(value)
             else:
                 value = str(value)
-        if isinstance(value, unicode):
+        if self.outputEncoding and isinstance(value, unicode):
             value = value.encode(self.outputEncoding)
         return value
 
@@ -1534,16 +1543,16 @@
                     self.message('status', state, status=res.status),
                     state, url)
 
-    
+
 class XRI(FancyValidator):
     r"""
     Validator for XRIs.
-    
+
     It supports both i-names and i-numbers, of the first version of the XRI
     standard.
-    
+
     ::
-        
+
         >>> inames = XRI(xri_type="i-name")
         >>> inames.to_python("   =John.Smith ")
         '=John.Smith'
@@ -1573,9 +1582,9 @@
         '!!1000!de21.4536.2cb2.8074'
         >>> inumbers.to_python("@!1000.9554.fabd.129c!2847.df3c")
         '@!1000.9554.fabd.129c!2847.df3c'
-    
+
     """
-    
+
     iname_valid_pattern = re.compile(r"""
     ^
     [\w]+                  # A global alphanumeric i-name
@@ -1583,11 +1592,11 @@
     (\*[\w]+(\.[\w]+)*)*   # A community i-name
     $
     """, re.VERBOSE|re.UNICODE)
-    
-    
+
+
     iname_invalid_start = re.compile(r"^[\d\.-]", re.UNICODE)
     """@cvar: These characters must not be at the beggining of the i-name"""
-    
+
     inumber_pattern = re.compile(r"""
     ^
     (
@@ -1599,7 +1608,7 @@
     (![\dA-F]{1,4}(\.[\dA-F]{1,4}){0,3})*   # Zero or more sub i-numbers
     $
     """, re.VERBOSE|re.IGNORECASE)
-    
+
     messages = {
         'noType': _("The type of i-name is not defined; it may be either 
individual or organizational"),
         'repeatedChar': _("Dots and dashes may not be repeated consecutively"),
@@ -1610,24 +1619,24 @@
         'badType': _("The XRI must be a string (not a %(type)s: %(value)r)"),
         'badXri': _('"%(xri_type)s" is not a valid type of XRI')
         }
-    
+
     def __init__(self, add_xri=False, xri_type="i-name", **kwargs):
         """Create an XRI validator.
-        
+
         @param add_xri: Should the schema be added if not present? Officially
             it's optional.
         @type add_xri: C{bool}
         @param xri_type: What type of XRI should be validated? Possible values:
             C{i-name} or C{i-number}.
         @type xri_type: C{str}
-        
+
         """
         self.add_xri = add_xri
         assert xri_type in ('i-name', 'i-number'), \
                            ('xri_type must be "i-name" or "i-number"')
         self.xri_type = xri_type
         super(XRI, self).__init__(**kwargs)
-    
+
     def _to_python(self, value, state):
         """Prepend the 'xri://' schema if necessary and then remove trailing
         spaces"""
@@ -1635,35 +1644,35 @@
         if self.add_xri and not value.startswith("xri://"):
             value = "xri://" + value
         return value
-    
+
     def validate_python(self, value, state=None):
         """Validate an XRI
-        
+
         @raise Invalid: If at least one of the following conditions in met:
             - C{value} is not a string.
             - The XRI is not a personal, organizational or network one.
             - The relevant validator (i-name or i-number) considers the XRI
                 is not valid.
-        
+
         """
         if not (isinstance(value, str) or isinstance(value, unicode)):
             raise Invalid(self.message("badType", state, type=str(type(value)),
                                        value=value),
                           value, state)
-        
+
         # Let's remove the schema, if any
         if value.startswith("xri://"):
             value = value[6:]
-        
+
         if not value[0] in ('@', '=') and not (self.xri_type == "i-number" \
         and value[0] == '!'):
             raise Invalid(self.message("noType", state), value, state)
-        
+
         if self.xri_type == "i-name":
             self._validate_iname(value, state)
         else:
             self._validate_inumber(value, state)
-    
+
     def _validate_iname(self, iname, state):
         """Validate an i-name"""
         # The type is not required here:
@@ -1675,7 +1684,7 @@
         if not self.iname_valid_pattern.match(iname) or "_" in iname:
             raise Invalid(self.message("badIname", state, iname=iname), iname,
                           state)
-    
+
     def _validate_inumber(self, inumber, state):
         """Validate an i-number"""
         if not self.__class__.inumber_pattern.match(inumber):
@@ -1687,7 +1696,7 @@
 class OpenId(FancyValidator):
     r"""
     OpenId validator.
-    
+
     ::
         >>> v = OpenId(add_schema=True)
         >>> v.to_python(' example.net ')
@@ -1705,24 +1714,24 @@
         Traceback (most recent call last):
         ...
         Invalid: "[email protected]" is not a valid OpenId (it is neither an URL nor 
an XRI)
-    
+
     """
-    
+
     messages = {
         'badId': _('"%(id)s" is not a valid OpenId (it is neither an URL nor 
an XRI)')
         }
-    
+
     def __init__(self, add_schema=False, **kwargs):
         """Create an OpenId validator.
-        
+
         @param add_schema: Should the schema be added if not present?
         @type add_schema: C{bool}
-        
+
         """
         self.url_validator = URL(add_http=add_schema)
         self.iname_validator = XRI(add_schema, xri_type="i-name")
         self.inumber_validator = XRI(add_schema, xri_type="i-number")
-    
+
     def _to_python(self, value, state):
         value = value.strip()
         try:
@@ -1737,7 +1746,7 @@
                     pass
         # It's not an OpenId!
         raise Invalid(self.message("badId", state, id=value), value, state)
-    
+
     def validate_python(self, value, state):
         self._to_python(value, state)
 


------------------------------------------------------------------------------
Apps built with the Adobe(R) Flex(R) framework and Flex Builder(TM) are
powering Web 2.0 with engaging, cross-platform capabilities. Quickly and
easily build your RIAs with Flex Builder, the Eclipse(TM)based development
software that enables intelligent coding and step-through debugging.
Download the free 60 day trial. http://p.sf.net/sfu/www-adobe-com
_______________________________________________
FormEncode-CVS mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/formencode-cvs

Reply via email to