#36163 closed Cleanup/optimization (fixed)
Change mail APIs to (mostly) keyword-only parameters
Reported by: | Mike Edmunds | Owned by: | Mike Edmunds |
---|---|---|---|
Component: | Core (Mail) | Version: | dev |
Severity: | Normal | Keywords: | |
Cc: | Triage Stage: | Ready for checkin | |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description (last modified by )
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. During a standard deprecation period, the affected parameters would be accepted as either positional or keyword arguments, but using posargs would raise a deprecation warning. After the deprecation period, continuing to use posargs for those params would result in Python's usual TypeError. [Edit: further forum discussion clarified need to follow the deprecation process.]
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 "frozen" send_mail() and send_mass_mail() functions, and the EmailMessage class with its documented parameter ordering.)
Proposed changes
This change would add *,
s where indicated below. All parameters after the *,
would become keyword only.
# 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):
# 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):
Change History (11)
comment:1 by , 7 months ago
Owner: | set to |
---|---|
Status: | new → assigned |
comment:2 by , 7 months ago
Triage Stage: | Unreviewed → Accepted |
---|---|
Version: | 5.1 → dev |
comment:3 by , 7 months ago
Description: | modified (diff) |
---|
Updated description to require a deprecation period based on additional forum feedback (and per the original proposal in the forum).
Opened https://github.com/django/django/pull/19145 with an implementation of an @deprecate_posargs
decorator to simplify the deprecation process.
comment:4 by , 7 months ago
Has patch: | set |
---|
@chaitanyarahalkar are you still working on this?
I'm marking it "has patch" to get a review for the @deprecate_posargs
decorator, but it will still need a separate PR (including deprecation docs) for the original issue.
comment:5 by , 7 months ago
Owner: | changed from | to
---|
comment:7 by , 7 weeks ago
Patch needs improvement: | set |
---|
Setting as patch needs improvement until Mike fixes conflicts and updates PR based on latest merges.
comment:8 by , 7 weeks ago
Patch needs improvement: | unset |
---|
comment:9 by , 7 weeks ago
Triage Stage: | Accepted → Ready for checkin |
---|
+1, I think this is good practice, helps code readability and avoid possible ambiguity when passing positional parameters.