changeset 34660:d00ec62d156f

i18n: cache translated messages per encoding This is a simpler workaround alternative to D958, "i18n: clean msgcache when encoding changes." The cache won't be bloated unless you run tons of commands with different --encoding options on command server, or serve many repositories of different web.encoding options on hgweb. The test was originally written by Jun Wu. Differential Revision: https://phab.mercurial-scm.org/D1053
author Yuya Nishihara <yuya@tcha.org>
date Fri, 13 Oct 2017 21:36:10 +0900
parents 3edfd472f3cb
children eb586ed5d8ce
files mercurial/i18n.py tests/test-i18n.t
diffstat 2 files changed, 26 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/mercurial/i18n.py	Thu Oct 12 22:09:11 2017 +0900
+++ b/mercurial/i18n.py	Fri Oct 13 21:36:10 2017 +0900
@@ -58,7 +58,7 @@
     except AttributeError:
         _ugettext = t.gettext
 
-_msgcache = {}
+_msgcache = {}  # encoding: {message: translation}
 
 def gettext(message):
     """Translate message.
@@ -74,7 +74,8 @@
     if message is None or not _ugettext:
         return message
 
-    if message not in _msgcache:
+    cache = _msgcache.setdefault(encoding.encoding, {})
+    if message not in cache:
         if type(message) is unicode:
             # goofy unicode docstrings in test
             paragraphs = message.split(u'\n\n')
@@ -90,11 +91,11 @@
             # the Python encoding defaults to 'ascii', this fails if the
             # translated string use non-ASCII characters.
             encodingstr = pycompat.sysstr(encoding.encoding)
-            _msgcache[message] = u.encode(encodingstr, "replace")
+            cache[message] = u.encode(encodingstr, "replace")
         except LookupError:
             # An unknown encoding results in a LookupError.
-            _msgcache[message] = message
-    return _msgcache[message]
+            cache[message] = message
+    return cache[message]
 
 def _plain():
     if ('HGPLAIN' not in encoding.environ
--- a/tests/test-i18n.t	Thu Oct 12 22:09:11 2017 +0900
+++ b/tests/test-i18n.t	Fri Oct 13 21:36:10 2017 +0900
@@ -48,3 +48,23 @@
   $ $PYTHON check-translation.py *.po
   $ $PYTHON check-translation.py --doctest
   $ cd $TESTTMP
+
+Check i18n cache isn't reused after encoding change:
+
+  $ cat > $TESTTMP/encodingchange.py << EOF
+  > from mercurial import encoding, registrar
+  > from mercurial.i18n import _
+  > cmdtable = {}
+  > command = registrar.command(cmdtable)
+  > @command(b'encodingchange', norepo=True)
+  > def encodingchange(ui):
+  >     for encode in (b'ascii', b'UTF-8', b'ascii', b'UTF-8'):
+  >         encoding.encoding = encode
+  >         ui.write(b'%s\n' % _(b'(EXPERIMENTAL)'))
+  > EOF
+
+  $ LANGUAGE=ja hg --config extensions.encodingchange=$TESTTMP/encodingchange.py encodingchange
+  (?????)
+  (\xe5\xae\x9f\xe9\xa8\x93\xe7\x9a\x84\xe5\xae\x9f\xe8\xa3\x85) (esc)
+  (?????)
+  (\xe5\xae\x9f\xe9\xa8\x93\xe7\x9a\x84\xe5\xae\x9f\xe8\xa3\x85) (esc)