]> git.ipfire.org Git - thirdparty/babel.git/commitdiff
Updated plurals.py to match Mozilla and CLDR references 431/head
authorMax Shenfield <shenfieldmax@gmail.com>
Mon, 11 Jul 2016 15:17:15 +0000 (10:17 -0500)
committerMax Shenfield <shenfieldmax@gmail.com>
Tue, 12 Jul 2016 00:43:55 +0000 (19:43 -0500)
This commit updates the plural rules, and in some cases the plural
number, for languages based on review of
https://developer.mozilla.org/en-US/docs/Mozilla/Localization/Localization_and_Plurals,
and
http://www.unicode.org/cldr/charts/29/supplemental/language_plural_rules.html.

I changed the interface (either the number of plurals, or the meaning
of each index), for the following languages:
• Arabic (ar): numplurals same, semantics differ per Mozilla's "Plural rule #12". 3 has been made more accurate, 4 has been switched with 5, and the meaning of both has been refined to match the rule.
• Belarusian (ar): numplurals updated to 3, using Mozilla's "Plural
rule #7". Previously the default, where anything except one is plural.
• Breton (br): numplurals updated to 6, using Mozilla's "Plural rule
• Bosnian (bs): numplurals updated to 3, using Mozilla's "Plural rule
• Irish Gaelic (ga): numplurals update from 3 to 5, using Mozilla's
"Plural rule #11". Cases have been added for n between 3 and 6, and n
between 7 and 10.
• Icelandic (is): same numplurals (2), semantics updated using
Mozilla's "Plural rule #15". 0 now means that n ends in 1, and is not
11, instead of just the number 1.
• Maltese (mt): same numplurals, same rule. Fixed rule, index 1 now
includes numbers ending in 1 (except the number 1)

I'm ignoring these two rules listed on the Mozilla resource
• Hungarian - listed as `(n != 1)`. It is not required to pluralize a
noun if a qualitative or quantitative amount precedes it
http://www.hungarianreference.com/plurals.aspx.
• Vietnamese - listed as `(n != 1)`. It only seems to have one plural
according to this lesson:
http://yourvietnamese.com/vietnamese-grammar/nouns-in-vietnamese/.

There are some additional languages listed in the Mozilla reference
that are not in the plurals document, and could be added:
• Lower Sorbian (dsb) (4, '(n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 ||
n%100==4 ? 2 : 3)')
• Upper Sorbian (hsb) (4, '(n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 ||
n%100==4 ? 2 : 3)')
• Scottish Gaelic (gd)  (4, '(n==1 || n==11 ? 0 : n==2 || n==12 ? 1 :
(n>=3 && n<=10) || (n>=13 && n<=19) ? 2 : 3)')
• Faroese (fo) (2, '(n != 1)')
• Frisian (fy) (2, '(n != 1)')
• Macedonian (mk) (3, '(n%10==1 ? 0 : n%10==2 ? 1 : 2)')

Closes https://github.com/python-babel/babel/issues/430

babel/messages/catalog.py
babel/messages/plurals.py
tests/messages/test_catalog.py
tests/messages/test_plurals.py

index 84cee432f6ce2aaa49e66358e571abe8ef4ac7d0..9a474a8453b9d6224eaaedb3f8072ef978e8375f 100644 (file)
@@ -479,7 +479,7 @@ class Catalog(object):
         >>> Catalog(locale='en').num_plurals
         2
         >>> Catalog(locale='ga').num_plurals
-        3
+        5
 
         :type: `int`"""
         if self._num_plurals is None:
@@ -496,7 +496,7 @@ class Catalog(object):
         >>> Catalog(locale='en').plural_expr
         '(n != 1)'
         >>> Catalog(locale='ga').plural_expr
-        '(n==1 ? 0 : n==2 ? 1 : 2)'
+        '(n==1 ? 0 : n==2 ? 1 : n>=3 && n<=6 ? 2 : n>=7 && n<=10 ? 3 : 4)'
 
         :type: `string_types`"""
         if self._plural_expr is None:
index 38c04ca44a2dc1b41138241d0f25184408b69346..92cefa79af860bb0642df2c219b622b169ac6f2d 100644 (file)
@@ -35,7 +35,7 @@ PLURALS = {
     # Aragonese
     # 'an': (),
     # Arabic - From Pootle's PO's
-    'ar': (6, '(n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n>=3 && n<=10 ? 3 : n>=11 && n<=99 ? 4 : 5)'),
+    'ar': (6, '(n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 : n%100>=0 && n%100<=2 ? 4 : 5)'),
     # Assamese
     # 'as': (),
     # Avaric
@@ -47,7 +47,7 @@ PLURALS = {
     # Bashkir
     # 'ba': (),
     # Belarusian
-    # 'be': (),
+    'be': (3, '(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2)'),
     # Bulgarian - From Pootle's PO's
     'bg': (2, '(n != 1)'),
     # Bihari
@@ -61,9 +61,14 @@ PLURALS = {
     # Tibetan - as discussed in private with Andrew West
     'bo': (1, '0'),
     # Breton
-    # 'br': (),
+    'br': (
+        6,
+        '(n==1 ? 0 : n%10==1 && n%100!=11 && n%100!=71 && n%100!=91 ? 1 : n%10==2 && n%100!=12 && n%100!=72 && '
+        'n%100!=92 ? 2 : (n%10==3 || n%10==4 || n%10==9) && n%100!=13 && n%100!=14 && n%100!=19 && n%100!=73 && '
+        'n%100!=74 && n%100!=79 && n%100!=93 && n%100!=94 && n%100!=99 ? 3 : n%1000000==0 ? 4 : 5)'
+    ),
     # Bosnian
-    # 'bs': (),
+    'bs': (3, '(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2)'),
     # Catalan - From Pootle's PO's
     'ca': (2, '(n != 1)'),
     # Chechen
@@ -111,7 +116,7 @@ PLURALS = {
     # Friulian - From Pootle's PO's
     'fur': (2, '(n > 1)'),
     # Irish
-    'ga': (3, '(n==1 ? 0 : n==2 ? 1 : 2)'),
+    'ga': (5, '(n==1 ? 0 : n==2 ? 1 : n>=3 && n<=6 ? 2 : n>=7 && n<=10 ? 3 : 4)'),
     # Galician - From Pootle's PO's
     'gl': (2, '(n != 1)'),
     # Hausa - From Pootle's PO's
@@ -127,7 +132,7 @@ PLURALS = {
     # Armenian - From Pootle's PO's
     'hy': (1, '0'),
     # Icelandic - From Pootle's PO's
-    'is': (2, '(n != 1)'),
+    'is': (2, '(n%10==1 && n%100!=11 ? 0 : 1)'),
     # Italian
     'it': (2, '(n != 1)'),
     # Japanese
@@ -149,7 +154,7 @@ PLURALS = {
     # Latvian
     'lv': (3, '(n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 : 2)'),
     # Maltese - From Pootle's PO's
-    'mt': (4, '(n==1 ? 0 : n==0 || ( n%100>1 && n%100<11) ? 1 : (n%100>10 && n%100<20 ) ? 2 : 3)'),
+    'mt': (4, '(n==1 ? 0 : n==0 || ( n%100=>1 && n%100<=10) ? 1 : (n%100>10 && n%100<20 ) ? 2 : 3)'),
     # Norwegian Bokmål
     'nb': (2, '(n != 1)'),
     # Dutch
@@ -223,7 +228,7 @@ def get_plural(locale=LC_CTYPE):
     >>> get_plural(locale='en')
     (2, '(n != 1)')
     >>> get_plural(locale='ga')
-    (3, '(n==1 ? 0 : n==2 ? 1 : 2)')
+    (5, '(n==1 ? 0 : n==2 ? 1 : n>=3 && n<=6 ? 2 : n>=7 && n<=10 ? 3 : 4)')
 
     The object returned is a special tuple with additional members:
 
index f16a4dcb7746ba2c57dbebc2a7cd0558e058513e..a6b9f512eb3e483b9a2a963845452a98a3cb2bff 100644 (file)
@@ -395,13 +395,13 @@ def test_catalog_mime_headers_set_locale():
 
 def test_catalog_num_plurals():
     assert catalog.Catalog(locale='en').num_plurals == 2
-    assert catalog.Catalog(locale='ga').num_plurals == 3
+    assert catalog.Catalog(locale='ga').num_plurals == 5
 
 
 def test_catalog_plural_expr():
     assert catalog.Catalog(locale='en').plural_expr == '(n != 1)'
     assert (catalog.Catalog(locale='ga').plural_expr
-            == '(n==1 ? 0 : n==2 ? 1 : 2)')
+            == '(n==1 ? 0 : n==2 ? 1 : n>=3 && n<=6 ? 2 : n>=7 && n<=10 ? 3 : 4)')
 
 
 def test_catalog_plural_forms():
index 1a50139f40709536832b01263cfe51fc3219234a..2e7553c16ba699e57f3a0a503cb0505084259928 100644 (file)
@@ -30,7 +30,7 @@ def test_get_plural_selection(locale, num_plurals, plural_expr):
 
 
 def test_get_plural_accpets_strings():
-    assert plurals.get_plural(locale='ga') == (3, '(n==1 ? 0 : n==2 ? 1 : 2)')
+    assert plurals.get_plural(locale='ga') == (5, '(n==1 ? 0 : n==2 ? 1 : n>=3 && n<=6 ? 2 : n>=7 && n<=10 ? 3 : 4)')
 
 
 def test_get_plural_falls_back_to_default():
@@ -40,7 +40,7 @@ def test_get_plural_falls_back_to_default():
 def test_get_plural():
     # See https://localization-guide.readthedocs.io/en/latest/l10n/pluralforms.html for more details.
     assert plurals.get_plural(locale='en') == (2, '(n != 1)')
-    assert plurals.get_plural(locale='ga') == (3, '(n==1 ? 0 : n==2 ? 1 : 2)')
+    assert plurals.get_plural(locale='ga') == (5, '(n==1 ? 0 : n==2 ? 1 : n>=3 && n<=6 ? 2 : n>=7 && n<=10 ? 3 : 4)')
 
     plural_ja = plurals.get_plural("ja")
     assert str(plural_ja) == 'nplurals=1; plural=0;'