Skip to content

Inflection-213 Support building and testing with ICU 79 - #214

Merged
nciric merged 5 commits into
unicode-org:mainfrom
nciric:Inflection-213-upgrade-to-icu-79
Oct 22, 2026
Merged

nciric merged 5 commits into
unicode-org:mainfrom
nciric:Inflection-213-upgrade-to-icu-79

Conversation

@nciric

@nciric nciric commented Oct 15, 2026

Copy link
Copy Markdown
Contributor

Fixes #213

Summary

Upgrades inflection to build and test against ICU 79 (CLDR 49 / Unicode 18), bumping ICU_VERSION_MINIMUM in cmake/versions.mk to 79.1.

Note

The GitHub Actions workflows currently set ICU_MINOR: '1rc' (release-79.1rc) so CI can run prior to the final ICU 79.1 release on Wednesday, at which point ICU_MINOR will be updated to '1'.

Changes

  1. MessageFormat 2 Custom Function API (ICU-23266):
    • Update MF2Factory.hpp, MF2Factory.cpp, and Message2Test.cpp to use ICU 79's unified Function, FunctionValue, and FunctionContext interfaces (.adoptFunction(...) on MFFunctionRegistry::Builder, integer index preferences in FunctionValue::selectKeys, and const FunctionOptionsMap& from FunctionOptions::getOptions()).
  2. MessageFormat 2 Default BiDi Isolation Strategy (ICU-23143):
    • Populate directionality metadata on InflectionFunctionValue from the FunctionContext locale/direction, and configure .setBidiIsolationStrategy(icu::U_MF_BIDI_OFF) in Message2Test#testLocales where XML test expectations do not include U+2068/U+2069 BiDi isolates.
  3. CLDR 49 Data Updates (ListTest & QuantifyTest):
    • Update 3-item and 4-item Hindi standard (and) list expectations in ListTest#testListHi (और without preceding serial comma in CLDR 49).
    • Remove #if U_ICU_VERSION_MAJOR_NUM <= 78 workarounds in QuantifyTest#testSerboCroatian.
  4. generateICUWrapper (U_LIFETIME_BOUND):
    • Strip \s*\bU_LIFETIME_BOUND\b in RunOnFile's normalizationMap in tools/generateICUWrapper/generateICUWrapper.cpp.
  5. Build & CI Workflows:
    • Update ICU_VERSION_MINIMUM := 79.1 in cmake/versions.mk.
    • Update Ubuntu CI workflows to use Ubuntu24.04-x64 ICU 79 release archives and install lld in create-distribution-packaging.yml.
    • Switch macOS CI jobs in cmake-multi-platform.yml and create-distribution-packaging.yml from Homebrew icu4c to building and caching ICU from the official release source archive (icu4c-${ICU_MAJOR}.${ICU_MINOR}-sources.tgz).

@nciric
nciric requested a review from grhoten October 15, 2026 19:52
Comment thread test/src/inflection/grammar/synthesis/QuantifyTest.cpp
Comment thread src/inflection/message2/MF2Factory.hpp
MessageFormatter::Builder builder(testError);
builder.setFunctionRegistry(hasSpeak ? ssmlRegistry : plainRegistry)
.setLocale(icuLocale)
.setBidiIsolationStrategy(icu::U_MF_BIDI_OFF)

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.

This seems interesting. It's a common problem. What's this about? There seems to be a lot of changes related to this option.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

ICU 79 (ICU-22939 / ICU-23143) turned on U_MF_BIDI_AUTO by default. Any placeholder with U_MF_DIRECTIONALITY_UNKNOWN now gets wrapped in U+2068 (FSI) / U+2069 (PDI) isolates, even in LTR locales.

InflectionFunctionValue in MF2Factory.cpp sets inputDir and dir from context.getDirection() and locale.isRightToLeft() (same as ICU's :number and :datetime) so :i:* functions report the locale directionality.

8 XML test cases in de_DE.xml, en_US.xml, and es_MX.xml had bare {$object} / {$name} variables (which default to :string with UNKNOWN directionality and got wrapped in FSI/PDI). Added :i:inflect to those 8 placeholders to match the rest of the XML tests and removed .setBidiIsolationStrategy(icu::U_MF_BIDI_OFF) from Message2Test.cpp.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Alternatively, instead of annotating those 8 bare {$object} / {$name} placeholders with :i:inflect in <source>, <print> can include the expected &#x2068; / &#x2069; isolates directly, e.g.:

<source>You opened {$object} and {$object2 :i:inflect}.</source>
<print>You opened &#x2068;something&#x2069; and something.</print>

That keeps the original bare-variable test inputs and verifies both behaviors side-by-side ({$object} gets isolated while {$object2 :i:inflect} does not). WDYT?

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.

I'm not really enjoying the extra syntax with i:inflect for plain strings that are not actually inflecting. It's extra writing that has no visible advantage for the average message writer. It should be simple. I'd rather go with the default behavior, and leave the bare strings alone.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Ok, then I implemented the other option - no more i:inflect, but expectation has to spell out the bidi characters that MF2.0 now inserts.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Another option is to just turn it off - which George and I agreed on.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

@grhoten Done in b0c369a — turned off bidi isolation in Message2Test.cpp (.setBidiIsolationStrategy(icu::U_MF_BIDI_OFF)) and reverted the bidi test changes in the XML files.

Comment thread test/src/inflection/message2/Message2Test.cpp Outdated
Comment thread tools/generateICUWrapper/generateICUWrapper.cpp

@grhoten grhoten 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.

Since the test files generally work the same, and the API header changes are adapting to the new ICU implementation, these changes seem good.

.adoptFunction(FunctionName("i:quantify"), inflection::message2::MF2Factory::createQuantifyFunction(mode), ec)
.adoptFunction(FunctionName("i:list"), inflection::message2::MF2Factory::createListFunction(mode), ec)
.adoptFunction(FunctionName("i:pronoun"), inflection::message2::MF2Factory::createPronounFunction(mode), ec)
.build();

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.

At first, I was worried about this change. Since the tests pass unmodified, and I believe that both the formatters and selectors are tested, this change should be fine.

@nciric
nciric merged commit 9b6704e into unicode-org:main Oct 22, 2026
11 checks passed
@nciric
nciric deleted the Inflection-213-upgrade-to-icu-79 branch October 22, 2026 21:17
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.

Support building and testing with ICU 79

2 participants