Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Fixed #22327 -- Turned BaseEmailBackend into a context manager

Changed the BaseEmailBackend to allow usage as context manager to open
and close connections.
  • Loading branch information...
commit 4aa80149e71d02947164a89ec5da6fd035393425 1 parent d902fd6
@DasIch DasIch authored timgraham committed
View
14 django/core/mail/backends/base.py
@@ -6,6 +6,13 @@ class BaseEmailBackend(object):
Base class for email backend implementations.
Subclasses must at least overwrite send_messages().
+
+ open() and close() can be called indirectly by using a backend object as a
+ context manager:
+
+ with backend as connection:
+ # do something with connection
+ pass
"""
def __init__(self, fail_silently=False, **kwargs):
self.fail_silently = fail_silently
@@ -32,6 +39,13 @@ def close(self):
"""Close a network connection."""
pass
+ def __enter__(self):
+ self.open()
+ return self
+
+ def __exit__(self, exc_type, exc_value, traceback):
+ self.close()
+
def send_messages(self, email_messages):
"""
Sends one or more EmailMessage objects and returns the number of email
View
3  docs/releases/1.8.txt
@@ -91,7 +91,8 @@ Cache
Email
^^^^^
-* ...
+* :ref:`Email backends <topic-email-backends>` now support the context manager
+ protocol for opening and closing connections.
File Storage
^^^^^^^^^^^^
View
15 docs/topics/email.txt
@@ -393,6 +393,21 @@ The email backend class has the following methods:
connection afterwards. If the connection is already open, it will be
left open after mail has been sent.
+It can also be used as a context manager, which will automatically call
+``open()`` and ``close()`` as needed::
+
+ from django.core import mail
+
+ with mail.get_connection() as connection:
+ mail.EmailMessage(subject1, body1, from1, [to1],
+ connection=connection).send()
+ mail.EmailMessage(subject2, body2, from2, [to2],
+ connection=connection).send()
+
+.. versionadded:: 1.8
+
+ The context manager protocol was added.
+
Obtaining an instance of an email backend
-----------------------------------------
View
21 tests/mail/tests.py
@@ -638,6 +638,27 @@ def test_close_connection(self):
except Exception as e:
self.fail("close() unexpectedly raised an exception: %s" % e)
+ def test_use_as_contextmanager(self):
+ """
+ Test that the connection can be used as a contextmanager.
+ """
+ opened = [False]
+ closed = [False]
+ conn = mail.get_connection(username='', password='')
+
+ def open():
+ opened[0] = True
+ conn.open = open
+
+ def close():
+ closed[0] = True
+ conn.close = close
+ with conn as same_conn:
+ self.assertTrue(opened[0])
+ self.assertIs(same_conn, conn)
+ self.assertFalse(closed[0])
+ self.assertTrue(closed[0])
+
class LocmemBackendTests(BaseEmailBackendTests, SimpleTestCase):
email_backend = 'django.core.mail.backends.locmem.EmailBackend'
Please sign in to comment.
Something went wrong with that request. Please try again.