From jython-checkins at python.org Sat Dec 10 02:07:09 2011 From: jython-checkins at python.org (philip.jenvey) Date: Sat, 10 Dec 2011 02:07:09 +0100 Subject: [Jython-checkins] =?utf8?q?jython=3A_remove_the_old_OS/IOError_me?= =?utf8?q?thods?= Message-ID: http://hg.python.org/jython/rev/0db163c83774 changeset: 6287:0db163c83774 user: Philip Jenvey date: Fri Dec 09 17:06:13 2011 -0800 summary: remove the old OS/IOError methods files: src/org/python/core/Py.java | 16 --------------- src/org/python/modules/cStringIO.java | 2 +- 2 files changed, 1 insertions(+), 17 deletions(-) diff --git a/src/org/python/core/Py.java b/src/org/python/core/Py.java --- a/src/org/python/core/Py.java +++ b/src/org/python/core/Py.java @@ -128,14 +128,6 @@ return new PyException(Py.OSError, args); } - /** - * @deprecated As of Jython 2.5.3, use {@link #OSerror(Constant, PyObject)} instead. - */ - @Deprecated - public static PyException OSError(Constant errno, String filename) { - return OSError(errno, Py.newString(filename)); - } - public static PyObject NotImplementedError; public static PyException NotImplementedError(String message) { return new PyException(Py.NotImplementedError, message); @@ -200,14 +192,6 @@ return new PyException(Py.IOError, args); } - /** - * @deprecated As of Jython 2.5.3, use {@link #IOError(Constant, PyObject)} instead. - */ - @Deprecated - public static PyException IOError(Constant errno, String filename) { - return IOError(errno, Py.newString(filename)); - } - private static PyException fromIOException(IOException ioe, PyObject err) { String message = ioe.getMessage(); if (message == null) { diff --git a/src/org/python/modules/cStringIO.java b/src/org/python/modules/cStringIO.java --- a/src/org/python/modules/cStringIO.java +++ b/src/org/python/modules/cStringIO.java @@ -308,7 +308,7 @@ */ public synchronized void truncate(long pos) { if (pos < 0) { - throw Py.IOError(Errno.EINVAL, "Negative size not allowed"); + throw Py.IOError("Negative size not allowed"); } int pos_int = _convert_to_int(pos); if (pos_int < 0) -- Repository URL: http://hg.python.org/jython From jython-checkins at python.org Sat Dec 10 02:07:09 2011 From: jython-checkins at python.org (philip.jenvey) Date: Sat, 10 Dec 2011 02:07:09 +0100 Subject: [Jython-checkins] =?utf8?q?jython_=28merge_2=2E5_-=3E_default=29?= =?utf8?q?=3A_merge_w/_2=2E5?= Message-ID: http://hg.python.org/jython/rev/d70e1a817a61 changeset: 6286:d70e1a817a61 parent: 6284:99821530273c parent: 6285:32b8ace8ef6d user: Philip Jenvey date: Fri Dec 09 17:05:23 2011 -0800 summary: merge w/ 2.5 files: Lib/test/test_chdir.py | 26 +- Lib/test/test_file_jy.py | 10 + Lib/test/test_os_jy.py | 22 + NEWS | 1 + src/org/python/core/Py.java | 28 +- src/org/python/core/PyFile.java | 2 +- src/org/python/core/io/FileIO.java | 12 +- src/org/python/modules/_py_compile.java | 2 +- src/org/python/modules/posix/PosixModule.java | 145 ++++----- src/org/python/modules/posix/PythonPOSIXHandler.java | 4 +- 10 files changed, 158 insertions(+), 94 deletions(-) diff --git a/Lib/test/test_chdir.py b/Lib/test/test_chdir.py --- a/Lib/test/test_chdir.py +++ b/Lib/test/test_chdir.py @@ -569,6 +569,29 @@ os.path.getatime(self.basename1)) +class SymlinkTestCase(BaseChdirTestCase): + + TEST_DIRS = 2 + + def setUp(self): + super(SymlinkTestCase, self).setUp() + self.relsrc = 'src' + self.src = os.path.join(self.dir1, self.relsrc) + self.link = os.path.join(self.dir2, 'link') + + def test_symlink_src_is_relative(self): + write(self.src, 'foo') + # Ensure that linking to os.path.basename(self.src) creates a + # dead link (since it lives in a different dir) + os.symlink(self.relsrc, self.link) + # If the cwd (self.dir1) was applied to os.link's src arg then + # the link would not be dead + self.assertTrue(self.is_dead_link(self.link)) + + def is_dead_link(self, link): + return os.path.lexists(link) and not os.path.exists(link) + + class ImportJavaClassTestCase(BaseChdirTestCase): SYSPATH = ('',) @@ -685,7 +708,8 @@ ExecfileTracebackTestCase, ListdirTestCase, DirsTestCase, - FilesTestCase] + FilesTestCase, + SymlinkTestCase] if WINDOWS: tests.append(WindowsChdirTestCase) if test_support.is_jython: diff --git a/Lib/test/test_file_jy.py b/Lib/test/test_file_jy.py --- a/Lib/test/test_file_jy.py +++ b/Lib/test/test_file_jy.py @@ -33,6 +33,16 @@ fp.seek(0) self.assertEqual(fp.read(), 'test1\n') + def test_issue1825(self): + testfnu = unicode(test_support.TESTFN) + try: + open(testfnu) + except IOError, e: + self.assertTrue(isinstance(e.filename, unicode)) + self.assertEqual(e.filename, testfnu) + else: + self.assertTrue(False) + def test_main(): test_support.run_unittest(FileTestCase) diff --git a/Lib/test/test_os_jy.py b/Lib/test/test_os_jy.py --- a/Lib/test/test_os_jy.py +++ b/Lib/test/test_os_jy.py @@ -27,6 +27,28 @@ self.assertRaises(OSError, os.link, test_support.TESTFN, test_support.TESTFN) + def test_issue1825(self): + os.remove(test_support.TESTFN) + testfnu = unicode(test_support.TESTFN) + try: + os.open(testfnu, os.O_RDONLY) + except OSError, e: + self.assertTrue(isinstance(e.filename, unicode)) + self.assertEqual(e.filename, testfnu) + else: + self.assertTrue(False) + + # XXX: currently fail + #for fn in os.chdir, os.listdir, os.rmdir: + for fn in (os.rmdir,): + try: + fn(testfnu) + except OSError, e: + self.assertTrue(isinstance(e.filename, unicode)) + self.assertEqual(e.filename, testfnu) + else: + self.assertTrue(False) + def test_main(): test_support.run_unittest(OSTestCase) diff --git a/NEWS b/NEWS --- a/NEWS +++ b/NEWS @@ -12,6 +12,7 @@ - [ 1811 ] Recursive import bug w/ SQLAlchemy 0.7.3 - [ 1819 ] Incorrect handling of Java object toString methods returning null - [ 1824 ] os.link() can silently fail + - [ 1825 ] EnvironmentError.filename is `str` even if original name is `unicode` Jython 2.5.2 same as 2.5.2rc4 diff --git a/src/org/python/core/Py.java b/src/org/python/core/Py.java --- a/src/org/python/core/Py.java +++ b/src/org/python/core/Py.java @@ -120,15 +120,22 @@ return new PyException(Py.OSError, args); } - public static PyException OSError(Constant errno, String filename) { + public static PyException OSError(Constant errno, PyObject filename) { 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)); + PyObject args = new PyTuple(Py.newInteger(value), PosixModule.strerror(value), filename); return new PyException(Py.OSError, args); } + /** + * @deprecated As of Jython 2.5.3, use {@link #OSerror(Constant, PyObject)} instead. + */ + @Deprecated + public static PyException OSError(Constant errno, String filename) { + return OSError(errno, Py.newString(filename)); + } + public static PyObject NotImplementedError; public static PyException NotImplementedError(String message) { return new PyException(Py.NotImplementedError, message); @@ -187,11 +194,18 @@ return new PyException(Py.IOError, args); } + public static PyException IOError(Constant errno, PyObject filename) { + int value = errno.value(); + PyObject args = new PyTuple(Py.newInteger(value), PosixModule.strerror(value), filename); + return new PyException(Py.IOError, args); + } + + /** + * @deprecated As of Jython 2.5.3, use {@link #IOError(Constant, PyObject)} instead. + */ + @Deprecated public static PyException IOError(Constant errno, String filename) { - int value = errno.value(); - PyObject args = new PyTuple(Py.newInteger(value), PosixModule.strerror(value), - Py.newString(filename)); - return new PyException(Py.IOError, args); + return IOError(errno, Py.newString(filename)); } private static PyException fromIOException(IOException ioe, PyObject err) { diff --git a/src/org/python/core/PyFile.java b/src/org/python/core/PyFile.java --- a/src/org/python/core/PyFile.java +++ b/src/org/python/core/PyFile.java @@ -147,7 +147,7 @@ } String mode = ap.getString(1, "r"); int bufsize = ap.getInt(2, -1); - file___init__(new FileIO(name.toString(), parseMode(mode)), name, mode, bufsize); + file___init__(new FileIO((PyString) name, parseMode(mode)), name, mode, bufsize); closer = new Closer(file, Py.getSystemState()); } diff --git a/src/org/python/core/io/FileIO.java b/src/org/python/core/io/FileIO.java --- a/src/org/python/core/io/FileIO.java +++ b/src/org/python/core/io/FileIO.java @@ -15,6 +15,7 @@ import com.kenai.constantine.platform.Errno; import org.jruby.ext.posix.util.Platform; import org.python.core.Py; +import org.python.core.PyString; import org.python.core.util.RelativeFile; import org.python.modules.posix.PosixModule; @@ -50,6 +51,13 @@ private boolean emulateAppend; /** + * @see #FileIO(PyString name, String mode) + */ + public FileIO(String name, String mode) { + this(Py.newString(name), mode); + } + + /** * Construct a FileIO instance for the specified file name. * * The mode can be 'r', 'w' or 'a' for reading (default), writing @@ -59,9 +67,9 @@ * @param name the name of the file * @param mode a raw io file mode String */ - public FileIO(String name, String mode) { + public FileIO(PyString name, String mode) { parseMode(mode); - File absPath = new RelativeFile(name); + File absPath = new RelativeFile(name.toString()); try { if (appending && !(reading || plus)) { diff --git a/src/org/python/modules/_py_compile.java b/src/org/python/modules/_py_compile.java --- a/src/org/python/modules/_py_compile.java +++ b/src/org/python/modules/_py_compile.java @@ -21,7 +21,7 @@ File file = new File(filename); if (!file.exists()) { - throw Py.IOError(Errno.ENOENT, filename); + throw Py.IOError(Errno.ENOENT, Py.newString(filename)); } String name = getModuleName(file); diff --git a/src/org/python/modules/posix/PosixModule.java b/src/org/python/modules/posix/PosixModule.java --- a/src/org/python/modules/posix/PosixModule.java +++ b/src/org/python/modules/posix/PosixModule.java @@ -33,13 +33,13 @@ import org.python.core.PyList; import org.python.core.PyObject; import org.python.core.PyString; +import org.python.core.PySystemState; import org.python.core.PyTuple; import org.python.core.imp; import org.python.core.io.IOBase; import org.python.core.io.FileDescriptors; import org.python.core.io.FileIO; import org.python.core.io.RawIOBase; -import org.python.core.util.RelativeFile; import org.python.core.util.StringUtil; /** @@ -154,10 +154,10 @@ "be used in a suid/sgid environment to test if the invoking user has the\n" + "specified access to the path. The mode argument can be F_OK to test\n" + "existence, or the inclusive-OR of R_OK, W_OK, and X_OK."); - public static boolean access(String path, int mode) { - ensurePath(path); + public static boolean access(PyObject path, int mode) { + String absolutePath = absolutePath(path); + File file = new File(absolutePath); boolean result = true; - File file = new RelativeFile(path); if (!file.exists()) { result = false; @@ -171,7 +171,7 @@ if ((mode & X_OK) != 0) { // NOTE: always true without native jna-posix stat try { - result = posix.stat(file.getPath()).isExecutable(); + result = posix.stat(absolutePath).isExecutable(); } catch (PyException pye) { if (!pye.match(Py.OSError)) { throw pye; @@ -186,13 +186,7 @@ public static PyString __doc__chdir = new PyString( "chdir(path)\n\n" + "Change the current working directory to the specified path."); - public static void chdir(PyObject pathObj) { - if (!(pathObj instanceof PyString)) { - throw Py.TypeError(String.format("coercing to Unicode: need string, '%s' type found", - pathObj.getType().fastGetName())); - } - - String path = pathObj.toString(); + public static void chdir(PyObject path) { // stat raises ENOENT for us if path doesn't exist if (!posix.stat(absolutePath(path)).isDirectory()) { throw Py.OSError(Errno.ENOTDIR, path); @@ -201,13 +195,13 @@ if (realpath == null) { realpath = imp.load("os.path").__getattr__("realpath"); } - Py.getSystemState().setCurrentWorkingDir(realpath.__call__(pathObj).toString()); + Py.getSystemState().setCurrentWorkingDir(realpath.__call__(path).asString()); } public static PyString __doc__chmod = new PyString( "chmod(path, mode)\n\n" + "Change the access permissions of a file."); - public static void chmod(String path, int mode) { + public static void chmod(PyObject path, int mode) { if (posix.chmod(absolutePath(path), mode) < 0) { throw errorFromErrno(path); } @@ -217,7 +211,7 @@ "chown(path, uid, gid)\n\n" + "Change the owner and group id of path to the numeric uid and gid."); @Hide(OS.NT) - public static void chown(String path, int uid, int gid) { + public static void chown(PyObject path, int uid, int gid) { if (posix.chown(absolutePath(path), uid, gid) < 0) { throw errorFromErrno(path); } @@ -442,7 +436,7 @@ "Change the access permissions of a file. If path is a symlink, this\n" + "affects the link itself rather than the target."); @Hide(OS.NT) - public static void lchmod(String path, int mode) { + public static void lchmod(PyObject path, int mode) { if (posix.lchmod(absolutePath(path), mode) < 0) { throw errorFromErrno(path); } @@ -453,7 +447,7 @@ "Change the owner and group id of path to the numeric uid and gid.\n" + "This function will not follow symbolic links."); @Hide(OS.NT) - public static void lchown(String path, int uid, int gid) { + public static void lchown(PyObject path, int uid, int gid) { if (posix.lchown(absolutePath(path), uid, gid) < 0) { throw errorFromErrno(path); } @@ -463,7 +457,7 @@ "link(src, dst)\n\n" + "Create a hard link to a file."); @Hide(OS.NT) - public static void link(String src, String dst) { + public static void link(PyObject src, PyObject dst) { if (posix.link(absolutePath(src), absolutePath(dst)) < 0) { throw errorFromErrno(); } @@ -475,16 +469,15 @@ "path: path of directory to list\n\n" + "The list is in arbitrary order. It does not include the special\n" + "entries '.' and '..' even if they are present in the directory."); - public static PyList listdir(PyObject pathObj) { - ensurePath(pathObj); - String path = pathObj.asString(); - PyList list = new PyList(); - File file = new RelativeFile(path); + public static PyList listdir(PyObject path) { + String absolutePath = absolutePath(path); + File file = new File(absolutePath); String[] names = file.list(); + if (names == null) { // Can't read the path for some reason. stat will throw an error if it can't // read it either - FileStat stat = posix.stat(file.getPath()); + FileStat stat = posix.stat(absolutePath); // It exists, maybe not a dir, or we don't have permission? if (!stat.isDirectory()) { throw Py.OSError(Errno.ENOTDIR, path); @@ -495,7 +488,8 @@ throw Py.OSError("listdir(): an unknown error occured: " + path); } - PyString string = (PyString) pathObj; + PyList list = new PyList(); + PyString string = (PyString) path; for (String name : names) { list.append(string.createInstance(name)); } @@ -516,11 +510,11 @@ public static PyString __doc__mkdir = new PyString( "mkdir(path [, mode=0777])\n\n" + "Create a directory."); - public static void mkdir(String path) { + public static void mkdir(PyObject path) { mkdir(path, 0777); } - public static void mkdir(String path, int mode) { + public static void mkdir(PyObject path, int mode) { if (posix.mkdir(absolutePath(path), mode) < 0) { throw errorFromErrno(path); } @@ -530,12 +524,13 @@ "open(filename, flag [, mode=0777]) -> fd\n\n" + "Open a file (for low level IO).\n\n" + "Note that the mode argument is not currently supported on Jython."); - public static FileIO open(String path, int flag) { + public static FileIO open(PyObject path, int flag) { return open(path, flag, 0777); } - public static FileIO open(String path, int flag, int mode) { - ensurePath(path); + public static FileIO open(PyObject path, int flag, int mode) { + String absolutePath = absolutePath(path); + File file = new File(absolutePath); boolean reading = (flag & O_RDONLY) != 0; boolean writing = (flag & O_WRONLY) != 0; boolean updating = (flag & O_RDWR) != 0; @@ -544,7 +539,6 @@ boolean truncating = (flag & O_TRUNC) != 0; boolean exclusive = (flag & O_EXCL) != 0; boolean sync = (flag & O_SYNC) != 0; - File file = new RelativeFile(path); if (updating && writing) { throw Py.OSError(Errno.EINVAL, path); @@ -563,7 +557,7 @@ if (truncating && !writing) { // Explicitly truncate, writing will truncate anyway - new FileIO(path, "w").close(); + new FileIO((PyString) path, "w").close(); } if (exclusive && creating) { @@ -585,7 +579,7 @@ throw Py.OSError(file.isDirectory() ? Errno.EISDIR : Errno.ENOENT, path); } } - return new FileIO(path, fileIOMode); + return new FileIO((PyString) path, fileIOMode); } public static PyString __doc__popen = new PyString( @@ -623,7 +617,7 @@ "readlink(path) -> path\n\n" + "Return a string representing the path to which the symbolic link points."); @Hide(OS.NT) - public static String readlink(String path) { + public static String readlink(PyObject path) { try { return posix.readlink(absolutePath(path)); } catch (IOException ioe) { @@ -634,15 +628,15 @@ public static PyString __doc__remove = new PyString( "remove(path)\n\n" + "Remove a file (same as unlink(path))."); - public static void remove(String path) { + public static void remove(PyObject path) { unlink(path); } public static PyString __doc__rename = new PyString( "rename(old, new)\n\n" + "Rename a file or directory."); - public static void rename(String oldpath, String newpath) { - if (!new RelativeFile(oldpath).renameTo(new RelativeFile(newpath))) { + public static void rename(PyObject oldpath, PyObject newpath) { + if (!new File(absolutePath(oldpath)).renameTo(new File(absolutePath(newpath)))) { PyObject args = new PyTuple(Py.Zero, new PyString("Couldn't rename file")); throw new PyException(Py.OSError, args); } @@ -651,15 +645,15 @@ public static PyString __doc__rmdir = new PyString( "rmdir(path)\n\n" + "Remove a directory."); - public static void rmdir(String path) { - File file = new RelativeFile(path); + public static void rmdir(PyObject path) { + File file = new File(absolutePath(path)); if (!file.exists()) { throw Py.OSError(Errno.ENOENT, path); } else if (!file.isDirectory()) { throw Py.OSError(Errno.ENOTDIR, path); } else if (!file.delete()) { PyObject args = new PyTuple(Py.Zero, new PyString("Couldn't delete directory"), - new PyString(path)); + path); throw new PyException(Py.OSError, args); } } @@ -705,9 +699,8 @@ "symlink(src, dst)\n\n" + "Create a symbolic link pointing to src named dst."); @Hide(OS.NT) - public static void symlink(String src, String dst) { - ensurePath(src); - if (posix.symlink(src, absolutePath(dst)) < 0) { + public static void symlink(PyObject src, PyObject dst) { + if (posix.symlink(asPath(src), absolutePath(dst)) < 0) { throw errorFromErrno(); } } @@ -732,12 +725,12 @@ public static PyString __doc__unlink = new PyString( "unlink(path)\n\n" + "Remove a file (same as remove(path))."); - public static void unlink(String path) { - ensurePath(path); - File file = new RelativeFile(path); + public static void unlink(PyObject path) { + String absolutePath = absolutePath(path); + File file = new File(absolutePath); if (!file.delete()) { // Something went wrong, does stat raise an error? - posix.stat(absolutePath(path)); + posix.stat(absolutePath); // It exists, is it a directory, or do we not have permissions? if (file.isDirectory()) { throw Py.OSError(Errno.EISDIR, path); @@ -745,7 +738,7 @@ if (!file.canWrite()) { throw Py.OSError(Errno.EPERM, path); } - throw Py.OSError("unlink(): an unknown error occured: " + path); + throw Py.OSError("unlink(): an unknown error occured" + absolutePath); } } @@ -754,7 +747,7 @@ "utime(path, None)\n\n" + "Set the access and modified time of the file to the given values. If the\n" + "second form is used, set the access and modified times to the current time."); - public static void utime(String path, PyObject times) { + public static void utime(PyObject path, PyObject times) { long[] atimeval; long[] mtimeval; @@ -891,27 +884,27 @@ } /** + * Return a path as a String from a PyObject + * + * @param path a PyObject, raising a TypeError if an invalid path type + * @return a String path + */ + private static String asPath(PyObject path) { + if (path instanceof PyString) { + return path.toString(); + } + throw Py.TypeError(String.format("coercing to Unicode: need string, %s type found", + path.getType().fastGetName())); + } + + /** * Return the absolute form of path. * - * @param path a path String, raising a TypeError when null + * @param path a PyObject, raising a TypeError if an invalid path type * @return an absolute path String */ - private static String absolutePath(String path) { - ensurePath(path); - return new RelativeFile(path).getPath(); - } - - private static void ensurePath(PyObject path) { - if (!(path instanceof PyString)) { - throw Py.TypeError(String.format("coercing to Unicode: need string, %s type found", - path.getType().fastGetName())); - } - } - - private static void ensurePath(String path) { - if (path == null) { - throw Py.TypeError("coercing to Unicode: need string or buffer, NoneType found"); - } + private static String absolutePath(PyObject path) { + return PySystemState.getPathLazy(asPath(path)); } private static PyException badFD() { @@ -922,7 +915,7 @@ return Py.OSError(Errno.valueOf(posix.errno())); } - private static PyException errorFromErrno(String path) { + private static PyException errorFromErrno(PyObject path) { return Py.OSError(Errno.valueOf(posix.errno()), path); } @@ -942,13 +935,8 @@ } @Override - public PyObject __call__(PyObject pathObj) { - if (!(pathObj instanceof PyString)) { - throw Py.TypeError(String.format("coercing to Unicode: need string or buffer, %s " + - "found", pathObj.getType().fastGetName())); - } - String absolutePath = absolutePath(pathObj.toString()); - return PyStatResult.fromFileStat(posix.lstat(absolutePath)); + public PyObject __call__(PyObject path) { + return PyStatResult.fromFileStat(posix.lstat(absolutePath(path))); } } @@ -962,13 +950,8 @@ } @Override - public PyObject __call__(PyObject pathObj) { - if (!(pathObj instanceof PyString)) { - throw Py.TypeError(String.format("coercing to Unicode: need string or buffer, %s " + - "found", pathObj.getType().fastGetName())); - } - String absolutePath = absolutePath(pathObj.toString()); - return PyStatResult.fromFileStat(posix.stat(absolutePath)); + public PyObject __call__(PyObject path) { + return PyStatResult.fromFileStat(posix.stat(absolutePath(path))); } } } diff --git a/src/org/python/modules/posix/PythonPOSIXHandler.java b/src/org/python/modules/posix/PythonPOSIXHandler.java --- a/src/org/python/modules/posix/PythonPOSIXHandler.java +++ b/src/org/python/modules/posix/PythonPOSIXHandler.java @@ -21,7 +21,9 @@ public class PythonPOSIXHandler implements POSIXHandler { public void error(Errno error, String extraData) { - throw Py.OSError(error, extraData); + // XXX: extraData (filename) could have been unicode! + // http://bugs.jython.org/issue1825 + throw Py.OSError(error, Py.newString(extraData)); } public void unimplementedError(String methodName) { -- Repository URL: http://hg.python.org/jython From jython-checkins at python.org Sat Dec 10 02:07:09 2011 From: jython-checkins at python.org (philip.jenvey) Date: Sat, 10 Dec 2011 02:07:09 +0100 Subject: [Jython-checkins] =?utf8?b?anl0aG9uICgyLjUpOiAjMTgyNTogZml4IEVu?= =?utf8?q?vironmentError=2Efilename_being_str_when_the_orig_path_was_unico?= =?utf8?q?de?= Message-ID: http://hg.python.org/jython/rev/32b8ace8ef6d changeset: 6285:32b8ace8ef6d branch: 2.5 parent: 6283:ef1eb2bc70f5 user: Philip Jenvey date: Fri Dec 09 15:43:18 2011 -0800 summary: #1825: fix EnvironmentError.filename being str when the orig path was unicode in open and some os module functions cleanup PosixModule, RelativeFile was confusing here files: Lib/test/test_chdir.py | 26 +- Lib/test/test_file_jy.py | 10 + Lib/test/test_os_jy.py | 22 + NEWS | 1 + src/org/python/core/Py.java | 28 +- src/org/python/core/PyFile.java | 2 +- src/org/python/core/io/FileIO.java | 12 +- src/org/python/modules/_py_compile.java | 2 +- src/org/python/modules/posix/PosixModule.java | 145 ++++----- src/org/python/modules/posix/PythonPOSIXHandler.java | 4 +- 10 files changed, 158 insertions(+), 94 deletions(-) diff --git a/Lib/test/test_chdir.py b/Lib/test/test_chdir.py --- a/Lib/test/test_chdir.py +++ b/Lib/test/test_chdir.py @@ -569,6 +569,29 @@ os.path.getatime(self.basename1)) +class SymlinkTestCase(BaseChdirTestCase): + + TEST_DIRS = 2 + + def setUp(self): + super(SymlinkTestCase, self).setUp() + self.relsrc = 'src' + self.src = os.path.join(self.dir1, self.relsrc) + self.link = os.path.join(self.dir2, 'link') + + def test_symlink_src_is_relative(self): + write(self.src, 'foo') + # Ensure that linking to os.path.basename(self.src) creates a + # dead link (since it lives in a different dir) + os.symlink(self.relsrc, self.link) + # If the cwd (self.dir1) was applied to os.link's src arg then + # the link would not be dead + self.assertTrue(self.is_dead_link(self.link)) + + def is_dead_link(self, link): + return os.path.lexists(link) and not os.path.exists(link) + + class ImportJavaClassTestCase(BaseChdirTestCase): SYSPATH = ('',) @@ -685,7 +708,8 @@ ExecfileTracebackTestCase, ListdirTestCase, DirsTestCase, - FilesTestCase] + FilesTestCase, + SymlinkTestCase] if WINDOWS: tests.append(WindowsChdirTestCase) if test_support.is_jython: diff --git a/Lib/test/test_file_jy.py b/Lib/test/test_file_jy.py --- a/Lib/test/test_file_jy.py +++ b/Lib/test/test_file_jy.py @@ -33,6 +33,16 @@ fp.seek(0) self.assertEqual(fp.read(), 'test1\n') + def test_issue1825(self): + testfnu = unicode(test_support.TESTFN) + try: + open(testfnu) + except IOError, e: + self.assertTrue(isinstance(e.filename, unicode)) + self.assertEqual(e.filename, testfnu) + else: + self.assertTrue(False) + def test_main(): test_support.run_unittest(FileTestCase) diff --git a/Lib/test/test_os_jy.py b/Lib/test/test_os_jy.py --- a/Lib/test/test_os_jy.py +++ b/Lib/test/test_os_jy.py @@ -27,6 +27,28 @@ self.assertRaises(OSError, os.link, test_support.TESTFN, test_support.TESTFN) + def test_issue1825(self): + os.remove(test_support.TESTFN) + testfnu = unicode(test_support.TESTFN) + try: + os.open(testfnu, os.O_RDONLY) + except OSError, e: + self.assertTrue(isinstance(e.filename, unicode)) + self.assertEqual(e.filename, testfnu) + else: + self.assertTrue(False) + + # XXX: currently fail + #for fn in os.chdir, os.listdir, os.rmdir: + for fn in (os.rmdir,): + try: + fn(testfnu) + except OSError, e: + self.assertTrue(isinstance(e.filename, unicode)) + self.assertEqual(e.filename, testfnu) + else: + self.assertTrue(False) + def test_main(): test_support.run_unittest(OSTestCase) diff --git a/NEWS b/NEWS --- a/NEWS +++ b/NEWS @@ -12,6 +12,7 @@ - [ 1811 ] Recursive import bug w/ SQLAlchemy 0.7.3 - [ 1819 ] Incorrect handling of Java object toString methods returning null - [ 1824 ] os.link() can silently fail + - [ 1825 ] EnvironmentError.filename is `str` even if original name is `unicode` Jython 2.5.2 same as 2.5.2rc4 diff --git a/src/org/python/core/Py.java b/src/org/python/core/Py.java --- a/src/org/python/core/Py.java +++ b/src/org/python/core/Py.java @@ -114,15 +114,22 @@ return new PyException(Py.OSError, args); } - public static PyException OSError(Constant errno, String filename) { + public static PyException OSError(Constant errno, PyObject filename) { 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)); + PyObject args = new PyTuple(Py.newInteger(value), PosixModule.strerror(value), filename); return new PyException(Py.OSError, args); } + /** + * @deprecated As of Jython 2.5.3, use {@link #OSerror(Constant, PyObject)} instead. + */ + @Deprecated + public static PyException OSError(Constant errno, String filename) { + return OSError(errno, Py.newString(filename)); + } + public static PyObject NotImplementedError; public static PyException NotImplementedError(String message) { return new PyException(Py.NotImplementedError, message); @@ -181,11 +188,18 @@ return new PyException(Py.IOError, args); } + public static PyException IOError(Constant errno, PyObject filename) { + int value = errno.value(); + PyObject args = new PyTuple(Py.newInteger(value), PosixModule.strerror(value), filename); + return new PyException(Py.IOError, args); + } + + /** + * @deprecated As of Jython 2.5.3, use {@link #IOError(Constant, PyObject)} instead. + */ + @Deprecated public static PyException IOError(Constant errno, String filename) { - int value = errno.value(); - PyObject args = new PyTuple(Py.newInteger(value), PosixModule.strerror(value), - Py.newString(filename)); - return new PyException(Py.IOError, args); + return IOError(errno, Py.newString(filename)); } private static PyException fromIOException(IOException ioe, PyObject err) { diff --git a/src/org/python/core/PyFile.java b/src/org/python/core/PyFile.java --- a/src/org/python/core/PyFile.java +++ b/src/org/python/core/PyFile.java @@ -147,7 +147,7 @@ } String mode = ap.getString(1, "r"); int bufsize = ap.getInt(2, -1); - file___init__(new FileIO(name.toString(), parseMode(mode)), name, mode, bufsize); + file___init__(new FileIO((PyString) name, parseMode(mode)), name, mode, bufsize); closer = new Closer(file, Py.getSystemState()); } diff --git a/src/org/python/core/io/FileIO.java b/src/org/python/core/io/FileIO.java --- a/src/org/python/core/io/FileIO.java +++ b/src/org/python/core/io/FileIO.java @@ -15,6 +15,7 @@ import com.kenai.constantine.platform.Errno; import org.jruby.ext.posix.util.Platform; import org.python.core.Py; +import org.python.core.PyString; import org.python.core.util.RelativeFile; import org.python.modules.posix.PosixModule; @@ -50,6 +51,13 @@ private boolean emulateAppend; /** + * @see #FileIO(PyString name, String mode) + */ + public FileIO(String name, String mode) { + this(Py.newString(name), mode); + } + + /** * Construct a FileIO instance for the specified file name. * * The mode can be 'r', 'w' or 'a' for reading (default), writing @@ -59,9 +67,9 @@ * @param name the name of the file * @param mode a raw io file mode String */ - public FileIO(String name, String mode) { + public FileIO(PyString name, String mode) { parseMode(mode); - File absPath = new RelativeFile(name); + File absPath = new RelativeFile(name.toString()); try { if (appending && !(reading || plus)) { diff --git a/src/org/python/modules/_py_compile.java b/src/org/python/modules/_py_compile.java --- a/src/org/python/modules/_py_compile.java +++ b/src/org/python/modules/_py_compile.java @@ -21,7 +21,7 @@ File file = new File(filename); if (!file.exists()) { - throw Py.IOError(Errno.ENOENT, filename); + throw Py.IOError(Errno.ENOENT, Py.newString(filename)); } String name = getModuleName(file); diff --git a/src/org/python/modules/posix/PosixModule.java b/src/org/python/modules/posix/PosixModule.java --- a/src/org/python/modules/posix/PosixModule.java +++ b/src/org/python/modules/posix/PosixModule.java @@ -33,13 +33,13 @@ import org.python.core.PyList; import org.python.core.PyObject; import org.python.core.PyString; +import org.python.core.PySystemState; import org.python.core.PyTuple; import org.python.core.imp; import org.python.core.io.IOBase; import org.python.core.io.FileDescriptors; import org.python.core.io.FileIO; import org.python.core.io.RawIOBase; -import org.python.core.util.RelativeFile; import org.python.core.util.StringUtil; /** @@ -154,10 +154,10 @@ "be used in a suid/sgid environment to test if the invoking user has the\n" + "specified access to the path. The mode argument can be F_OK to test\n" + "existence, or the inclusive-OR of R_OK, W_OK, and X_OK."); - public static boolean access(String path, int mode) { - ensurePath(path); + public static boolean access(PyObject path, int mode) { + String absolutePath = absolutePath(path); + File file = new File(absolutePath); boolean result = true; - File file = new RelativeFile(path); if (!file.exists()) { result = false; @@ -171,7 +171,7 @@ if ((mode & X_OK) != 0) { // NOTE: always true without native jna-posix stat try { - result = posix.stat(file.getPath()).isExecutable(); + result = posix.stat(absolutePath).isExecutable(); } catch (PyException pye) { if (!pye.match(Py.OSError)) { throw pye; @@ -186,13 +186,7 @@ public static PyString __doc__chdir = new PyString( "chdir(path)\n\n" + "Change the current working directory to the specified path."); - public static void chdir(PyObject pathObj) { - if (!(pathObj instanceof PyString)) { - throw Py.TypeError(String.format("coercing to Unicode: need string, '%s' type found", - pathObj.getType().fastGetName())); - } - - String path = pathObj.toString(); + public static void chdir(PyObject path) { // stat raises ENOENT for us if path doesn't exist if (!posix.stat(absolutePath(path)).isDirectory()) { throw Py.OSError(Errno.ENOTDIR, path); @@ -201,13 +195,13 @@ if (realpath == null) { realpath = imp.load("os.path").__getattr__("realpath"); } - Py.getSystemState().setCurrentWorkingDir(realpath.__call__(pathObj).toString()); + Py.getSystemState().setCurrentWorkingDir(realpath.__call__(path).asString()); } public static PyString __doc__chmod = new PyString( "chmod(path, mode)\n\n" + "Change the access permissions of a file."); - public static void chmod(String path, int mode) { + public static void chmod(PyObject path, int mode) { if (posix.chmod(absolutePath(path), mode) < 0) { throw errorFromErrno(path); } @@ -217,7 +211,7 @@ "chown(path, uid, gid)\n\n" + "Change the owner and group id of path to the numeric uid and gid."); @Hide(OS.NT) - public static void chown(String path, int uid, int gid) { + public static void chown(PyObject path, int uid, int gid) { if (posix.chown(absolutePath(path), uid, gid) < 0) { throw errorFromErrno(path); } @@ -442,7 +436,7 @@ "Change the access permissions of a file. If path is a symlink, this\n" + "affects the link itself rather than the target."); @Hide(OS.NT) - public static void lchmod(String path, int mode) { + public static void lchmod(PyObject path, int mode) { if (posix.lchmod(absolutePath(path), mode) < 0) { throw errorFromErrno(path); } @@ -453,7 +447,7 @@ "Change the owner and group id of path to the numeric uid and gid.\n" + "This function will not follow symbolic links."); @Hide(OS.NT) - public static void lchown(String path, int uid, int gid) { + public static void lchown(PyObject path, int uid, int gid) { if (posix.lchown(absolutePath(path), uid, gid) < 0) { throw errorFromErrno(path); } @@ -463,7 +457,7 @@ "link(src, dst)\n\n" + "Create a hard link to a file."); @Hide(OS.NT) - public static void link(String src, String dst) { + public static void link(PyObject src, PyObject dst) { if (posix.link(absolutePath(src), absolutePath(dst)) < 0) { throw errorFromErrno(); } @@ -475,16 +469,15 @@ "path: path of directory to list\n\n" + "The list is in arbitrary order. It does not include the special\n" + "entries '.' and '..' even if they are present in the directory."); - public static PyList listdir(PyObject pathObj) { - ensurePath(pathObj); - String path = pathObj.asString(); - PyList list = new PyList(); - File file = new RelativeFile(path); + public static PyList listdir(PyObject path) { + String absolutePath = absolutePath(path); + File file = new File(absolutePath); String[] names = file.list(); + if (names == null) { // Can't read the path for some reason. stat will throw an error if it can't // read it either - FileStat stat = posix.stat(file.getPath()); + FileStat stat = posix.stat(absolutePath); // It exists, maybe not a dir, or we don't have permission? if (!stat.isDirectory()) { throw Py.OSError(Errno.ENOTDIR, path); @@ -495,7 +488,8 @@ throw Py.OSError("listdir(): an unknown error occured: " + path); } - PyString string = (PyString) pathObj; + PyList list = new PyList(); + PyString string = (PyString) path; for (String name : names) { list.append(string.createInstance(name)); } @@ -516,11 +510,11 @@ public static PyString __doc__mkdir = new PyString( "mkdir(path [, mode=0777])\n\n" + "Create a directory."); - public static void mkdir(String path) { + public static void mkdir(PyObject path) { mkdir(path, 0777); } - public static void mkdir(String path, int mode) { + public static void mkdir(PyObject path, int mode) { if (posix.mkdir(absolutePath(path), mode) < 0) { throw errorFromErrno(path); } @@ -530,12 +524,13 @@ "open(filename, flag [, mode=0777]) -> fd\n\n" + "Open a file (for low level IO).\n\n" + "Note that the mode argument is not currently supported on Jython."); - public static FileIO open(String path, int flag) { + public static FileIO open(PyObject path, int flag) { return open(path, flag, 0777); } - public static FileIO open(String path, int flag, int mode) { - ensurePath(path); + public static FileIO open(PyObject path, int flag, int mode) { + String absolutePath = absolutePath(path); + File file = new File(absolutePath); boolean reading = (flag & O_RDONLY) != 0; boolean writing = (flag & O_WRONLY) != 0; boolean updating = (flag & O_RDWR) != 0; @@ -544,7 +539,6 @@ boolean truncating = (flag & O_TRUNC) != 0; boolean exclusive = (flag & O_EXCL) != 0; boolean sync = (flag & O_SYNC) != 0; - File file = new RelativeFile(path); if (updating && writing) { throw Py.OSError(Errno.EINVAL, path); @@ -563,7 +557,7 @@ if (truncating && !writing) { // Explicitly truncate, writing will truncate anyway - new FileIO(path, "w").close(); + new FileIO((PyString) path, "w").close(); } if (exclusive && creating) { @@ -585,7 +579,7 @@ throw Py.OSError(file.isDirectory() ? Errno.EISDIR : Errno.ENOENT, path); } } - return new FileIO(path, fileIOMode); + return new FileIO((PyString) path, fileIOMode); } public static PyString __doc__popen = new PyString( @@ -623,7 +617,7 @@ "readlink(path) -> path\n\n" + "Return a string representing the path to which the symbolic link points."); @Hide(OS.NT) - public static String readlink(String path) { + public static String readlink(PyObject path) { try { return posix.readlink(absolutePath(path)); } catch (IOException ioe) { @@ -634,15 +628,15 @@ public static PyString __doc__remove = new PyString( "remove(path)\n\n" + "Remove a file (same as unlink(path))."); - public static void remove(String path) { + public static void remove(PyObject path) { unlink(path); } public static PyString __doc__rename = new PyString( "rename(old, new)\n\n" + "Rename a file or directory."); - public static void rename(String oldpath, String newpath) { - if (!new RelativeFile(oldpath).renameTo(new RelativeFile(newpath))) { + public static void rename(PyObject oldpath, PyObject newpath) { + if (!new File(absolutePath(oldpath)).renameTo(new File(absolutePath(newpath)))) { PyObject args = new PyTuple(Py.Zero, new PyString("Couldn't rename file")); throw new PyException(Py.OSError, args); } @@ -651,15 +645,15 @@ public static PyString __doc__rmdir = new PyString( "rmdir(path)\n\n" + "Remove a directory."); - public static void rmdir(String path) { - File file = new RelativeFile(path); + public static void rmdir(PyObject path) { + File file = new File(absolutePath(path)); if (!file.exists()) { throw Py.OSError(Errno.ENOENT, path); } else if (!file.isDirectory()) { throw Py.OSError(Errno.ENOTDIR, path); } else if (!file.delete()) { PyObject args = new PyTuple(Py.Zero, new PyString("Couldn't delete directory"), - new PyString(path)); + path); throw new PyException(Py.OSError, args); } } @@ -705,9 +699,8 @@ "symlink(src, dst)\n\n" + "Create a symbolic link pointing to src named dst."); @Hide(OS.NT) - public static void symlink(String src, String dst) { - ensurePath(src); - if (posix.symlink(src, absolutePath(dst)) < 0) { + public static void symlink(PyObject src, PyObject dst) { + if (posix.symlink(asPath(src), absolutePath(dst)) < 0) { throw errorFromErrno(); } } @@ -732,12 +725,12 @@ public static PyString __doc__unlink = new PyString( "unlink(path)\n\n" + "Remove a file (same as remove(path))."); - public static void unlink(String path) { - ensurePath(path); - File file = new RelativeFile(path); + public static void unlink(PyObject path) { + String absolutePath = absolutePath(path); + File file = new File(absolutePath); if (!file.delete()) { // Something went wrong, does stat raise an error? - posix.stat(absolutePath(path)); + posix.stat(absolutePath); // It exists, is it a directory, or do we not have permissions? if (file.isDirectory()) { throw Py.OSError(Errno.EISDIR, path); @@ -745,7 +738,7 @@ if (!file.canWrite()) { throw Py.OSError(Errno.EPERM, path); } - throw Py.OSError("unlink(): an unknown error occured: " + path); + throw Py.OSError("unlink(): an unknown error occured" + absolutePath); } } @@ -754,7 +747,7 @@ "utime(path, None)\n\n" + "Set the access and modified time of the file to the given values. If the\n" + "second form is used, set the access and modified times to the current time."); - public static void utime(String path, PyObject times) { + public static void utime(PyObject path, PyObject times) { long[] atimeval; long[] mtimeval; @@ -891,27 +884,27 @@ } /** + * Return a path as a String from a PyObject + * + * @param path a PyObject, raising a TypeError if an invalid path type + * @return a String path + */ + private static String asPath(PyObject path) { + if (path instanceof PyString) { + return path.toString(); + } + throw Py.TypeError(String.format("coercing to Unicode: need string, %s type found", + path.getType().fastGetName())); + } + + /** * Return the absolute form of path. * - * @param path a path String, raising a TypeError when null + * @param path a PyObject, raising a TypeError if an invalid path type * @return an absolute path String */ - private static String absolutePath(String path) { - ensurePath(path); - return new RelativeFile(path).getPath(); - } - - private static void ensurePath(PyObject path) { - if (!(path instanceof PyString)) { - throw Py.TypeError(String.format("coercing to Unicode: need string, %s type found", - path.getType().fastGetName())); - } - } - - private static void ensurePath(String path) { - if (path == null) { - throw Py.TypeError("coercing to Unicode: need string or buffer, NoneType found"); - } + private static String absolutePath(PyObject path) { + return PySystemState.getPathLazy(asPath(path)); } private static PyException badFD() { @@ -922,7 +915,7 @@ return Py.OSError(Errno.valueOf(posix.errno())); } - private static PyException errorFromErrno(String path) { + private static PyException errorFromErrno(PyObject path) { return Py.OSError(Errno.valueOf(posix.errno()), path); } @@ -942,13 +935,8 @@ } @Override - public PyObject __call__(PyObject pathObj) { - if (!(pathObj instanceof PyString)) { - throw Py.TypeError(String.format("coercing to Unicode: need string or buffer, %s " + - "found", pathObj.getType().fastGetName())); - } - String absolutePath = absolutePath(pathObj.toString()); - return PyStatResult.fromFileStat(posix.lstat(absolutePath)); + public PyObject __call__(PyObject path) { + return PyStatResult.fromFileStat(posix.lstat(absolutePath(path))); } } @@ -962,13 +950,8 @@ } @Override - public PyObject __call__(PyObject pathObj) { - if (!(pathObj instanceof PyString)) { - throw Py.TypeError(String.format("coercing to Unicode: need string or buffer, %s " + - "found", pathObj.getType().fastGetName())); - } - String absolutePath = absolutePath(pathObj.toString()); - return PyStatResult.fromFileStat(posix.stat(absolutePath)); + public PyObject __call__(PyObject path) { + return PyStatResult.fromFileStat(posix.stat(absolutePath(path))); } } } diff --git a/src/org/python/modules/posix/PythonPOSIXHandler.java b/src/org/python/modules/posix/PythonPOSIXHandler.java --- a/src/org/python/modules/posix/PythonPOSIXHandler.java +++ b/src/org/python/modules/posix/PythonPOSIXHandler.java @@ -21,7 +21,9 @@ public class PythonPOSIXHandler implements POSIXHandler { public void error(Errno error, String extraData) { - throw Py.OSError(error, extraData); + // XXX: extraData (filename) could have been unicode! + // http://bugs.jython.org/issue1825 + throw Py.OSError(error, Py.newString(extraData)); } public void unimplementedError(String methodName) { -- Repository URL: http://hg.python.org/jython From jython-checkins at python.org Fri Dec 16 01:20:30 2011 From: jython-checkins at python.org (philip.jenvey) Date: Fri, 16 Dec 2011 01:20:30 +0100 Subject: [Jython-checkins] =?utf8?q?jython_=282=2E5=29=3A_clarify_comment?= Message-ID: http://hg.python.org/jython/rev/e334a2a95e66 changeset: 6288:e334a2a95e66 branch: 2.5 parent: 6285:32b8ace8ef6d user: Philip Jenvey date: Thu Dec 15 15:26:45 2011 -0800 summary: clarify comment files: Lib/test/test_chdir.py | 7 ++++--- 1 files changed, 4 insertions(+), 3 deletions(-) diff --git a/Lib/test/test_chdir.py b/Lib/test/test_chdir.py --- a/Lib/test/test_chdir.py +++ b/Lib/test/test_chdir.py @@ -582,13 +582,14 @@ def test_symlink_src_is_relative(self): write(self.src, 'foo') # Ensure that linking to os.path.basename(self.src) creates a - # dead link (since it lives in a different dir) + # dead link (as self.src lives in a different dir than + # self.link) os.symlink(self.relsrc, self.link) # If the cwd (self.dir1) was applied to os.link's src arg then # the link would not be dead - self.assertTrue(self.is_dead_link(self.link)) + self.assertTrue(self.isdeadlink(self.link)) - def is_dead_link(self, link): + def isdeadlink(self, link): return os.path.lexists(link) and not os.path.exists(link) -- Repository URL: http://hg.python.org/jython From jython-checkins at python.org Fri Dec 16 01:20:30 2011 From: jython-checkins at python.org (philip.jenvey) Date: Fri, 16 Dec 2011 01:20:30 +0100 Subject: [Jython-checkins] =?utf8?b?anl0aG9uICgyLjUpOiAjMTgyODogZml4IHJl?= =?utf8?q?pr_and_bool_on_long_subclasses?= Message-ID: http://hg.python.org/jython/rev/68626d94a76d changeset: 6289:68626d94a76d branch: 2.5 user: Philip Jenvey date: Thu Dec 15 16:18:57 2011 -0800 summary: #1828: fix repr and bool on long subclasses thanks Pekka Klarck files: Lib/test/test_long_jy.py | 34 +++++++++++++++++++++ NEWS | 1 + src/org/python/core/PyLong.java | 13 +++++-- 3 files changed, 44 insertions(+), 4 deletions(-) diff --git a/Lib/test/test_long_jy.py b/Lib/test/test_long_jy.py new file mode 100644 --- /dev/null +++ b/Lib/test/test_long_jy.py @@ -0,0 +1,34 @@ +"""Misc long tests + +Made for Jython. +""" +from test import test_support +import unittest + +class MyLong(long): + pass + + +class LongTestCase(unittest.TestCase): + + def _test_long_repr(self, type2test): + val = type2test(42) + self.assertEqual(str(val), '42') + self.assertEqual(repr(val), '42L') + + def test_long_repr(self): + self._test_long_repr(long) + + def test_long_subclass_repr(self): + self._test_long_repr(MyLong) + + def test_subclass_bool(self): + # http://bugs.jython.org/issue1828 + self.assertTrue(bool(MyLong(42))) + + +def test_main(): + test_support.run_unittest(LongTestCase) + +if __name__ == '__main__': + test_main() diff --git a/NEWS b/NEWS --- a/NEWS +++ b/NEWS @@ -13,6 +13,7 @@ - [ 1819 ] Incorrect handling of Java object toString methods returning null - [ 1824 ] os.link() can silently fail - [ 1825 ] EnvironmentError.filename is `str` even if original name is `unicode` + - [ 1828 ] Problems inheriting from long Jython 2.5.2 same as 2.5.2rc4 diff --git a/src/org/python/core/PyLong.java b/src/org/python/core/PyLong.java --- a/src/org/python/core/PyLong.java +++ b/src/org/python/core/PyLong.java @@ -134,7 +134,7 @@ return long_toString(); } - @ExposedMethod(names = {"__str__", "__repr__"}, doc = BuiltinDocs.long___str___doc) + @ExposedMethod(names = "__repr__", doc = BuiltinDocs.long___repr___doc) final String long_toString() { return getValue().toString() + "L"; } @@ -151,12 +151,12 @@ @Override public boolean __nonzero__() { - return !getValue().equals(BigInteger.ZERO); + return long___nonzero__(); } @ExposedMethod(doc = BuiltinDocs.long___nonzero___doc) public boolean long___nonzero__() { - return __nonzero__(); + return !getValue().equals(BigInteger.ZERO); } public double doubleValue() { @@ -933,9 +933,14 @@ } } + @ExposedMethod(doc = BuiltinDocs.long___str___doc) + public PyString long___str__() { + return Py.newString(getValue().toString()); + } + @Override public PyString __str__() { - return Py.newString(getValue().toString()); + return long___str__(); } @Override -- Repository URL: http://hg.python.org/jython From jython-checkins at python.org Fri Dec 16 01:20:30 2011 From: jython-checkins at python.org (philip.jenvey) Date: Fri, 16 Dec 2011 01:20:30 +0100 Subject: [Jython-checkins] =?utf8?q?jython_=28merge_2=2E5_-=3E_default=29?= =?utf8?q?=3A_merge_w/_2=2E5?= Message-ID: http://hg.python.org/jython/rev/825546a4600e changeset: 6290:825546a4600e parent: 6287:0db163c83774 parent: 6289:68626d94a76d user: Philip Jenvey date: Thu Dec 15 16:19:46 2011 -0800 summary: merge w/ 2.5 files: Lib/test/test_chdir.py | 7 ++- Lib/test/test_long_jy.py | 34 +++++++++++++++++++++ NEWS | 1 + src/org/python/core/PyLong.java | 13 +++++-- 4 files changed, 48 insertions(+), 7 deletions(-) diff --git a/Lib/test/test_chdir.py b/Lib/test/test_chdir.py --- a/Lib/test/test_chdir.py +++ b/Lib/test/test_chdir.py @@ -582,13 +582,14 @@ def test_symlink_src_is_relative(self): write(self.src, 'foo') # Ensure that linking to os.path.basename(self.src) creates a - # dead link (since it lives in a different dir) + # dead link (as self.src lives in a different dir than + # self.link) os.symlink(self.relsrc, self.link) # If the cwd (self.dir1) was applied to os.link's src arg then # the link would not be dead - self.assertTrue(self.is_dead_link(self.link)) + self.assertTrue(self.isdeadlink(self.link)) - def is_dead_link(self, link): + def isdeadlink(self, link): return os.path.lexists(link) and not os.path.exists(link) diff --git a/Lib/test/test_long_jy.py b/Lib/test/test_long_jy.py new file mode 100644 --- /dev/null +++ b/Lib/test/test_long_jy.py @@ -0,0 +1,34 @@ +"""Misc long tests + +Made for Jython. +""" +from test import test_support +import unittest + +class MyLong(long): + pass + + +class LongTestCase(unittest.TestCase): + + def _test_long_repr(self, type2test): + val = type2test(42) + self.assertEqual(str(val), '42') + self.assertEqual(repr(val), '42L') + + def test_long_repr(self): + self._test_long_repr(long) + + def test_long_subclass_repr(self): + self._test_long_repr(MyLong) + + def test_subclass_bool(self): + # http://bugs.jython.org/issue1828 + self.assertTrue(bool(MyLong(42))) + + +def test_main(): + test_support.run_unittest(LongTestCase) + +if __name__ == '__main__': + test_main() diff --git a/NEWS b/NEWS --- a/NEWS +++ b/NEWS @@ -13,6 +13,7 @@ - [ 1819 ] Incorrect handling of Java object toString methods returning null - [ 1824 ] os.link() can silently fail - [ 1825 ] EnvironmentError.filename is `str` even if original name is `unicode` + - [ 1828 ] Problems inheriting from long Jython 2.5.2 same as 2.5.2rc4 diff --git a/src/org/python/core/PyLong.java b/src/org/python/core/PyLong.java --- a/src/org/python/core/PyLong.java +++ b/src/org/python/core/PyLong.java @@ -155,7 +155,7 @@ return long_toString(); } - @ExposedMethod(names = {"__str__", "__repr__"}, doc = BuiltinDocs.long___str___doc) + @ExposedMethod(names = "__repr__", doc = BuiltinDocs.long___repr___doc) final String long_toString() { return getValue().toString() + "L"; } @@ -172,12 +172,12 @@ @Override public boolean __nonzero__() { - return !getValue().equals(BigInteger.ZERO); + return long___nonzero__(); } @ExposedMethod(doc = BuiltinDocs.long___nonzero___doc) public boolean long___nonzero__() { - return __nonzero__(); + return !getValue().equals(BigInteger.ZERO); } public double doubleValue() { @@ -951,9 +951,14 @@ } } + @ExposedMethod(doc = BuiltinDocs.long___str___doc) + public PyString long___str__() { + return Py.newString(getValue().toString()); + } + @Override public PyString __str__() { - return Py.newString(getValue().toString()); + return long___str__(); } @Override -- Repository URL: http://hg.python.org/jython From jython-checkins at python.org Sat Dec 31 19:31:43 2011 From: jython-checkins at python.org (frank.wierzbicki) Date: Sat, 31 Dec 2011 19:31:43 +0100 Subject: [Jython-checkins] =?utf8?b?anl0aG9uICgyLjUpOiAjMTc4NjogUHJvcGVy?= =?utf8?q?ly_close_file_handles_in_sys-package-mgr=2E_Thanks_Jeff_Allen!?= Message-ID: http://hg.python.org/jython/rev/958ecf3eb8f0 changeset: 6291:958ecf3eb8f0 branch: 2.5 parent: 6289:68626d94a76d user: Frank Wierzbicki date: Sat Dec 31 10:11:32 2011 -0800 summary: #1786: Properly close file handles in sys-package-mgr. Thanks Jeff Allen! files: src/org/python/core/packagecache/CachedJarsPackageManager.java | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/src/org/python/core/packagecache/CachedJarsPackageManager.java b/src/org/python/core/packagecache/CachedJarsPackageManager.java --- a/src/org/python/core/packagecache/CachedJarsPackageManager.java +++ b/src/org/python/core/packagecache/CachedJarsPackageManager.java @@ -317,6 +317,7 @@ } zipPackages = getZipPackages(jarin); + jarin.close(); if (caching) { writeCacheFile(entry, jarcanon, zipPackages, brandNew); -- Repository URL: http://hg.python.org/jython From jython-checkins at python.org Sat Dec 31 19:31:43 2011 From: jython-checkins at python.org (frank.wierzbicki) Date: Sat, 31 Dec 2011 19:31:43 +0100 Subject: [Jython-checkins] =?utf8?q?jython_=28merge_2=2E5_-=3E_default=29?= =?utf8?q?=3A_Merge_w/_2=2E5?= Message-ID: http://hg.python.org/jython/rev/b3007362260c changeset: 6292:b3007362260c parent: 6290:825546a4600e parent: 6291:958ecf3eb8f0 user: Frank Wierzbicki date: Sat Dec 31 10:31:12 2011 -0800 summary: Merge w/ 2.5 files: src/org/python/core/packagecache/CachedJarsPackageManager.java | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/src/org/python/core/packagecache/CachedJarsPackageManager.java b/src/org/python/core/packagecache/CachedJarsPackageManager.java --- a/src/org/python/core/packagecache/CachedJarsPackageManager.java +++ b/src/org/python/core/packagecache/CachedJarsPackageManager.java @@ -317,6 +317,7 @@ } zipPackages = getZipPackages(jarin); + jarin.close(); if (caching) { writeCacheFile(entry, jarcanon, zipPackages, brandNew); -- Repository URL: http://hg.python.org/jython From pjenvey at underboss.org Sat Dec 31 20:14:26 2011 From: pjenvey at underboss.org (Philip Jenvey) Date: Sat, 31 Dec 2011 11:14:26 -0800 Subject: [Jython-checkins] jython (2.5): #1786: Properly close file handles in sys-package-mgr. Thanks Jeff Allen! In-Reply-To: References: Message-ID: <60AAAA44-C08B-424F-9837-B3D959BDF218@underboss.org> On Dec 31, 2011, at 10:31 AM, frank.wierzbicki wrote: > http://hg.python.org/jython/rev/958ecf3eb8f0 > changeset: 6291:958ecf3eb8f0 > branch: 2.5 > parent: 6289:68626d94a76d > user: Frank Wierzbicki > date: Sat Dec 31 10:11:32 2011 -0800 > summary: > #1786: Properly close file handles in sys-package-mgr. Thanks Jeff Allen! > > files: > src/org/python/core/packagecache/CachedJarsPackageManager.java | 1 + > 1 files changed, 1 insertions(+), 0 deletions(-) > > > diff --git a/src/org/python/core/packagecache/CachedJarsPackageManager.java b/src/org/python/core/packagecache/CachedJarsPackageManager.java > --- a/src/org/python/core/packagecache/CachedJarsPackageManager.java > +++ b/src/org/python/core/packagecache/CachedJarsPackageManager.java > @@ -317,6 +317,7 @@ > } > > zipPackages = getZipPackages(jarin); > + jarin.close(); > > if (caching) { > writeCacheFile(entry, jarcanon, zipPackages, brandNew); This might as well be in a try/finally -- Philip Jenvey