##// END OF EJS Templates
typing: add type annotations to mercurial/i18n.py...
Matt Harbison -
r47388:b9f40b74 default
parent child Browse files
Show More
@@ -1,115 +1,127
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 from __future__ import absolute_import
9 9
10 10 import gettext as gettextmod
11 11 import locale
12 12 import os
13 13 import sys
14 14
15 15 from .pycompat import getattr
16 16 from .utils import resourceutil
17 17 from . import (
18 18 encoding,
19 19 pycompat,
20 20 )
21 21
22 if pycompat.TYPE_CHECKING:
23 from typing import (
24 Callable,
25 List,
26 Optional,
27 )
28
29
22 30 # modelled after templater.templatepath:
23 31 if getattr(sys, 'frozen', None) is not None:
24 32 module = pycompat.sysexecutable
25 33 else:
26 34 module = pycompat.fsencode(__file__)
27 35
28 36 _languages = None
29 37 if (
30 38 pycompat.iswindows
31 39 and b'LANGUAGE' not in encoding.environ
32 40 and b'LC_ALL' not in encoding.environ
33 41 and b'LC_MESSAGES' not in encoding.environ
34 42 and b'LANG' not in encoding.environ
35 43 ):
36 44 # Try to detect UI language by "User Interface Language Management" API
37 45 # if no locale variables are set. Note that locale.getdefaultlocale()
38 46 # uses GetLocaleInfo(), which may be different from UI language.
39 47 # (See http://msdn.microsoft.com/en-us/library/dd374098(v=VS.85).aspx )
40 48 try:
41 49 import ctypes
42 50
51 # pytype: disable=module-attr
43 52 langid = ctypes.windll.kernel32.GetUserDefaultUILanguage()
53 # pytype: enable=module-attr
54
44 55 _languages = [locale.windows_locale[langid]]
45 56 except (ImportError, AttributeError, KeyError):
46 57 # ctypes not found or unknown langid
47 58 pass
48 59
49 60
50 61 datapath = pycompat.fsdecode(resourceutil.datapath)
51 62 localedir = os.path.join(datapath, 'locale')
52 63 t = gettextmod.translation('hg', localedir, _languages, fallback=True)
53 64 try:
54 _ugettext = t.ugettext
65 _ugettext = t.ugettext # pytype: disable=attribute-error
55 66 except AttributeError:
56 67 _ugettext = t.gettext
57 68
58 69
59 70 _msgcache = {} # encoding: {message: translation}
60 71
61 72
62 73 def gettext(message):
74 # type: (Optional[bytes]) -> Optional[bytes]
63 75 """Translate message.
64 76
65 77 The message is looked up in the catalog to get a Unicode string,
66 78 which is encoded in the local encoding before being returned.
67 79
68 80 Important: message is restricted to characters in the encoding
69 81 given by sys.getdefaultencoding() which is most likely 'ascii'.
70 82 """
71 83 # If message is None, t.ugettext will return u'None' as the
72 84 # translation whereas our callers expect us to return None.
73 85 if message is None or not _ugettext:
74 86 return message
75 87
76 88 cache = _msgcache.setdefault(encoding.encoding, {})
77 89 if message not in cache:
78 90 if type(message) is pycompat.unicode:
79 91 # goofy unicode docstrings in test
80 paragraphs = message.split(u'\n\n')
92 paragraphs = message.split(u'\n\n') # type: List[pycompat.unicode]
81 93 else:
82 94 # should be ascii, but we have unicode docstrings in test, which
83 95 # are converted to utf-8 bytes on Python 3.
84 96 paragraphs = [p.decode("utf-8") for p in message.split(b'\n\n')]
85 97 # Be careful not to translate the empty string -- it holds the
86 98 # meta data of the .po file.
87 99 u = u'\n\n'.join([p and _ugettext(p) or u'' for p in paragraphs])
88 100 try:
89 101 # encoding.tolocal cannot be used since it will first try to
90 102 # decode the Unicode string. Calling u.decode(enc) really
91 103 # means u.encode(sys.getdefaultencoding()).decode(enc). Since
92 104 # the Python encoding defaults to 'ascii', this fails if the
93 105 # translated string use non-ASCII characters.
94 106 encodingstr = pycompat.sysstr(encoding.encoding)
95 107 cache[message] = u.encode(encodingstr, "replace")
96 108 except LookupError:
97 109 # An unknown encoding results in a LookupError.
98 110 cache[message] = message
99 111 return cache[message]
100 112
101 113
102 114 def _plain():
103 115 if (
104 116 b'HGPLAIN' not in encoding.environ
105 117 and b'HGPLAINEXCEPT' not in encoding.environ
106 118 ):
107 119 return False
108 120 exceptions = encoding.environ.get(b'HGPLAINEXCEPT', b'').strip().split(b',')
109 121 return b'i18n' not in exceptions
110 122
111 123
112 124 if _plain():
113 _ = lambda message: message
125 _ = lambda message: message # type: Callable[[bytes], bytes]
114 126 else:
115 127 _ = gettext
General Comments 0
You need to be logged in to leave comments. Login now