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