#36163: Change mail APIs to (mostly) keyword-only parameters
-------------------------------------+-------------------------------------
Reporter: Mike Edmunds | Type:
| Cleanup/optimization
Status: new | Component: Core
| (Mail)
Version: 5.1 | Severity: Normal
Keywords: | Triage Stage:
| Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Several of Django's email APIs have extremely long parameter lists. This
complicates adding—and documenting—new parameters where they would
logically fit, as the existing positional order must be maintained for
compatibility.
This ticket proposes changing the public django.core.mail APIs to require
keyword-only arguments, starting at the first boolean or "uncommon"
parameter. That's `fail_silently` for the functional APIs, and `bcc` for
the class constructors (specifics below).
Forum discussion:
https://forum.djangoproject.com/t/change-send-mail-and-
emailmessage-to-kwargs-only/38239
Consensus in the forum was that this change should be made '''without a
deprecation period.''' Existing code that uses positional arguments for
the affected params would raise a TypeError after the change.
A quick (and by no means exhaustive) GitHub code search suggests a lot of
existing code already uses keyword arguments for these params, but that
positional arguments are common for the earlier ones. One potential
exception is custom EmailMultiAlternatives subclasses. (More details in
the forum.)
(This originally came up in the context of #35514, which must add a new
`provider` parameter to several existing APIs—including the
"[
https://github.com/django/django/blob/8eca4077f60fa0705ecfd9437c9ceaeef7a3808b/django/core/mail/__init__.py#L78-L79
frozen]" send_mail() and send_mass_mail() functions, and the EmailMessage
class with its [
https://docs.djangoproject.com/en/5.1/topics/email
/#emailmessage-
objects:~:text=in%20the%20given%20order%2C%20if%20positional%20arguments%20are%20used
documented parameter ordering].)
=== Proposed changes ===
This change would add `*,`s where indicated below. All parameters after
the `*,` would become keyword only.
{{{#!python
# django/core/mail/__init__.py
def get_connection(
backend=None,
*,
fail_silently=False, **kwds):
def send_mail(
subject, message, from_email, recipient_list,
*,
fail_silently=False, auth_user=None, auth_password=None,
connection=None, html_message=None):
def send_mass_mail(
datatuple,
*,
fail_silently=False, auth_user=None, auth_password=None,
connection=None):
def mail_admins(
subject, message,
*,
fail_silently=False, connection=None, html_message=None):
def mail_managers(
subject, message,
*,
fail_silently=False, connection=None, html_message=None):
}}}
{{{#!python
# django/core/mail/message.py
class EmailMessage:
def __init__(
self,
subject="", body="", from_email=None, to=None,
*,
bcc=None, connection=None,
attachments=None, headers=None,
cc=None, reply_to=None):
class EmailMultiAlternatives(EmailMessage):
def __init__(
self,
subject="", body="", from_email=None, to=None,
*,
bcc=None, connection=None,
attachments=None, headers=None,
alternatives=None,
cc=None, reply_to=None):
}}}
--
Ticket URL: <
https://code.djangoproject.com/ticket/36163>
Django <
https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.