Merged revisions 84814 via svnmerge from

svn+ssh://pythondev@svn.python.org/python/branches/py3k

........
  r84814 | antoine.pitrou | 2010-09-14 20:37:24 +0200 (mar., 14 sept. 2010) | 4 lines

  Issue #9854: The default read() implementation in io.RawIOBase now
  handles non-blocking readinto() returning None correctly.
........
This commit is contained in:
Antoine Pitrou 2010-09-14 18:53:07 +00:00
parent 0e428f2c3a
commit e5e75c64f2
5 changed files with 45 additions and 15 deletions

View File

@ -361,8 +361,9 @@ I/O Base Classes
.. method:: readinto(b)
Read up to len(b) bytes into bytearray *b* and return the number of bytes
read.
Read up to len(b) bytes into bytearray *b* and return the number ofbytes
read. If the object is in non-blocking mode and no bytes are available,
``None`` is returned.
.. method:: write(b)

View File

@ -542,6 +542,8 @@ class RawIOBase(IOBase):
return self.readall()
b = bytearray(n.__index__())
n = self.readinto(b)
if n is None:
return None
del b[n:]
return bytes(b)
@ -559,7 +561,7 @@ class RawIOBase(IOBase):
"""Read up to len(b) bytes into b.
Returns number of bytes read (0 for EOF), or None if the object
is set not to block as has no data to read.
is set not to block and has no data to read.
"""
self._unsupported("readinto")

View File

@ -47,7 +47,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)
@ -55,14 +57,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)
@ -109,6 +103,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
@ -554,6 +565,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
@ -2557,7 +2581,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)
MockNonBlockWriterIO, 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}

View File

@ -117,6 +117,9 @@ C-API
Library
-------
- Issue #9854: The default read() implementation in io.RawIOBase now
handles non-blocking readinto() returning None correctly.
- Issue #9853: Fix the signature of SSLSocket.recvfrom() and
SSLSocket.sendto() to match the corresponding socket methods.

View File

@ -776,9 +776,9 @@ rawiobase_read(PyObject *self, PyObject *args)
return NULL;
res = PyObject_CallMethodObjArgs(self, _PyIO_str_readinto, b, NULL);
if (res == NULL) {
if (res == NULL || res == Py_None) {
Py_DECREF(b);
return NULL;
return res;
}
n = PyNumber_AsSsize_t(res, PyExc_ValueError);