From: Max Shenfield Date: Mon, 11 Jul 2016 15:17:15 +0000 (-0500) Subject: Updated plurals.py to match Mozilla and CLDR references X-Git-Tag: v2.4.0~14^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=38556ee3dfb23d22604ec726fef5e9bf1e58973a;p=thirdparty%2Fbabel.git Updated plurals.py to match Mozilla and CLDR references 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 --- diff --git a/babel/messages/catalog.py b/babel/messages/catalog.py index 84cee432..9a474a84 100644 --- a/babel/messages/catalog.py +++ b/babel/messages/catalog.py @@ -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: diff --git a/babel/messages/plurals.py b/babel/messages/plurals.py index 38c04ca4..92cefa79 100644 --- a/babel/messages/plurals.py +++ b/babel/messages/plurals.py @@ -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: diff --git a/tests/messages/test_catalog.py b/tests/messages/test_catalog.py index f16a4dcb..a6b9f512 100644 --- a/tests/messages/test_catalog.py +++ b/tests/messages/test_catalog.py @@ -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(): diff --git a/tests/messages/test_plurals.py b/tests/messages/test_plurals.py index 1a50139f..2e7553c1 100644 --- a/tests/messages/test_plurals.py +++ b/tests/messages/test_plurals.py @@ -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;'