]> granicus.if.org Git - python/commitdiff
Merged revisions 88622 via svnmerge from
authorAntoine Pitrou <solipsis@pitrou.net>
Fri, 25 Feb 2011 23:14:08 +0000 (23:14 +0000)
committerAntoine Pitrou <solipsis@pitrou.net>
Fri, 25 Feb 2011 23:14:08 +0000 (23:14 +0000)
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.
........

Lib/socket.py
Lib/test/test_socket.py
Misc/NEWS

index 95901aeca1c5342b4d915f04b8df6239137f051b..1e285493c48e289687d9c73e98ab35f92219c34f 100644 (file)
@@ -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:
index 23d22a8695fe57af3cfe991b6037a05aa012fe65..9ba391e7cbc03fe86abe82a5e6562db8a9edd9f3 100644 (file)
@@ -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)
index 65ea12ad5be55c1630813e3ad33a0931867d3a95..5a9f49810e7a60a837619bb17693e3bf9aa3400d 100644 (file)
--- 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.