##// END OF EJS Templates
i18n: cache the result of every gettext call...
Augie Fackler -
r23031:3c0983cc default
parent child Browse files
Show More
@@ -1,86 +1,90 b''
1 1 # i18n.py - internationalization support for mercurial
2 2 #
3 3 # Copyright 2005, 2006 Matt Mackall <mpm@selenic.com>
4 4 #
5 5 # This software may be used and distributed according to the terms of the
6 6 # GNU General Public License version 2 or any later version.
7 7
8 8 import encoding
9 9 import gettext as gettextmod, sys, os, locale
10 10
11 11 # modelled after templater.templatepath:
12 12 if getattr(sys, 'frozen', None) is not None:
13 13 module = sys.executable
14 14 else:
15 15 module = __file__
16 16
17 17
18 18 _languages = None
19 19 if (os.name == 'nt'
20 20 and 'LANGUAGE' not in os.environ
21 21 and 'LC_ALL' not in os.environ
22 22 and 'LC_MESSAGES' not in os.environ
23 23 and 'LANG' not in os.environ):
24 24 # Try to detect UI language by "User Interface Language Management" API
25 25 # if no locale variables are set. Note that locale.getdefaultlocale()
26 26 # uses GetLocaleInfo(), which may be different from UI language.
27 27 # (See http://msdn.microsoft.com/en-us/library/dd374098(v=VS.85).aspx )
28 28 try:
29 29 import ctypes
30 30 langid = ctypes.windll.kernel32.GetUserDefaultUILanguage()
31 31 _languages = [locale.windows_locale[langid]]
32 32 except (ImportError, AttributeError, KeyError):
33 33 # ctypes not found or unknown langid
34 34 pass
35 35
36 36 _ugettext = None
37 37
38 38 def setdatapath(datapath):
39 39 localedir = os.path.join(datapath, 'locale')
40 40 t = gettextmod.translation('hg', localedir, _languages, fallback=True)
41 41 global _ugettext
42 42 _ugettext = t.ugettext
43 43
44 _msgcache = {}
45
44 46 def gettext(message):
45 47 """Translate message.
46 48
47 49 The message is looked up in the catalog to get a Unicode string,
48 50 which is encoded in the local encoding before being returned.
49 51
50 52 Important: message is restricted to characters in the encoding
51 53 given by sys.getdefaultencoding() which is most likely 'ascii'.
52 54 """
53 55 # If message is None, t.ugettext will return u'None' as the
54 56 # translation whereas our callers expect us to return None.
55 57 if message is None or not _ugettext:
56 58 return message
57 59
58 if type(message) is unicode:
59 # goofy unicode docstrings in test
60 paragraphs = message.split(u'\n\n')
61 else:
62 paragraphs = [p.decode("ascii") for p in message.split('\n\n')]
63 # Be careful not to translate the empty string -- it holds the
64 # meta data of the .po file.
65 u = u'\n\n'.join([p and _ugettext(p) or '' for p in paragraphs])
66 try:
67 # encoding.tolocal cannot be used since it will first try to
68 # decode the Unicode string. Calling u.decode(enc) really
69 # means u.encode(sys.getdefaultencoding()).decode(enc). Since
70 # the Python encoding defaults to 'ascii', this fails if the
71 # translated string use non-ASCII characters.
72 return u.encode(encoding.encoding, "replace")
73 except LookupError:
74 # An unknown encoding results in a LookupError.
75 return message
60 if message not in _msgcache:
61 if type(message) is unicode:
62 # goofy unicode docstrings in test
63 paragraphs = message.split(u'\n\n')
64 else:
65 paragraphs = [p.decode("ascii") for p in message.split('\n\n')]
66 # Be careful not to translate the empty string -- it holds the
67 # meta data of the .po file.
68 u = u'\n\n'.join([p and _ugettext(p) or '' for p in paragraphs])
69 try:
70 # encoding.tolocal cannot be used since it will first try to
71 # decode the Unicode string. Calling u.decode(enc) really
72 # means u.encode(sys.getdefaultencoding()).decode(enc). Since
73 # the Python encoding defaults to 'ascii', this fails if the
74 # translated string use non-ASCII characters.
75 _msgcache[message] = u.encode(encoding.encoding, "replace")
76 except LookupError:
77 # An unknown encoding results in a LookupError.
78 _msgcache[message] = message
79 return _msgcache[message]
76 80
77 81 def _plain():
78 82 if 'HGPLAIN' not in os.environ and 'HGPLAINEXCEPT' not in os.environ:
79 83 return False
80 84 exceptions = os.environ.get('HGPLAINEXCEPT', '').strip().split(',')
81 85 return 'i18n' not in exceptions
82 86
83 87 if _plain():
84 88 _ = lambda message: message
85 89 else:
86 90 _ = gettext
General Comments 0
You need to be logged in to leave comments. Login now