mirror of
https://github.com/python/cpython.git
synced 2025-08-30 21:48:47 +00:00
Issue #9854: The default read() implementation in io.RawIOBase now
handles non-blocking readinto() returning None correctly.
This commit is contained in:
parent
9e0b864ac0
commit
328ec7455f
5 changed files with 45 additions and 15 deletions
|
@ -48,7 +48,9 @@ def _default_chunk_size():
|
|||
return f._CHUNK_SIZE
|
||||
|
||||
|
||||
class MockRawIO:
|
||||
class MockRawIOWithoutRead:
|
||||
"""A RawIO implementation without read(), so as to exercise the default
|
||||
RawIO.read() which calls readinto()."""
|
||||
|
||||
def __init__(self, read_stack=()):
|
||||
self._read_stack = list(read_stack)
|
||||
|
@ -56,14 +58,6 @@ class MockRawIO:
|
|||
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):
|
||||
self._write_stack.append(bytes(b))
|
||||
return len(b)
|
||||
|
@ -110,6 +104,23 @@ class MockRawIO:
|
|||
def truncate(self, pos=None):
|
||||
return pos
|
||||
|
||||
class CMockRawIOWithoutRead(MockRawIOWithoutRead, io.RawIOBase):
|
||||
pass
|
||||
|
||||
class PyMockRawIOWithoutRead(MockRawIOWithoutRead, pyio.RawIOBase):
|
||||
pass
|
||||
|
||||
|
||||
class MockRawIO(MockRawIOWithoutRead):
|
||||
|
||||
def read(self, n=None):
|
||||
self._reads += 1
|
||||
try:
|
||||
return self._read_stack.pop(0)
|
||||
except:
|
||||
self._extraneous_reads += 1
|
||||
return b""
|
||||
|
||||
class CMockRawIO(MockRawIO, io.RawIOBase):
|
||||
pass
|
||||
|
||||
|
@ -582,6 +593,19 @@ class IOTest(unittest.TestCase):
|
|||
f.close()
|
||||
self.assertRaises(ValueError, f.flush)
|
||||
|
||||
def test_RawIOBase_read(self):
|
||||
# Exercise the default RawIOBase.read() implementation (which calls
|
||||
# readinto() internally).
|
||||
rawio = self.MockRawIOWithoutRead((b"abc", b"d", None, b"efg", None))
|
||||
self.assertEqual(rawio.read(2), b"ab")
|
||||
self.assertEqual(rawio.read(2), b"c")
|
||||
self.assertEqual(rawio.read(2), b"d")
|
||||
self.assertEqual(rawio.read(2), None)
|
||||
self.assertEqual(rawio.read(2), b"ef")
|
||||
self.assertEqual(rawio.read(2), b"g")
|
||||
self.assertEqual(rawio.read(2), None)
|
||||
self.assertEqual(rawio.read(2), b"")
|
||||
|
||||
class CIOTest(IOTest):
|
||||
pass
|
||||
|
||||
|
@ -2590,7 +2614,7 @@ def test_main():
|
|||
# Put the namespaces of the IO module we are testing and some useful mock
|
||||
# classes in the __dict__ of each test.
|
||||
mocks = (MockRawIO, MisbehavedRawIO, MockFileIO, CloseFailureIO,
|
||||
MockNonBlockWriterIO, MockUnseekableIO)
|
||||
MockNonBlockWriterIO, MockUnseekableIO, MockRawIOWithoutRead)
|
||||
all_members = io.__all__ + ["IncrementalNewlineDecoder"]
|
||||
c_io_ns = {name : getattr(io, name) for name in all_members}
|
||||
py_io_ns = {name : getattr(pyio, name) for name in all_members}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue