Test and sync: the two sentences that count messages have no plural forms and read “1 messages” #10

Closed
opened 2026-10-01 10:47:56 +00:00 by tiagoagueda · 1 comment
Owner

Found on 2026-09-29 in a read-only review of postulo-imap at cc09c6381, reading every string that carries a count and running Test with one message waiting in three languages.

Both sentences in which the plugin states a number go through gettext, not ngettext. English says "1 messages", and a language with more than two plural forms can be given only one of them in its catalogue.

  • Where:

    • src/postulo_imap/sync.py:158, test(): _("Signed in. %(count)d messages in “%(folder)s” are waiting to be read.").
    • src/postulo_imap/sync.py:221, sync(): _("%(count)d could not be matched to an application; attach them by hand.").
    • tests/test_imap.py:466 asserts the wrong form: assert result.ok and "1 messages" in result.message.
    • src/postulo_imap/locale/pl/LC_MESSAGES/django.po:21-22 and :161-162: one msgstr each, under a header that declares nplurals=3. No catalogue of the 68 has a msgid_plural.
  • What happens: with one message in the folder, Test answered (run on the snapshot):

    • en-gb: "Signed in. 1 messages in “Jobs” are waiting to be read."
    • pl: "Zalogowano. 1 wiadomości w „Jobs” czeka na odczytanie." Polish needs 1 wiadomość … czeka, 2 wiadomości … czekają, 5 wiadomości … czeka; the catalogue has room for one.
    • pt-pt: "Sessão iniciada. 1 mensagens em «Jobs» esperam ser lidas."

    A pass with one unmatched message stores "1 could not be matched to an application; attach them by hand." on the connection. One message waiting and one message unmatched are the ordinary cases for a folder read as often as every fifteen minutes.

  • Why it matters: these are the two sentences the person reads most often from this plugin, and they are ungrammatical in every language whenever the count is one, and wrong for part of the numbers in Polish, Czech, Slovak, Slovenian, Lithuanian, Irish, Arabic and the other languages the catalogues cover with three or more forms.

  • Fix: use ngettext for both strings, with the count as the selector. The core's catalogue tool already extracts ngettext and checks that every catalogue carries as many forms as its header declares (core/messages_tool.py in postulo; tests/test_catalogues.py:89 here runs that check). Regenerate the catalogues with postulo-messages extract, fill the forms, and correct the assertion at tests/test_imap.py:466.

Done when

  • tests/test_imap.py:466 asserts "1 message " for one message and a second assertion covers "2 messages"; the first fails today.
  • tests/test_imap.py has a test that a pass with exactly one unmatched message produces a note in the singular; it fails today.
  • grep -c msgid_plural src/postulo_imap/locale/pl/LC_MESSAGES/django.po prints 2, and tests/test_catalogues.py::test_placeholders_and_plural_forms_agree passes.
Found on 2026-09-29 in a read-only review of postulo-imap at cc09c6381, reading every string that carries a count and running *Test* with one message waiting in three languages. Both sentences in which the plugin states a number go through `gettext`, not `ngettext`. English says "1 messages", and a language with more than two plural forms can be given only one of them in its catalogue. - **Where:** - `src/postulo_imap/sync.py:158`, `test()`: `_("Signed in. %(count)d messages in “%(folder)s” are waiting to be read.")`. - `src/postulo_imap/sync.py:221`, `sync()`: `_("%(count)d could not be matched to an application; attach them by hand.")`. - `tests/test_imap.py:466` asserts the wrong form: `assert result.ok and "1 messages" in result.message`. - `src/postulo_imap/locale/pl/LC_MESSAGES/django.po:21-22` and `:161-162`: one `msgstr` each, under a header that declares `nplurals=3`. No catalogue of the 68 has a `msgid_plural`. - **What happens:** with one message in the folder, *Test* answered (run on the snapshot): - `en-gb`: "Signed in. 1 messages in “Jobs” are waiting to be read." - `pl`: "Zalogowano. 1 wiadomości w „Jobs” czeka na odczytanie." Polish needs *1 wiadomość … czeka*, *2 wiadomości … czekają*, *5 wiadomości … czeka*; the catalogue has room for one. - `pt-pt`: "Sessão iniciada. 1 mensagens em «Jobs» esperam ser lidas." A pass with one unmatched message stores "1 could not be matched to an application; attach them by hand." on the connection. One message waiting and one message unmatched are the ordinary cases for a folder read as often as every fifteen minutes. - **Why it matters:** these are the two sentences the person reads most often from this plugin, and they are ungrammatical in every language whenever the count is one, and wrong for part of the numbers in Polish, Czech, Slovak, Slovenian, Lithuanian, Irish, Arabic and the other languages the catalogues cover with three or more forms. - **Fix:** use `ngettext` for both strings, with the count as the selector. The core's catalogue tool already extracts `ngettext` and checks that every catalogue carries as many forms as its header declares (`core/messages_tool.py` in postulo; `tests/test_catalogues.py:89` here runs that check). Regenerate the catalogues with `postulo-messages extract`, fill the forms, and correct the assertion at `tests/test_imap.py:466`. ## Done when - `tests/test_imap.py:466` asserts "1 message " for one message and a second assertion covers "2 messages"; the first fails today. - `tests/test_imap.py` has a test that a pass with exactly one unmatched message produces a note in the singular; it fails today. - `grep -c msgid_plural src/postulo_imap/locale/pl/LC_MESSAGES/django.po` prints 2, and `tests/test_catalogues.py::test_placeholders_and_plural_forms_agree` passes.
tiagoagueda added this to the 0.6.0 milestone 2026-10-01 10:47:56 +00:00
Author
Owner

Fixed by pull request #25.

Fixed by pull request #25.
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-imap#10
No description provided.