changeset 375:324e747f0b09

Added babel.messages.plurals.get_plural which returns a special tuple with the plural information.
author aronacher
date Tue, 01 Jul 2008 09:16:30 +0000
parents 0d84e90bf376
children 69260c099d9f
files babel/messages/catalog.py babel/messages/plurals.py
diffstat 2 files changed, 68 insertions(+), 11 deletions(-) [+]
line wrap: on
line diff
--- a/babel/messages/catalog.py
+++ b/babel/messages/catalog.py
@@ -28,7 +28,7 @@
 from babel import __version__ as VERSION
 from babel.core import Locale
 from babel.dates import format_datetime
-from babel.messages.plurals import PLURALS
+from babel.messages.plurals import get_plural
 from babel.util import odict, distinct, LOCALTZ, UTC, FixedOffsetTimezone
 
 __all__ = ['Message', 'Catalog', 'TranslationError']
@@ -411,13 +411,10 @@
     """)
 
     def num_plurals(self):
-        if not self._num_plurals:
+        if self._num_plurals is None:
             num = 2
             if self.locale:
-                if str(self.locale) in PLURALS:
-                    num = PLURALS[str(self.locale)][0]
-                elif self.locale.language in PLURALS:
-                    num = PLURALS[self.locale.language][0]
+                num = get_plural(self.locale)[0]
             self._num_plurals = num
         return self._num_plurals
     num_plurals = property(num_plurals, doc="""\
@@ -432,13 +429,10 @@
     """)
 
     def plural_expr(self):
-        if not self._plural_expr:
+        if self._plural_expr is None:
             expr = '(n != 1)'
             if self.locale:
-                if str(self.locale) in PLURALS:
-                    expr = PLURALS[str(self.locale)][1]
-                elif self.locale.language in PLURALS:
-                    expr = PLURALS[self.locale.language][1]
+                expr = get_plural(self.locale)[1]
             self._plural_expr = expr
         return self._plural_expr
     plural_expr = property(plural_expr, doc="""\
--- a/babel/messages/plurals.py
+++ b/babel/messages/plurals.py
@@ -13,6 +13,14 @@
 
 """Plural form definitions."""
 
+
+from operator import itemgetter
+from babel.core import default_locale, Locale
+
+
+LC_CTYPE = default_locale('LC_CTYPE')
+
+
 PLURALS = {
     # Afar
     # 'aa': (),
@@ -191,3 +199,58 @@
     'zh_HK': (1, '0'),
     'zh_TW': (1, '0'),
 }
+
+
+DEFAULT_PLURAL = (2, '(n != 1)')
+
+
+class _PluralTuple(tuple):
+    """A tuple with plural information."""
+
+    __slots__ = ()
+    num_plurals = property(itemgetter(0), doc="""
+    The number of plurals used by the locale.""")
+    plural_expr = property(itemgetter(1), doc="""
+    The plural expression used by the locale.""")
+    plural_forms = property(lambda x: 'npurals=%s; plural=%s' % x, doc="""
+    The plural expression used by the catalog or locale.""")
+
+    def __str__(self):
+        return self.plural_forms
+
+
+def get_plural(locale=LC_CTYPE):
+    """A tuple with the information catalogs need to perform proper
+    pluralization.  The first item of the tuple is the number of plural
+    forms, the second the plural expression.
+
+    >>> get_plural(locale='en')
+    (2, '(n != 1)')
+    >>> get_plural(locale='ga')
+    (3, '(n==1 ? 0 : n==2 ? 1 : 2)')
+
+    The object returned is a special tuple with additional members:
+
+    >>> tup = get_plural("ja")
+    >>> tup.num_plurals
+    1
+    >>> tup.plural_expr
+    '0'
+    >>> tup.plural_forms
+    'npurals=1; plural=0'
+
+    Converting the tuple into a string prints the plural forms for a
+    gettext catalog:
+
+    >>> str(tup)
+    'npurals=1; plural=0'
+    """
+    locale = Locale.parse(locale)
+    try:
+        tup = PLURALS[str(locale)]
+    except KeyError:
+        try:
+            tup = PLURALS[locale.language]
+        except KeyError:
+            tup = DEFAULT_PLURAL
+    return _PluralTuple(tup)
Copyright (C) 2012-2017 Edgewall Software