﻿id	summary	reporter	owner	description	type	status	component	version	severity	resolution	keywords	cc	stage	has_patch	needs_docs	needs_tests	needs_better_patch	easy	ui_ux
37167	(Officially) allow Address objects as email addresses	Mike Edmunds	Mike Edmunds	"Django should officially support Python `email.headerregistry.Address` objects in django.core.mail functions and the `ADMINS`, `MANAGERS`, `DEFAULT_FROM_EMAIL`, and `SERVER_EMAIL` settings.

This actually works now (for everything except `ADMINS` and `MANAGERS`), but isn't officially documented or tested. (And it ''would'' work for `ADMINS` and `MANAGERS` except that they specifically reject any non-`str` values to help avoid config errors.)

Forum request: https://forum.djangoproject.com/t/ticket-34753-document-how-to-properly-escape-to-in-email-messages/43551/10.

== Background

Python's [https://docs.python.org/3/library/email.headerregistry.html#email.headerregistry.Address email.headerregistry.Address] object can be used to compose an email address from parts (a `display_name` and `addr_spec` or `username` and `domain`). And for security, it ''should'' be used when building an email address from user-supplied parts (see #34753 and [https://github.com/django/django/pull/21467 PR #21467]).

Python's `EmailMessage` class accepts `Address` objects in all address headers. You can a set a message's ""From"" header to an `Address`, or its ""Cc"" header to a list of `Address` objects. (You can also set a ""Date"" header to a `datetime` object, etc.)

Django's `EmailMessage` class accidentally supports `Address` objects, in all headers since 6.0 and in all but ""From"" since at least 5.2 (maybe earlier). It currently converts the address objects to strings, and then Python parses them back into address objects.

== Proposal

* Update the `ADMINS` and `MANAGERS` recipient-type check in `django.core.mail._send_server_message()` to allow `Address`.
* Change `EmailMessage.message()` and `_set_list_header_if_not_empty()` to avoid casting an `Address` to a `str` just so Python can parse it back again. (The cast is there primarily for lazy strings.)
* Add tests!"	Cleanup/optimization	assigned	Core (Mail)	6.0	Normal				Unreviewed	0	0	0	0	0	0
