[Jython-checkins] jython: Tolerate localisation and non-ascii strings in os.uname(). Fixes #2726.

jeff.allen jython-checkins at python.org
Tue Jan 1 18:58:21 EST 2019


https://hg.python.org/jython/rev/9f020857adce
changeset:   8211:9f020857adce
user:        Jeff Allen <ja.py at farowl.co.uk>
date:        Tue Jan 01 12:21:30 2019 +0000
summary:
  Tolerate localisation and non-ascii strings in os.uname(). Fixes #2726.

files:
  Lib/test/test_os_jy.py                        |  12 ++++
  NEWS                                          |   1 +
  src/org/python/core/PySystemState.java        |  26 ++++-----
  src/org/python/modules/posix/PosixModule.java |   8 +-
  4 files changed, 28 insertions(+), 19 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
@@ -322,6 +322,18 @@
                     "File %r (%r) should be testable for existence" %
                     (f, entry_path))
 
+    def test_uname(self):
+        # Test that os.uname returns a tuple of (arbitrary) strings.
+        # uname failed on on a Chinese localised system (see
+        # https://bugs.jython.org/issue2726). This test really needs to
+        # run in that environment or it passes too easily.
+        result = os.uname()
+        # (sysname, nodename, release, version, machine)
+        self.assertEqual(type(result), tuple)
+        self.assertEqual(len(result), 5)
+        for s in result: self.assertEqual(type(s), str)
+
+
 class LocaleTestCase(unittest.TestCase):
 
     def get_installed_locales(self, codes, msg=None):
diff --git a/NEWS b/NEWS
--- a/NEWS
+++ b/NEWS
@@ -5,6 +5,7 @@
 
 Development tip
   Bugs fixed
+    - [ 2726 ] os.uname() throws IllegalArgumentException on Windows (Chinese localisation)
     - [ 2719 ] Divergence of __str__ and __repr__ from CPython
     - [ 2714 ] Locale and java version failures in test_os_jy
     - [ GH-111 ] Proper processing of gzip trailer without resubmission
diff --git a/src/org/python/core/PySystemState.java b/src/org/python/core/PySystemState.java
--- a/src/org/python/core/PySystemState.java
+++ b/src/org/python/core/PySystemState.java
@@ -1772,30 +1772,26 @@
 
     /**
      * Attempt to find the OS version. The mechanism on Windows is to extract it from the result of
-     * <code>cmd.exe /C ver</code>, and otherwise (assumed Unix-like OS) to use
-     * <code>uname -v</code>.
+     * {@code cmd.exe /C ver}, and otherwise (assumed Unix-like OS) to use {@code uname -v</code>}.
      */
     public static String getSystemVersionString() {
         if (System.getProperty("os.name").startsWith("Windows")) {
-            String ver = getCommandResult("cmd.exe", "/c", "ver");
-            int start = ver.toLowerCase().indexOf("version ");
-            if (start != -1) {
-                start += 8;
-                int end = ver.length();
-                if (ver.endsWith("]")) {
-                    --end;
-                }
-                ver = ver.substring(start, end);
-            }
-            return ver;
+            // Windows ver command returns a string similar to:
+            // "Microsoft Windows [Version 10.0.10586]"
+            // "Microsoft Windows XP [Version 5.1.2600]"
+            // "Microsoft Windows [版本 10.0.17134.472]"
+            // We match the dots and digits within square brackets.
+            Pattern p = Pattern.compile("\\[.* ([\\d.]+)\\]");
+            Matcher m = p.matcher(getCommandResult("cmd.exe", "/c", "ver"));
+            return m.find() ? m.group(1) : "";
         } else {
             return getCommandResult("uname", "-v");
         }
     }
 
     /**
-     * Run a command as a sub-process and return as the result the first line of output that consist
-     * of more than white space. It returns "" on any kind of error.
+     * Run a command as a sub-process and return as the result the first line of output that
+     * consists of more than white space. It returns "" on any kind of error.
      *
      * @param command as strings (as for <code>ProcessBuilder</code>)
      * @return the first line with content, or ""
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
@@ -1167,11 +1167,11 @@
         }
 
         PyObject[] vals = {
-                Py.newString(sysname),
+                Py.fileSystemEncode(sysname),
                 Py.fileSystemEncode(uname_nodename),
-                Py.newString(sysrelease),
-                Py.newString(uname_sysver),
-                Py.newString(uname_machine)
+                Py.fileSystemEncode(sysrelease),
+                Py.fileSystemEncode(uname_sysver),
+                Py.fileSystemEncode(uname_machine)
         };
         uname_cache = new PyTuple(vals, false);
         return uname_cache;

-- 
Repository URL: https://hg.python.org/jython


More information about the Jython-checkins mailing list