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.
........
diff --git a/Lib/test/test_io.py b/Lib/test/test_io.py
index 3a3e074..4c7ce31 100644
--- a/Lib/test/test_io.py
+++ b/Lib/test/test_io.py
@@ -47,7 +47,9 @@
         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 @@
         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 @@
     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 @@
         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 @@
     # 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}