from babel.core import Locale
from babel.messages.catalog import Catalog, Message
-from babel.util import TextWrapper, _cmp
+from babel.util import TextWrapper
if TYPE_CHECKING:
from typing import IO, AnyStr
escaped_lines = string.splitlines()
if string.startswith('""'):
escaped_lines = escaped_lines[1:]
- return ''.join(unescape(line) for line in escaped_lines)
+ return ''.join(map(unescape, escaped_lines))
else:
return unescape(string)
self.lineno = lineno
-class _NormalizedString:
-
+class _NormalizedString(list):
def __init__(self, *args: str) -> None:
- self._strs: list[str] = []
- for arg in args:
- self.append(arg)
-
- def append(self, s: str) -> None:
- self._strs.append(s.strip())
+ super().__init__(map(str.strip, args))
def denormalize(self) -> str:
- return ''.join(unescape(s) for s in self._strs)
-
- def __bool__(self) -> bool:
- return bool(self._strs)
-
- def __repr__(self) -> str:
- return os.linesep.join(self._strs)
-
- def __cmp__(self, other: object) -> int:
- if not other:
- return 1
-
- return _cmp(str(self), str(other))
-
- def __gt__(self, other: object) -> bool:
- return self.__cmp__(other) > 0
-
- def __lt__(self, other: object) -> bool:
- return self.__cmp__(other) < 0
-
- def __ge__(self, other: object) -> bool:
- return self.__cmp__(other) >= 0
-
- def __le__(self, other: object) -> bool:
- return self.__cmp__(other) <= 0
-
- def __eq__(self, other: object) -> bool:
- return self.__cmp__(other) == 0
-
- def __ne__(self, other: object) -> bool:
- return self.__cmp__(other) != 0
+ if not self:
+ return ""
+ return ''.join(map(unescape, self))
class PoFileParser:
if self.messages:
if not self.translations:
self._invalid_pofile("", self.offset, f"missing msgstr for msgid '{self.messages[0].denormalize()}'")
- self.translations.append([0, _NormalizedString("")])
+ self.translations.append([0, _NormalizedString()])
self._add_message()
def _process_message_line(self, lineno, line, obsolete=False) -> None:
self.in_msgstr = True
if arg.startswith('['):
idx, msg = arg[1:].split(']', 1)
- self.translations.append([int(idx), _NormalizedString(msg)])
+ idx = int(idx)
else:
- self.translations.append([0, _NormalizedString(arg)])
+ idx = 0
+ msg = arg
+ s = _NormalizedString(msg) if msg != '""' else _NormalizedString()
+ self.translations.append([idx, s])
elif keyword == 'msgctxt':
self.in_msgctxt = True
else:
self._invalid_pofile(line, lineno, "Got line starting with \" but not in msgid, msgstr or msgctxt")
return
- s.append(line)
+ s.append(line.strip()) # For performance reasons, `NormalizedString` doesn't strip internally
def _process_comment(self, line) -> None:
# No actual messages found, but there was some info in comments, from which
# we'll construct an empty header message
if not self.counter and (self.flags or self.user_comments or self.auto_comments):
- self.messages.append(_NormalizedString('""'))
- self.translations.append([0, _NormalizedString('""')])
+ self.messages.append(_NormalizedString())
+ self.translations.append([0, _NormalizedString()])
self._add_message()
def _invalid_pofile(self, line, lineno, msg) -> None:
+++ /dev/null
-from babel.messages.pofile import _NormalizedString
-
-
-def test_normalized_string():
- ab1 = _NormalizedString('a', 'b ')
- ab2 = _NormalizedString('a', ' b')
- ac1 = _NormalizedString('a', 'c')
- ac2 = _NormalizedString(' a', 'c ')
- z = _NormalizedString()
- assert ab1 == ab2 and ac1 == ac2 # __eq__
- assert ab1 < ac1 # __lt__
- assert ac1 > ab2 # __gt__
- assert ac1 >= ac2 # __ge__
- assert ab1 <= ab2 # __le__
- assert ab1 != ac1 # __ne__
- assert not z # __nonzero__ / __bool__
- assert sorted([ab1, ab2, ac1]) # the sort order is not stable so we can't really check it, just that we can sort