changeset: 105108:6ca91a14a555 branch: 2.7 parent: 105097:77cb8fa47138 user: Serhiy Storchaka date: Mon Nov 14 19:25:44 2016 +0200 files: Lib/gettext.py Lib/test/test_gettext.py description: Issue #28563: Make plural form selection more lenient and accepting non-integer numbers. Django tests depend on this. diff -r 77cb8fa47138 -r 6ca91a14a555 Lib/gettext.py --- a/Lib/gettext.py Mon Nov 14 04:13:55 2016 +0000 +++ b/Lib/gettext.py Mon Nov 14 19:25:44 2016 +0200 @@ -158,6 +158,14 @@ return result, nexttok +def _as_int(n): + try: + i = round(n) + except TypeError: + raise TypeError('Plural value must be an integer, got %s' % + (n.__class__.__name__,)) + return n + def c2py(plural): """Gets a C expression as used in PO files for plural forms and returns a Python function that implements an equivalent expression. @@ -181,11 +189,11 @@ elif c == ')': depth -= 1 - ns = {} + ns = {'_as_int': _as_int} exec('''if 1: def func(n): if not isinstance(n, int): - raise ValueError('Plural value must be an integer.') + n = _as_int(n) return int(%s) ''' % result, ns) return ns['func'] diff -r 77cb8fa47138 -r 6ca91a14a555 Lib/test/test_gettext.py --- a/Lib/test/test_gettext.py Mon Nov 14 04:13:55 2016 +0000 +++ b/Lib/test/test_gettext.py Mon Nov 14 19:25:44 2016 +0200 @@ -372,12 +372,16 @@ self.assertRaises(ZeroDivisionError, f, 0) def test_plural_number(self): - f = gettext.c2py('1') - self.assertEqual(f(1), 1) - self.assertRaises(ValueError, f, 1.0) - self.assertRaises(ValueError, f, '1') - self.assertRaises(ValueError, f, []) - self.assertRaises(ValueError, f, object()) + f = gettext.c2py('n != 1') + self.assertEqual(f(1), 0) + self.assertEqual(f(2), 1) + self.assertEqual(f(1.0), 0) + self.assertEqual(f(2.0), 1) + self.assertEqual(f(1.1), 1) + self.assertRaises(TypeError, f, '2') + self.assertRaises(TypeError, f, b'2') + self.assertRaises(TypeError, f, []) + self.assertRaises(TypeError, f, object()) class GNUTranslationParsingTest(GettextBaseTest):