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.3.tar.gz.

File metadata

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

File hashes

Hashes for generaltranslation_intl_messageformat-0.0.3.tar.gz
Algorithm Hash digest
SHA256 30e55a2a2d333f989dcf49ddc429353cb31e7cee07638fd23303170cb891ef37
MD5 3ec6769ee36d9b2bec21138e3874a9ea
BLAKE2b-256 a928ee0bff1eaacf6d419e0cf6e23f3e713da3700d328ed8f2154695373a1e30

See more details on using hashes here.

File details

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

File metadata

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

File hashes

Hashes for generaltranslation_intl_messageformat-0.0.3-py3-none-any.whl
Algorithm Hash digest
SHA256 d6daba9b57ce0905e38abcbf9db7a356f58566885fa39819f45cf80a90873229
MD5 5d238d7c55287219f3f44422184ae882
BLAKE2b-256 48cc126c402f5670505621f8a7b85a3c45469ecb099d953186eba07d238e7880

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