Skip to content

Support the CLDR 49 ordinal day of month pattern field - #1383

Open
summeriver13 wants to merge 2 commits into
python-babel:masterfrom
summeriver13:fix/ordinal-day-of-month-ddd
Open

summeriver13 wants to merge 2 commits into
python-babel:masterfrom
summeriver13:fix/ordinal-day-of-month-ddd

Conversation

@summeriver13

@summeriver13 summeriver13 commented Oct 12, 2026 •

Copy link
Copy Markdown

scripts/import_cldr.py aborts on the CLDR 49 data with ValueError: Invalid length for field: 'ddd' (babel/dates.py:1809): CLDR 49 uses ddd for ordinal days of the month
("Sept 13th"), which the d field did not accept.

Changes

  • babel/dates.py: accept ddd for d and format the ordinal day picked by
    Locale.ordinal_form; locales without ordinal forms fall back to a single d as the CLDR
    spec prescribes, so the day is not zero-padded.
  • babel/core.py: new Locale.ordinal_day_formats property (CLDR 49 <dayOfMonth> patterns
    by ordinal plural category, {0} replaced by the day).
  • scripts/import_cldr.py: import dayOfMonths for the gregorian calendar
    (dayOfMonthContext[@type="format"] / dayOfMonthWidth[@type="abbreviated"]), plus tests
    for parsing, the ordinal output and the fallback.

Verification

$ uv run python scripts/import_cldr.py <cldr-49-beta2>/common   # exit 0, 0 errors, 183 locales
$ uv run python -c "from datetime import date; from babel.dates import format_date as f; print(f(date(2026, 9, 13), 'MMM ddd, y', locale='en'))"
Sep 13th, 2026
  • uv run pytest -q on the pinned CLDR 48.2 data: 7875 passed, 10 skipped, 2 xfailed.
  • The new tests fail without the code change, with exactly the ValueError from the issue.

I left the second half of #1379 (cldr-exemplars-delta import) to the maintainers.

Disclosure: written with AI assistance; I reviewed the diff, ran the importer and the suite.

@tomasr8 tomasr8 mentioned this pull request Nov 3, 2026
@akx

akx commented Nov 5, 2026

Copy link
Copy Markdown
Member

@summeriver13 #1427 was just merged, so we are on CLDR 49. Could you rebase this?

@summeriver13

Copy link
Copy Markdown
Author

Rebased onto master (b33ab76, CLDR 49). #1427 already added ddd to PATTERN_CHARS, so that hunk dropped out. The remaining change is the formatting semantics: ddd used to zero-pad the day to three digits (001); it now uses the locale's <dayOfMonths> patterns and falls back to a single d when the locale has none. scripts/import_cldr.py imports those patterns.

@akx
akx requested review from akx and tomasr8 and a balanced review from Copilot November 5, 2026 11:17
@codecov

codecov Bot commented Nov 5, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 93.67%. Comparing base (b33ab76) to head (870cceb).

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #1383      +/-   ##
==========================================
+ Coverage   93.66%   93.67%   +0.01%     
==========================================
  Files          27       27              
  Lines        4972     4982      +10     
==========================================
+ Hits         4657     4667      +10     
  Misses        315      315              
Flag Coverage Δ
macos-14-3.10 ?
macos-14-3.11 ?
macos-14-3.12 ?
macos-14-3.13 ?
macos-14-3.14 ?
macos-14-3.15 ?
macos-14-3.8 ?
macos-14-3.9 ?
macos-14-pypy3.10 ?
ubuntu-24.04-3.10 92.73% <100.00%> (+0.01%) ⬆️
ubuntu-24.04-3.11 92.67% <100.00%> (+0.01%) ⬆️
ubuntu-24.04-3.12 92.93% <100.00%> (+0.01%) ⬆️
ubuntu-24.04-3.13 92.93% <100.00%> (+0.01%) ⬆️
ubuntu-24.04-3.14 92.91% <100.00%> (+0.01%) ⬆️
ubuntu-24.04-3.15 92.91% <100.00%> (+0.01%) ⬆️
ubuntu-24.04-3.8 92.60% <100.00%> (+0.01%) ⬆️
ubuntu-24.04-3.9 92.66% <100.00%> (+0.01%) ⬆️
ubuntu-24.04-pypy3.10 92.73% <100.00%> (+0.01%) ⬆️
windows-2022-3.10 92.72% <100.00%> (+0.01%) ⬆️
windows-2022-3.11 92.66% <100.00%> (+0.01%) ⬆️
windows-2022-3.12 92.92% <100.00%> (+0.01%) ⬆️
windows-2022-3.13 92.92% <100.00%> (+0.01%) ⬆️
windows-2022-3.14 92.90% <100.00%> (+0.01%) ⬆️
windows-2022-3.15 92.90% <100.00%> (+0.01%) ⬆️
windows-2022-3.8 92.70% <100.00%> (+0.01%) ⬆️
windows-2022-3.9 92.66% <100.00%> (+0.01%) ⬆️
windows-2022-pypy3.10 92.72% <100.00%> (+0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@codspeed

codspeed Bot commented Nov 5, 2026 •

Copy link
Copy Markdown

Merging this PR will not alter performance

✅ 88 untouched benchmarks


Comparing summeriver13:fix/ordinal-day-of-month-ddd (870cceb) with master (b33ab76)

Open in CodSpeed

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.

🟢 Approval recommended

The ordinal day-of-month support changes have no active review issues blocking approval.

No open issues 🎉

What changed in this PR

Adds CLDR 49 ordinal day-of-month support to Babel’s locale-data importer and date formatter, addressing the ordinal-field portion of #1379. The separate locale migration issue remains out of scope.

Changes:

  • Imports ordinal day patterns and exposes them through Locale.ordinal_day_formats.
  • Formats ordinal days using locale plural rules, falling back to an unpadded day when no matching pattern exists.
  • Adds tests for ddd parsing, ordinal output, fallback behavior, and unsupported field lengths.
File Description
tests/​test_dates.py Tests ordinal day parsing, formatting, and fallback behavior.
scripts/​import_cldr.py Imports abbreviated ordinal day patterns from calendar data.
babel/​dates.py Adds locale-aware ordinal day formatting.
babel/​core.py Exposes ordinal day patterns through a new locale property.

Review effort: Balanced

@akx akx left a comment

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.

Small test changes -- and we'll see if other changes are needed once CI rolls through.

Comment thread tests/test_dates.py Resolved
Comment thread tests/test_dates.py Resolved
@summeriver13
summeriver13 force-pushed the fix/ordinal-day-of-month-ddd branch from 98659e8 to 1ae0152 Compare November 5, 2026 11:26
@summeriver13

Copy link
Copy Markdown
Author

Done in 1ae0152:

  • removed test_parse_pattern_ordinal_day and test_parse_pattern_rejects_unsupported_day_length.
  • test_format_ordinal_day_of_month now formats with the imported en data instead of monkeypatching. The fallback test already used the real de data.

Local run with CLDR 49 data: tests/test_dates.py + tests/test_core.py 2541 passed, 2 xfailed; doctests 176 passed; ruff check clean. With CLDR 48 data the ordinal test fails on Feb 1, 2016, as expected.

@akx akx left a comment

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.

LGTM. @tomasr8 if you have a moment to also check this, that'd be grand!

@tomasr8

tomasr8 commented Nov 5, 2026

Copy link
Copy Markdown
Member

I have a few nits, if you give me a few hours I'll post my review :)

@tomasr8 tomasr8 left a comment

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.

A few nits, but otherwise LGTM :)

Comment thread babel/core.py Resolved
Comment thread babel/dates.py Resolved
Comment thread scripts/import_cldr.py Resolved
Comment thread scripts/import_cldr.py Resolved
Comment thread tests/test_dates.py Resolved
Comment thread tests/test_dates.py Resolved
@akx
akx enabled auto-merge (squash) November 6, 2026 07:16
summeriver13 and others added 2 commits November 9, 2026 16:48
CLDR 49 adds the "ddd" pattern field for ordinal days of the month ("Sept 13th")
and the matching <dayOfMonths> data. PATTERN_CHARS already accepts "ddd", so
formatting "ddd" zero-padded the day to three digits ("001"). "ddd" now formats
the day with the locale's ordinal forms, keyed by the ordinal plural category,
and falls back to a single "d" for locales that have none, as the CLDR spec
prescribes. scripts/import_cldr.py imports the dayOfMonth patterns.

Refs python-babel#1379
Remove the CLDR version note from the property docstring.
Document the format character count.
Warn on unsupported CLDR element types.
Extend the tests to French and the fallback path.

Co-Authored-By: pi <noreply@pi.dev>
@akx
akx force-pushed the fix/ordinal-day-of-month-ddd branch from 870cceb to b2b25e6 Compare November 9, 2026 14:49

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.

4 participants