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

afa at codespeak.net afa at codespeak.net
Tue Oct 19 14:46:32 CEST 2010


Author: afa
Date: Tue Oct 19 14:46:29 2010
New Revision: 78081

Modified:
   pypy/branch/fast-forward/pypy/module/_io/__init__.py
   pypy/branch/fast-forward/pypy/module/_io/interp_fileio.py
   pypy/branch/fast-forward/pypy/module/_io/interp_iobase.py
   pypy/branch/fast-forward/pypy/module/_io/test/test_fileio.py
   pypy/branch/fast-forward/pypy/module/_io/test/test_io.py
Log:
Implement FileIO.readall(), io.UnsupportedOperation
+ translation fixes


Modified: pypy/branch/fast-forward/pypy/module/_io/__init__.py
==============================================================================
--- pypy/branch/fast-forward/pypy/module/_io/__init__.py	(original)
+++ pypy/branch/fast-forward/pypy/module/_io/__init__.py	Tue Oct 19 14:46:29 2010
@@ -24,6 +24,14 @@
         'TextIOWrapper': 'interp_io.W_TextIOWrapper',
 
         'open': 'interp_io.open',
-        'UnsupportedOperation': 'space.w_None',
         'IncrementalNewlineDecoder': 'space.w_None',
         }
+
+    def init(self, space):
+        w_UnsupportedOperation = space.call_function(
+            space.w_type,
+            space.wrap('UnsupportedOperation'),
+            space.newtuple([space.w_ValueError, space.w_IOError]),
+            space.newdict())
+        space.setattr(self, space.wrap('UnsupportedOperation'),
+                      w_UnsupportedOperation)

Modified: pypy/branch/fast-forward/pypy/module/_io/interp_fileio.py
==============================================================================
--- pypy/branch/fast-forward/pypy/module/_io/interp_fileio.py	(original)
+++ pypy/branch/fast-forward/pypy/module/_io/interp_fileio.py	Tue Oct 19 14:46:29 2010
@@ -5,6 +5,7 @@
 from pypy.interpreter.baseobjspace import ObjSpace, W_Root
 from pypy.interpreter.error import OperationError, wrap_oserror, wrap_oserror2
 from pypy.rlib.rarithmetic import r_longlong
+from pypy.rlib.rstring import StringBuilder
 from os import O_RDONLY, O_WRONLY, O_RDWR, O_CREAT, O_TRUNC
 import os, stat, errno
 
@@ -76,6 +77,33 @@
     else:
         return space.int_w(w_size)
 
+SMALLCHUNK = 8 * 1024
+BIGCHUNK = 512 * 1024
+
+def new_buffersize(fd, currentsize):
+    try:
+        st = os.fstat(fd)
+        end = st.st_size
+        pos = os.lseek(fd, 0, 1)
+    except OSError:
+        pass
+    else:
+        # Files claiming a size smaller than SMALLCHUNK may
+        # actually be streaming pseudo-files. In this case, we
+        # apply the more aggressive algorithm below.
+        if end >= SMALLCHUNK and end >= pos:
+            # Add 1 so if the file were to grow we'd notice.
+            return currentsize + end - pos + 1
+
+    if currentsize > SMALLCHUNK:
+        # Keep doubling until we reach BIGCHUNK;
+        # then keep adding BIGCHUNK.
+        if currentsize <= BIGCHUNK:
+            return currentsize + currentsize
+        else:
+            return currentsize + BIGCHUNK
+    return currentsize + SMALLCHUNK
+
 def verify_fd(fd):
     return
 
@@ -136,7 +164,7 @@
                     space, w_name, flags, 0666)
             except OSError, e:
                 raise wrap_oserror2(space, e, w_name,
-                                    exception_name='w_OSError')
+                                    exception_name='w_IOError')
 
             self._dircheck(space, w_name)
         self.w_name = w_name
@@ -198,9 +226,9 @@
         except OSError:
             return
         if stat.S_ISDIR(st.st_mode):
-            self._close()
-            raise wrap_oserror2(space, OSError(EISDIR), w_filename,
-                                exception_name='w_IOError')
+            self._close(space)
+            raise wrap_oserror2(space, OSError(errno.EISDIR, "fstat"),
+                                w_filename, exception_name='w_IOError')
 
     @unwrap_spec('self', ObjSpace, r_longlong, int)
     def seek_w(self, space, pos, whence=0):
@@ -255,16 +283,43 @@
         size = convert_size(space, w_size)
 
         if size < 0:
-            return self.readall_w(self, space)
+            return self.readall_w(space)
 
         try:
             s = os.read(self.fd, size)
         except OSError, e:
             raise wrap_oserror(space, e,
-                               exception_name='w_OSError')
+                               exception_name='w_IOError')
 
         return space.wrap(s)
 
+    @unwrap_spec('self', ObjSpace)
+    def readall_w(self, space):
+        self._check_closed(space)
+        total = 0
+
+        builder = StringBuilder()
+        while True:
+            newsize = int(new_buffersize(self.fd, total))
+
+            try:
+                chunk = os.read(self.fd, newsize - total)
+            except OSError, e:
+                if e.errno == errno.EAGAIN:
+                    if total > 0:
+                        # return what we've got so far
+                        break
+                    return space.w_None
+                raise wrap_oserror(space, e,
+                                   exception_name='w_IOError')
+
+            if not chunk:
+                break
+            builder.append(chunk)
+            total += len(chunk)
+        return space.wrap(builder.build())
+
+
 W_FileIO.typedef = TypeDef(
     'FileIO', W_RawIOBase.typedef,
     __new__  = interp2app(W_FileIO.descr_new.im_func),
@@ -272,6 +327,7 @@
 
     seek = interp2app(W_FileIO.seek_w),
     read = interp2app(W_FileIO.read_w),
+    readall = interp2app(W_FileIO.readall_w),
     close = interp2app(W_FileIO.close_w),
 
     readable = interp2app(W_FileIO.readable_w),

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 Oct 19 14:46:29 2010
@@ -2,7 +2,7 @@
 from pypy.interpreter.typedef import (
     TypeDef, GetSetProperty, generic_new_descr)
 from pypy.interpreter.gateway import interp2app, Arguments, unwrap_spec
-from pypy.interpreter.error import OperationError
+from pypy.interpreter.error import OperationError, operationerrfmt
 from pypy.rlib.rstring import StringBuilder
 
 def convert_size(space, w_size):
@@ -113,14 +113,15 @@
         has_peek = space.findattr(self, space.wrap("peek"))
 
         builder = StringBuilder()
+        size = 0
 
-        while limit < 0 or len(buffer) < limit:
+        while limit < 0 or size < limit:
             nreadahead = 1
 
             if has_peek:
                 w_readahead = space.call_method(self, "peek", space.wrap(1))
                 if not space.isinstance_w(w_readahead, space.w_str):
-                    raise operationerrorfmt(
+                    raise operationerrfmt(
                         space.w_IOError,
                         "peek() should have returned a bytes object, "
                         "not '%s'", space.type(w_readahead).getname(space, '?'))
@@ -145,9 +146,8 @@
                     nreadahead = n
 
             w_read = space.call_method(self, "read", space.wrap(nreadahead))
-            print "AFA", nreadahead, w_read
             if not space.isinstance_w(w_read, space.w_str):
-                raise operationerrorfmt(
+                raise operationerrfmt(
                     space.w_IOError,
                     "peek() should have returned a bytes object, "
                     "not '%s'", space.type(w_read).getname(space, '?'))
@@ -155,13 +155,12 @@
             if not read:
                 break
 
-            print "AFA APPEND", repr(read)
+            size += len(read)
             builder.append(read)
 
             if read[-1] == '\n':
                 break
 
-        print "AFA RETURN", repr(builder.build())
         return space.wrap(builder.build())
 
 W_IOBase.typedef = TypeDef(

Modified: pypy/branch/fast-forward/pypy/module/_io/test/test_fileio.py
==============================================================================
--- pypy/branch/fast-forward/pypy/module/_io/test/test_fileio.py	(original)
+++ pypy/branch/fast-forward/pypy/module/_io/test/test_fileio.py	Tue Oct 19 14:46:29 2010
@@ -30,7 +30,7 @@
 
     def test_open_directory(self):
         import _io
-        raises(OSError, _io.FileIO, self.tmpdir, "rb")
+        raises(IOError, _io.FileIO, self.tmpdir, "rb")
 
     def test_readline(self):
         import _io
@@ -41,3 +41,8 @@
         assert f.readline() == 'c'
         assert f.readline() == ''
         f.close()
+
+    def test_readall(self):
+        import _io
+        f = _io.FileIO(self.tmpfile, 'rb')
+        assert f.readall() == "a\nb\nc"

Modified: pypy/branch/fast-forward/pypy/module/_io/test/test_io.py
==============================================================================
--- pypy/branch/fast-forward/pypy/module/_io/test/test_io.py	(original)
+++ pypy/branch/fast-forward/pypy/module/_io/test/test_io.py	Tue Oct 19 14:46:29 2010
@@ -38,6 +38,10 @@
 
         assert list(MyFile()) == ["line1", "line2"]
 
+    def test_exception(self):
+        import _io
+        e = _io.UnsupportedOperation("seek")
+
 class AppTestOpen:
     def setup_class(cls):
         tmpfile = udir.join('tmpfile').ensure()



More information about the Pypy-commit mailing list