From f6be836f74b9f6d010a17acdc2b2ea3c58edeb0a Mon Sep 17 00:00:00 2001 From: Alex Marandon Date: Fri, 13 Dec 2013 17:36:28 +0100 Subject: [PATCH 1/2] Allow translation of messages returned by asdict Fix #152 --- colander/__init__.py | 4 +++- colander/tests/test_colander.py | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/colander/__init__.py b/colander/__init__.py index bbebe4b..f1d2f00 100644 --- a/colander/__init__.py +++ b/colander/__init__.py @@ -165,7 +165,7 @@ class Invalid(Exception): return str(self.pos) return str(self.node.name) - def asdict(self): + def asdict(self, translate=None): """ Return a dictionary containing a basic (non-language-translated) error report for this exception""" paths = self.paths() @@ -177,6 +177,8 @@ class Invalid(Exception): exc.msg and msgs.extend(exc.messages()) keyname = exc._keyname() keyname and keyparts.append(keyname) + if translate: + msgs = [translate(msg) for msg in msgs] errors['.'.join(keyparts)] = '; '.join(interpolate(msgs)) return errors diff --git a/colander/tests/test_colander.py b/colander/tests/test_colander.py index 7d60998..18c9810 100644 --- a/colander/tests/test_colander.py +++ b/colander/tests/test_colander.py @@ -3398,6 +3398,39 @@ class TestFunctional(object): errors = e.asdict() self.assertEqual(errors, expected) + def test_invalid_asdict_translation_callback(self): + from translationstring import TranslationString + + expected = { + 'schema.int': 'translated', + 'schema.ob': 'translated', + 'schema.seq.0.0': 'translated', + 'schema.seq.1.0': 'translated', + 'schema.seq.2.0': 'translated', + 'schema.seq.3.0': 'translated', + 'schema.seq2.0.key': 'translated', + 'schema.seq2.0.key2': 'translated', + 'schema.seq2.1.key': 'translated', + 'schema.seq2.1.key2': 'translated', + 'schema.tup.0': 'translated', + } + data = { + 'int': '20', + 'ob': 'no.way.this.exists', + 'seq': [('q', 's'), ('w', 's'), ('e', 's'), ('r', 's')], + 'seq2': [{'key': 't', 'key2': 'y'}, {'key':'u', 'key2':'i'}], + 'tup': ('s', 's'), + } + schema = self._makeSchema() + e = invalid_exc(schema.deserialize, data) + + def translation_function(string): + return TranslationString('translated') + + errors = e.asdict(translate=translation_function) + self.assertEqual(errors, expected) + + class TestImperative(unittest.TestCase, TestFunctional): def _makeSchema(self, name='schema'): From d8d2681c40acc5362e7038e715e49b68d65eeee3 Mon Sep 17 00:00:00 2001 From: Alex Marandon Date: Sat, 21 Dec 2013 20:55:41 +0100 Subject: [PATCH 2/2] Document translate argument of Invalid.asdict --- CHANGES.txt | 6 ++++++ CONTRIBUTORS.txt | 1 + colander/__init__.py | 7 ++++++- 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/CHANGES.txt b/CHANGES.txt index 63f1b89..abdecff 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -7,6 +7,12 @@ Bug Fixes - Un-break wrapping of callable instances as ``colander.deferred``. See https://github.com/Pylons/colander/issues/141. +Features +~~~~~~~~ + +- Allow localization of error messages returned by ``colander.Invalid.asdict`` + by adding an optional ``translate`` callable argument. + 1.0b1 (2013-09-01) ------------------ diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt index a1cf78f..065840e 100644 --- a/CONTRIBUTORS.txt +++ b/CONTRIBUTORS.txt @@ -114,3 +114,4 @@ Contributors - Brian Sutherland, 2013/08/16 - Peter Lamut, 2013/08/16 - Veeti Paananen, 2013/08/20 +- Alex Marandon, 2013/12/21 diff --git a/colander/__init__.py b/colander/__init__.py index f1d2f00..a68913b 100644 --- a/colander/__init__.py +++ b/colander/__init__.py @@ -167,7 +167,12 @@ class Invalid(Exception): def asdict(self, translate=None): """ Return a dictionary containing a basic - (non-language-translated) error report for this exception""" + (non-language-translated) error report for this exception. + + If ``translate`` is supplied, it must be a callable taking a + translation string as its sole argument and returning a localized, + interpolated string. + """ paths = self.paths() errors = {} for path in paths: