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

File metadata

  • Download URL: generaltranslation_intl_messageformat-0.0.2.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.2.tar.gz
Algorithm Hash digest
SHA256 95b80f9ba8434e534b9a9925cf720793fed3e2c2147ed8ed8b2e631b7c778025
MD5 7847a7e6a32aa2e0742e96897ea93c46
BLAKE2b-256 05ea897c9a116a9676b4fef5ec81f070ce1d2586448d51d911073b3dc177a4dc

See more details on using hashes here.

File details

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

File metadata

  • Download URL: generaltranslation_intl_messageformat-0.0.2-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.2-py3-none-any.whl
Algorithm Hash digest
SHA256 5b7b467676e05bf11e24cb152f693c1a82031e81e946acf797a5757081832def
MD5 2b3145e486f0de71a490578ca4d72144
BLAKE2b-256 5168a69866784107e00c345fa2670640a656ff8fbb4202c81c7afe861a0e39a5

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