Skip to content

Commit

Permalink
storage: make UnitId parsing more robust
Browse files Browse the repository at this point in the history
- Gracefully handle non-numeric index parts
- Add tests for parsing
- Add __eq__ and __repr__ to UnitId class
  • Loading branch information
nijel committed Dec 13, 2023
1 parent 9f7a97d commit 2a9c325
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 7 deletions.
27 changes: 26 additions & 1 deletion tests/translate/storage/test_jsonl10n.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from io import BytesIO

from pytest import raises
from pytest import mark, raises

from translate.misc.multistring import multistring
from translate.storage import base, jsonl10n
Expand Down Expand Up @@ -668,6 +668,31 @@ def test_add_other(self):

assert bytes(newstore).decode() == jsontext

@mark.parametrize(
("id_string", "expected"),
[
("[0]", [("index", 0)]),
("test[0]", [("key", "test"), ("index", 0)]),
(
"test[0][1][2][3]",
[
("key", "test"),
("index", 0),
("index", 1),
("index", 2),
("index", 3),
],
),
("[test]selection", [("key", "[test]selection")]),
("[test][0]selection", [("key", "[test][0]selection")]),
("[0][test]selection", [("index", 0), ("key", "[test]selection")]),
],
)
def test_from_string(self, id_string, expected):
id_class = self.StoreClass.UnitClass.IdClass
from_string = id_class.from_string
assert from_string(id_string) == id_class(expected)


class TestWebExtensionUnit(test_monolingual.TestMonolingualUnit):
UnitClass = jsonl10n.WebExtensionJsonUnit
Expand Down
22 changes: 16 additions & 6 deletions translate/storage/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -952,18 +952,28 @@ def from_string(cls, text):
for item in text.split(cls.KEY_SEPARATOR):
bracepos = item.find("[")
endbracepos = item.find("]")
if bracepos != -1 and endbracepos != -1:
while (
(bracepos := item.find("[")) != -1
and (endbracepos := item.find("]")) != -1
and item[bracepos + 1 : endbracepos].isdigit()
):
if bracepos > 0:
result.append(("key", item[:bracepos]))
item = item[bracepos:]
result.extend(
("index", int(pos))
for pos in item.replace("[", " ").replace("]", " ").split()
)
else:
endbracepos -= bracepos
bracepos = 0
result.append(("index", int(item[bracepos + 1 : endbracepos])))
item = item[endbracepos + 1 :]
if item:
result.append(("key", item))
return cls(result)

def __eq__(self, other):
return self.parts == other.parts

def __repr__(self):
return f"<UnitId:{self.parts}>"


class DictUnit(TranslationUnit):
IdClass = UnitId
Expand Down

0 comments on commit 2a9c325

Please sign in to comment.