[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