Skip to content

Fix compact decimal plural selection after rounding - #1430

Open
0718lol wants to merge 2 commits into
python-babel:masterfrom
0718lol:fix/compact-plural-after-rounding
Open

0718lol wants to merge 2 commits into
python-babel:masterfrom
0718lol:fix/compact-plural-after-rounding

Conversation

@0718lol

@0718lol 0718lol commented Nov 4, 2026

Copy link
Copy Markdown

Fixes #1429.

Select compact decimal plural forms using the rounded displayed value rather than the unrounded scaled value. Normalize optional fractional zeros before plural selection, since they are not displayed. For example, Russian 1100 now renders as 1 тысяча instead of 1 тысячи, and Polish 1900 renders as 2 tysiące instead of 2 tysiąca.

Add 11 regression cases covering positive and negative values, retained fractions, trimmed zeros, and five locales. Update the existing Italian 1234 expectation from 1 mila to mille, matching the rounded-value plural rule and Node's Intl formatter. The separate exact-1 pattern selection is unchanged.

Validation: CLDR 48.2 imported using the repository script; Python 3.12.15 on macOS; full suite: 7856 passed, 8 skipped, 2 xfailed. Ruff and git diff --check pass. The new regression tests fail on the original implementation.

Developed and tested with Codex assistance.

Comment thread babel/numbers.py Outdated
plural_form = locale.plural_form(plural_number)
if plural_form not in compact_format:
plural_form = "other"
if scaled == 1 and "1" in compact_format:

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's also use the rounded value here:

Suggested change
if scaled == 1 and "1" in compact_format:
if rounded == 1 and "1" in compact_format:

and then change the tests accordingly and add

    ('fr', 1234, 0, 'mille'),
    ('fr', -1234, 0, '-1 millier'),

to the tests (this ought to match what Node ICU does).

@akx akx self-assigned this Nov 4, 2026
@akx akx added this to the Babel 2.19 milestone Nov 4, 2026
@0718lol

0718lol commented Nov 4, 2026 via email

Copy link
Copy Markdown
Author

@akx

akx commented Nov 5, 2026

Copy link
Copy Markdown
Member

@0718lol Sorry, I can't read that (without Google Translate anyway). Are you able to enact the changes requested?

As requested in review: the special case should test the rounded display
value instead of the scaled input, so e.g. fr 1234 with fraction_digits=0
formats as 'mille' (matching Node ICU), while fr -1234 keeps '-1 millier'.

Adds the two French cases to test_compact_plural_uses_displayed_number and
updates the matching expectation in test_compact.
@0718lol

0718lol commented Nov 8, 2026

Copy link
Copy Markdown
Author

Done, pushed as f6411c5:

  • babel/numbers.py: the special case now tests the rounded display value (if rounded == 1 ...), exactly as suggested.
  • Added ('fr', 1234, 0, 'mille') and ('fr', -1234, 0, '-1 millier') to test_compact_plural_uses_displayed_number — both behave as you described.
  • Updated the pre-existing expectation in tests/test_numbers_format_decimal.py::test_compact (fr 1234 is now 'mille', matching Node ICU and the Italian case right above it).

Verification: the two new cases fail before the change and pass after. Full tests/ run: 6689 passed, 1180 skipped, 1 xfailed, and one failure in test_extract.py::test_input_paths_is_treated_as_list that I verified also fails on the unmodified branch HEAD locally (it is triggered by my checkout directory name containing --, not by this patch).

Sorry for the earlier reply in Chinese. This update was prepared with AI assistance under my direction, as disclosed in the PR description.

@akx
akx requested review from akx and a balanced review from Copilot and removed request for akx November 9, 2026 09:47

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The exact-1 pattern now applies to scaled values that round to 1, contradicting the description and requiring either a description update or restoration of the exact comparison.

1 open issue
What changed in this PR

Updates Babel’s compact decimal formatting to select plural forms from the rounded displayed value, addressing #1429.

Changes:

  • Uses rounded values with optional trailing zeros removed for plural selection.
  • Extends literal exact-1 pattern selection to values that round to 1.
  • Adds 13 regression cases across five locales and updates Italian and French expectations.
File Description
tests/​test_numbers.py Adds coverage for rounding, signs, retained fractions, and trimmed zeros.
tests/​test_numbers_format_decimal.py Updates Italian and French compact-format expectations.
babel/​numbers.py Uses normalized rounded values for plural rules and rounded values for exact-1 matching.

Review effort: Balanced

Comment thread babel/numbers.py
if plural_form not in compact_format:
plural_form = "other"
if scaled == 1 and "1" in compact_format:
if rounded == 1 and "1" in compact_format:

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Compact decimal plural forms use the value before rounding

3 participants