Opened 8 years ago

Closed 8 years ago

Last modified 8 years ago

#26123 closed Bug (invalid)

Wrong Plural-Froms value in the 'ru' locale (regression from version 1.8.x)

Reported by: generalov Owned by: nobody
Component: Internationalization Version: 1.9
Severity: Normal Keywords:
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no


There are 3 plural forms in the Russian language.

"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2)\n"

Django 1.9.1 locale catalog contains wrong Plural-Forms value:

"Plural-Forms: nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
"%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || (n"

The makemessages management command copies this value to the new *.po files and makes them wrong.

This bug is present in the core Django translations files too. For example

This is looks like a regression because a previous Django-1.8.x had the right Plural-Forms value

Change History (4)

comment:1 by Tim Graham, 8 years ago

Resolution: invalid
Status: newclosed

Thanks for the report, however, translations are handled at Transifex and not in this tracker.

comment:2 by Claude Paroz, 8 years ago

See also #17065, which explains that Transifex is following the rules from

comment:3 by generalov, 8 years ago

Thank you! It's wery interesting case. I've used Django for many years and makemessages -l ru management command always was generate the ru/django.po files with npluarls=3 for Russian. I've surpriced by this change last month.

tldr: It is a strange issue because in the case of nplurals=4 translators should fill the additional plural form (that CLDR was introduce for fractions in Russian language) in order to the message take a 'translated' state. But this form will nether used by Django world, because gettext advisedly doesn't support fractions in the pluralization functions and recommends to use the another way to handle them.

It seems there is a difference between CLDR and gettext here.

The CLDR was introduce in the Russian language the forth plural form ('other' category) for fractions:

In some languages, fractions require a separate category. For example, Russian 'other' in the example above and they are note below the "fractions are often a bit tricky".

The Django framework uses the ngettext that uses GNU gettext (man 3 ngettext) and there is special note about fractions too at (look at last paragraphs below the languages list). Because the fractions are often a bit tricky, they are recommend to use the another way to handle them. The gettext functions advisedly accepts a decimal positive integers values only (unsigned long int n) for pluralization and doesn't have any deal with fractions:

char * ngettext (const char * msgid, const char * msgid_plural,
                        unsigned long int n);

gettext po catalog itself uses nplurals=3 for Russian. . For example

comment:4 by Claude Paroz, 8 years ago

Thank you for the detailed explanation. Django is currently using the Transifex service for its translations, and AFAIK Transifex doesn't allow setting different plural strings per project. So for us the alternative is either use Transifex and abide to the plural forms on that platform, or choose another platform with more flexibility (which would be a heavy move).

Note: See TracTickets for help on using tickets.
Back to Top