Title: email.utils.formataddr does not support RFC 6532
Type: enhancement Stage: resolved
Components: email Versions: Python 3.5
Status: closed Resolution: not a bug
Dependencies: Superseder:
Assigned To: Nosy List: Sergei Maertens, acucci, barry, claudep, r.david.murray
Priority: normal Keywords:

Created on 2015-12-26 13:17 by Sergei Maertens, last changed 2015-12-26 21:04 by Sergei Maertens. This issue is now closed.

Messages (4)
msg257034 - (view) Author: Sergei Maertens (Sergei Maertens) Date: 2015-12-26 13:17
The function `formataddr` in stdlib `email.utils` does not allow unicode e-mail addresses where the first part (before the @) is unicode. Python 3.5 promises support for SMTPUTF8 through `EmailPoliy.utf8` (, but this utility function doesn't respect this, as it calls `address.encode('ascii')`.

For unicode addresses, an obvious `UnicodeEncodeError` is raised.

Reproduce steps:

➜  ~  python
Python 3.5.1 (default, Dec  7 2015, 12:58:09) 
[GCC 5.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from email.utils import formataddr
>>> formataddr(('dummy', 'juan.ló'))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python3.5/email/", line 91, in formataddr
UnicodeEncodeError: 'ascii' codec can't encode character '\xf3' in position 6: ordinal not in range(128)

Interesting is that on Python 2.7 the behaviour is more naive, but it works::

➜  ~  python2
Python 2.7.11 (default, Dec  6 2015, 15:43:46) 
[GCC 5.2.0] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from email.utils import formataddr
>>> formataddr(('dummy', u'juan.ló'))
u'dummy <juan.l\>'
msg257038 - (view) Author: Alessandro Cucci (acucci) * Date: 2015-12-26 15:26
Sergei can you submit a patch? 
Otherwise I can work on that, I have free time.
msg257039 - (view) Author: R. David Murray (r.david.murray) * (Python committer) Date: 2015-12-26 15:48
formataddr is part of the legacy interface and has no knowledge of the current policy.  So it doesn't support RFC 6532.  For that you need to use the new API: just assign your address to the appropriate field, or create a headerregistry.Address object.

I'm in the process of rewriting the docs to make all of this clear, but, well, I'm slow...
msg257048 - (view) Author: Sergei Maertens (Sergei Maertens) Date: 2015-12-26 21:04
I could probably come up with a patch, but the reason I ran into this is because it's used in the core of Django. I already submitted a bug with Django, and with the legaciness of this function it feels like Django should move to the new API or implement its own variant of the function. I'll report as such in tje downstream bug report.
Date User Action Args
2015-12-26 21:04:30Sergei Maertenssetmessages: + msg257048
2015-12-26 15:48:00r.david.murraysetstatus: open -> closed
resolution: not a bug
messages: + msg257039

stage: resolved
2015-12-26 15:26:57acuccisetnosy: + acucci
messages: + msg257038
2015-12-26 13:43:01claudepsetnosy: + claudep
2015-12-26 13:17:02Sergei Maertenscreate