summaryrefslogtreecommitdiffstats
path: root/Lib/test/test_io.py
diff options
context:
space:
mode:
authorSanyam Khurana <8039608+CuriousLearner@users.noreply.github.com>2017-12-11 13:42:09 (GMT)
committerVictor Stinner <victor.stinner@gmail.com>2017-12-11 13:42:09 (GMT)
commit1b74f9b77a6fa1d7828986cb79d5b10942ff9141 (patch)
tree8c1f1d7b3e5b2a0a128868fa7e78c4b688c02ea9 /Lib/test/test_io.py
parent48d4dd974f0c8d47c54990eedd322b96b19c60ec (diff)
downloadcpython-1b74f9b77a6fa1d7828986cb79d5b10942ff9141.zip
cpython-1b74f9b77a6fa1d7828986cb79d5b10942ff9141.tar.gz
cpython-1b74f9b77a6fa1d7828986cb79d5b10942ff9141.tar.bz2
bpo-22671: Clarify and test default read method implementations (#4568)
Original patch written by Martin Panter, enhanced by Sanyam Khurana.
Diffstat (limited to 'Lib/test/test_io.py')
-rw-r--r--Lib/test/test_io.py53
1 files changed, 51 insertions, 2 deletions
diff --git a/Lib/test/test_io.py b/Lib/test/test_io.py
index 2ac2e17..6bb4127 100644
--- a/Lib/test/test_io.py
+++ b/Lib/test/test_io.py
@@ -807,8 +807,8 @@ class IOTest(unittest.TestCase):
self.assertRaises(ValueError, f.flush)
def test_RawIOBase_read(self):
- # Exercise the default RawIOBase.read() implementation (which calls
- # readinto() internally).
+ # Exercise the default limited RawIOBase.read(n) 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")
@@ -916,6 +916,55 @@ class IOTest(unittest.TestCase):
with self.assertRaisesRegex(ValueError, 'read/write/append mode'):
self.open(PathLike(support.TESTFN), 'rwxa')
+ def test_RawIOBase_readall(self):
+ # Exercise the default unlimited RawIOBase.read() and readall()
+ # implementations.
+ rawio = self.MockRawIOWithoutRead((b"abc", b"d", b"efg"))
+ self.assertEqual(rawio.read(), b"abcdefg")
+ rawio = self.MockRawIOWithoutRead((b"abc", b"d", b"efg"))
+ self.assertEqual(rawio.readall(), b"abcdefg")
+
+ def test_BufferedIOBase_readinto(self):
+ # Exercise the default BufferedIOBase.readinto() and readinto1()
+ # implementations (which call read() or read1() internally).
+ class Reader(self.BufferedIOBase):
+ def __init__(self, avail):
+ self.avail = avail
+ def read(self, size):
+ result = self.avail[:size]
+ self.avail = self.avail[size:]
+ return result
+ def read1(self, size):
+ """Returns no more than 5 bytes at once"""
+ return self.read(min(size, 5))
+ tests = (
+ # (test method, total data available, read buffer size, expected
+ # read size)
+ ("readinto", 10, 5, 5),
+ ("readinto", 10, 6, 6), # More than read1() can return
+ ("readinto", 5, 6, 5), # Buffer larger than total available
+ ("readinto", 6, 7, 6),
+ ("readinto", 10, 0, 0), # Empty buffer
+ ("readinto1", 10, 5, 5), # Result limited to single read1() call
+ ("readinto1", 10, 6, 5), # Buffer larger than read1() can return
+ ("readinto1", 5, 6, 5), # Buffer larger than total available
+ ("readinto1", 6, 7, 5),
+ ("readinto1", 10, 0, 0), # Empty buffer
+ )
+ UNUSED_BYTE = 0x81
+ for test in tests:
+ with self.subTest(test):
+ method, avail, request, result = test
+ reader = Reader(bytes(range(avail)))
+ buffer = bytearray((UNUSED_BYTE,) * request)
+ method = getattr(reader, method)
+ self.assertEqual(method(buffer), result)
+ self.assertEqual(len(buffer), request)
+ self.assertSequenceEqual(buffer[:result], range(result))
+ unused = (UNUSED_BYTE,) * (request - result)
+ self.assertSequenceEqual(buffer[result:], unused)
+ self.assertEqual(len(reader.avail), avail - result)
+
class CIOTest(IOTest):