From 6cf8070fc71bad27bf7b5da9540f3af9a86d7871 Mon Sep 17 00:00:00 2001 From: Aarni Koskela Date: Mon, 3 Feb 2025 11:34:27 +0200 Subject: [PATCH] Allow passthrough of xgettext's plural templates Fixes #1154 --- babel/messages/catalog.py | 15 +++++++++------ tests/messages/test_pofile.py | 14 ++++++++++++++ 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/babel/messages/catalog.py b/babel/messages/catalog.py index 954dad0e..856ccbc6 100644 --- a/babel/messages/catalog.py +++ b/babel/messages/catalog.py @@ -398,8 +398,9 @@ class Catalog: # Dictionary of obsolete messages self.obsolete: dict[str | tuple[str, str], Message] = {} - self._num_plurals = None - self._plural_expr = None + + self._num_plurals: str | int | None = None + self._plural_expr: str | None = None def _set_locale(self, locale: Locale | str | None) -> None: if locale is None: @@ -538,7 +539,8 @@ class Catalog: self.charset = params['charset'].lower() elif name == 'plural-forms': params = parse_separated_header(f" ;{value}") - self._num_plurals = int(params.get('nplurals', 2)) + nplurals = params.get('nplurals') + self._num_plurals = int(nplurals, 10) if nplurals.isdigit() else nplurals self._plural_expr = params.get('plural', '(n != 1)') elif name == 'pot-creation-date': self.creation_date = _parse_datetime_header(value) @@ -600,15 +602,16 @@ class Catalog: """) @property - def num_plurals(self) -> int: + def num_plurals(self) -> int | str: """The number of plurals used by the catalog or locale. + If read from a catalog template, this may be a string. + >>> Catalog(locale='en').num_plurals 2 >>> Catalog(locale='ga').num_plurals 5 - - :type: `int`""" + """ if self._num_plurals is None: num = 2 if self.locale: diff --git a/tests/messages/test_pofile.py b/tests/messages/test_pofile.py index 2bcc3df8..f8eabfad 100644 --- a/tests/messages/test_pofile.py +++ b/tests/messages/test_pofile.py @@ -1096,3 +1096,17 @@ def test_issue_1134(case: str, abort_invalid: bool): output = pofile.read_po(buf) assert len(output) == 1 assert output["foo"].string in ((''), ('', '')) + + +def test_issue_1154(): + # Via `echo 'ngettext("Hello World!", "Hello Worlds!", 3);' | xgettext --output=- - --language=C`, + # minimized for reproducing the issue. + template = """ +msgid "" +msgstr "" +"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n" + """.strip() + cat = pofile.read_po(StringIO(template)) + assert cat.num_plurals == "INTEGER" + assert cat.plural_expr == "EXPRESSION" + assert cat.plural_forms == "nplurals=INTEGER; plural=EXPRESSION;" -- 2.47.2