comparison mercurial/mail.py @ 39023:858fe9625dab

mail: fix _encode to be more correct on Python 3 This code appears to be on the wrong side of the law in Python 2, at least some of the time. In Python 3, it's definitely wrong in places, but fortunately that's easy to fix. Differential Revision: https://phab.mercurial-scm.org/D3953
author Augie Fackler <augie@google.com>
date Mon, 16 Jul 2018 17:48:03 -0400
parents 7b12a2d2eedc
children eabdf3c25b8b
comparison
equal deleted inserted replaced
39022:b95538a21613 39023:858fe9625dab
250 '''Returns (converted) string, charset tuple. 250 '''Returns (converted) string, charset tuple.
251 Finds out best charset by cycling through sendcharsets in descending 251 Finds out best charset by cycling through sendcharsets in descending
252 order. Tries both encoding and fallbackencoding for input. Only as 252 order. Tries both encoding and fallbackencoding for input. Only as
253 last resort send as is in fake ascii. 253 last resort send as is in fake ascii.
254 Caveat: Do not use for mail parts containing patches!''' 254 Caveat: Do not use for mail parts containing patches!'''
255 sendcharsets = charsets or _charsets(ui)
256 if not isinstance(s, bytes):
257 # We have unicode data, which we need to try and encode to
258 # some reasonable-ish encoding. Try the encodings the user
259 # wants, and fall back to garbage-in-ascii.
260 for ocs in sendcharsets:
261 try:
262 return s.encode(pycompat.sysstr(ocs)), ocs
263 except UnicodeEncodeError:
264 pass
265 except LookupError:
266 ui.warn(_('ignoring invalid sendcharset: %s\n') % ocs)
267 else:
268 # Everything failed, ascii-armor what we've got and send it.
269 return s.encode('ascii', 'backslashreplace')
270 # We have a bytes of unknown encoding. We'll try and guess a valid
271 # encoding, falling back to pretending we had ascii even though we
272 # know that's wrong.
255 try: 273 try:
256 s.decode('ascii') 274 s.decode('ascii')
257 except UnicodeDecodeError: 275 except UnicodeDecodeError:
258 sendcharsets = charsets or _charsets(ui)
259 for ics in (encoding.encoding, encoding.fallbackencoding): 276 for ics in (encoding.encoding, encoding.fallbackencoding):
260 try: 277 try:
261 u = s.decode(ics) 278 u = s.decode(ics)
262 except UnicodeDecodeError: 279 except UnicodeDecodeError:
263 continue 280 continue
264 for ocs in sendcharsets: 281 for ocs in sendcharsets:
265 try: 282 try:
266 return u.encode(ocs), ocs 283 return u.encode(pycompat.sysstr(ocs)), ocs
267 except UnicodeEncodeError: 284 except UnicodeEncodeError:
268 pass 285 pass
269 except LookupError: 286 except LookupError:
270 ui.warn(_('ignoring invalid sendcharset: %s\n') % ocs) 287 ui.warn(_('ignoring invalid sendcharset: %s\n') % ocs)
271 # if ascii, or all conversion attempts fail, send (broken) ascii 288 # if ascii, or all conversion attempts fail, send (broken) ascii