[pypy-commit] pypy use-file-star-for-file: merge default

bdkearns noreply at buildbot.pypy.org
Fri Aug 29 19:31:40 CEST 2014


Author: Brian Kearns <bdkearns at gmail.com>
Branch: use-file-star-for-file
Changeset: r73183:64c36466fbba
Date: 2014-08-29 13:31 -0400
http://bitbucket.org/pypy/pypy/changeset/64c36466fbba/

Log:	merge default

diff --git a/pypy/module/_file/interp_file.py b/pypy/module/_file/interp_file.py
--- a/pypy/module/_file/interp_file.py
+++ b/pypy/module/_file/interp_file.py
@@ -28,6 +28,8 @@
     w_name   = None
     mode     = "<uninitialized file>"
     binary   = False
+    readable = False
+    writable = False
     softspace= 0     # Required according to file object docs
     encoding = None
     errors   = None
@@ -57,6 +59,12 @@
         self.stream = stream
         self.mode = mode
         self.binary = "b" in mode
+        if 'r' in mode or 'U' in mode:
+            self.readable = True
+        if 'w' in mode or 'a' in mode:
+            self.writable = True
+        if '+' in mode:
+            self.readable = self.writable = True
         getopenstreams(self.space)[stream] = None
 
     def check_closed(self):
@@ -65,6 +73,16 @@
                 self.space.wrap("I/O operation on closed file")
             )
 
+    def check_readable(self):
+        if not self.readable:
+            raise OperationError(self.space.w_IOError, self.space.wrap(
+                "File not open for reading"))
+
+    def check_writable(self):
+        if not self.writable:
+            raise OperationError(self.space.w_IOError, self.space.wrap(
+                "File not open for writing"))
+
     def getstream(self):
         """Return self.stream or raise an app-level ValueError if missing
         (i.e. if the file is closed)."""
@@ -140,16 +158,19 @@
     @unwrap_spec(n=int)
     def direct_read(self, n=-1):
         stream = self.getstream()
+        self.check_readable()
         return stream.read(n)
 
     @unwrap_spec(size=int)
     def direct_readline(self, size=-1):
         stream = self.getstream()
+        self.check_readable()
         return stream.readline(size)
 
     @unwrap_spec(size=int)
     def direct_readlines(self, size=0):
         stream = self.getstream()
+        self.check_readable()
         # this is implemented as: .read().split('\n')
         # except that it keeps the \n in the resulting strings
         if size <= 0:
@@ -183,6 +204,7 @@
 
     def direct_truncate(self, w_size=None):  # note: a wrapped size!
         stream = self.getstream()
+        self.check_writable()
         space = self.space
         if space.is_none(w_size):
             size = stream.tell()
@@ -192,6 +214,7 @@
 
     def direct_write(self, w_data):
         space = self.space
+        self.check_writable()
         if self.binary:
             data = space.getarg_w('s*', w_data).as_str()
         else:
@@ -389,6 +412,7 @@
 
         space = self.space
         self.check_closed()
+        self.check_writable()
         lines = space.fixedview(w_lines)
         for i, w_line in enumerate(lines):
             if not space.isinstance_w(w_line, space.w_str):
diff --git a/pypy/module/_file/test/test_file_extra.py b/pypy/module/_file/test/test_file_extra.py
--- a/pypy/module/_file/test/test_file_extra.py
+++ b/pypy/module/_file/test/test_file_extra.py
@@ -555,15 +555,7 @@
         import errno, sys
         f = open(fn)
         exc = raises(IOError, f.truncate, 3)
-        # CPython explicitly checks the file mode
-        # PyPy relies on the libc to raise the error
-        if '__pypy__' not in sys.builtin_module_names:
-            assert str(exc.value) == "File not open for writing"
-        else:
-            if sys.platform == 'win32':
-                assert exc.value.errno == 5 # ERROR_ACCESS_DENIED
-            else:
-                assert exc.value.errno == errno.EINVAL
+        assert str(exc.value) == "File not open for writing"
         f.close()
 
     def test_readinto(self):
diff --git a/rpython/rlib/rfile.py b/rpython/rlib/rfile.py
--- a/rpython/rlib/rfile.py
+++ b/rpython/rlib/rfile.py
@@ -188,6 +188,7 @@
 
     def write(self, value):
         self._check_closed()
+        assert value is not None
         ll_value = rffi.get_nonmovingbuffer(value)
         try:
             # note that since we got a nonmoving buffer, it is either raw
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
@@ -23,7 +23,7 @@
 
     def test_open_errors(self):
         def f(exc):
-            def g():
+            def g(run):
                 try:
                     open('zzz', 'badmode')
                 except ValueError:
@@ -61,17 +61,18 @@
                     assert os.name == 'nt' and e.errno == errno.EACCES
                 else:
                     assert os.name != 'nt'
-                    try:
-                        os.fdopen(fd)
-                    except exc as e:
-                        assert e.errno == errno.EISDIR
-                    else:
-                        assert False
+                    if run:
+                        try:
+                            os.fdopen(fd)
+                        except exc as e:
+                            assert e.errno == errno.EISDIR
+                        else:
+                            assert False
                     os.close(fd)
             return g
 
-        f(IOError)()
-        self.interpret(f(OSError), [])
+        f(IOError)(sys.version_info >= (2, 7, 9))
+        self.interpret(f(OSError), [True])
 
     @py.test.mark.skipif("sys.platform == 'win32'")
     # http://msdn.microsoft.com/en-us/library/86cebhfs.aspx


More information about the pypy-commit mailing list