comparison mercurial/encoding.py @ 30034:e4a6b439acc5

py3: provide encoding.environ which is a dict of bytes This can't be moved to pycompat.py since we need encoding.tolocal() to build bytes dict from unicode os.environ.
author Yuya Nishihara <yuya@tcha.org>
date Wed, 28 Sep 2016 20:05:34 +0900
parents 02dbfaa6df0b
children ce36fa9b140c
comparison
equal deleted inserted replaced
30033:02dbfaa6df0b 30034:e4a6b439acc5
45 if "\xe2" in s or "\xef" in s: 45 if "\xe2" in s or "\xef" in s:
46 for c in _ignore: 46 for c in _ignore:
47 s = s.replace(c, '') 47 s = s.replace(c, '')
48 return s 48 return s
49 49
50 # encoding.environ is provided read-only, which may not be used to modify
51 # the process environment
52 _nativeenviron = (not pycompat.ispy3 or os.supports_bytes_environ)
53 if not pycompat.ispy3:
54 environ = os.environ
55 elif _nativeenviron:
56 environ = os.environb
57 else:
58 # preferred encoding isn't known yet; use utf-8 to avoid unicode error
59 # and recreate it once encoding is settled
60 environ = dict((k.encode(u'utf-8'), v.encode(u'utf-8'))
61 for k, v in os.environ.items())
62
50 def _getpreferredencoding(): 63 def _getpreferredencoding():
51 ''' 64 '''
52 On darwin, getpreferredencoding ignores the locale environment and 65 On darwin, getpreferredencoding ignores the locale environment and
53 always returns mac-roman. http://bugs.python.org/issue6202 fixes this 66 always returns mac-roman. http://bugs.python.org/issue6202 fixes this
54 for Python 2.7 and up. This is the same corrected code for earlier 67 for Python 2.7 and up. This is the same corrected code for earlier
76 'ANSI_X3.4-1968': lambda: 'ascii', 89 'ANSI_X3.4-1968': lambda: 'ascii',
77 'mac-roman': _getpreferredencoding 90 'mac-roman': _getpreferredencoding
78 } 91 }
79 92
80 try: 93 try:
81 encoding = os.environ.get("HGENCODING") 94 encoding = environ.get("HGENCODING")
82 if not encoding: 95 if not encoding:
83 encoding = locale.getpreferredencoding() or 'ascii' 96 encoding = locale.getpreferredencoding() or 'ascii'
84 encoding = _encodingfixers.get(encoding, lambda: encoding)() 97 encoding = _encodingfixers.get(encoding, lambda: encoding)()
85 except locale.Error: 98 except locale.Error:
86 encoding = 'ascii' 99 encoding = 'ascii'
87 encodingmode = os.environ.get("HGENCODINGMODE", "strict") 100 encodingmode = environ.get("HGENCODINGMODE", "strict")
88 fallbackencoding = 'ISO-8859-1' 101 fallbackencoding = 'ISO-8859-1'
89 102
90 class localstr(str): 103 class localstr(str):
91 '''This class allows strings that are unmodified to be 104 '''This class allows strings that are unmodified to be
92 round-tripped to the local encoding and back''' 105 round-tripped to the local encoding and back'''
181 sub = s[max(0, inst.start - 10):inst.start + 10] 194 sub = s[max(0, inst.start - 10):inst.start + 10]
182 raise error.Abort("decoding near '%s': %s!" % (sub, inst)) 195 raise error.Abort("decoding near '%s': %s!" % (sub, inst))
183 except LookupError as k: 196 except LookupError as k:
184 raise error.Abort(k, hint="please check your locale settings") 197 raise error.Abort(k, hint="please check your locale settings")
185 198
199 if not _nativeenviron:
200 # now encoding and helper functions are available, recreate the environ
201 # dict to be exported to other modules
202 environ = dict((tolocal(k.encode(u'utf-8')), tolocal(v.encode(u'utf-8')))
203 for k, v in os.environ.items())
204
186 # How to treat ambiguous-width characters. Set to 'wide' to treat as wide. 205 # How to treat ambiguous-width characters. Set to 'wide' to treat as wide.
187 wide = (os.environ.get("HGENCODINGAMBIGUOUS", "narrow") == "wide" 206 wide = (environ.get("HGENCODINGAMBIGUOUS", "narrow") == "wide"
188 and "WFA" or "WF") 207 and "WFA" or "WF")
189 208
190 def colwidth(s): 209 def colwidth(s):
191 "Find the column width of a string for display in the local encoding" 210 "Find the column width of a string for display in the local encoding"
192 return ucolwidth(s.decode(_sysstr(encoding), u'replace')) 211 return ucolwidth(s.decode(_sysstr(encoding), u'replace'))