This is an archive of the discontinued Mercurial Phabricator instance.

mail: cope with Py3 unicode antics on email addresses
ClosedPublic

Authored by durin42 on Jul 16 2018, 7:16 PM.

Details

Diff Detail

Repository
rHG Mercurial
Lint
Lint Skipped
Unit
Unit Tests Skipped

Event Timeline

durin42 created this revision.Jul 16 2018, 7:16 PM
yuja added a subscriber: yuja.Jul 17 2018, 9:25 AM
  • return email.utils.formataddr((name, addr))

+ return pycompat.bytesurl(
+ email.utils.formataddr((name, addr.decode('ascii'))))

Maybe this would bring unicode to Python 2.

def addressencode(ui, address, charsets=None, display=False):

'''Turns address into RFC-2047 compliant header.'''
if display or not address:
    return address or ''
  • name, addr = email.utils.parseaddr(address)

+ name, addr = email.utils.parseaddr(pycompat.strurl(address))

strurl() is too strict to convert a user input. encoding.strfromlocal()
can be used instead.

result = []
  • for name, addr in email.utils.getaddresses(addrs):

+ for name, addr in email.utils.getaddresses(
+ [pycompat.strurl(a) for a in addrs]):

Same here.

durin42 updated this revision to Diff 10190.Aug 9 2018, 4:43 PM
durin42 updated this revision to Diff 10194.Aug 9 2018, 4:48 PM
This revision was automatically updated to reflect the committed changes.
yuja added a comment.Aug 11 2018, 10:17 PM

def _addressencode(ui, name, addr, charsets=None):

name = headencode(ui, name, charsets)
try:
  • acc, dom = addr.split('@')

+ acc, dom = addr.split(r'@')

I think addr here should be a byte string since dom is decoded to unicode,
and addr is embedded in abort message.

acc = acc.encode('ascii')
dom = dom.decode(encoding.encoding).encode('idna')
addr = '%s@%s' % (acc, dom)

@@ -311,27 +311,31 @@

    addr = addr.encode('ascii')
except UnicodeDecodeError:
    raise error.Abort(_('invalid local address: %s') % addr)
  • return email.utils.formataddr((name, addr))

+ return pycompat.bytesurl(
+ email.utils.formataddr((name, encoding.strfromlocal(addr))))

result = []
  • for name, addr in email.utils.getaddresses(addrs):

+ for name, addr in email.utils.getaddresses(
+ [encoding.strfromlocal(a) for a in addrs]):

if name or addr:
    result.append(_addressencode(ui, name, addr, charsets))
  • return result

+ return [pycompat.bytesurl(r) for r in result]

_addressencode() retunrs bytes.