Anonymous avatar Anonymous committed eab0ca9

Make _io.PyFileIO inherit _io.PyRawFileIO
Now PyFileIO is part of the _io hierarchy, it also adopts the Closer that PyIOBase provides, in place of its own, and the base class' approach to close and flush. test_io errors are lower (as promised) at fail/error/skip = 19/20/99.

Comments (0)

Files changed (1)

src/org/python/modules/_io/PyFileIO.java

 package org.python.modules._io;
 
 import java.nio.ByteBuffer;
-import java.util.concurrent.Callable;
 
 import org.python.core.ArgParser;
 import org.python.core.BaseBytes;
 import org.python.core.PyJavaType;
 import org.python.core.PyObject;
 import org.python.core.PyString;
-import org.python.core.PySystemState;
 import org.python.core.PyType;
 import org.python.core.PyUnicode;
 import org.python.core.io.FileIO;
 import org.python.expose.ExposedNew;
 import org.python.expose.ExposedType;
 
-@ExposedType(name = "_io.FileIO")
-public class PyFileIO extends PyObject {
+@ExposedType(name = "_io.FileIO", base = PyRawIOBase.class)
+public class PyFileIO extends PyRawIOBase {
 
     public static final PyType TYPE = PyType.fromClass(PyFileIO.class);
 
     @ExposedGet(doc = BuiltinDocs.file_mode_doc)
     public String mode;
 
-    /** The file's closer object; ensures the file is closed at shutdown */
-    private Closer closer;
-
     public PyFileIO() {
         super(TYPE);
     }
         }
 
         FileIO___init__((PyString)name, mode, closefd);
-        closer = new Closer(file, Py.getSystemState());
     }
 
     private void FileIO___init__(PyString name, String mode, boolean closefd) {
                 + "b" + (updating ? "+" : "");
     }
 
-    @ExposedMethod(doc = BuiltinDocs.file_close_doc)
+    /**
+     * Close the underlying file only if <code>closefd</code> was specified as (or defaulted to)
+     * <code>True</code>.
+     */
+    @Override
+    public void close() {
+        FileIO_close();
+    }
+
+    @ExposedMethod
     final synchronized void FileIO_close() {
-        if (closer != null) {
-            closer.close();
-            closer = null;
-        } else {
+        // Close this object to further input (also calls flush)
+        super.close();
+        // Now close downstream (if required to)
+        if (closefd) {
             file.close();
         }
     }
 
-    public void close() {
-        FileIO_close();
-    }
-
+    @Override
     public boolean readable() {
         return FileIO_readable();
     }
         return Py.java2py(file.seek(pos, how));
     }
 
+    @Override
     public boolean seekable() {
         return FileIO_seekable();
     }
         return file.tell();
     }
 
+    @Override
     public long tell() {
         return FileIO_tell();
     }
 
-    @ExposedMethod(defaults = {"null"}, doc = BuiltinDocs.file_truncate_doc)
-    final PyObject FileIO_truncate(PyObject position) {
-        if (position == null) {
-            return Py.java2py(FileIO_truncate());
-        }
-    	return Py.java2py(FileIO_truncate(position.asLong()));
+    @Override
+    public long truncate() {
+        return _truncate();
     }
 
-    final synchronized long FileIO_truncate(long position) {
-        return file.truncate(position);
+    @Override
+    public long truncate(long size) {
+        return _truncate(size);
     }
 
-    public long truncate(long position) {
-        return FileIO_truncate(position);
+    @ExposedMethod(defaults = "null", doc = truncate_doc)
+    final long FileIO_truncate(PyObject size) {
+        return (size != null) ? _truncate(size.asLong()) : _truncate();
     }
 
-    final synchronized long FileIO_truncate() {
-        return file.truncate(file.tell());
+    /** Common to FileIO_truncate(null) and truncate(). */
+    private final long _truncate() {
+        synchronized (file) {
+            return file.truncate(file.tell());
+        }
     }
 
-    public void truncate() {
-        FileIO_truncate();
+    /** Common to FileIO_truncate(size) and truncate(size). */
+    private final long _truncate(long size) {
+        synchronized (file) {
+            return file.truncate(size);
+        }
     }
 
+    @Override
     public boolean isatty() {
         return FileIO_isatty();
     }
         return file.isatty();
     }
 
+    @Override
     public boolean writable() {
         return FileIO_writable();
     }
         return file.writable();
     }
 
+    @Override
     public PyObject fileno() {
         return FileIO_fileno();
     }
         return new PyString(StringUtil.fromBytes(buf));
     }
 
+    @Override
     public PyString read(int size) {
         return FileIO_read(size);
     }
         return file.closed();
     }
 
-    /**
-     * XXX update docs - A mechanism to make sure PyFiles are closed on exit. On creation Closer adds itself
-     * to a list of Closers that will be run by PyFileCloser on JVM shutdown. When a
-     * PyFile's close or finalize methods are called, PyFile calls its Closer.close which
-     * clears Closer out of the shutdown queue.
-     *
-     * We use a regular object here rather than WeakReferences and their ilk as they may
-     * be collected before the shutdown hook runs. There's no guarantee that finalize will
-     * be called during shutdown, so we can't use it. It's vital that this Closer has no
-     * reference to the PyFile it's closing so the PyFile remains garbage collectable.
-     */
-    private static class Closer implements Callable<Void> {
-
-        /**
-         * The underlying file
-         */
-        private final FileIO file;
-        private PySystemState sys;
-
-        public Closer(FileIO file, PySystemState sys) {
-            this.file = file;
-            this.sys = sys;
-            sys.registerCloser(this);
-        }
-
-        /** For closing directly */
-        public void close() {
-            sys.unregisterCloser(this);
-            file.close();
-            sys = null;
-        }
-
-        /** For closing as part of a shutdown process */
-        @Override
-        public Void call() {
-            file.close();
-            sys = null;
-            return null;
-        }
-
-    }
 }
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.