Index: Lib/poplib.py =================================================================== --- Lib/poplib.py (revisione 81547) +++ Lib/poplib.py (copia locale) @@ -331,16 +331,26 @@ 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, + context=None, timeout=socket._GLOBAL_DEFAULT_TIMEOUT): + 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") Index: Lib/test/test_poplib.py =================================================================== --- Lib/test/test_poplib.py (revisione 81547) +++ Lib/test/test_poplib.py (copia locale) @@ -122,6 +122,7 @@ 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 @@ 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,7 +287,24 @@ 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): def setUp(self): Index: Doc/library/poplib.rst =================================================================== --- Doc/library/poplib.rst (revisione 81547) +++ Doc/library/poplib.rst (copia locale) @@ -32,15 +32,21 @@ 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, context=None[, timeout]) 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. + *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. *timeout* works as in the :class:`POP3` constructor. + .. versionchanged:: 3.2 + *context* parameter added. + One exception is defined as an attribute of the :mod:`poplib` module: