diff options
author | Antoine Pitrou <solipsis@pitrou.net> | 2010-08-11 13:38:10 (GMT) |
---|---|---|
committer | Antoine Pitrou <solipsis@pitrou.net> | 2010-08-11 13:38:10 (GMT) |
commit | 00091cada63a756937a39d5e6967666301154b57 (patch) | |
tree | a184d24e4ed961701500dccb1560c753788af353 /Lib | |
parent | 91ecc5667fa4c336087e1c3cd16aeedd916dde81 (diff) | |
download | cpython-00091cada63a756937a39d5e6967666301154b57.zip cpython-00091cada63a756937a39d5e6967666301154b57.tar.gz cpython-00091cada63a756937a39d5e6967666301154b57.tar.bz2 |
Merged revisions 83944 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/branches/py3k
........
r83944 | antoine.pitrou | 2010-08-11 15:31:33 +0200 (mer., 11 août 2010) | 6 lines
Issue #9550: a BufferedReader could issue an additional read when the
original read request had been satisfied, which can block indefinitely
when the underlying raw IO channel is e.g. a socket. Report and original
patch by Jason V. Miller.
........
Diffstat (limited to 'Lib')
-rw-r--r-- | Lib/test/test_io.py | 24 |
1 files changed, 24 insertions, 0 deletions
diff --git a/Lib/test/test_io.py b/Lib/test/test_io.py index f6175c8..8241bbe 100644 --- a/Lib/test/test_io.py +++ b/Lib/test/test_io.py @@ -51,12 +51,14 @@ class MockRawIO: self._read_stack = list(read_stack) self._write_stack = [] self._reads = 0 + self._extraneous_reads = 0 def read(self, n=None): self._reads += 1 try: return self._read_stack.pop(0) except: + self._extraneous_reads += 1 return b"" def write(self, b): @@ -87,6 +89,7 @@ class MockRawIO: try: data = self._read_stack[0] except IndexError: + self._extraneous_reads += 1 return 0 if data is None: del self._read_stack[0] @@ -822,6 +825,27 @@ class BufferedReaderTest(unittest.TestCase, CommonBufferedTests): self.assertRaises(IOError, bufio.seek, 0) self.assertRaises(IOError, bufio.tell) + def test_no_extraneous_read(self): + # Issue #9550; when the raw IO object has satisfied the read request, + # we should not issue any additional reads, otherwise it may block + # (e.g. socket). + bufsize = 16 + for n in (2, bufsize - 1, bufsize, bufsize + 1, bufsize * 2): + rawio = self.MockRawIO([b"x" * n]) + bufio = self.tp(rawio, bufsize) + self.assertEqual(bufio.read(n), b"x" * n) + # Simple case: one raw read is enough to satisfy the request. + self.assertEqual(rawio._extraneous_reads, 0, + "failed for {}: {} != 0".format(n, rawio._extraneous_reads)) + # A more complex case where two raw reads are needed to satisfy + # the request. + rawio = self.MockRawIO([b"x" * (n - 1), b"x"]) + bufio = self.tp(rawio, bufsize) + self.assertEqual(bufio.read(n), b"x" * n) + self.assertEqual(rawio._extraneous_reads, 0, + "failed for {}: {} != 0".format(n, rawio._extraneous_reads)) + + class CBufferedReaderTest(BufferedReaderTest): tp = io.BufferedReader |