Skip to content

Commit

Permalink
storage: share logic for synchronizing plural strings
Browse files Browse the repository at this point in the history
The same logic was implemented in several formats so bring the
implementation in sync.
  • Loading branch information
nijel committed Mar 6, 2024
1 parent 8800dad commit 476811d
Show file tree
Hide file tree
Showing 6 changed files with 45 additions and 35 deletions.
17 changes: 17 additions & 0 deletions tests/translate/storage/test_jsonl10n.py
Original file line number Diff line number Diff line change
Expand Up @@ -1224,6 +1224,23 @@ def test_plurals_2(self):

assert bytes(store).decode() == JSON_GOI18N_V2

def test_plurals_blank(self):
store = self.StoreClass()
store.settargetlanguage("ar")
store.parse(JSON_GOI18N_V2)
# Remove one of plurals
store.units[1].target = multistring(
[
"the plural form 0",
"the plural form 1",
"the plural form 2",
"the plural form 3",
"the plural form 4",
]
)

assert bytes(store).decode() == JSON_GOI18N_V2.replace("the plural form 5", "")

def test_plurals_missing(self):
store = self.StoreClass()
store.parse(JSON_GOI18N_V2_SIMPLE)
Expand Down
12 changes: 1 addition & 11 deletions translate/storage/aresource.py
Original file line number Diff line number Diff line change
Expand Up @@ -456,18 +456,8 @@ def target(self, target):

plural_tags = self.get_plural_tags()

# Get string list to handle, wrapping non multistring/list targets into a list.
if isinstance(target, multistring):
plural_strings = target.strings
elif isinstance(target, list):
plural_strings = target
else:
plural_strings = [target]

# Sync plural_strings elements to plural_tags count.
if len(plural_strings) < len(plural_tags):
plural_strings += [""] * (len(plural_tags) - len(plural_strings))
plural_strings = plural_strings[: len(plural_tags)]
plural_strings = self.sync_plural_count(target, plural_tags)

# Rebuild plurals.
for entry in self.xmlelement.iterchildren():
Expand Down
22 changes: 22 additions & 0 deletions translate/storage/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -518,6 +518,28 @@ def infer_state(self):
current state(_n) of the unit from its current state.
"""

@staticmethod
def sync_plural_count(
target: list[str] | str | multistring, plural_tags: list[str]
) -> list[str]:
"""Ensure that plural count in string matches tags definition."""
# Get string list to handle, wrapping non multistring/list targets into a list.
if isinstance(target, multistring):
# Coerce all items to string, they might be multistrings
plural_strings = [str(string) for string in target.strings]
elif isinstance(target, list):
plural_strings = target
else:
plural_strings = [target]

# Add missing strings
missing = len(plural_tags) - len(plural_strings)
if missing:
plural_strings += [""] * missing

# Remove extra ones
return plural_strings[: len(plural_tags)]


class TranslationStore:
"""Base class for stores for multiple translation units of type UnitClass."""
Expand Down
12 changes: 3 additions & 9 deletions translate/storage/jsonl10n.py
Original file line number Diff line number Diff line change
Expand Up @@ -546,9 +546,7 @@ def __init__(
def getvalue(self):
target = self.target
if isinstance(target, multistring):
strings = list(target.strings)
if len(self._store.plural_tags) > len(target.strings):
strings += [""] * (len(self._store.plural_tags) - len(target.strings))
strings = self.sync_plural_count(target, self._store.plural_tags)
target = {
"select": {
"feature": "plural",
Expand Down Expand Up @@ -660,9 +658,7 @@ class GoI18NJsonUnit(BaseJsonUnit):
def getvalue(self):
target = self.target
if isinstance(target, multistring):
strings = list(target.strings)
if len(self._store.plural_tags) > len(target.strings):
strings += [""] * (len(self._store.plural_tags) - len(target.strings))
strings = self.sync_plural_count(target, self._store.plural_tags)
target = {
plural: strings[offset]
for offset, plural in enumerate(self._store.plural_tags)
Expand Down Expand Up @@ -743,9 +739,7 @@ def converttarget(self):
if self.notes:
target["description"] = self.notes

strings = self.target.strings
if len(self._store.plural_tags) > len(strings):
strings += [""] * (len(self._store.plural_tags) - len(target.strings))
strings = self.sync_plural_count(self.target, self._store.plural_tags)
for offset, plural in enumerate(self._store.plural_tags):
target[plural] = strings[offset]

Expand Down
11 changes: 1 addition & 10 deletions translate/storage/stringsdict.py
Original file line number Diff line number Diff line change
Expand Up @@ -182,17 +182,8 @@ def serialize(self, out):

plural_tags = self.target_plural_tags

if isinstance(u.target, multistring):
plural_strings = u.target.strings
elif isinstance(u.target, list):
plural_strings = u.target
else:
plural_strings = [u.target]

# Sync plural_strings elements to plural_tags count.
if len(plural_strings) < len(plural_tags):
plural_strings += [""] * (len(plural_tags) - len(plural_strings))
plural_strings = plural_strings[: len(plural_tags)]
plural_strings = self.UnitClass.sync_plural_count(u.target, plural_tags)

for plural_tag, plural_string in zip(plural_tags, plural_strings):
if plural_string:
Expand Down
6 changes: 1 addition & 5 deletions translate/storage/yaml.py
Original file line number Diff line number Diff line change
Expand Up @@ -188,12 +188,8 @@ def convert_target(self):

tags = plural_tags.get(self._store.targetlanguage, plural_tags["en"])

strings = [str(s) for s in self.target.strings]

# Sync plural_strings elements to plural_tags count.
if len(strings) < len(tags):
strings += [""] * (len(tags) - len(strings))
strings = strings[: len(tags)]
strings = self.sync_plural_count(self.target, tags)

return CommentedMap(zip(tags, strings))

Expand Down

0 comments on commit 476811d

Please sign in to comment.