Opened 5 months ago
Last modified 2 weeks ago
#35581 assigned Cleanup/optimization
Upgrade django.core.mail to use Python's modern email API
Reported by: | Mike Edmunds | Owned by: | Mike Edmunds |
---|---|---|---|
Component: | Core (Mail) | Version: | dev |
Severity: | Normal | Keywords: | email, compat32 |
Cc: | bcail | Triage Stage: | Accepted |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
django.core.mail.EmailMessage currently uses Python's "legacy" email API. Updating that code to Python's newer "modern" email API would fix bugs and substantially simplify it.
The update should be mostly transparent for users of Django's documented mail APIs, but will rework the internals of django.core.mail.message in ways that may require changes to some third-party email backends and other code that borrows undocumented (but popular) functions from that module. In addition, parts of Django's mail test suite will need reworking to avoid dependence on legacy implementation specifics.
Some relevant posts from django-developers:
- Background and rationale for switching to Python's modern email API
- Proposed implementation details (some of these were modified in later discussion—in particular, we don't expect to combine EmailMultiAlternatives into EmailMessage as part of this ticket, and we won't deprecate MIMEBase attachments just yet)
- Deprecation details for the documented BadHeaderError, SafeMIMEText and SafeMIMEMultipart, and the undocumented forbid_multi_line_headers() and sanitize_address()
Change History (17)
comment:1 by , 5 months ago
Triage Stage: | Unreviewed → Accepted |
---|---|
Version: | → dev |
comment:2 by , 4 months ago
Owner: | changed from | to
---|
comment:3 by , 4 months ago
Owner: | changed from | to
---|
@YashRaj1506 I have a bunch of work underway on this and will open a PR soon. Don't want you to needlessly duplicate effort. Code review on the PR would be very welcome once it's ready.
Part of the delay is I've run into a handful of open issues in Python's modern email API that may require further discussion:
- Modern set_content() forces a trailing newline on text content (https://github.com/python/cpython/issues/121515). I think this is probably fine, but it touches a lot of tests.
- Security issues in modern header serialization (https://github.com/python/cpython/issues/80222, https://github.com/python/cpython/issues/121284). I think these would block this change.
Also trying to decide how best to handle Django's EmailMessage.encoding
. It's not documented, but a bunch of tests cover setting it and checking the results. (The only relevant docs are this note about the DEFAULT_CHARSET setting also applying to django.core.mail.)
comment:4 by , 4 months ago
Has patch: | set |
---|
I've opened two sequential PRs, as suggested in the django-developers discussion. Both are ready for review:
- https://github.com/django/django/pull/18502 improves the test suite for django.core.mail while staying on the existing (legacy) API.
- https://github.com/medmunds/django/pull/2 implements the changeover to the modern email API.
(The second PR is in my own Django fork so that it can be based on the first PR without overlap. I'll reopen it upstream once the first PR is closed. But reviews are welcome now if you don't mind working in my fork; just note any discussion history there won't transfer to the eventual upstream PR.)
Some additional notes are in the PR comments.
comment:5 by , 4 months ago
Patch needs improvement: | set |
---|
comment:6 by , 4 months ago
Patch needs improvement: | unset |
---|
comment:7 by , 2 months ago
Cc: | added |
---|
comment:12 by , 2 weeks ago
Triage Stage: | Accepted → Ready for checkin |
---|
comment:16 by , 2 weeks ago
Triage Stage: | Ready for checkin → Accepted |
---|
comment:17 by , 2 weeks ago
Has patch: | unset |
---|
I will try to solve this.