[pypy-svn] r79164 - in pypy/branch/fast-forward/pypy/module/_io: . test
afa at codespeak.net
afa at codespeak.net
Tue Nov 16 19:49:10 CET 2010
Author: afa
Date: Tue Nov 16 19:49:09 2010
New Revision: 79164
Modified:
pypy/branch/fast-forward/pypy/module/_io/interp_bufferedio.py
pypy/branch/fast-forward/pypy/module/_io/test/test_bufferedio.py
Log:
Test and fix for the BlockingIOError.written attribute
Modified: pypy/branch/fast-forward/pypy/module/_io/interp_bufferedio.py
==============================================================================
--- pypy/branch/fast-forward/pypy/module/_io/interp_bufferedio.py (original)
+++ pypy/branch/fast-forward/pypy/module/_io/interp_bufferedio.py Tue Nov 16 19:49:09 2010
@@ -78,6 +78,9 @@
self.state = STATE_ZERO
self.buffer = lltype.nullptr(rffi.CCHARP.TO)
+
+ self.abs_pos = 0 # Absolute position inside the raw stream (-1 if
+ # unknown).
self.pos = 0 # Current logical position in the buffer
self.raw_pos = 0 # Position of the raw stream in the buffer.
@@ -282,11 +285,13 @@
if not e.match(space, space.gettypeobject(
W_BlockingIOError.typedef)):
raise
- self.write_pos += e.written
+ w_exc = e.get_w_value(space)
+ assert isinstance(w_exc, W_BlockingIOError)
+ self.write_pos += w_exc.written
self.raw_pos = self.write_pos
- written += e.written
+ written += w_exc.written
# re-raise the error
- e.written = written
+ w_exc.written = written
raise
self.write_pos += n
self.raw_pos = self.write_pos
@@ -666,6 +671,8 @@
if not e.match(space, space.gettypeobject(
W_BlockingIOError.typedef)):
raise
+ w_exc = space.get_w_value(space)
+ assert isinstance(w_exc, W_BlockingIOError)
if self.readable:
self._reader_reset_buf()
# Make some place by shifting the buffer
@@ -687,7 +694,7 @@
self.buffer[self.write_end + i] = data[i]
self.write_end += available
# Raise previous exception
- e.written = available
+ w_exc.written = available
raise
# Adjust the raw stream position if it is away from the logical
@@ -709,8 +716,10 @@
if not e.match(space, space.gettypeobject(
W_BlockingIOError.typedef)):
raise
- written += e.written
- remaining -= e.written
+ w_exc = e.get_w_value(space)
+ assert isinstance(w_exc, W_BlockingIOError)
+ written += w_exc.written
+ remaining -= w_exc.written
if remaining > self.buffer_size:
# Can't buffer everything, still buffer as much as
# possible
@@ -719,7 +728,7 @@
self.raw_pos = 0
self._adjust_position(self.buffer_size)
self.write_end = self.buffer_size
- e.written = written + self.buffer_size
+ w_exc.written = written + self.buffer_size
raise
break
written += n
Modified: pypy/branch/fast-forward/pypy/module/_io/test/test_bufferedio.py
==============================================================================
--- pypy/branch/fast-forward/pypy/module/_io/test/test_bufferedio.py (original)
+++ pypy/branch/fast-forward/pypy/module/_io/test/test_bufferedio.py Tue Nov 16 19:49:09 2010
@@ -211,6 +211,69 @@
assert b.truncate() == 8
assert b.tell() == 8
+ def test_write_non_blocking(self):
+ import _io, io
+ class MockNonBlockWriterIO(io.RawIOBase):
+ def __init__(self):
+ self._write_stack = []
+ self._blocker_char = None
+
+ def writable(self):
+ return True
+ closed = False
+
+ def pop_written(self):
+ s = ''.join(self._write_stack)
+ self._write_stack[:] = []
+ return s
+
+ def block_on(self, char):
+ """Block when a given char is encountered."""
+ self._blocker_char = char
+
+ def write(self, b):
+ try:
+ b = b.tobytes()
+ except AttributeError:
+ pass
+ n = -1
+ if self._blocker_char:
+ try:
+ n = b.index(self._blocker_char)
+ except ValueError:
+ pass
+ else:
+ self._blocker_char = None
+ self._write_stack.append(b[:n])
+ raise _io.BlockingIOError(0, "test blocking", n)
+ self._write_stack.append(b)
+ return len(b)
+
+ raw = MockNonBlockWriterIO()
+ bufio = _io.BufferedWriter(raw, 8)
+
+ assert bufio.write("abcd") == 4
+ assert bufio.write("efghi") == 5
+ # 1 byte will be written, the rest will be buffered
+ raw.block_on(b"k")
+ assert bufio.write("jklmn") == 5
+
+ # 8 bytes will be written, 8 will be buffered and the rest will be lost
+ raw.block_on(b"0")
+ try:
+ bufio.write(b"opqrwxyz0123456789")
+ except _io.BlockingIOError as e:
+ written = e.characters_written
+ else:
+ self.fail("BlockingIOError should have been raised")
+ assert written == 16
+ assert raw.pop_written() == "abcdefghijklmnopqrwxyz"
+
+ assert bufio.write("ABCDEFGHI") == 9
+ s = raw.pop_written()
+ # Previously buffered bytes were flushed
+ assert s.startswith("01234567A")
+
class AppTestBufferedRWPair:
def test_pair(self):
import _io
More information about the Pypy-commit
mailing list