Hey Tim,
Thanks for following up here.
Thanks also for the link to the previous discussion, very interesting.
So, looking at that, this was first discussed 7 years ago, when there were (just)
6 email related settings.
I liked Jannis' initial reaction at the time: "Oh god, YES!!"
It didn't get accepted in the end for arguments along the lines of
"Just for purity" and "No cost to adding an additional setting".
All this time later though, I would argue that those judgements, whilst
reasonable at the time, underplayed the costs.
We currently have 11 `EMAIL_` settings in `global_settings.py`[0].
The suggested PR here[1] would add three more. And there's another PR[1] open
suggesting adding yet another.
That would make 15 `EMAIL_` prefixed settings.
I would suggest that's too much. That it's time we changed tack.
The issue for me is that we're failing to insulate our users from a whole
swathe of unnecessary complexity that they shouldn't have to deal with.
As it is every reader of `settings.txt` has to go through each of these
`EMAIL_` settings, parse them, and answer the questions _Does this apply to me?
And how?_. Instead of encapsulating the details of the SMTP, and now SSLContext
modules, we've added a set of pass-through parameters which force users to
address them.
Particularly for the proposed SSLContext parameters, most user will never need
them — they'll just want the default `None` to use the default system CA certs.
So, we're adding to the cognitive load of all users, to address a use case
affecting only a small subgroup.
I don't see/accept/agree with the "boilerplate" point. I need to create a subclass yes:
```
from django.core.mail.backends.smtp import EmailBackend as SMTPBackend
class EmailBackend(SMTPBackend):
def __init__(self, *args, **kwargs):
# Set Environment kwargs here.
```
So it's an import and two lines for the class and init definitions.
The trade-off for that is insulating the plurality of users for whom these
advanced configuration options just simply aren't relevant.
The pay-off is that, by moving some of the more esoteric options out of
settings, we make Django's settings easier to navigate and comprehend for every
body.
It's like a form or the Sorites Paradox[3]: it turns out that in project with the
lifespan of Django, the seemingly harmless, "There's little cost to adding one
more setting" fails the induction rule.
FWIW: I think this same issue applies to the HTTP security headers thread,
which we're still thinking about. We should encapsulate these with sane
defaults, in a module that users can go and investigate, customise and apply,
with a single setting, rather than added an every longer list, which forces
every user to face decisions that we should have made for them, for ourselves.
So that's my concern.
To address yours, I certainly don't think configuration details should be
"scattered".
I'd recommend a `project.conf.email` module (or package if needs be) containing
all the email related details. Keeping it all together makes it easier to
maintain. (It's locality of behaviour: Where's email stuff? It's all in there.)
I'd then have a `EmailBackend` subclass per environment and set it with the
`EMAIL_BACKEND` setting. (Folks can use environment variables and all the rest
of it as they see fit here, much as they do now.)
I think most users are using SMTP, and they **all** need to set
host/username/password, so those settings should likely remain.
The email section in `settings.txt` then says (roughly):
* Use `EMAIL_BACKEND`.
* The following few convenience settings for `SMTP` are available.
* See email docs for more advanced use-cases.
I think that would be a simplification for everyone, including those with the
more advanced use-cases. (If you were subclassing EmailBackend, I would expect
you to put all conf details in the subclass, rather than using the convenience
settings for some…)
Finally, just on the format here — I suggest a subclass because I think it's
simple. Discussion on the old ticket you linked and on the thread about HTTP
headers goes back and forth a bit about dicts, and tuples, and classes with
clever fallback behaviour, and so on. (It then get's stuck on those points.)
I don't think we need to be committed on those points. A subclass is easy. It's
a couple of lines of "boilerplate" but unlike strings you get editor
autocomplete and validation. If someone comes up with a clever subclass that
handles a dict, or env vars or…, then folks can adopt that.
I don't think the general principle, that we should insulate users (ourselves)
from having to deal with the advanced use-cases every time should depend on
needing to find a perfect serialisation format.
I hope all that makes sense. I appreciate that the simplest thing to do at any
given moment is to continue just adding settings. Looking another 7 years out,
I can't help but think that doing so fails on appropriate complexity
management.
As I said on the PR, I was at the point of saying, yes OK, let's just add the
settings. Then reviewing the PR again I had the same conclusion, conferred with
Mariusz, commentted as I did, and now we're here.
It's a style thing right? We can live with it either way, but what should we do
for the best?
Thanks!
Kind Regards,
Carlton