summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Doc/library/poplib.rst10
-rw-r--r--Doc/whatsnew/3.2.rst7
-rw-r--r--Lib/poplib.py18
-rw-r--r--Lib/test/test_poplib.py21
-rw-r--r--Misc/NEWS5
5 files changed, 53 insertions, 8 deletions
diff --git a/Doc/library/poplib.rst b/Doc/library/poplib.rst
index b397b4b..b60ad0e 100644
--- a/Doc/library/poplib.rst
+++ b/Doc/library/poplib.rst
@@ -32,13 +32,19 @@ A single class is provided by the :mod:`poplib` module:
be used).
-.. class:: POP3_SSL(host, port=POP3_SSL_PORT, keyfile=None, certfile=None[, timeout])
+.. class:: POP3_SSL(host, port=POP3_SSL_PORT, keyfile=None, certfile=None, timeout=None, context=None)
This is a subclass of :class:`POP3` that connects to the server over an SSL
encrypted socket. If *port* is not specified, 995, the standard POP3-over-SSL
port is used. *keyfile* and *certfile* are also optional - they can contain a
PEM formatted private key and certificate chain file for the SSL connection.
- *timeout* works as in the :class:`POP3` constructor.
+ *timeout* works as in the :class:`POP3` constructor. *context* parameter is a
+ :class:`ssl.SSLContext` object which allows bundling SSL configuration
+ options, certificates and private keys into a single (potentially long-lived)
+ structure.
+
+ .. versionchanged:: 3.2
+ *context* parameter added.
One exception is defined as an attribute of the :mod:`poplib` module:
diff --git a/Doc/whatsnew/3.2.rst b/Doc/whatsnew/3.2.rst
index d03a67f..a2b7af4 100644
--- a/Doc/whatsnew/3.2.rst
+++ b/Doc/whatsnew/3.2.rst
@@ -186,6 +186,13 @@ New, Improved, and Deprecated Modules
(Contributed by Giampaolo RodolĂ ; :issue:`8866`.)
+* :class:`~poplib.POP3_SSL` class now accepts a *context* parameter, which is a
+ :class:`ssl.SSLContext` object allowing bundling SSL configuration options,
+ certificates and private keys into a single (potentially long-lived)
+ structure.
+
+ (Contributed by Giampaolo RodolĂ ; :issue:`8807`.)
+
Multi-threading
===============
diff --git a/Lib/poplib.py b/Lib/poplib.py
index 1a529d0..84ea88d 100644
--- a/Lib/poplib.py
+++ b/Lib/poplib.py
@@ -331,16 +331,26 @@ else:
See the methods of the parent class POP3 for more documentation.
"""
- def __init__(self, host, port=POP3_SSL_PORT,
- keyfile=None, certfile=None,
- timeout=socket._GLOBAL_DEFAULT_TIMEOUT):
+ def __init__(self, host, port=POP3_SSL_PORT, keyfile=None, certfile=None,
+ timeout=socket._GLOBAL_DEFAULT_TIMEOUT, context=None):
+ if context is not None and keyfile is not None:
+ raise ValueError("context and keyfile arguments are mutually "
+ "exclusive")
+ if context is not None and certfile is not None:
+ raise ValueError("context and certfile arguments are mutually "
+ "exclusive")
self.keyfile = keyfile
self.certfile = certfile
+ self.context = context
POP3.__init__(self, host, port, timeout)
def _create_socket(self, timeout):
sock = POP3._create_socket(self, timeout)
- return ssl.wrap_socket(sock, self.keyfile, self.certfile)
+ if self.context is not None:
+ sock = self.context.wrap_socket(sock)
+ else:
+ sock = ssl.wrap_socket(sock, self.keyfile, self.certfile)
+ return sock
__all__.append("POP3_SSL")
diff --git a/Lib/test/test_poplib.py b/Lib/test/test_poplib.py
index c831fb4..2adc849 100644
--- a/Lib/test/test_poplib.py
+++ b/Lib/test/test_poplib.py
@@ -122,6 +122,7 @@ class DummyPOP3Server(asyncore.dispatcher, threading.Thread):
self.active = False
self.active_lock = threading.Lock()
self.host, self.port = self.socket.getsockname()[:2]
+ self.handler_instance = None
def start(self):
assert not self.active
@@ -145,8 +146,7 @@ class DummyPOP3Server(asyncore.dispatcher, threading.Thread):
def handle_accept(self):
conn, addr = self.accept()
- self.handler = self.handler(conn)
- self.close()
+ self.handler_instance = self.handler(conn)
def handle_connect(self):
self.close()
@@ -287,6 +287,23 @@ if hasattr(poplib, 'POP3_SSL'):
def test__all__(self):
self.assertIn('POP3_SSL', poplib.__all__)
+ def test_context(self):
+ ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
+ self.assertRaises(ValueError, poplib.POP3_SSL, self.server.host,
+ self.server.port, keyfile=CERTFILE, context=ctx)
+ self.assertRaises(ValueError, poplib.POP3_SSL, self.server.host,
+ self.server.port, certfile=CERTFILE, context=ctx)
+ self.assertRaises(ValueError, poplib.POP3_SSL, self.server.host,
+ self.server.port, keyfile=CERTFILE,
+ certfile=CERTFILE, context=ctx)
+
+ self.client.quit()
+ self.client = poplib.POP3_SSL(self.server.host, self.server.port,
+ context=ctx)
+ self.assertIsInstance(self.client.sock, ssl.SSLSocket)
+ self.assertIs(self.client.sock.context, ctx)
+ self.assertTrue(self.client.noop().startswith(b'+OK'))
+
class TestTimeouts(TestCase):
diff --git a/Misc/NEWS b/Misc/NEWS
index 8e68e71..95a9d58 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -93,6 +93,11 @@ Extensions
Library
-------
+- Issue #8807: poplib.POP3_SSL class now accepts a context parameter, which is a
+ ssl.SSLContext object allowing bundling SSL configuration options,
+ certificates and private keys into a single (potentially long-lived)
+ structure.
+
- Issue #8866: parameters passed to socket.getaddrinfo can now be specified as
single keyword arguments.