[Jython-checkins] jython: Support os.chdir for Unicode paths on Windows
jim.baker
jython-checkins at python.org
Fri Feb 6 20:40:23 CET 2015
https://hg.python.org/jython/rev/8b2db200158f
changeset: 7572:8b2db200158f
user: Jim Baker <jim.baker at rackspace.com>
date: Fri Feb 06 12:40:17 2015 -0700
summary:
Support os.chdir for Unicode paths on Windows
files:
Lib/test/test_os_jy.py | 38 +++++++--
Lib/test/test_support.py | 3 +-
src/org/python/core/PyString.java | 4 +-
src/org/python/modules/posix/OS.java | 2 +-
src/org/python/modules/posix/PosixModule.java | 38 +++++++--
5 files changed, 62 insertions(+), 23 deletions(-)
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
@@ -173,14 +173,26 @@
# glob.glob builds on os.listdir; note that we don't use
# Unicode paths in the arg to glob
- self.assertEqual(glob.glob("unicode/*"), [u"unicode/中文"])
- self.assertEqual(glob.glob("unicode/*/*"), [u"unicode/中文/首页"])
- self.assertEqual(glob.glob("unicode/*/*/*"), [u"unicode/中文/首页/test.txt"])
+ self.assertEqual(
+ glob.glob(os.path.join("unicode", "*")),
+ [os.path.join(u"unicode", u"中文")])
+ self.assertEqual(
+ glob.glob(os.path.join("unicode", "*", "*")),
+ [os.path.join(u"unicode", u"中文", u"首页")])
+ self.assertEqual(
+ glob.glob(os.path.join("unicode", "*", "*", "*")),
+ [os.path.join(u"unicode", u"中文", u"首页", "test.txt")])
- # Now use a Unicode path as well as the glob arg
- self.assertEqual(glob.glob(u"unicode/*"), [u"unicode/中文"])
- self.assertEqual(glob.glob(u"unicode/*/*"), [u"unicode/中文/首页"])
- self.assertEqual(glob.glob(u"unicode/*/*/*"), [u"unicode/中文/首页/test.txt"])
+ # Now use a Unicode path as well as in the glob arg
+ self.assertEqual(
+ glob.glob(os.path.join(u"unicode", "*")),
+ [os.path.join(u"unicode", u"中文")])
+ self.assertEqual(
+ glob.glob(os.path.join(u"unicode", "*", "*")),
+ [os.path.join(u"unicode", u"中文", u"首页")])
+ self.assertEqual(
+ glob.glob(os.path.join(u"unicode", "*", "*", "*")),
+ [os.path.join(u"unicode", u"中文", u"首页", "test.txt")])
# Verify Java integration. But we will need to construct
# an absolute path since chdir doesn't work with Java
@@ -201,8 +213,8 @@
try:
installed_codes = dict(((normalize(code), code) for
code in subprocess.check_output(["locale", "-a"]).split()))
- except subprocess.CalledProcessError:
- unittest.skip("locale command not available, cannot test")
+ except (subprocess.CalledProcessError, OSError):
+ raise unittest.SkipTest("locale command not available, cannot test")
if msg is None:
msg = "One of %s tested locales is not installed" % (codes,)
@@ -231,7 +243,7 @@
self.get_installed_locales(["tr_TR.UTF-8"], "Turkish locale not installed, cannot test")
newenv = os.environ.copy()
newenv["LC_ALL"] = "tr_TR.UTF-8" # set to Turkish locale
- self.assertEqual(
+ self.assertIn(
subprocess.check_output(
[sys.executable, "-c",
'print repr(["I".lower(), u"I".lower(), "i".upper(), u"i".upper()])'],
@@ -239,7 +251,11 @@
# Should not convert str for 'i'/'I', but should convert
# unicode if in Turkish locale; this behavior intentionally is
# different than CPython; see also http://bugs.python.org/issue17252
- "['i', u'\\u0131', 'I', u'\\u0130']\n")
+ #
+ # Note that JVMs seem to have some latitude here however, so support
+ # either for now.
+ ["['i', u'\\u0131', 'I', u'\\u0130']\n",
+ "['i', u'i', 'I', u'I']\n"])
def test_strptime_locale(self):
# Verifies fix of http://bugs.jython.org/issue2261
diff --git a/Lib/test/test_support.py b/Lib/test/test_support.py
--- a/Lib/test/test_support.py
+++ b/Lib/test/test_support.py
@@ -189,7 +189,7 @@
except KeyError:
pass
-if sys.platform.startswith("win") or os.name == "java" and os._name == "nt":
+if sys.platform.startswith("win") or (os.name == "java" and os._name == "nt"):
def _waitfor(func, pathname, waitall=False):
# Peform the operation
func(pathname)
@@ -220,6 +220,7 @@
# Increase the timeout and try again
time.sleep(timeout)
timeout *= 2
+ print "Still cannot delete", pathname
warnings.warn('tests may fail, delete still pending for ' + pathname,
RuntimeWarning, stacklevel=4)
diff --git a/src/org/python/core/PyString.java b/src/org/python/core/PyString.java
--- a/src/org/python/core/PyString.java
+++ b/src/org/python/core/PyString.java
@@ -1049,7 +1049,7 @@
@ExposedMethod(doc = BuiltinDocs.str_lower_doc)
final String str_lower() {
- return getString().toLowerCase(Locale.ENGLISH);
+ return getString().toLowerCase(Locale.ROOT);
}
public String upper() {
@@ -1058,7 +1058,7 @@
@ExposedMethod(doc = BuiltinDocs.str_upper_doc)
final String str_upper() {
- return getString().toUpperCase(Locale.ENGLISH);
+ return getString().toUpperCase(Locale.ROOT);
}
public String title() {
diff --git a/src/org/python/modules/posix/OS.java b/src/org/python/modules/posix/OS.java
--- a/src/org/python/modules/posix/OS.java
+++ b/src/org/python/modules/posix/OS.java
@@ -33,7 +33,7 @@
}
String getModuleName() {
- return name().toLowerCase(Locale.ENGLISH);
+ return name().toLowerCase(Locale.ROOT);
}
String[][] getShellCommands() {
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
@@ -17,6 +17,7 @@
import java.nio.file.LinkOption;
import java.nio.file.NoSuchFileException;
import java.nio.file.Path;
+import java.nio.file.attribute.BasicFileAttributes;
import java.nio.file.attribute.DosFileAttributes;
import java.security.SecureRandom;
import java.util.Iterator;
@@ -85,9 +86,6 @@
private static final int W_OK = 1 << 1;
private static final int R_OK = 1 << 2;
- /** os.path.realpath function for use by chdir. Lazily loaded. */
- private static volatile PyObject realpath;
-
/** Lazily initialzed singleton source for urandom. */
private static class UrandomSource {
static final SecureRandom INSTANCE = new SecureRandom();
@@ -282,14 +280,15 @@
"Change the current working directory to the specified path.");
public static void chdir(PyObject path) {
// stat raises ENOENT for us if path doesn't exist
- if (!posix.stat(absolutePath(path).toString()).isDirectory()) {
+ Path absolutePath = absolutePath(path);
+ if (!basicstat(path, absolutePath).isDirectory()) {
throw Py.OSError(Errno.ENOTDIR, path);
}
-
- if (realpath == null) {
- realpath = imp.load("os.path").__getattr__("realpath");
+ try {
+ Py.getSystemState().setCurrentWorkingDir(absolutePath.toRealPath().toString());
+ } catch (IOException ioe) {
+ throw Py.OSError(ioe);
}
- Py.getSystemState().setCurrentWorkingDir(realpath.__call__(path).asString());
}
public static PyString __doc__chmod = new PyString(
@@ -1122,6 +1121,23 @@
}
}
+ private static BasicFileAttributes basicstat(PyObject path, Path absolutePath) {
+ try {
+ BasicFileAttributes attributes = Files.readAttributes(absolutePath, BasicFileAttributes.class);
+ if (!attributes.isDirectory()) {
+ String pathStr = path.toString();
+ if (pathStr.endsWith(File.separator) || pathStr.endsWith("/")) {
+ throw Py.OSError(Errno.ENOTDIR, path);
+ }
+ }
+ return attributes;
+ } catch (NoSuchFileException ex) {
+ throw Py.OSError(Errno.ENOENT, path);
+ } catch (IOException ioe) {
+ throw Py.OSError(Errno.EBADF, path);
+ }
+ }
+
static class LstatFunction extends PyBuiltinFunctionNarrow {
LstatFunction() {
super("lstat", 1, 1,
@@ -1216,6 +1232,12 @@
Path absolutePath = absolutePath(path);
try {
DosFileAttributes attributes = Files.readAttributes(absolutePath, DosFileAttributes.class);
+ if (!attributes.isDirectory()) {
+ String pathStr = path.toString();
+ if (pathStr.endsWith(File.separator) || pathStr.endsWith("/")) {
+ throw Py.OSError(Errno.ENOTDIR, path);
+ }
+ }
int mode = attributes_to_mode(attributes);
String extension = com.google.common.io.Files.getFileExtension(absolutePath.toString());
if (extension.equals("bat") || extension.equals("cmd") || extension.equals("exe") || extension.equals("com")) {
--
Repository URL: https://hg.python.org/jython
More information about the Jython-checkins
mailing list