Skip to main content

ICU MessageFormat formatter with locale-aware plural and select rules

Project description

generaltranslation-intl-messageformat

⚠️ Experimental / Unstable — This package is under active development and may be subject to breaking changes.

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

File metadata

  • Download URL: generaltranslation_intl_messageformat-0.0.4.tar.gz
  • Upload date:
  • Size: 5.8 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.4.tar.gz
Algorithm Hash digest
SHA256 671e970e4072a4da03affb331002252d0e6eed5f03a59fc9b1192558aabe7314
MD5 49f19a9a4d59d0f33424393dbf8e16d6
BLAKE2b-256 9b41d01e7ebf50b30621f8aafed66579e45a4bd74ab32215e4ad64b41391f942

See more details on using hashes here.

File details

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

File metadata

  • Download URL: generaltranslation_intl_messageformat-0.0.4-py3-none-any.whl
  • Upload date:
  • Size: 7.8 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.4-py3-none-any.whl
Algorithm Hash digest
SHA256 494b0fc265a3fde3f69c77cc6f98229398cf1ebeac70a8f4a7651b1010c16f27
MD5 a2016516cfd4495f897ebed7a7e8a216
BLAKE2b-256 c6901cec0c1c8997b51f81edef76de4943f7b7bedc7af77fc7f64cc429381045

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