Mercurial > hg > mercurial-source
comparison mercurial/mail.py @ 39810:eabdf3c25b8b
mail: cope with Py3 unicode antics on email addresses
Differential Revision: https://phab.mercurial-scm.org/D3954
author | Augie Fackler <augie@google.com> |
---|---|
date | Mon, 16 Jul 2018 17:49:17 -0400 (2018-07-16) |
parents | 858fe9625dab |
children | 569d662816de |
comparison
equal
deleted
inserted
replaced
39809:858fe9625dab | 39810:eabdf3c25b8b |
---|---|
297 return s | 297 return s |
298 | 298 |
299 def _addressencode(ui, name, addr, charsets=None): | 299 def _addressencode(ui, name, addr, charsets=None): |
300 name = headencode(ui, name, charsets) | 300 name = headencode(ui, name, charsets) |
301 try: | 301 try: |
302 acc, dom = addr.split('@') | 302 acc, dom = addr.split(r'@') |
303 acc = acc.encode('ascii') | 303 acc = acc.encode('ascii') |
304 dom = dom.decode(encoding.encoding).encode('idna') | 304 dom = dom.decode(encoding.encoding).encode('idna') |
305 addr = '%s@%s' % (acc, dom) | 305 addr = '%s@%s' % (acc, dom) |
306 except UnicodeDecodeError: | 306 except UnicodeDecodeError: |
307 raise error.Abort(_('invalid email address: %s') % addr) | 307 raise error.Abort(_('invalid email address: %s') % addr) |
309 try: | 309 try: |
310 # too strict? | 310 # too strict? |
311 addr = addr.encode('ascii') | 311 addr = addr.encode('ascii') |
312 except UnicodeDecodeError: | 312 except UnicodeDecodeError: |
313 raise error.Abort(_('invalid local address: %s') % addr) | 313 raise error.Abort(_('invalid local address: %s') % addr) |
314 return email.utils.formataddr((name, addr)) | 314 return pycompat.bytesurl( |
315 email.utils.formataddr((name, encoding.strfromlocal(addr)))) | |
315 | 316 |
316 def addressencode(ui, address, charsets=None, display=False): | 317 def addressencode(ui, address, charsets=None, display=False): |
317 '''Turns address into RFC-2047 compliant header.''' | 318 '''Turns address into RFC-2047 compliant header.''' |
318 if display or not address: | 319 if display or not address: |
319 return address or '' | 320 return address or '' |
320 name, addr = email.utils.parseaddr(address) | 321 name, addr = email.utils.parseaddr(encoding.strfromlocal(address)) |
321 return _addressencode(ui, name, addr, charsets) | 322 return _addressencode(ui, name, addr, charsets) |
322 | 323 |
323 def addrlistencode(ui, addrs, charsets=None, display=False): | 324 def addrlistencode(ui, addrs, charsets=None, display=False): |
324 '''Turns a list of addresses into a list of RFC-2047 compliant headers. | 325 '''Turns a list of addresses into a list of RFC-2047 compliant headers. |
325 A single element of input list may contain multiple addresses, but output | 326 A single element of input list may contain multiple addresses, but output |
326 always has one address per item''' | 327 always has one address per item''' |
328 for a in addrs: | |
329 assert isinstance(a, bytes), (r'%r unexpectedly not a bytestr' % a) | |
327 if display: | 330 if display: |
328 return [a.strip() for a in addrs if a.strip()] | 331 return [a.strip() for a in addrs if a.strip()] |
329 | 332 |
330 result = [] | 333 result = [] |
331 for name, addr in email.utils.getaddresses(addrs): | 334 for name, addr in email.utils.getaddresses( |
335 [encoding.strfromlocal(a) for a in addrs]): | |
332 if name or addr: | 336 if name or addr: |
333 result.append(_addressencode(ui, name, addr, charsets)) | 337 result.append(_addressencode(ui, name, addr, charsets)) |
334 return result | 338 return [pycompat.bytesurl(r) for r in result] |
335 | 339 |
336 def mimeencode(ui, s, charsets=None, display=False): | 340 def mimeencode(ui, s, charsets=None, display=False): |
337 '''creates mime text object, encodes it if needed, and sets | 341 '''creates mime text object, encodes it if needed, and sets |
338 charset and transfer-encoding accordingly.''' | 342 charset and transfer-encoding accordingly.''' |
339 cs = 'us-ascii' | 343 cs = 'us-ascii' |