Skip to main content

ICU MessageFormat formatter with locale-aware plural and select rules

Project description

generaltranslation-intl-messageformat

ICU MessageFormat formatter with locale-aware plural and select rules. Python equivalent of intl-messageformat.

Uses generaltranslation-icu-messageformat-parser for parsing and Babel for CLDR plural rules.

Installation

pip install generaltranslation-intl-messageformat

Dependencies: generaltranslation-icu-messageformat-parser, babel>=2.18.0. Pure Python, no C extensions.

Quick Start

from generaltranslation_intl_messageformat import IntlMessageFormat

# Simple variable interpolation
mf = IntlMessageFormat("Hello, {name}!", "en")
mf.format({"name": "World"})  # "Hello, World!"

# Plural with CLDR rules
mf = IntlMessageFormat("{count, plural, one {# item} other {# items}}", "en")
mf.format({"count": 1})   # "1 item"
mf.format({"count": 5})   # "5 items"
mf.format({"count": 1000})  # "1,000 items"

# Select
mf = IntlMessageFormat("{gender, select, male {He} female {She} other {They}} left.", "en")
mf.format({"gender": "female"})  # "She left."

# Selectordinal
mf = IntlMessageFormat("{n, selectordinal, one {#st} two {#nd} few {#rd} other {#th}}", "en")
mf.format({"n": 1})   # "1st"
mf.format({"n": 22})  # "22nd"
mf.format({"n": 3})   # "3rd"
mf.format({"n": 4})   # "4th"

API

IntlMessageFormat(pattern, locale="en")

Create a message formatter.

Args:

  • pattern (str): An ICU MessageFormat pattern string.
  • locale (str): A BCP 47 locale tag. Defaults to "en". Falls back to "en" if the locale is invalid.

IntlMessageFormat.format(values=None)

Format the message with variable values.

Args:

  • values (dict | None): A dict mapping variable names to values. Values can be str, int, float, or any type convertible via str(). Missing variables resolve to empty string.

Returns: str — The formatted message.

IntlMessageFormat.pattern

Type: str — The original pattern string (read-only property).

IntlMessageFormat.locale

Type: babel.Locale — The resolved Babel locale (read-only property).

Supported ICU Features

Simple variables

IntlMessageFormat("Hello, {name}!", "en").format({"name": "World"})
# "Hello, World!"

Plural

Selects a branch based on CLDR plural rules for the locale. Supports one, two, few, many, other, and zero categories, plus exact matches with =N.

# English: one/other
IntlMessageFormat("{n, plural, one {# dog} other {# dogs}}", "en").format({"n": 1})
# "1 dog"

# Arabic: zero/one/two/few/many/other
IntlMessageFormat(
    "{n, plural, zero {صفر} one {واحد} two {اثنان} few {# قليل} many {# كثير} other {# آخر}}", "ar"
).format({"n": 3})
# "3 قليل"

# Russian: one/few/many/other
IntlMessageFormat(
    "{n, plural, one {# книга} few {# книги} many {# книг} other {# книг}}", "ru"
).format({"n": 21})
# "21 книга"

Exact match

IntlMessageFormat(
    "{n, plural, =0 {no items} =1 {one item} other {# items}}", "en"
).format({"n": 0})
# "no items"

Plural with offset

The offset value is subtracted before plural rule evaluation. The # hash displays the offset-adjusted value.

IntlMessageFormat(
    "{guests, plural, offset:1 =0 {nobody} =1 {{host}} one {{host} and # other} other {{host} and # others}}", "en"
).format({"guests": 3, "host": "Alice"})
# "Alice and 2 others"

Selectordinal

Selects a branch based on CLDR ordinal plural rules.

IntlMessageFormat(
    "{n, selectordinal, one {#st} two {#nd} few {#rd} other {#th}}", "en"
).format({"n": 23})
# "23rd"

Select

Matches a string value to a branch key, falls back to other.

IntlMessageFormat(
    "{type, select, cat {meow} dog {woof} other {???}}", "en"
).format({"type": "cat"})
# "meow"

Nested expressions

Plural inside select, select inside plural, variables inside branches — all work.

IntlMessageFormat(
    "{gender, select, male {He has {n, plural, one {# item} other {# items}}} other {They have {n, plural, one {# item} other {# items}}}}", "en"
).format({"gender": "male", "n": 1})
# "He has 1 item"

Hash # replacement

Inside plural/selectordinal branches, # is replaced with the numeric value (locale-formatted with grouping separators).

IntlMessageFormat("{n, plural, other {# items}}", "en").format({"n": 1000})
# "1,000 items"

IntlMessageFormat("{n, plural, other {# Artikel}}", "de").format({"n": 1000})
# "1.000 Artikel"

Locale Support

Uses Babel's CLDR data for plural rules, covering 100+ locales. Tested against icu4py (ICU4C bindings) for correctness across:

  • English (en) — one/other
  • French (fr) — one/other (0 is "one")
  • German (de) — one/other
  • Arabic (ar) — zero/one/two/few/many/other
  • Russian (ru) — one/few/many/other
  • Polish (pl) — one/few/many/other
  • Japanese (ja) — other only
  • And all other locales supported by Babel/CLDR

Known Carve-outs

  • Boolean values: Python True/False are formatted as "True"/"False" (Python convention). ICU4C formats them as 1/0.
  • Escape sequences: '' and '{...}' are unescaped during parsing (matching @formatjs/icu-messageformat-parser behavior). The formatted output contains the unescaped text.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

File details

Details for the file generaltranslation_intl_messageformat-0.0.0.tar.gz.

File metadata

  • Download URL: generaltranslation_intl_messageformat-0.0.0.tar.gz
  • Upload date:
  • Size: 5.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.10.8 {"installer":{"name":"uv","version":"0.10.8","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for generaltranslation_intl_messageformat-0.0.0.tar.gz
Algorithm Hash digest
SHA256 e7e73478b44b5c847595cf2ec7ed9da185685ec06838d98eb01586400b466bdb
MD5 b102ef54094870ab7341c4bb425083f9
BLAKE2b-256 5172144fc3579cfc30062282a839b924cd2d13f594b52f26e66ed789f62d18fc

See more details on using hashes here.

File details

Details for the file generaltranslation_intl_messageformat-0.0.0-py3-none-any.whl.

File metadata

  • Download URL: generaltranslation_intl_messageformat-0.0.0-py3-none-any.whl
  • Upload date:
  • Size: 7.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.10.8 {"installer":{"name":"uv","version":"0.10.8","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for generaltranslation_intl_messageformat-0.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 e233101d18439a7b0e9f80e5255245c2706982468f091ac5686cf51344c24709
MD5 746e69faf59a750587f6a6154ab4c65c
BLAKE2b-256 5f2e51e269b600502d7b5fce2d27601d64339e94446372d20eae537a2c7e2627

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page