From 782d89986fb5a234c65eddbd0765bf788d340706 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Fri, 2 Apr 2010 17:26:30 +0000 Subject: [PATCH] - Fix bug in serialization of non-Unicode values in the ``String`` class. --- CHANGES.txt | 5 +++++ colander/__init__.py | 15 +++++++++++++-- colander/tests.py | 8 ++++++++ 3 files changed, 26 insertions(+), 2 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index 41fd0b3..77e5d02 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,6 +1,11 @@ Changes ======= +Next release +------------ + +- Fix bug in serialization of non-Unicode values in the ``String`` class. + 0.5.1 (2010-04-02) ------------------ diff --git a/colander/__init__.py b/colander/__init__.py index 64c81b7..94277a9 100644 --- a/colander/__init__.py +++ b/colander/__init__.py @@ -525,6 +525,11 @@ class String(Type): which should be applied to object serialization. It defaults to ``utf-8`` if not provided. + If a string (as opposed to a unicode object) is provided as a + value to either the serialize or deserialize method of this type, + it must be encoded with the type's encoding; an + :exc:`colander.Invalid` error will result if not. + The subnodes of the :class:`colander.SchemaNode` that wraps this type are ignored. """ @@ -545,10 +550,16 @@ class String(Type): def serialize(self, node, value): try: - return unicode(value).encode(self.encoding or default_encoding) + encoding = self.encoding or default_encoding + if isinstance(value, unicode): + result = value.encode(encoding) + else: + # do validation here + result = unicode(value, encoding).encode(encoding) + return result except Exception, e: raise Invalid(node, - '%r is cannot be serialized to str: %s' % (value, e)) + '%r cannot be serialized to str: %s' % (value, e)) Str = String diff --git a/colander/tests.py b/colander/tests.py index 3a4c0d4..bbdf631 100644 --- a/colander/tests.py +++ b/colander/tests.py @@ -703,6 +703,14 @@ class TestString(unittest.TestCase): result = typ.serialize(node, uni) self.assertEqual(result, utf16) + def test_serialize_string_with_high_unresolveable_high_order_chars(self): + not_utf8 = '\xff\xfe\xf8\x00' + node = DummySchemaNode(None) + typ = self._makeOne('utf-8') + e = invalid_exc(typ.serialize, node, not_utf8) + self.failUnless('cannot be serialized to str' in e.msg) + + class TestInteger(unittest.TestCase): def _makeOne(self): from colander import Integer