[pypy-commit] pypy default: test file mode in rfile

bdkearns noreply at buildbot.pypy.org
Mon Sep 8 00:41:52 CEST 2014


Author: Brian Kearns <bdkearns at gmail.com>
Branch: 
Changeset: r73370:44d6afd69be3
Date: 2014-09-07 18:41 -0400
http://bitbucket.org/pypy/pypy/changeset/44d6afd69be3/

Log:	test file mode in rfile

diff --git a/rpython/rlib/rfile.py b/rpython/rlib/rfile.py
--- a/rpython/rlib/rfile.py
+++ b/rpython/rlib/rfile.py
@@ -150,7 +150,7 @@
             c_setvbuf(ll_file, buf, _IOLBF, BUFSIZ)
         else:
             c_setvbuf(ll_file, buf, _IOFBF, buffering)
-    return RFile(ll_file)
+    return RFile(ll_file, mode)
 
 
 def create_fdopen_rfile(fd, mode="r"):
@@ -166,7 +166,7 @@
     finally:
         lltype.free(ll_mode, flavor='raw')
     _dircheck(ll_file)
-    return RFile(ll_file)
+    return RFile(ll_file, mode)
 
 
 def create_temp_rfile():
@@ -190,12 +190,21 @@
             lltype.free(ll_type, flavor='raw')
     finally:
         lltype.free(ll_command, flavor='raw')
-    return RFile(ll_file, _pclose2)
+    return RFile(ll_file, close2=_pclose2)
 
 
 class RFile(object):
-    def __init__(self, ll_file, close2=_fclose2):
+    _readable = False
+    _writable = False
+
+    def __init__(self, ll_file, mode='+', close2=_fclose2):
         self._ll_file = ll_file
+        if 'r' in mode:
+            self._readable = True
+        if 'w' in mode or 'a' in mode:
+            self._writable = True
+        if '+' in mode:
+            self._readable = self._writable = True
         self._close2 = close2
 
     def __del__(self):
@@ -232,9 +241,18 @@
         if not self._ll_file:
             raise ValueError("I/O operation on closed file")
 
+    def _check_reading(self):
+        if not self._readable:
+            raise IOError(0, "File not open for reading")
+
+    def _check_writing(self):
+        if not self._writable:
+            raise IOError(0, "File not open for writing")
+
     def read(self, size=-1):
         # XXX CPython uses a more delicate logic here
         self._check_closed()
+        self._check_reading()
         ll_file = self._ll_file
         if size == 0:
             return ""
@@ -300,6 +318,7 @@
 
     def readline(self, size=-1):
         self._check_closed()
+        self._check_reading()
         if size == 0:
             return ""
         elif size < 0:
@@ -335,6 +354,7 @@
     @enforceargs(None, str)
     def write(self, value):
         self._check_closed()
+        self._check_writing()
         ll_value = rffi.get_nonmovingbuffer(value)
         try:
             # note that since we got a nonmoving buffer, it is either raw
@@ -356,6 +376,7 @@
 
     def truncate(self, arg=-1):
         self._check_closed()
+        self._check_writing()
         if arg == -1:
             arg = self.tell()
         self.flush()
diff --git a/rpython/rlib/test/test_rfile.py b/rpython/rlib/test/test_rfile.py
--- a/rpython/rlib/test/test_rfile.py
+++ b/rpython/rlib/test/test_rfile.py
@@ -129,13 +129,25 @@
             try:
                 f.read()
             except IOError as e:
-                pass
+                assert not e.errno
+            else:
+                assert False
+            try:
+                f.readline()
+            except IOError as e:
+                assert not e.errno
             else:
                 assert False
             f.write("dupa\x00dupb")
             f.close()
             for mode in ['r', 'U']:
                 f2 = open(fname, mode)
+                try:
+                    f2.write('')
+                except IOError as e:
+                    assert not e.errno
+                else:
+                    assert False
                 dupa = f2.read(0)
                 assert dupa == ""
                 dupa = f2.read()
@@ -215,6 +227,12 @@
             new_fno = os.dup(f.fileno())
             f2 = os.fdopen(new_fno, "w")
             f.close()
+            try:
+                f2.read()
+            except IOError as e:
+                assert not e.errno
+            else:
+                assert False
             f2.write("xxx")
             f2.close()
 
@@ -281,6 +299,14 @@
             data = f.read()
             assert data == "hello w"
             f.close()
+            f = open(fname)
+            try:
+                f.truncate()
+            except IOError as e:
+                assert not e.errno
+            else:
+                assert False
+            f.close()
 
         f()
         self.interpret(f, [])


More information about the pypy-commit mailing list