[Django] #34221: Plural-Forms in .po files break Django's translation precedence.

21 views
Skip to first unread message

Django

unread,
Dec 21, 2022, 3:27:01 AM12/21/22
to django-...@googlegroups.com
#34221: Plural-Forms in .po files break Django's translation precedence.
------------------------------------------------+------------------------
Reporter: Stefano Parmesan | Owner: nobody
Type: Bug | Status: new
Component: Internationalization | Version: 4.1
Severity: Normal | Keywords: i18n
Triage Stage: Unreviewed | Has patch: 0
Needs documentation: 0 | Needs tests: 0
Patch needs improvement: 0 | Easy pickings: 0
UI/UX: 0 |
------------------------------------------------+------------------------
According to the
[https://docs.djangoproject.com/en/4.1/topics/i18n/translation/#how-
django-discovers-translations| documentation], Django reads translations
from `LOCALE_PATHS` first, then from apps in `INSTALLED_APPS`, and then
from its own folders.

This behaviour breaks if the files in `LOCALE_PATHS` contain `Plural-
Forms` while those found in `INSTALLED_APPS` don't.

To test this behaviour I created a test project on github here:

https://github.com/armisael/test-django-i18n-preference

The project contains a .po file with `Plural-Forms` and a single
translation that is also included in one of the dependencies. A single
test checks which translation is picked.

With the current configuration, the test fails by using the dependency
translation. It passes if:
1) the dependency is removed from `INSTALLED_APPS`; or if
2) `Plural-Forms` is removed from the .po file.

1) proves that i18n is correctly configured, and that the dependency
translation is picked over the project one; 2) proves that `Plural-Forms`
is involved in the bug.

--
Ticket URL: <https://code.djangoproject.com/ticket/34221>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

Django

unread,
Dec 21, 2022, 3:38:57 AM12/21/22
to django-...@googlegroups.com
#34221: Plural-Forms in .po files break Django's translation precedence.
-------------------------------------+-------------------------------------

Reporter: Stefano Parmesan | Owner: nobody
Type: Bug | Status: new
Component: | Version: 4.1
Internationalization |
Severity: Normal | Resolution:

Keywords: i18n | Triage Stage:
| Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Mariusz Felisiak):

* cc: Claude Paroz (added)


--
Ticket URL: <https://code.djangoproject.com/ticket/34221#comment:1>

Django

unread,
Dec 21, 2022, 2:53:44 PM12/21/22
to django-...@googlegroups.com
#34221: Plural-Forms in .po files break Django's translation precedence.
--------------------------------------+------------------------------------

Reporter: Stefano Parmesan | Owner: nobody
Type: Bug | Status: new
Component: Internationalization | Version: 4.1
Severity: Normal | Resolution:
Keywords: i18n | Triage Stage: Accepted

Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
--------------------------------------+------------------------------------
Changes (by Claude Paroz):

* stage: Unreviewed => Accepted


Comment:

Thanks for the detailed report and test project!

To solve #30439 and allow for different plural forms for a same language,
we had to refrain from merging all translations in a unique catalog, as
was done before. However, your setup demonstrates that the algorithm to
decide between merge or separating catalogs is flawed (the third catalog
from LOCALE_PATH having the same plural forms as the Django one, it is
merge with it, hence loosing it's priority over the intermediary django-
extension catalog).

The following patch should fix the issue:
{{{
diff --git a/django/utils/translation/trans_real.py
b/django/utils/translation/trans_real.py
index c1e64d4ebd..f4d05b8f76 100644
--- a/django/utils/translation/trans_real.py
+++ b/django/utils/translation/trans_real.py
@@ -96,11 +96,9 @@ class TranslationCatalog:
yield from cat.keys()

def update(self, trans):
- # Merge if plural function is the same, else prepend.
- for cat, plural in zip(self._catalogs, self._plurals):
- if trans.plural.__code__ == plural.__code__:
- cat.update(trans._catalog)
- break
+ # Merge if plural function is the same as the top catalog, else
prepend.
+ if trans.plural.__code__ == self._plurals[0]:
+ self._catalogs[0].update(trans._catalog)
else:
self._catalogs.insert(0, trans._catalog.copy())
self._plurals.insert(0, trans.plural)
}}}

--
Ticket URL: <https://code.djangoproject.com/ticket/34221#comment:2>

Django

unread,
Dec 27, 2022, 6:36:25 AM12/27/22
to django-...@googlegroups.com
#34221: Plural-Forms in .po files break Django's translation precedence.
--------------------------------------+------------------------------------
Reporter: Stefano Parmesan | Owner: nobody
Type: Bug | Status: new
Component: Internationalization | Version: 4.1
Severity: Normal | Resolution:
Keywords: i18n | Triage Stage: Accepted
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
--------------------------------------+------------------------------------

Comment (by Bhuvnesh):

Hi, I'm stuck at writing test for this one, how do i include dependency in
the test?

--
Ticket URL: <https://code.djangoproject.com/ticket/34221#comment:3>

Django

unread,
Jan 28, 2023, 1:21:41 PM1/28/23
to django-...@googlegroups.com
#34221: Plural-Forms in .po files break Django's translation precedence.
-------------------------------------+-------------------------------------
Reporter: Stefano Parmesan | Owner:
| rajdesai24
Type: Bug | Status: assigned
Component: | Version: 4.1
Internationalization |

Severity: Normal | Resolution:
Keywords: i18n | Triage Stage: Accepted
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by rajdesai24):

* owner: nobody => rajdesai24
* status: new => assigned


--
Ticket URL: <https://code.djangoproject.com/ticket/34221#comment:4>

Django

unread,
Feb 10, 2023, 2:44:03 PM2/10/23
to django-...@googlegroups.com
#34221: Plural-Forms in .po files break Django's translation precedence.
-------------------------------------+-------------------------------------
Reporter: Stefano Parmesan | Owner:
| rajdesai24
Type: Bug | Status: assigned
Component: | Version: 4.1
Internationalization |
Severity: Normal | Resolution:
Keywords: i18n | Triage Stage: Accepted
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by rajdesai24):

hey Claude, I tested the patch with the test project that Stefano has
provided but it did not work.

--
Ticket URL: <https://code.djangoproject.com/ticket/34221#comment:5>

Django

unread,
Feb 10, 2023, 2:51:26 PM2/10/23
to django-...@googlegroups.com
#34221: Plural-Forms in .po files break Django's translation precedence.
-------------------------------------+-------------------------------------
Reporter: Stefano Parmesan | Owner:
| rajdesai24
Type: Bug | Status: assigned
Component: | Version: 4.1
Internationalization |
Severity: Normal | Resolution:
Keywords: i18n | Triage Stage: Accepted
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by rajdesai24):

will figure out what can we add to the current patch

--
Ticket URL: <https://code.djangoproject.com/ticket/34221#comment:6>

Django

unread,
May 23, 2024, 11:27:27 AM5/23/24
to django-...@googlegroups.com
#34221: Plural-Forms in .po files break Django's translation precedence.
-------------------------------------+-------------------------------------
Reporter: Stefano Parmesan | Owner:
| rajdesai24
Type: Bug | Status: assigned
Component: | Version: 4.1
Internationalization |
Severity: Normal | Resolution:
Keywords: i18n | Triage Stage: Accepted
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Dmytro Litvinov):

* cc: Dmytro Litvinov (added)

--
Ticket URL: <https://code.djangoproject.com/ticket/34221#comment:7>

Django

unread,
Jun 8, 2024, 10:40:19 AM6/8/24
to django-...@googlegroups.com
#34221: Plural-Forms in .po files break Django's translation precedence.
-------------------------------------+-------------------------------------
Reporter: Stefano Parmesan | Owner:
| rajdesai24
Type: Bug | Status: assigned
Component: | Version: 4.1
Internationalization |
Severity: Normal | Resolution:
Keywords: i18n | Triage Stage: Accepted
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by viktorparipas92):

* cc: viktorparipas92 (added)

--
Ticket URL: <https://code.djangoproject.com/ticket/34221#comment:8>

Django

unread,
Aug 27, 2024, 12:41:10 PM8/27/24
to django-...@googlegroups.com
#34221: Plural-Forms in .po files break Django's translation precedence.
--------------------------------------+------------------------------------
Reporter: Stefano Parmesan | Owner: (none)
Type: Bug | Status: new
Component: Internationalization | Version: 4.1
Severity: Normal | Resolution:
Keywords: i18n | Triage Stage: Accepted
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
--------------------------------------+------------------------------------
Changes (by Claude Paroz):

* owner: rajdesai24 => (none)
* status: assigned => new

Comment:

De-assigning due to inactivity.
--
Ticket URL: <https://code.djangoproject.com/ticket/34221#comment:9>

Django

unread,
Sep 13, 2024, 8:05:12 AM9/13/24
to django-...@googlegroups.com
#34221: Plural-Forms in .po files break Django's translation precedence.
--------------------------------------+------------------------------------
Reporter: Stefano Parmesan | Owner: (none)
Type: Bug | Status: new
Component: Internationalization | Version: 4.1
Severity: Normal | Resolution:
Keywords: i18n | Triage Stage: Accepted
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
--------------------------------------+------------------------------------
Comment (by Wladislav Artsimovich):

We also came across this, which caused a bug in Translation
https://code.djangoproject.com/ticket/35760 , as diagnosed by
[https://github.com/sarahboyce Sarah Boyce] in
[https://code.djangoproject.com/ticket/35760#comment:3 this comment].
Looking forward to a workaround-free fix 👍
--
Ticket URL: <https://code.djangoproject.com/ticket/34221#comment:10>

Django

unread,
Sep 14, 2024, 1:05:41 PM9/14/24
to django-...@googlegroups.com
#34221: Plural-Forms in .po files break Django's translation precedence.
-------------------------------------+-------------------------------------
Reporter: Stefano Parmesan | Owner: Claude
| Paroz
Type: Bug | Status: assigned
Component: | Version: 4.1
Internationalization |
Severity: Normal | Resolution:
Keywords: i18n | Triage Stage: Accepted
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Claude Paroz):

* owner: (none) => Claude Paroz
* status: new => assigned

--
Ticket URL: <https://code.djangoproject.com/ticket/34221#comment:11>

Django

unread,
Sep 14, 2024, 1:14:11 PM9/14/24
to django-...@googlegroups.com
#34221: Plural-Forms in .po files break Django's translation precedence.
-------------------------------------+-------------------------------------
Reporter: Stefano Parmesan | Owner: Claude
| Paroz
Type: Bug | Status: assigned
Component: | Version: 4.1
Internationalization |
Severity: Normal | Resolution:
Keywords: i18n | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Claude Paroz):

* has_patch: 0 => 1

Comment:

[https://github.com/django/django/pull/18584 PR]
--
Ticket URL: <https://code.djangoproject.com/ticket/34221#comment:12>

Django

unread,
Sep 16, 2024, 5:04:00 AM9/16/24
to django-...@googlegroups.com
#34221: Plural-Forms in .po files break Django's translation precedence.
-------------------------------------+-------------------------------------
Reporter: Stefano Parmesan | Owner: Claude
| Paroz
Type: Bug | Status: assigned
Component: | Version: 4.1
Internationalization |
Severity: Normal | Resolution:
Keywords: i18n | Triage Stage: Ready for
| checkin
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Sarah Boyce):

* stage: Accepted => Ready for checkin

--
Ticket URL: <https://code.djangoproject.com/ticket/34221#comment:13>

Django

unread,
Sep 16, 2024, 5:04:18 AM9/16/24
to django-...@googlegroups.com
#34221: Plural-Forms in .po files break Django's translation precedence.
-------------------------------------+-------------------------------------
Reporter: Stefano Parmesan | Owner: Claude
| Paroz
Type: Bug | Status: closed
Component: | Version: 4.1
Internationalization |
Severity: Normal | Resolution: fixed
Keywords: i18n | Triage Stage: Ready for
| checkin
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Sarah Boyce <42296566+sarahboyce@…>):

* resolution: => fixed
* status: assigned => closed

Comment:

In [changeset:"b579485d991da65ebe4a6cdbcab20f59f7515d3f" b579485d]:
{{{#!CommitTicketReference repository=""
revision="b579485d991da65ebe4a6cdbcab20f59f7515d3f"
Fixed #34221 -- Honored translation precedence with mixed plural forms.
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/34221#comment:14>
Reply all
Reply to author
Forward
0 new messages