From: <pj...@us...> - 2009-10-20 00:21:20
|
Revision: 6878 http://jython.svn.sourceforge.net/jython/?rev=6878&view=rev Author: pjenvey Date: 2009-10-20 00:20:58 +0000 (Tue, 20 Oct 2009) Log Message: ----------- o jna-posix does the pure java stat for us, simplify it + move it to PosixModule o move strerror to PosixModule because it does the work of falling back to Linux errno descriptions on Windows, and we need that from some Java calls Modified Paths: -------------- trunk/jython/Lib/posix.py trunk/jython/Lib/test/test_fileno.py trunk/jython/src/org/python/core/Py.java trunk/jython/src/org/python/modules/posix/PosixModule.java trunk/jython/src/org/python/modules/posix/PyStatResult.java trunk/jython/src/org/python/modules/posix/PythonPOSIXHandler.java Modified: trunk/jython/Lib/posix.py =================================================================== --- trunk/jython/Lib/posix.py 2009-10-20 00:06:05 UTC (rev 6877) +++ trunk/jython/Lib/posix.py 2009-10-20 00:20:58 UTC (rev 6878) @@ -18,18 +18,14 @@ from java.io import File from org.python.core.io import FileDescriptors, FileIO, IOBase from org.python.core.Py import newString as asPyString -try: - from org.python.constantine.platform import Errno -except ImportError: - from com.kenai.constantine.platform import Errno __all__ = _posix.__all__[:] __all__.extend(['_exit', 'access', 'chdir', 'chmod', 'close', 'environ', 'fdopen', 'fsync', 'ftruncate', 'getcwd', 'getcwdu', 'getenv', - 'getpid', 'isatty', 'listdir', 'lseek', 'lstat', 'mkdir', - 'open', 'popen', 'putenv', 'read', 'remove', 'rename', 'rmdir', - 'stat', 'strerror', 'system', 'umask', 'unlink', 'unsetenv', - 'urandom', 'utime', 'write']) + 'getpid', 'isatty', 'listdir', 'lseek', 'mkdir', 'open', + 'popen', 'putenv', 'read', 'remove', 'rename', 'rmdir', + 'system', 'umask', 'unlink', 'unsetenv', 'urandom', 'utime', + 'write']) _name = _posix.__name__[1:] @@ -151,28 +147,6 @@ elif not f.delete(): raise OSError(0, "couldn't delete directory", path) -def strerror(code): - """strerror(code) -> string - - Translate an error code to a message string. - """ - if not isinstance(code, (int, long)): - raise TypeError('an integer is required') - constant = Errno.valueOf(code) - if constant is Errno.__UNKNOWN_CONSTANT__: - return 'Unknown error: %d' % code - if constant.name() == constant.description(): - # XXX: have constantine handle this fallback - # Fake constant or just lacks a description, fallback to Linux's - try: - from org.python.constantine.platform.linux import Errno as LinuxErrno - except ImportError: - from com.kenai.constantine.platform.linux import Errno as LinuxErrno - constant = getattr(LinuxErrno, constant.name(), None) - if not constant: - return 'Unknown error: %d' % code - return asPyString(constant.toString()) - def access(path, mode): """access(path, mode) -> True if granted, False otherwise @@ -201,75 +175,6 @@ result = False return result -def stat(path): - """stat(path) -> stat result - - Perform a stat system call on the given path. - - The Java stat implementation only returns a small subset of - the standard fields: size, modification time and change time. - """ - abs_path = sys.getPath(path) - try: - return _from_jnastat(_posix_impl.stat(abs_path)) - except NotImplementedError: - pass - f = File(abs_path) - if not f.exists(): - raise OSError(errno.ENOENT, strerror(errno.ENOENT), path) - size = f.length() - mtime = f.lastModified() / 1000.0 - mode = 0 - if f.isDirectory(): - mode = _stat.S_IFDIR - elif f.isFile(): - mode = _stat.S_IFREG - if f.canRead(): - mode = mode | _stat.S_IREAD - if f.canWrite(): - mode = mode | _stat.S_IWRITE - return stat_result((mode, 0, 0, 0, 0, 0, size, mtime, mtime, 0)) - -def lstat(path): - """lstat(path) -> stat result - - Like stat(path), but do not follow symbolic links. - """ - abs_path = sys.getPath(path) - try: - return _from_jnastat(_posix_impl.lstat(abs_path)) - except NotImplementedError: - pass - f = File(sys.getPath(path)) - # XXX: jna-posix implements similar link detection in - # JavaFileStat.calculateSymlink, fallback to that instead when not - # native - abs_parent = f.getAbsoluteFile().getParentFile() - if not abs_parent: - # root isn't a link - return stat(path) - can_parent = abs_parent.getCanonicalFile() - - if can_parent.getAbsolutePath() == abs_parent.getAbsolutePath(): - # The parent directory's absolute path is canonical.. - if f.getAbsolutePath() != f.getCanonicalPath(): - # but the file's absolute and canonical paths differ (a - # link) - return stat_result((_stat.S_IFLNK, 0, 0, 0, 0, 0, 0, 0, 0, 0)) - - # The parent directory's path is not canonical (one of the parent - # directories is a symlink). Build a new path with the parent's - # canonical path and compare the files - f = File(can_parent.getAbsolutePath(), f.getName()) - if f.getAbsolutePath() != f.getCanonicalPath(): - return stat_result((_stat.S_IFLNK, 0, 0, 0, 0, 0, 0, 0, 0, 0)) - - # Not a link, only now can we determine if it exists (because - # File.exists() returns False for dead links) - if not f.exists(): - raise OSError(errno.ENOENT, strerror(errno.ENOENT), path) - return stat(path) - def utime(path, times): """utime(path, (atime, mtime)) utime(path, None) @@ -723,13 +628,3 @@ buffer = jarray.zeros(n, 'b') urandom_source.nextBytes(buffer) return buffer.tostring() - -def _from_jnastat(s): - results = [] - for meth in (s.mode, s.ino, s.dev, s.nlink, s.uid, s.gid, s.st_size, - s.atime, s.mtime, s.ctime): - try: - results.append(meth()) - except NotImplementedError: - results.append(0) - return stat_result(results) Modified: trunk/jython/Lib/test/test_fileno.py =================================================================== --- trunk/jython/Lib/test/test_fileno.py 2009-10-20 00:06:05 UTC (rev 6877) +++ trunk/jython/Lib/test/test_fileno.py 2009-10-20 00:20:58 UTC (rev 6878) @@ -327,7 +327,7 @@ except exc, val: if expected and str(val) != msg: raise test_support.TestFailed( - "Message %r, expected %r" % (str(value), msg)) + "Message %r, expected %r" % (str(val), msg)) else: raise test_support.TestFailed("Expected %s" % exc) Modified: trunk/jython/src/org/python/core/Py.java =================================================================== --- trunk/jython/src/org/python/core/Py.java 2009-10-20 00:06:05 UTC (rev 6877) +++ trunk/jython/src/org/python/core/Py.java 2009-10-20 00:20:58 UTC (rev 6878) @@ -27,6 +27,7 @@ import java.util.List; import org.python.core.adapter.ClassicPyObjectAdapter; import org.python.core.adapter.ExtensiblePyObjectAdapter; +import org.python.modules.posix.PosixModule; import org.python.util.Generic; public final class Py { @@ -104,7 +105,10 @@ } public static PyException OSError(Constant errno, String filename) { - PyObject args = new PyTuple(Py.newInteger(errno.value()), Py.newString(errno.toString()), + int value = errno.value(); + // Pass to strerror because constantine currently lacks Errno descriptions on + // Windows, and strerror falls back to Linux's + PyObject args = new PyTuple(Py.newInteger(value), PosixModule.strerror(value), Py.newString(filename)); return new PyException(Py.OSError, args); } @@ -171,12 +175,14 @@ } public static PyException IOError(Constant errno) { - PyObject args = new PyTuple(Py.newInteger(errno.value()), Py.newString(errno.toString())); + int value = errno.value(); + PyObject args = new PyTuple(Py.newInteger(value), PosixModule.strerror(value)); return new PyException(Py.IOError, args); } public static PyException IOError(Constant errno, String filename) { - PyObject args = new PyTuple(Py.newInteger(errno.value()), Py.newString(errno.toString()), + int value = errno.value(); + PyObject args = new PyTuple(Py.newInteger(value), PosixModule.strerror(value), Py.newString(filename)); return new PyException(Py.IOError, args); } Modified: trunk/jython/src/org/python/modules/posix/PosixModule.java =================================================================== --- trunk/jython/src/org/python/modules/posix/PosixModule.java 2009-10-20 00:06:05 UTC (rev 6877) +++ trunk/jython/src/org/python/modules/posix/PosixModule.java 2009-10-20 00:20:58 UTC (rev 6878) @@ -1,7 +1,9 @@ /* Copyright (c) Jython Developers */ package org.python.modules.posix; +import com.kenai.constantine.Constant; import com.kenai.constantine.ConstantSet; +import com.kenai.constantine.platform.Errno; import org.jruby.ext.posix.JavaPOSIX; import org.jruby.ext.posix.POSIX; @@ -70,6 +72,39 @@ dict.__setitem__("__all__", dict.invoke("keys")); } + public static PyString __doc__lstat = new PyString( + "lstat(path) -> stat result\n\n" + + "Like stat(path), but do not follow symbolic links."); + public static PyObject lstat(String path) { + return PyStatResult.fromFileStat(posix.lstat(Py.getSystemState().getPath(path))); + } + + public static PyString __doc__stat = new PyString( + "stat(path) -> stat result\n\n" + + "Perform a stat system call on the given path.\n\n" + + "Note that some platforms may return only a small subset of the\n" + + "standard fields"); + public static PyObject stat(String path) { + return PyStatResult.fromFileStat(posix.stat(Py.getSystemState().getPath(path))); + } + + public static PyString __doc__strerror = new PyString( + "strerror(code) -> string\n\n" + + "Translate an error code to a message string."); + public static PyObject strerror(int code) { + Constant errno = Errno.valueOf(code); + if (errno == Errno.__UNKNOWN_CONSTANT__) { + return new PyString("Unknown error: " + code); + } + if (errno.name() == errno.toString()) { + // Fake constant or just lacks a description, fallback to Linux's + // XXX: have constantine handle this fallback + errno = Enum.valueOf(com.kenai.constantine.platform.linux.Errno.class, + errno.name()); + } + return new PyString(errno.toString()); + } + /** * Helper function for the subprocess module, returns the potential shell commands for * this OS. Modified: trunk/jython/src/org/python/modules/posix/PyStatResult.java =================================================================== --- trunk/jython/src/org/python/modules/posix/PyStatResult.java 2009-10-20 00:06:05 UTC (rev 6877) +++ trunk/jython/src/org/python/modules/posix/PyStatResult.java 2009-10-20 00:20:58 UTC (rev 6878) @@ -1,11 +1,7 @@ /* Copyright (c) Jython Developers */ package org.python.modules.posix; -import org.python.expose.ExposedGet; -import org.python.expose.ExposedMethod; -import org.python.expose.ExposedNew; -import org.python.expose.ExposedType; -import org.python.expose.MethodType; +import org.jruby.ext.posix.FileStat; import org.python.core.ArgParser; import org.python.core.Py; @@ -15,6 +11,12 @@ import org.python.core.PyTuple; import org.python.core.PyType; +import org.python.expose.ExposedGet; +import org.python.expose.ExposedMethod; +import org.python.expose.ExposedNew; +import org.python.expose.ExposedType; +import org.python.expose.MethodType; + @ExposedType(name = "posix.stat_result", isBaseType = false) public class PyStatResult extends PyTuple { @@ -66,6 +68,17 @@ } } + /** + * Return a Python stat result from a posix layer FileStat object. + */ + public static PyStatResult fromFileStat(FileStat stat) { + return new PyStatResult(Py.newInteger(stat.mode()), Py.newLong(stat.ino()), + Py.newLong(stat.dev()), Py.newInteger(stat.nlink()), + Py.newInteger(stat.uid()), Py.newInteger(stat.gid()), + Py.newLong(stat.st_size()), Py.newLong(stat.atime()), + Py.newLong(stat.mtime()), Py.newLong(stat.ctime())); + } + @Override public synchronized PyObject __eq__(PyObject o) { return stat_result___eq__(o); Modified: trunk/jython/src/org/python/modules/posix/PythonPOSIXHandler.java =================================================================== --- trunk/jython/src/org/python/modules/posix/PythonPOSIXHandler.java 2009-10-20 00:06:05 UTC (rev 6877) +++ trunk/jython/src/org/python/modules/posix/PythonPOSIXHandler.java 2009-10-20 00:20:58 UTC (rev 6878) @@ -31,6 +31,10 @@ } public void unimplementedError(String methodName) { + if (methodName.startsWith("stat.")) { + // Ignore unimplemented FileStat methods + return; + } throw Py.NotImplementedError(methodName); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |