From: Antoine Pitrou Date: Fri, 25 Feb 2011 23:14:08 +0000 (+0000) Subject: Merged revisions 88622 via svnmerge from X-Git-Tag: v3.2.1b1~370 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=5d5381ed002a03486b7364f9ae8b69fa2d2a1ede;p=python Merged revisions 88622 via svnmerge from svn+ssh://pythondev@svn.python.org/python/branches/py3k ........ r88622 | antoine.pitrou | 2011-02-26 00:07:44 +0100 (sam., 26 févr. 2011) | 5 lines Issue #7322: Trying to read from a socket's file-like object after a timeout occurred now raises an error instead of silently losing data. Patch by Ross Lagerwall. ........ --- diff --git a/Lib/socket.py b/Lib/socket.py index 95901aeca1..1e285493c4 100644 --- a/Lib/socket.py +++ b/Lib/socket.py @@ -257,6 +257,7 @@ class SocketIO(io.RawIOBase): self._mode = mode self._reading = "r" in mode self._writing = "w" in mode + self._timeout_occurred = False def readinto(self, b): """Read up to len(b) bytes into the writable buffer *b* and return @@ -268,9 +269,14 @@ class SocketIO(io.RawIOBase): """ self._checkClosed() self._checkReadable() + if self._timeout_occurred: + raise IOError("cannot read from timed out object") while True: try: return self._sock.recv_into(b) + except timeout: + self._timeout_occurred = True + raise except error as e: n = e.args[0] if n == EINTR: diff --git a/Lib/test/test_socket.py b/Lib/test/test_socket.py index 23d22a8695..9ba391e7cb 100644 --- a/Lib/test/test_socket.py +++ b/Lib/test/test_socket.py @@ -1109,6 +1109,23 @@ class FileObjectClassTestCase(SocketConnectedTest): self.write_file = None SocketConnectedTest.clientTearDown(self) + def testReadAfterTimeout(self): + # Issue #7322: A file object must disallow further reads + # after a timeout has occurred. + self.cli_conn.settimeout(1) + self.read_file.read(3) + # First read raises a timeout + self.assertRaises(socket.timeout, self.read_file.read, 1) + # Second read is disallowed + with self.assertRaises(IOError) as ctx: + self.read_file.read(1) + self.assertIn("cannot read from timed out object", str(ctx.exception)) + + def _testReadAfterTimeout(self): + self.write_file.write(self.write_msg[0:3]) + self.write_file.flush() + self.serv_finished.wait() + def testSmallRead(self): # Performing small file read test first_seg = self.read_file.read(len(self.read_msg)-3) diff --git a/Misc/NEWS b/Misc/NEWS index 65ea12ad5b..5a9f49810e 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -24,6 +24,9 @@ Core and Builtins Library ------- +- Issue #7322: Trying to read from a socket's file-like object after a timeout + occurred now raises an error instead of silently losing data. + - Issue #10956: Buffered I/O classes retry reading or writing after a signal has arrived and the handler returned successfully.