[pypy-commit] pypy use-file-star-for-file: test/fix stdio flush on close

bdkearns noreply at buildbot.pypy.org
Thu Sep 11 10:37:57 CEST 2014


Author: Brian Kearns <bdkearns at gmail.com>
Branch: use-file-star-for-file
Changeset: r73451:dc9cc4507de8
Date: 2014-09-11 04:14 -0400
http://bitbucket.org/pypy/pypy/changeset/dc9cc4507de8/

Log:	test/fix stdio flush on close

diff --git a/rpython/rlib/rfile.py b/rpython/rlib/rfile.py
--- a/rpython/rlib/rfile.py
+++ b/rpython/rlib/rfile.py
@@ -86,6 +86,7 @@
 c_fwrite = llexternal('fwrite', [rffi.CCHARP, rffi.SIZE_T, rffi.SIZE_T, FILEP],
                       rffi.SIZE_T)
 c_fflush = llexternal('fflush', [FILEP], rffi.INT)
+c_fflush_nogil = llexternal('fflush', [FILEP], rffi.INT, releasegil=False)
 c_ftruncate = llexternal(ftruncate, [rffi.INT, OFF_T], rffi.INT, macro=True)
 
 c_fseek = llexternal('fseek', [FILEP, rffi.LONG, rffi.INT], rffi.INT)
@@ -195,9 +196,14 @@
     return RFile(ll_file, close2=_pclose2)
 
 
+def _check_and_flush(ll_file):
+    prev_fail = c_ferror(ll_file)
+    return c_fflush(ll_file) or (EOF if prev_fail else 0)
+
+
 def create_stdio():
-    close2 = (None, None)
-    stdin = RFile(c_stdin(), close2=close2)
+    close2 = (_check_and_flush, c_fflush_nogil)
+    stdin = RFile(c_stdin(), close2=(None, None))
     stdout = RFile(c_stdout(), close2=close2)
     stderr = RFile(c_stderr(), close2=close2)
     return stdin, stdout, stderr
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
@@ -389,12 +389,23 @@
         cls.tmpdir = udir.join('test_rfile_direct')
         cls.tmpdir.ensure(dir=True)
 
-    def test_stdio(self):
+    def test_stdio_close(self, capfd):
         i, o, e = rfile.create_stdio()
         o.write("test\n")
         i.close()
         o.close()
         e.close()
+        out, err = capfd.readouterr()
+        assert out == "test\n"
+
+    def test_stdio_del(self, capfd):
+        i, o, e = rfile.create_stdio()
+        o.write("test\n")
+        del i
+        del o
+        del e
+        out, err = capfd.readouterr()
+        assert out == "test\n"
 
     def test_auto_close(self):
         fname = str(self.tmpdir.join('file_auto_close'))


More information about the pypy-commit mailing list