Skip to content

Use ngettext for progress percentages and update Russian plurals#19707

Merged
seanbudd merged 6 commits into
nvaccess:masterfrom
Kostenkov-2021:Percent-plural-forms-addition
Feb 27, 2026
Merged

Use ngettext for progress percentages and update Russian plurals#19707
seanbudd merged 6 commits into
nvaccess:masterfrom
Kostenkov-2021:Percent-plural-forms-addition

Conversation

@Kostenkov-2021

@Kostenkov-2021 Kostenkov-2021 commented Feb 26, 2026

Copy link
Copy Markdown
Contributor

Link to issue number:

n/a

Summary of the issue:

The string "%d percent" is currently translated with a single form (e.g. "%d процент" in Russian). In languages like Russian that have multiple plural forms, this results in incorrect grammar (e.g. “1 процент” is correct, but “2 процент” should be “2 процента”, “5 процент” should be “5 процентов”). The code uses _() (gettext) which always picks the singular form from the translation catalogue, so plural forms cannot be used even if they are defined in the .po file.

Description of user facing changes:

Russian‑speaking users will now hear correctly pluralised percentage announcements:

  • 1% → “1 процент”
  • 2% → “2 процента”
  • 5% → “5 процентов”
    (and similarly for other numbers following Russian plural rules).

The same improvement can be applied to any other language that defines plural forms for this string; translators only need to supply the plural forms in their .po file.

Description of developer facing changes:

Two occurrences of _("%d percent") (in NVDAObjects/behaviors.py and winAPI/_powerTracking.py) have been replaced with ngettext("%d percent", "%d percent", n) % n. This allows the translation system to select the correct plural form based on the numeric value n. The gettext.ngettext function is imported where needed.

The Russian translation file (nvda.po) has been updated to include the three plural forms required for Russian:

msgid "%d percent"
msgid_plural "%d percent"
msgstr[0] "%d процент"
msgstr[1] "%d процента"
msgstr[2] "%d процентов"

Description of development approach:

  • Used ngettext because it is the standard gettext mechanism for pluralisation.
  • The change is minimal and isolated to two files, ensuring no unintended side effects.
  • The string remains exactly the same for English (which only uses one form), so no change for English users.
  • The approach is compatible with all existing translations – languages that do not define plural forms will simply fall back to the singular msgstr.

Testing strategy:

Manual testing performed:

  • Built NVDA with the modified source and recompiled the Russian .mo file.
  • Tested battery percentage announcements:
    • Pressed NVDA+Shift+B with various charge levels (1%, 2%, 5%, 11%, 21%, 22%, 25%, 100%).
    • Verified that the spoken text matched the expected Russian plural forms.
  • Tested progress bar updates (e.g. in file copy dialogs) and confirmed correct pluralisation.
  • Ensured that English announcements remain unchanged.
  • Checked that no errors appear in the log when percentages are announced.

Automated tests:

  • No unit tests directly cover this string, but existing tests for speech output pass.
  • The change is purely localisation‑related and does not affect functional logic.

Known issues with pull request:

None.

Code Review Checklist:

  • Documentation:
    • Change log entry: Added under "Changes for Developers" (or "Bug fixes" if preferred) – "The percentage announcements for battery and progress bars now correctly use plural forms in languages that require them (e.g. Russian)."
    • User Documentation: Not required – the change is transparent to users.
    • Developer / Technical Documentation: Not required – the use of ngettext is already documented.
    • Context sensitive help for GUI changes: Not applicable.
  • Testing:
    • Unit tests: Not applicable.
    • System (end to end) tests: Not applicable.
    • Manual testing: Performed as described above.
  • UX of all users considered:
    • Speech: Improved for Russian; unchanged for others.
    • Braille: Braille output is unaffected because the same string is used.
    • Low Vision: Not applicable.
    • Different web browsers: Not applicable.
    • Localization in other languages / culture than English: Now possible for any language to add plural forms.
  • API is compatible with existing add-ons. – No API changes.
  • Security precautions taken. – No security impact.

Kostenkov-2021 and others added 3 commits February 26, 2026 15:31
Replace a simple _() call with ngettext() when speaking progress percentages so the message is pluralization-aware. Update Russian locale file header (Plural-Forms, PO-Revision-Date, and X-Generator) to use the 3-form plural rule and refresh translations. Also include minor adjustments in winAPI/_powerTracking.py.
@Kostenkov-2021 Kostenkov-2021 marked this pull request as ready for review February 26, 2026 13:17
@Kostenkov-2021 Kostenkov-2021 requested a review from a team as a code owner February 26, 2026 13:17
Comment thread source/locale/ru/LC_MESSAGES/nvda.po
@seanbudd

Copy link
Copy Markdown
Member

thanks @Kostenkov-2021

@seanbudd seanbudd enabled auto-merge (squash) February 27, 2026 03:29
@seanbudd seanbudd merged commit 8c66883 into nvaccess:master Feb 27, 2026
77 of 79 checks passed
@github-actions github-actions Bot added this to the 2026.2 milestone Feb 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants