diff -r a7e0a1dbfbb6 Lib/email/utils.py --- a/Lib/email/utils.py Sun Mar 27 10:15:57 2011 +0200 +++ b/Lib/email/utils.py Sun Mar 27 15:26:36 2011 +0200 @@ -56,21 +56,34 @@ # Helpers -def formataddr(pair): +def formataddr(pair, encoding='utf-8'): """The inverse of parseaddr(), this takes a 2-tuple of the form (realname, email_address) and returns the string value suitable for an RFC 2822 From, To or Cc header. If the first element of pair is false, then the second element is returned unmodified. + + Optional encoding if given this is the encoding that is used + to quote the name if it is not ascii safe. """ name, address = pair + # Will throw UnicodeEncodeError when address is not plain ascii. + # I am not sure of this should be caught or if this is a proper way + # to expose that error. + address.encode('ascii') if name: - quotes = '' - if specialsre.search(name): - quotes = '"' - name = escapesre.sub(r'\\\g<0>', name) - return '%s%s%s <%s>' % (quotes, name, quotes, address) + try: + name.encode('ascii') + quotes = '' + if specialsre.search(name): + quotes = '"' + name = escapesre.sub(r'\\\g<0>', name) + return '%s%s%s <%s>' % (quotes, name, quotes, address) + except UnicodeEncodeError: + bytes = name.encode(encoding) + b64_encoded = str(_bencode(bytes), 'ascii').rstrip() + return "=?%s?B?%s?= <%s>" % (encoding, b64_encoded, address) return address diff -r a7e0a1dbfbb6 Lib/test/test_email/test_email.py --- a/Lib/test/test_email/test_email.py Sun Mar 27 10:15:57 2011 +0200 +++ b/Lib/test/test_email/test_email.py Sun Mar 27 15:26:36 2011 +0200 @@ -2408,6 +2408,13 @@ b = 'person@dom.ain' self.assertEqual(utils.parseaddr(utils.formataddr((a, b))), (a, b)) + def test_quotes_unicode_names(self): + # issue 1690608. email.utils.formataddr() should be rfc2047 aware + name = "H\u00e4ns W\u00fcrst" + addr = 'person@dom.ain' + quoted = "=?utf-8?B?SMOkbnMgV8O8cnN0?= " + self.assertEqual(utils.formataddr((name, addr)), quoted) + def test_name_with_dot(self): x = 'John X. Doe ' y = '"John X. Doe" ' diff -r a7e0a1dbfbb6 Misc/ACKS --- a/Misc/ACKS Sun Mar 27 10:15:57 2011 +0200 +++ b/Misc/ACKS Sun Mar 27 15:26:36 2011 +0200 @@ -977,3 +977,4 @@ Kai Zhu Tarek Ziadé Peter Åstrand +Torsten Becker