Test button: 'Delivered to N services' chooses singular or plural in code, so languages with more than two forms cannot be translated #14

Closed
opened 2026-10-01 10:48:16 +00:00 by tiagoagueda · 1 comment
Owner

Found on 2026-09-29 in a read-only review of postulo-apprise at 7637d899d, reading every translated string in the notifier against its catalogues.

The result of the Test button picks between two separate sentences with count == 1. That is the English rule written into the code. A language with three or more plural forms gets two unrelated entries to translate and no way to supply the others.

  • Where: src/postulo_apprise/notifier.py:216-224, in test():

    _("Delivered to %(count)d service.")
    if count == 1
    else _("Delivered to %(count)d services.")
    
  • What happens: the plugin ships 68 catalogues, and their headers declare the right rules: nplurals=4 for Slovenian, nplurals=5 for Irish, nplurals=6 for Arabic. The two msgids appear in each as separate singular entries (for example src/postulo_apprise/locale/sl/LC_MESSAGES/django.po:46 and :51), so a person reading Postulo in one of those languages who tests a connection with two, three or five lines is shown the one sentence written for "not one", whatever the count. A translator in Weblate sees two sentences and no plural entry to fill. There is no ngettext anywhere in the package.

  • Why it matters: every user-facing string is meant to be translatable, and this one cannot be translated correctly outside languages that share English's rule. The core's catalogue tool already extracts ngettext (core/messages_tool.py:116) and postulo-messages check already verifies that plural forms agree, so the plugin has everything it needs.

  • Fix: ngettext("Delivered to %(count)d service.", "Delivered to %(count)d services.", count) % {"count": count}, imported from django.utils.translation; then uv run postulo-messages extract, refill the entry in the working languages, and uv run postulo-messages compile.

Done when

  • A test in tests/test_catalogues.py asserts that the catalogue holds "Delivered to %(count)d service." as an entry with a plural (msgid_plural) and no separate "Delivered to %(count)d services." entry; it fails today.
  • tests/test_apprise.py keeps its assertion for two lines ("Delivered to 2 services.", line 194) and gains one for a single line ("Delivered to 1 service.").
Found on 2026-09-29 in a read-only review of postulo-apprise at 7637d899d, reading every translated string in the notifier against its catalogues. The result of the *Test* button picks between two separate sentences with `count == 1`. That is the English rule written into the code. A language with three or more plural forms gets two unrelated entries to translate and no way to supply the others. - **Where:** `src/postulo_apprise/notifier.py:216-224`, in `test()`: ```python _("Delivered to %(count)d service.") if count == 1 else _("Delivered to %(count)d services.") ``` - **What happens:** the plugin ships 68 catalogues, and their headers declare the right rules: `nplurals=4` for Slovenian, `nplurals=5` for Irish, `nplurals=6` for Arabic. The two msgids appear in each as separate singular entries (for example `src/postulo_apprise/locale/sl/LC_MESSAGES/django.po:46` and `:51`), so a person reading Postulo in one of those languages who tests a connection with two, three or five lines is shown the one sentence written for "not one", whatever the count. A translator in Weblate sees two sentences and no plural entry to fill. There is no `ngettext` anywhere in the package. - **Why it matters:** every user-facing string is meant to be translatable, and this one cannot be translated correctly outside languages that share English's rule. The core's catalogue tool already extracts `ngettext` (`core/messages_tool.py:116`) and `postulo-messages check` already verifies that plural forms agree, so the plugin has everything it needs. - **Fix:** `ngettext("Delivered to %(count)d service.", "Delivered to %(count)d services.", count) % {"count": count}`, imported from `django.utils.translation`; then `uv run postulo-messages extract`, refill the entry in the working languages, and `uv run postulo-messages compile`. ## Done when - A test in `tests/test_catalogues.py` asserts that the catalogue holds "Delivered to %(count)d service." as an entry with a plural (`msgid_plural`) and no separate "Delivered to %(count)d services." entry; it fails today. - `tests/test_apprise.py` keeps its assertion for two lines ("Delivered to 2 services.", line 194) and gains one for a single line ("Delivered to 1 service.").
tiagoagueda added this to the 0.6.0 milestone 2026-10-01 10:48:16 +00:00
Author
Owner

Fixed by pull request #23.

Fixed by pull request #23.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
Postulo/postulo-apprise#14
No description provided.