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

bdkearns noreply at buildbot.pypy.org
Fri Aug 29 07:20:16 CEST 2014


Author: Brian Kearns <bdkearns at gmail.com>
Branch: use-file-star-for-file
Changeset: r73152:58d64536f9b4
Date: 2014-08-29 01:19 -0400
http://bitbucket.org/pypy/pypy/changeset/58d64536f9b4/

Log:	merge default

diff --git a/rpython/rlib/rfile.py b/rpython/rlib/rfile.py
--- a/rpython/rlib/rfile.py
+++ b/rpython/rlib/rfile.py
@@ -3,7 +3,7 @@
 python builtin open()
 """
 
-import os
+import os, stat, errno
 from rpython.rlib import rposix
 from rpython.rlib.rarithmetic import intmask
 from rpython.rlib.rstring import StringBuilder
@@ -79,9 +79,20 @@
 
 
 def _error(ll_file):
-    errno = c_ferror(ll_file)
+    err = c_ferror(ll_file)
     c_clearerr(ll_file)
-    raise OSError(errno, os.strerror(errno))
+    raise OSError(err, os.strerror(err))
+
+
+def _dircheck(ll_file):
+    try:
+        st = os.fstat(c_fileno(ll_file))
+    except OSError:
+        pass
+    else:
+        if stat.S_ISDIR(st[0]):
+            err = errno.EISDIR
+            raise OSError(err, os.strerror(err))
 
 
 def create_file(filename, mode="r", buffering=-1):
@@ -97,6 +108,7 @@
             lltype.free(ll_mode, flavor='raw')
     finally:
         lltype.free(ll_name, flavor='raw')
+    _dircheck(ll_f)
     if buffering >= 0:
         if buffering == 0:
             c_setvbuf(ll_f, lltype.nullptr(rffi.CCHARP.TO), _IONBF, 0)
@@ -124,6 +136,7 @@
             raise OSError(errno, os.strerror(errno))
     finally:
         lltype.free(ll_mode, flavor='raw')
+    _dircheck(ll_f)
     return RFile(ll_f)
 
 
@@ -190,7 +203,9 @@
         # XXX CPython uses a more delicate logic here
         self._check_closed()
         ll_file = self.ll_file
-        if size < 0:
+        if size == 0:
+            return ""
+        elif size < 0:
             # read the entire contents
             buf = lltype.malloc(rffi.CCHARP.TO, BASE_BUF_SIZE, flavor='raw')
             try:
@@ -206,7 +221,7 @@
                     s.append_charpsize(buf, returned_size)
             finally:
                 lltype.free(buf, flavor='raw')
-        else:
+        else:  # size > 0
             with rffi.scoped_alloc_buffer(size) as buf:
                 returned_size = c_fread(buf.raw, 1, size, ll_file)
                 returned_size = intmask(returned_size)  # is between 0 and size
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
@@ -1,4 +1,4 @@
-import os, sys, py
+import os, sys, py, errno
 from rpython.rtyper.test.tool import BaseRtypingTest
 from rpython.tool.udir import udir
 from rpython.rlib import rfile
@@ -17,9 +17,37 @@
             f.write("dupa")
             f.close()
 
+        f()
         self.interpret(f, [])
         assert open(fname, "r").read() == "dupa"
 
+    def test_open_errors(self):
+        def f():
+            try:
+                open('zzz')
+            except OSError as e:
+                assert e.errno == errno.ENOENT
+            else:
+                assert False
+
+            try:
+                open('.')
+            except OSError as e:
+                assert e.errno == errno.EISDIR
+            else:
+                assert False
+
+            fd = os.open('.', os.O_RDONLY, 0777)
+            try:
+                os.fdopen(fd)
+            except OSError as e:
+                assert e.errno == errno.EISDIR
+            else:
+                assert False
+            os.close(fd)
+
+        self.interpret(f, [])
+
     def test_open_buffering_line(self):
         fname = str(self.tmpdir.join('file_1a'))
 
@@ -60,6 +88,8 @@
             f.write("dupa\x00dupb")
             f.close()
             f2 = open(fname)
+            dupa = f2.read(0)
+            assert dupa == ""
             dupa = f2.read()
             assert dupa == "dupa\x00dupb"
             f2.seek(0)


More information about the pypy-commit mailing list