From: <cg...@us...> - 2008-10-26 22:13:10
|
Revision: 5514 http://jython.svn.sourceforge.net/jython/?rev=5514&view=rev Author: cgroves Date: 2008-10-26 22:13:05 +0000 (Sun, 26 Oct 2008) Log Message: ----------- Move Java Stream wrapping off into FileUtil so PyFile doesn't have to be exposed as the type file and as the PyJavaClass PyFile Modified Paths: -------------- trunk/jython/Lib/os.py trunk/jython/Lib/popen2.py trunk/jython/Lib/test/test_java_integration.py trunk/jython/Lib/test/test_javashell.py trunk/jython/src/org/python/core/Options.java trunk/jython/src/org/python/core/Py.java trunk/jython/src/org/python/core/PyFile.java trunk/jython/src/org/python/core/StdoutWrapper.java trunk/jython/src/org/python/core/io/FileDescriptors.java trunk/jython/src/org/python/core/util/FileUtil.java Modified: trunk/jython/Lib/os.py =================================================================== --- trunk/jython/Lib/os.py 2008-10-26 21:13:51 UTC (rev 5513) +++ trunk/jython/Lib/os.py 2008-10-26 22:13:05 UTC (rev 5514) @@ -46,7 +46,6 @@ import stat as _stat import sys from java.io import File -from org.python.core import PyFile from org.python.core.io import FileDescriptors, FileIO, IOBase from org.python.core.Py import newString as asPyString @@ -554,7 +553,7 @@ raise OSError(errno.EBADF, errno.strerror(errno.EBADF)) try: - fp = PyFile(rawio, '<fdopen>', mode, bufsize) + fp = FileDescriptors.wrap(rawio, mode, bufsize) except IOError: raise OSError(errno.EINVAL, errno.strerror(errno.EINVAL)) return fp Modified: trunk/jython/Lib/popen2.py =================================================================== --- trunk/jython/Lib/popen2.py 2008-10-26 21:13:51 UTC (rev 5513) +++ trunk/jython/Lib/popen2.py 2008-10-26 22:13:05 UTC (rev 5514) @@ -27,9 +27,10 @@ from java.io import BufferedInputStream from java.io import PipedOutputStream from java.io import PipedInputStream -from org.python.core import PyFile from javashell import shellexecute +from org.python.core.util import FileUtil + __all__ = ["popen", "popen2", "popen3", "popen4", "Popen3", "Popen4"] _active = [] @@ -43,7 +44,7 @@ the close method. """ def __init__(self, stream, process, name): - self._file = PyFile(stream, "'%s'" % name) + self._file = FileUtil.wrap(stream) self._process = process def __getattr__(self, name): @@ -92,10 +93,10 @@ bufsize ) - self.tochild = PyFile( self._tochild ) - self.fromchild = PyFile( self._fromchild ) + self.tochild = FileUtil.wrap(self._tochild) + self.fromchild = FileUtil.wrap(self._fromchild) if self._childerr: - self.childerr = PyFile( self._childerr ) + self.childerr = FileUtil.wrap(self._childerr) def _startChildWaiter(self): """Start a subthread that waits for the child process to exit.""" @@ -197,7 +198,7 @@ "%s-stderr" % self.process, self._close ) - return PyFile( joinedStream ) + return FileUtil.wrap(joinedStream) def _close( self ): """Must be closed twice (once for each of the two joined pipes)""" Modified: trunk/jython/Lib/test/test_java_integration.py =================================================================== --- trunk/jython/Lib/test/test_java_integration.py 2008-10-26 21:13:51 UTC (rev 5513) +++ trunk/jython/Lib/test/test_java_integration.py 2008-10-26 22:13:05 UTC (rev 5514) @@ -155,7 +155,8 @@ self.assertRaises(FileNotFoundException, FileInputStream, "garbage") def test_unsupported(self): - fp = open(System.out) + from org.python.core.util import FileUtil + fp = FileUtil.wrap(System.out) self.assertRaises(IOError, fp.tell) class VectorTest(unittest.TestCase): Modified: trunk/jython/Lib/test/test_javashell.py =================================================================== --- trunk/jython/Lib/test/test_javashell.py 2008-10-26 21:13:51 UTC (rev 5513) +++ trunk/jython/Lib/test/test_javashell.py 2008-10-26 22:13:05 UTC (rev 5514) @@ -1,11 +1,11 @@ import unittest from test import test_support -from org.python.core import PyFile import re import os import javashell +from org.python.core.util import FileUtil # testCmds is a list of (command, expectedOutput) # each command is executed twice, once in unitialized environment and @@ -73,7 +73,7 @@ for cmd, pattern in testCmds: dprint( "\nExecuting '%s' with %s environment" % (cmd, whichEnv)) p = javashell.shellexecute(cmd) - line = PyFile( p.getInputStream() ).readlines()[0] + line = FileUtil.wrap(p.getInputStream()).readlines()[0] assert re.match( pattern, line ), \ "expected match for %s, got %s" % ( pattern, line ) dprint( "waiting for", cmd, "to complete") Modified: trunk/jython/src/org/python/core/Options.java =================================================================== --- trunk/jython/src/org/python/core/Options.java 2008-10-26 21:13:51 UTC (rev 5513) +++ trunk/jython/src/org/python/core/Options.java 2008-10-26 22:13:05 UTC (rev 5514) @@ -22,7 +22,7 @@ * considerably. */ public static boolean includeJavaStackInExceptions = false; - + /** * When true, python exception raised in overriden methods will be shown on * stderr. This option is remarkably useful when python is used for @@ -123,7 +123,7 @@ // Set the more unusual options Options.showJavaExceptions = getBooleanOption( "options.showJavaExceptions", Options.showJavaExceptions); - + Options.includeJavaStackInExceptions = getBooleanOption( "options.includeJavaStackInExceptions", Options.includeJavaStackInExceptions); Modified: trunk/jython/src/org/python/core/Py.java =================================================================== --- trunk/jython/src/org/python/core/Py.java 2008-10-26 21:13:51 UTC (rev 5513) +++ trunk/jython/src/org/python/core/Py.java 2008-10-26 22:13:05 UTC (rev 5514) @@ -455,13 +455,13 @@ @param o the <code>PyObject</code> to convert. @param c the class to convert it to. **/ - public static Object tojava(PyObject o, Class c) { + public static <T> T tojava(PyObject o, Class<T> c) { Object obj = o.__tojava__(c); if (obj == Py.NoConversion) { throw Py.TypeError("can't convert " + o.__repr__() + " to " + c.getName()); } - return obj; + return (T)obj; } // ??pending: was @deprecated but is actually used by proxie code. @@ -1963,7 +1963,7 @@ if (file instanceof PyJavaInstance) { Object tojava = file.__tojava__(OutputStream.class); if (tojava != null && tojava != Py.NoConversion) { - this.file = new PyFile((OutputStream) tojava, "<java OutputStream>"); + this.file = new PyFile((OutputStream) tojava); } } } Modified: trunk/jython/src/org/python/core/PyFile.java =================================================================== --- trunk/jython/src/org/python/core/PyFile.java 2008-10-26 21:13:51 UTC (rev 5513) +++ trunk/jython/src/org/python/core/PyFile.java 2008-10-26 22:13:05 UTC (rev 5514) @@ -3,7 +3,6 @@ import java.io.InputStream; import java.io.OutputStream; -import java.io.RandomAccessFile; import java.util.LinkedList; import org.python.core.io.BinaryIOWrapper; @@ -20,13 +19,13 @@ import org.python.core.io.TextIOBase; import org.python.core.io.TextIOWrapper; import org.python.core.io.UniversalIOWrapper; +import org.python.core.util.FileUtil; import org.python.expose.ExposedDelete; import org.python.expose.ExposedGet; import org.python.expose.ExposedMethod; import org.python.expose.ExposedNew; import org.python.expose.ExposedSet; import org.python.expose.ExposedType; -import org.python.expose.MethodType; /** * A python file wrapper around a java stream, reader/writer or file. @@ -35,7 +34,7 @@ public class PyFile extends PyObject { public static final PyType TYPE = PyType.fromClass(PyFile.class); - + /** The filename */ @ExposedGet public PyObject name; @@ -75,14 +74,13 @@ private Closer closer; /** All PyFiles' closers */ - private static LinkedList closers = new LinkedList(); + private static LinkedList<Closer> closers = new LinkedList<Closer>(); static { initCloser(); } - public PyFile() { - } + public PyFile() {} public PyFile(PyType subType) { super(subType); @@ -93,100 +91,41 @@ file___init__(raw, name, mode, bufsize); } - public PyFile(InputStream istream, String name, String mode, int bufsize, - boolean closefd) { + PyFile(InputStream istream, String name, String mode, int bufsize, boolean closefd) { parseMode(mode); file___init__(new StreamIO(istream, closefd), name, mode, bufsize); } - public PyFile(InputStream istream, String name, String mode, int bufsize) { - this(istream, name, mode, -1, true); - } - - public PyFile(InputStream istream, String name, String mode) { - this(istream, name, mode, -1); - } - - public PyFile(InputStream istream, String name) { - this(istream, name, "r"); - } - + /** + * Creates a file object wrapping the given <code>InputStream</code>. The builtin methods + * <code>file</code> and <code>open</code> don't expose this functionality as it isn't available + * to regular Python code. To wrap an InputStream in a file from Python, use + * {@link FileUtil#wrap(InputStream)} + */ public PyFile(InputStream istream) { - this(istream, "<???>", "r"); + this(istream, "<Java InputStream '" + istream + "' as file>", "r", -1, true); } - public PyFile(OutputStream ostream, String name, String mode, int bufsize, boolean closefd) { + PyFile(OutputStream ostream, String name, String mode, int bufsize, boolean closefd) { parseMode(mode); file___init__(new StreamIO(ostream, closefd), name, mode, bufsize); } - public PyFile(OutputStream ostream, String name, String mode, int bufsize) { - this(ostream, name, mode, -1, true); - } - - public PyFile(OutputStream ostream, String name, String mode) { - this(ostream, name, mode, -1); - } - - public PyFile(OutputStream ostream, String name) { - this(ostream, name, "w"); - } - + /** + * Creates a file object wrapping the given <code>OutputStream</code>. The builtin methods + * <code>file</code> and <code>open</code> don't expose this functionality as it isn't available + * to regular Python code. To wrap an OutputStream in a file from Python, use + * {@link FileUtil#wrap(OutputStream)} + */ public PyFile(OutputStream ostream) { - this(ostream, "<???>", "w"); + this(ostream, "<Java OutputStream '" + ostream + "' as file>", "w", -1, true); } - public PyFile(RandomAccessFile file, String name, String mode, int bufsize) { - file___init__(new FileIO(file.getChannel(), parseMode(mode)), name, mode, bufsize); - } - - public PyFile(RandomAccessFile file, String name, String mode) { - this(file, name, mode, -1); - } - - public PyFile(RandomAccessFile file, String name) { - this(file, name, "r+"); - } - - public PyFile(RandomAccessFile file) { - this(file, "<???>", "r+"); - } - public PyFile(String name, String mode, int bufsize) { file___init__(new FileIO(name, parseMode(mode)), name, mode, bufsize); } @ExposedNew - static final PyObject file_new(PyNewWrapper new_, boolean init, PyType subtype, - PyObject[] args, String[] keywords) { - PyFile newFile; - if (new_.for_type == subtype) { - if (init) { - if (args.length - keywords.length == 0) { - newFile = new PyFile(); - newFile.file___init__(args, keywords); - } else if (args[0] instanceof PyString || - (args[0] instanceof PyJavaInstance && - ((PyJavaInstance)args[0]).javaProxy == String.class)) { - // If first arg is a PyString or String, assume - // its being called as a builtin. - newFile = new PyFile(); - newFile.file___init__(args, keywords); - newFile.closer = new Closer(newFile.file); - } else { - // assume it's being called as a java class - PyJavaClass pjc = new PyJavaClass(PyFile.class); - newFile = (PyFile)pjc.__call__(args, keywords); - } - } else { - newFile = new PyFile(); - } - } else { - newFile = new PyFileDerived(subtype); - } - return newFile; - } - @ExposedMethod final void file___init__(PyObject[] args, String[] kwds) { ArgParser ap = new ArgParser("file", args, kwds, new String[] {"name", "mode", "bufsize"}, @@ -199,6 +138,7 @@ String mode = ap.getString(1, "r"); int bufsize = ap.getInt(2, -1); file___init__(new FileIO(name.toString(), parseMode(mode)), name, mode, bufsize); + closer = new Closer(file); } private void file___init__(RawIOBase raw, String name, String mode, int bufsize) { @@ -613,18 +553,15 @@ } /** - * 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. + * 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. + * 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 { @@ -667,7 +604,7 @@ synchronized (closers) { while (closers.size() > 0) { try { - ((Closer)closers.removeFirst()).doClose(); + closers.removeFirst().doClose(); } catch (PyException e) { // continue } Modified: trunk/jython/src/org/python/core/StdoutWrapper.java =================================================================== --- trunk/jython/src/org/python/core/StdoutWrapper.java 2008-10-26 21:13:51 UTC (rev 5513) +++ trunk/jython/src/org/python/core/StdoutWrapper.java 2008-10-26 22:13:05 UTC (rev 5514) @@ -31,7 +31,7 @@ Object tojava = obj.__tojava__(OutputStream.class); if (tojava != null && tojava != Py.NoConversion) { - f = new PyFile((OutputStream)tojava, "<java OutputStream>"); + f = new PyFile((OutputStream)tojava); } if (f != null) { setObject(ss, f); Modified: trunk/jython/src/org/python/core/io/FileDescriptors.java =================================================================== --- trunk/jython/src/org/python/core/io/FileDescriptors.java 2008-10-26 21:13:51 UTC (rev 5513) +++ trunk/jython/src/org/python/core/io/FileDescriptors.java 2008-10-26 22:13:05 UTC (rev 5514) @@ -2,7 +2,7 @@ package org.python.core.io; import org.python.core.Py; -import org.python.core.PyJavaInstance; +import org.python.core.PyFile; import org.python.core.PyObject; /** @@ -14,22 +14,20 @@ */ public class FileDescriptors { + public static PyFile wrap(RawIOBase raw, String mode, int bufsize) { + return new PyFile(raw, "<fdopen>", mode, bufsize); + } + /** - * Return the RawIOBase associated with the specified file - * descriptor. + * Return the RawIOBase associated with the specified file descriptor. * * Raises a Python exception is the file descriptor is invalid * - * @param fd a Jython file descriptor object + * @param fd + * a Jython file descriptor object * @return the RawIOBase associated with the file descriptor */ public static RawIOBase get(PyObject fd) { - if (fd instanceof PyJavaInstance) { - Object tojava = ((PyJavaInstance)fd).__tojava__(RawIOBase.class); - if (tojava instanceof RawIOBase) { - return (RawIOBase)tojava; - } - } - throw Py.TypeError("a fileno is required"); + return Py.tojava(fd, RawIOBase.class); } } Modified: trunk/jython/src/org/python/core/util/FileUtil.java =================================================================== --- trunk/jython/src/org/python/core/util/FileUtil.java 2008-10-26 21:13:51 UTC (rev 5513) +++ trunk/jython/src/org/python/core/util/FileUtil.java 2008-10-26 22:13:05 UTC (rev 5514) @@ -2,14 +2,32 @@ package org.python.core.util; import java.io.ByteArrayOutputStream; +import java.io.IOException; import java.io.InputStream; -import java.io.IOException; +import java.io.OutputStream; +import org.python.core.PyFile; + /** * Utility methods for Java file handling. */ public class FileUtil { + /** + * Creates a PyFile that reads from the given <code>InputStream</code>. + */ + public static PyFile wrap(InputStream is) { + return new PyFile(is); + } + + /** + * Creates a PyFile that writes to the given <code>OutputStream</code>. + */ + public static PyFile wrap(OutputStream os) { + return new PyFile(os); + } + + /** * Read all bytes from the input stream. <p/> Note that using this method to * read very large streams could cause out-of-memory exceptions and/or block * for large periods of time. This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |