Index: Lib/io.py =================================================================== --- Lib/io.py (revision 67105) +++ Lib/io.py (working copy) @@ -1062,8 +1062,9 @@ # We've hit max_buffer_size. We have to accept a # partial write and cut back our buffer. overage = len(self._write_buf) - self.max_buffer_size + written -= overage self._write_buf = self._write_buf[:self.max_buffer_size] - raise BlockingIOError(e.errno, e.strerror, overage) + raise BlockingIOError(e.errno, e.strerror, written) return written def truncate(self, pos=None): Index: Lib/test/test_io.py =================================================================== --- Lib/test/test_io.py (revision 67105) +++ Lib/test/test_io.py (working copy) @@ -476,6 +476,56 @@ # algorithm actually works, which we might change. Refactor # later. + def testWriteNonBlockingOverage(self): + raw = MockNonBlockWriterIO((-1,)) + bufio = io.BufferedWriter(raw, 8, 16) + + data = b"a" * 20 + write_buf = bytearray(b"a" * 16) + try: + bufio.write(data) + except io.BlockingIOError as e: + # 1 written, 16 in buffer + self.assertEqual(bufio._write_buf, write_buf) + self.assertEqual(e.characters_written, 17) + + def testWriteNonBlockingOverageSmallWrite(self): + raw = MockNonBlockWriterIO((-1,)) + bufio = io.BufferedWriter(raw, 8, 16) + + data_1 = b"a" * 5 + # data_1 goes straight to buffer, no raw.write() call + bufio.write(data_1) + self.assertEqual(bufio._write_buf, data_1) + + data_2 = b"b" * 20 + write_buf = bytearray(b"a" * 4) + write_buf.extend(b"b" * 12) + try: + bufio.write(data_2) + except io.BlockingIOError as e: + self.assertEqual(bufio._write_buf, write_buf) + # 1 written (1 old), 4 old and 12 new in buffer + self.assertEqual(e.characters_written, 12) + + def testWriteNonBlockingOverageBigWrite(self): + raw = MockNonBlockWriterIO((-11,)) + bufio = io.BufferedWriter(raw, 8, 16) + + data_1 = b"a" * 5 + # data_1 goes straight to buffer, no raw.write() call + bufio.write(data_1) + self.assertEqual(bufio._write_buf, data_1) + + data_2 = b"b" * 30 + write_buf = bytearray(b"b" * 16) + try: + bufio.write(data_2) + except io.BlockingIOError as e: + self.assertEqual(bufio._write_buf, write_buf) + # 11 written (5 old, 6 new), 16 new in buffer + self.assertEqual(e.characters_written, 22) + def testFileno(self): rawio = MockRawIO((b"abc", b"d", b"efg")) bufio = io.BufferedWriter(rawio)