From c39b52f1527868c7ada9385669c38edf98858921 Mon Sep 17 00:00:00 2001 From: Dong-hee Na Date: Fri, 10 Jan 2020 23:34:05 +0900 Subject: bpo-39259: poplib now rejects timeout = 0 (GH-17912) poplib.POP3 and poplib.POP3_SSL now raise a ValueError if the given timeout for their constructor is zero to prevent the creation of a non-blocking socket. --- Doc/library/poplib.rst | 8 +++++++- Doc/whatsnew/3.9.rst | 7 +++++++ Lib/poplib.py | 2 ++ Lib/test/test_poplib.py | 12 +++++++----- .../next/Library/2020-01-09-10-58-58.bpo-39259.RmDgCC.rst | 3 +++ 5 files changed, 26 insertions(+), 6 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2020-01-09-10-58-58.bpo-39259.RmDgCC.rst diff --git a/Doc/library/poplib.rst b/Doc/library/poplib.rst index 28b42fa..2f349b3 100644 --- a/Doc/library/poplib.rst +++ b/Doc/library/poplib.rst @@ -47,6 +47,9 @@ The :mod:`poplib` module provides two classes: ``poplib.putline`` with arguments ``self`` and ``line``, where ``line`` is the bytes about to be sent to the remote host. + .. versionchanged:: 3.9 + If the *timeout* parameter is set to be zero, it will raise a + :class:`ValueError` to prevent the creation of a non-blocking socket. .. class:: POP3_SSL(host, port=POP3_SSL_PORT, keyfile=None, certfile=None, timeout=None, context=None) @@ -85,6 +88,10 @@ The :mod:`poplib` module provides two classes: :func:`ssl.create_default_context` select the system's trusted CA certificates for you. + .. versionchanged:: 3.9 + If the *timeout* parameter is set to be zero, it will raise a + :class:`ValueError` to prevent the creation of a non-blocking socket. + One exception is defined as an attribute of the :mod:`poplib` module: @@ -268,4 +275,3 @@ retrieves and prints all messages:: At the end of the module, there is a test section that contains a more extensive example of usage. - diff --git a/Doc/whatsnew/3.9.rst b/Doc/whatsnew/3.9.rst index ea6d8f5..3320b7c 100644 --- a/Doc/whatsnew/3.9.rst +++ b/Doc/whatsnew/3.9.rst @@ -187,6 +187,13 @@ Exposed the Linux-specific :func:`os.pidfd_open` (:issue:`38692`) and :data:`os.P_PIDFD` (:issue:`38713`) for process management with file descriptors. +poplib +------ + +:class:`~poplib.POP3` and :class:`~poplib.POP3_SSL` now raise a :class:`ValueError` +if the given timeout for their constructor is zero to prevent the creation of +a non-blocking socket. (Contributed by Dong-hee Na in :issue:`39259`.) + threading --------- diff --git a/Lib/poplib.py b/Lib/poplib.py index 0b6750d..0f85873 100644 --- a/Lib/poplib.py +++ b/Lib/poplib.py @@ -107,6 +107,8 @@ class POP3: self.welcome = self._getresp() def _create_socket(self, timeout): + if timeout is not None and not timeout: + raise ValueError('Non-blocking socket (timeout=0) is not supported') return socket.create_connection((self.host, self.port), timeout) def _putline(self, line): diff --git a/Lib/test/test_poplib.py b/Lib/test/test_poplib.py index 911cba1..7f06d19 100644 --- a/Lib/test/test_poplib.py +++ b/Lib/test/test_poplib.py @@ -481,7 +481,7 @@ class TestTimeouts(TestCase): self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.sock.settimeout(60) # Safety net. Look issue 11812 self.port = test_support.bind_port(self.sock) - self.thread = threading.Thread(target=self.server, args=(self.evt,self.sock)) + self.thread = threading.Thread(target=self.server, args=(self.evt, self.sock)) self.thread.daemon = True self.thread.start() self.evt.wait() @@ -505,12 +505,12 @@ class TestTimeouts(TestCase): def testTimeoutDefault(self): self.assertIsNone(socket.getdefaulttimeout()) - socket.setdefaulttimeout(30) + socket.setdefaulttimeout(test_support.LOOPBACK_TIMEOUT) try: pop = poplib.POP3(HOST, self.port) finally: socket.setdefaulttimeout(None) - self.assertEqual(pop.sock.gettimeout(), 30) + self.assertEqual(pop.sock.gettimeout(), test_support.LOOPBACK_TIMEOUT) pop.close() def testTimeoutNone(self): @@ -524,9 +524,11 @@ class TestTimeouts(TestCase): pop.close() def testTimeoutValue(self): - pop = poplib.POP3(HOST, self.port, timeout=30) - self.assertEqual(pop.sock.gettimeout(), 30) + pop = poplib.POP3(HOST, self.port, timeout=test_support.LOOPBACK_TIMEOUT) + self.assertEqual(pop.sock.gettimeout(), test_support.LOOPBACK_TIMEOUT) pop.close() + with self.assertRaises(ValueError): + poplib.POP3(HOST, self.port, timeout=0) def test_main(): diff --git a/Misc/NEWS.d/next/Library/2020-01-09-10-58-58.bpo-39259.RmDgCC.rst b/Misc/NEWS.d/next/Library/2020-01-09-10-58-58.bpo-39259.RmDgCC.rst new file mode 100644 index 0000000..c7ef8be --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-01-09-10-58-58.bpo-39259.RmDgCC.rst @@ -0,0 +1,3 @@ +:class:`~poplib.POP3` and :class:`~poplib.POP3_SSL` now raise a +:class:`ValueError` if the given timeout for their constructor is zero to +prevent the creation of a non-blocking socket. Patch by Dong-hee Na. -- cgit v0.12