Mercurial > public > mercurial-scm > hg
comparison mercurial/mail.py @ 39106:ebf54a34b7b7
mail: pass in addr to _addressencode() in bytes
_addressencode() doesn't process a unicode addr well. For example,
acc.encode('ascii') would raise UnicodeEncodeError if acc was a unicode.
This patch temporarily restores the pre-952bf3c948f0 _addressencode().
Several tests would be broken on Python 3.
author | Yuya Nishihara <yuya@tcha.org> |
---|---|
date | Sun, 12 Aug 2018 12:11:36 +0900 |
parents | f68ad9b4a43b |
children | c2327bb3505d |
comparison
equal
deleted
inserted
replaced
39105:f68ad9b4a43b | 39106:ebf54a34b7b7 |
---|---|
306 s, cs = _encode(ui, s, charsets) | 306 s, cs = _encode(ui, s, charsets) |
307 return str(email.header.Header(s, cs)) | 307 return str(email.header.Header(s, cs)) |
308 return s | 308 return s |
309 | 309 |
310 def _addressencode(ui, name, addr, charsets=None): | 310 def _addressencode(ui, name, addr, charsets=None): |
311 assert isinstance(addr, bytes) | |
311 name = headencode(ui, name, charsets) | 312 name = headencode(ui, name, charsets) |
312 try: | 313 try: |
313 acc, dom = addr.split(r'@') | 314 acc, dom = addr.split('@') |
314 acc = acc.encode('ascii') | 315 acc = acc.encode('ascii') |
315 if isinstance(dom, bytes): | 316 dom = dom.decode(encoding.encoding).encode('idna') |
316 dom = dom.decode(encoding.encoding) | |
317 dom = dom.encode('idna') | |
318 addr = '%s@%s' % (acc, dom) | 317 addr = '%s@%s' % (acc, dom) |
319 except UnicodeDecodeError: | 318 except UnicodeDecodeError: |
320 raise error.Abort(_('invalid email address: %s') % addr) | 319 raise error.Abort(_('invalid email address: %s') % addr) |
321 except ValueError: | 320 except ValueError: |
322 try: | 321 try: |
330 def addressencode(ui, address, charsets=None, display=False): | 329 def addressencode(ui, address, charsets=None, display=False): |
331 '''Turns address into RFC-2047 compliant header.''' | 330 '''Turns address into RFC-2047 compliant header.''' |
332 if display or not address: | 331 if display or not address: |
333 return address or '' | 332 return address or '' |
334 name, addr = email.utils.parseaddr(encoding.strfromlocal(address)) | 333 name, addr = email.utils.parseaddr(encoding.strfromlocal(address)) |
335 return _addressencode(ui, name, addr, charsets) | 334 return _addressencode(ui, name, encoding.strtolocal(addr), charsets) |
336 | 335 |
337 def addrlistencode(ui, addrs, charsets=None, display=False): | 336 def addrlistencode(ui, addrs, charsets=None, display=False): |
338 '''Turns a list of addresses into a list of RFC-2047 compliant headers. | 337 '''Turns a list of addresses into a list of RFC-2047 compliant headers. |
339 A single element of input list may contain multiple addresses, but output | 338 A single element of input list may contain multiple addresses, but output |
340 always has one address per item''' | 339 always has one address per item''' |
345 | 344 |
346 result = [] | 345 result = [] |
347 for name, addr in email.utils.getaddresses( | 346 for name, addr in email.utils.getaddresses( |
348 [encoding.strfromlocal(a) for a in addrs]): | 347 [encoding.strfromlocal(a) for a in addrs]): |
349 if name or addr: | 348 if name or addr: |
350 result.append(_addressencode(ui, name, addr, charsets)) | 349 r = _addressencode(ui, name, encoding.strtolocal(addr), charsets) |
350 result.append(r) | |
351 return result | 351 return result |
352 | 352 |
353 def mimeencode(ui, s, charsets=None, display=False): | 353 def mimeencode(ui, s, charsets=None, display=False): |
354 '''creates mime text object, encodes it if needed, and sets | 354 '''creates mime text object, encodes it if needed, and sets |
355 charset and transfer-encoding accordingly.''' | 355 charset and transfer-encoding accordingly.''' |