[pypy-svn] r79152 - in pypy/branch/fast-forward/pypy/module/_io: . test

afa at codespeak.net afa at codespeak.net
Tue Nov 16 17:31:28 CET 2010


Author: afa
Date: Tue Nov 16 17:31:26 2010
New Revision: 79152

Modified:
   pypy/branch/fast-forward/pypy/module/_io/interp_bufferedio.py
   pypy/branch/fast-forward/pypy/module/_io/interp_iobase.py
   pypy/branch/fast-forward/pypy/module/_io/test/test_bufferedio.py
Log:
Start implementing _io.BufferedRWPair


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 17:31:26 2010
@@ -1,13 +1,15 @@
 from __future__ import with_statement
 from pypy.interpreter.typedef import (
     TypeDef, GetSetProperty, generic_new_descr)
-from pypy.interpreter.gateway import interp2app, unwrap_spec
+from pypy.interpreter.gateway import interp2app, unwrap_spec, Arguments
 from pypy.interpreter.baseobjspace import ObjSpace, W_Root
 from pypy.interpreter.error import OperationError, operationerrfmt
 from pypy.rpython.lltypesystem import lltype, rffi
 from pypy.rlib.rstring import StringBuilder
 from pypy.rlib.rarithmetic import r_longlong
-from pypy.module._io.interp_iobase import W_IOBase, convert_size
+from pypy.tool.sourcetools import func_renamer
+from pypy.module._io.interp_iobase import (
+    W_IOBase, convert_size, check_readable_w, check_writable_w)
 from pypy.module._io.interp_io import DEFAULT_BUFFER_SIZE, W_BlockingIOError
 from pypy.module.thread.os_lock import Lock
 
@@ -25,6 +27,10 @@
     def _check_init(self, space):
         raise NotImplementedError
 
+    def _deprecated_max_buffer_size(self, space):
+        space.warn("max_buffer_size is deprecated",
+                   space.w_DeprecationWarning)
+
     @unwrap_spec('self', ObjSpace, W_Root)
     def read_w(self, space, w_size=None):
         self._unsupportedoperation(space, "read")
@@ -126,12 +132,8 @@
         self._check_init(space)
         W_IOBase._check_closed(self, space, message)
 
-    def _deprecated_max_buffer_size(self, space):
-        space.warn("max_buffer_size is deprecated",
-                   space.w_DeprecationWarning)
-
     def _raw_tell(self, space):
-        w_pos = space.call_method(self.raw, "tell")
+        w_pos = space.call_method(self.w_raw, "tell")
         pos = space.r_longlong_w(w_pos)
         if pos < 0:
             raise OperationError(space.w_IOError, space.wrap(
@@ -142,7 +144,7 @@
 
     def closed_get_w(space, self):
         self._check_init(space)
-        return space.getattr(self.raw, space.wrap("closed"))
+        return space.getattr(self.w_raw, space.wrap("closed"))
 
     def _readahead(self):
         if self.readable and self.read_end != -1:
@@ -201,7 +203,7 @@
             return space.wrap(n)
 
     def _raw_seek(self, space, pos, whence):
-        w_pos = space.call_method(self.raw, "seek",
+        w_pos = space.call_method(self.w_raw, "seek",
                                   space.wrap(pos), space.wrap(whence))
         pos = space.r_longlong_w(w_pos)
         if pos < 0:
@@ -210,7 +212,7 @@
         return pos
 
     def _closed(self, space):
-        return self.raw._closed(space)
+        return space.is_true(space.getattr(self.w_raw, space.wrap("closed")))
 
     @unwrap_spec('self', ObjSpace)
     def close_w(self, space):
@@ -220,12 +222,12 @@
                 return
         space.call_method(self, "flush")
         with self.lock:
-            space.call_method(self.raw, "close")
+            space.call_method(self.w_raw, "close")
 
     @unwrap_spec('self', ObjSpace)
     def flush_w(self, space):
         self._check_init(space)
-        return space.call_method(self.raw, "flush")
+        return space.call_method(self.w_raw, "flush")
 
     def _writer_flush_unlocked(self, space, restore_pos=False):
         if self.write_end == -1 or self.write_pos == self.write_end:
@@ -268,7 +270,7 @@
 
     def _write(self, space, data):
         w_data = space.wrap(data)
-        w_written = space.call_method(self.raw, "write", w_data)
+        w_written = space.call_method(self.w_raw, "write", w_data)
         written = space.getindex_w(w_written, space.w_IOError)
         if not 0 <= written <= len(data):
             raise OperationError(space.w_IOError, space.wrap(
@@ -288,15 +290,15 @@
     def detach_w(self, space):
         self._check_init(space)
         space.call_method(self, "flush")
-        raw = self.raw
-        self.raw = None
+        w_raw = self.w_raw
+        self.w_raw = None
         self.state = STATE_DETACHED
-        return space.wrap(raw)
+        return w_raw
 
     @unwrap_spec('self', ObjSpace)
     def fileno_w(self, space):
         self._check_init(space)
-        return space.call_method(self.raw, "fileno")
+        return space.call_method(self.w_raw, "fileno")
 
     @unwrap_spec('self', ObjSpace, W_Root)
     def truncate_w(self, space, w_size=None):
@@ -313,16 +315,16 @@
             # invalidate cached position
             self.abs_pos = -1
 
-            return space.call_method(self.raw, "truncate", w_size)
+            return space.call_method(self.w_raw, "truncate", w_size)
 
 class W_BufferedReader(BufferedMixin, W_BufferedIOBase):
     @unwrap_spec('self', ObjSpace, W_Root, int)
     def descr_init(self, space, w_raw, buffer_size=DEFAULT_BUFFER_SIZE):
         self.state = STATE_ZERO
-        raw = space.interp_w(W_IOBase, w_raw)
-        raw.check_readable_w(space)
+        check_readable_w(space, w_raw)
+        space.call_method(w_raw, "_checkReadable")
 
-        self.raw = raw
+        self.w_raw = w_raw
         self.buffer_size = buffer_size
         self.readable = True
 
@@ -403,7 +405,7 @@
 
         while True:
             # Read until EOF or until read() would block
-            w_data = space.call_method(self.raw, "read")
+            w_data = space.call_method(self.w_raw, "read")
             if space.is_w(w_data, space.w_None):
                 break
             data = space.str_w(w_data)
@@ -417,7 +419,7 @@
         return builder.build()
 
     def _raw_read(self, space, n):
-        w_data = space.call_method(self.raw, "read", space.wrap(n))
+        w_data = space.call_method(self.w_raw, "read", space.wrap(n))
         if space.is_w(w_data, space.w_None):
             raise BlockingIOError()
         data = space.str_w(w_data)
@@ -547,10 +549,9 @@
             self._deprecated_max_buffer_size(space)
 
         self.state = STATE_ZERO
-        raw = space.interp_w(W_IOBase, w_raw)
-        raw.check_writable_w(space)
+        space.call_method(w_raw, "_checkWritable")
 
-        self.raw = raw
+        self.w_raw = w_raw
         self.buffer_size = buffer_size
         self.writable = True
 
@@ -700,11 +701,81 @@
     closed = GetSetProperty(W_BufferedWriter.closed_get_w),
     )
 
+def _forward_call(space, w_obj, method, __args__):
+    w_meth = self.getattr(w_obj, self.wrap(method))
+    return self.call_args(w_meth, __args__)
+
+def make_forwarding_method(method, writer=False, reader=False):
+    @func_renamer(method + '_w')
+    @unwrap_spec('self', ObjSpace, Arguments)
+    def method_w(self, space, __args__):
+        if writer:
+            w_meth = space.getattr(self.w_writer, space.wrap(method))
+            return space.call_args(w_meth, __args__)
+        if reader:
+            w_meth = space.getattr(self.w_reader, space.wrap(method))
+            return space.call_args(w_meth, __args__)
+    return method_w
+
 class W_BufferedRWPair(W_BufferedIOBase):
-    pass
+    w_reader = None
+    w_writer = None
+
+    @unwrap_spec('self', ObjSpace, W_Root, W_Root, int, int)
+    def descr_init(self, space, w_reader, w_writer,
+                   buffer_size=DEFAULT_BUFFER_SIZE, max_buffer_size=-234):
+        if max_buffer_size != -234:
+            self._deprecated_max_buffer_size(space)
+
+        try:
+            self.w_reader = W_BufferedReader(space)
+            self.w_reader.descr_init(space, w_reader, buffer_size)
+            self.w_writer = W_BufferedWriter(space)
+            self.w_writer.descr_init(space, w_writer, buffer_size)
+        except Exception:
+            self.w_reader = None
+            self.w_writer = None
+            raise
+
+    def __del__(self):
+        pass # no not close the files
+
+    # forward to reader
+    for method in ['read', 'peek', 'read1', 'readinto', 'readable']:
+        locals()[method + '_w'] = make_forwarding_method(
+            method, reader=True)
+
+    # forward to writer
+    for method in ['write', 'flush', 'writable']:
+        locals()[method + '_w'] = make_forwarding_method(
+            method, writer=True)
+
+    # forward to both
+    for method in ['close']:
+        locals()[method + '_w'] = make_forwarding_method(
+            method, writer=True, reader=True)
+
+    @unwrap_spec('self', ObjSpace)
+    def isatty_w(self, space):
+        if space.is_true(space.call_method(self.w_writer, "isatty")):
+            return space.w_True
+        return space.call_method(self.w_reader, "isatty")
+
+    def closed_get_w(space, self):
+        return space.getattr(self.w_writer, space.wrap("closed"))
+
+methods = dict((method, interp2app(getattr(W_BufferedRWPair, method + '_w')))
+               for method in ['read', 'peek', 'read1', 'readinto', 'readable',
+                              'write', 'flush', 'writable',
+                              'close',
+                              'isatty'])
+
 W_BufferedRWPair.typedef = TypeDef(
     'BufferedRWPair', W_BufferedIOBase.typedef,
     __new__ = generic_new_descr(W_BufferedRWPair),
+    __init__  = interp2app(W_BufferedRWPair.descr_init),
+    closed = GetSetProperty(W_BufferedRWPair.closed_get_w),
+    **methods
     )
 
 class W_BufferedRandom(W_BufferedIOBase):

Modified: pypy/branch/fast-forward/pypy/module/_io/interp_iobase.py
==============================================================================
--- pypy/branch/fast-forward/pypy/module/_io/interp_iobase.py	(original)
+++ pypy/branch/fast-forward/pypy/module/_io/interp_iobase.py	Tue Nov 16 17:31:26 2010
@@ -11,6 +11,30 @@
     else:
         return space.int_w(w_size)
 
+# May be called with any object
+ at unwrap_spec(ObjSpace, W_Root)
+def check_readable_w(space, w_obj):
+    if not space.is_true(space.call_method(w_obj, 'readable')):
+        raise OperationError(
+            space.w_IOError,
+            space.wrap("file or stream is not readable"))
+
+# May be called with any object
+ at unwrap_spec(ObjSpace, W_Root)
+def check_writable_w(space, w_obj):
+    if not space.is_true(space.call_method(w_obj, 'writable')):
+        raise OperationError(
+            space.w_IOError,
+            space.wrap("file or stream is not writable"))
+
+# May be called with any object
+ at unwrap_spec(ObjSpace, W_Root)
+def check_seekable_w(space, w_obj):
+    if not space.is_true(space.call_method(w_obj, 'seekable')):
+        raise OperationError(
+            space.w_IOError,
+            space.wrap("file or stream is not seekable"))
+
 class W_IOBase(Wrappable):
     def __init__(self, space):
         # XXX: IOBase thinks it has to maintain its own internal state in
@@ -114,27 +138,6 @@
     def seekable_w(self, space):
         return space.w_False
 
-    @unwrap_spec('self', ObjSpace)
-    def check_readable_w(self, space):
-        if not space.is_true(space.call_method(self, 'readable')):
-            raise OperationError(
-                space.w_IOError,
-                space.wrap("file or stream is not readable"))
-
-    @unwrap_spec('self', ObjSpace)
-    def check_writable_w(self, space):
-        if not space.is_true(space.call_method(self, 'writable')):
-            raise OperationError(
-                space.w_IOError,
-                space.wrap("file or stream is not writable"))
-
-    @unwrap_spec('self', ObjSpace)
-    def check_seekable_w(self, space):
-        if not space.is_true(space.call_method(self, 'seekable')):
-            raise OperationError(
-                space.w_IOError,
-                space.wrap("file or stream is not seekable"))
-
     # ______________________________________________________________
 
     @unwrap_spec('self', ObjSpace, W_Root)
@@ -234,9 +237,9 @@
     readable = interp2app(W_IOBase.readable_w),
     writable = interp2app(W_IOBase.writable_w),
     seekable = interp2app(W_IOBase.seekable_w),
-    _checkReadable = interp2app(W_IOBase.check_readable_w),
-    _checkWritable = interp2app(W_IOBase.check_writable_w),
-    _checkSeekable = interp2app(W_IOBase.check_seekable_w),
+    _checkReadable = interp2app(check_readable_w),
+    _checkWritable = interp2app(check_writable_w),
+    _checkSeekable = interp2app(check_seekable_w),
     closed = GetSetProperty(W_IOBase.closed_get_w),
 
     readline = interp2app(W_IOBase.readline_w),

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 17:31:26 2010
@@ -195,3 +195,19 @@
         assert b.seek(8) == 8
         assert b.truncate() == 8
         assert b.tell() == 8
+
+class AppTestBufferedRWPair:
+    def test_pair(self):
+        import _io
+        pair = _io.BufferedRWPair(_io.BytesIO("abc"), _io.BytesIO())
+        assert not pair.closed
+        assert pair.read() == "abc"
+        assert pair.write("abc") == 3
+
+    def test_constructor_with_not_readable(self):
+        import _io, io
+        class NotReadable(io.BytesIO):
+            def readable(self):
+                return False
+
+        raises(IOError, _io.BufferedRWPair, NotReadable(), _io.BytesIO())



More information about the Pypy-commit mailing list