[Jython-checkins] jython: Fix regression in PySystemStateTest caused by change to PrePy

jeff.allen jython-checkins at python.org
Tue Dec 24 06:10:13 EST 2019


https://hg.python.org/jython/rev/05b258a6573c
changeset:   8317:05b258a6573c
user:        Jeff Allen <ja.py at farowl.co.uk>
date:        Tue Dec 24 09:43:29 2019 +0000
summary:
  Fix regression in PySystemStateTest caused by change to PrePy

A change to PrePy.getJarFileNameFromURL(URL) in cset:159c277c4a80 broke
the test. getJarFileNameFromURL now no longer insists on a particular
class as target (so we can avoid e.g. waking the type system).

Also, let's test it with non-ascii file names.

files:
  src/org/python/core/PrePy.java                    |  36 +++--
  tests/java/org/python/core/PySystemStateTest.java |  56 ++++++---
  2 files changed, 60 insertions(+), 32 deletions(-)


diff --git a/src/org/python/core/PrePy.java b/src/org/python/core/PrePy.java
--- a/src/org/python/core/PrePy.java
+++ b/src/org/python/core/PrePy.java
@@ -13,6 +13,8 @@
 import java.util.Properties;
 import java.util.logging.Level;
 import java.util.logging.Logger;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 import jnr.posix.util.Platform;
 
@@ -361,20 +363,25 @@
     }
 
     /**
-     * Return the path in the file system (as a string) of a JAR located by a URL. Three protocols
-     * are supported, Java JAR-file protocol, and two JBoss protocols "vfs" and "vfszip".
+     * Return the path in the file system (as a string) of a JAR located using the URL of a class
+     * file that it contains. Classes in Java can be asked for the URL of their associated resources
+     * (including their own class definition), and so the caller of this method may present such a
+     * URL as the basis for locating the JAR from which it came.
+     * <p>
+     * Three protocols are supported, Java JAR-file protocol, and two JBoss protocols "vfs" and
+     * "vfszip".
      * <p>
      * The JAR-file protocol URL, which must be a {@code jar:file:} reference to a contained element
      * (that is, it has a "!/" part) is able to identify an actual JAR in a file system that may
      * then be opened using {@code jarFile = new JarFile(jarFileName)}. The path to the JAR is
      * returned. If the JAR is accessed by another mechanism ({@code http:} say) this will fail.
      * <p>
-     * The JBoss URL must be a reference to exactly {@code vfs:<JAR>/org/python/core/PrePy.class},
-     * or the same thing using the {@code vfszip:} protocol, where <JAR> stands for the
-     * absolute path to the Jython JAR in VFS. There is no "!/" marker: in JBoss VFS a JAR is
-     * treated just like a directory and can no longer be opened as a JAR. The method essentially
-     * just swaps a VFS protocol for the Java {@code file:} protocol. The path returned will be
-     * correct only if this naive swap is valid.
+     * The JBoss URL must be a reference to a class in {@code vfs:<JAR>/org/python/core/}, or the
+     * same thing using the {@code vfszip:} protocol, where <JAR> stands for the absolute path
+     * to the Jython JAR in VFS. There is no "!/" marker: in JBoss VFS a JAR is treated just like a
+     * directory and can no longer be opened as a JAR. The method essentially just swaps a VFS
+     * protocol for the Java {@code file:} protocol. The path returned will be correct only if this
+     * naive swap is valid.
      *
      * @param url into the JAR
      * @return the file path or {@code null} in the event of a detectable error
@@ -397,13 +404,14 @@
 
                 case "vfs":
                 case "vfszip":
-                    // path is /some/path/some-jython.jar/org/python/core/PrePy.class
+                    // path is /some/path/some-jython.jar/org/python/core/some-name.class
                     String path = url.getPath();
-                    final String target = ".jar/org/python/core/PrePy.class";
-                    int jarIndex = path.indexOf(target);
-                    if (jarIndex > 0) {
-                        // path contains the target class in a JAR, so make a file URL for it
-                        fileURI = new URL("file:" + path.substring(0, jarIndex + 4)).toURI();
+                    Pattern p = Pattern.compile("/([^./]+\\.jar)/org/python/core/\\w+.class");
+                    Matcher m = p.matcher(path);
+                    if (m.find()) {
+                        // path contains the target class in a JAR (named in group 1).
+                        // Make a file URL from all the text up to the end of group 1.
+                        fileURI = new URL("file:" + path.substring(0, m.end(1))).toURI();
                     }
                     break;
 
diff --git a/tests/java/org/python/core/PySystemStateTest.java b/tests/java/org/python/core/PySystemStateTest.java
--- a/tests/java/org/python/core/PySystemStateTest.java
+++ b/tests/java/org/python/core/PySystemStateTest.java
@@ -115,41 +115,61 @@
         final String host = "";
         final int port = -1;
         final URLStreamHandler handler = new TestJBossURLStreamHandler();
+        // Test with any class file in org.python.core
+        final String classPart = "/org/python/core/PySystemState.class";
         String file;
         URL url;
         if (Platform.IS_WINDOWS) {
             // plain jboss url
-            file = "/C:/some_dir/some.jar/org/python/core/PySystemState.class";
+            file = "/C:/some_dir/some.jar" + classPart;
             url = new URL(protocol, host, port, file, handler);
             // tests with jboss on windows gave URL's like this:
-            assertEquals("vfszip:/C:/some_dir/some.jar/org/python/core/PySystemState.class", url.toString());
-            assertEquals("C:\\some_dir\\some.jar", Py.getJarFileNameFromURL(url));
+            assertEquals("vfszip:/C:/some_dir/some.jar" + classPart, url.toString());
+            String result = Py.getJarFileNameFromURL(url);
+            assertEquals("C:\\some_dir\\some.jar", result);
             // jboss url to decode
-            file = "/C:/some%20dir/some.jar/org/python/core/PySystemState.class";
+            file = "/C:/some%20dir/some.jar" + classPart;
             url = new URL(protocol, host, port, file, handler);
-            assertEquals("vfszip:/C:/some%20dir/some.jar/org/python/core/PySystemState.class", url.toString());
-            assertEquals("C:\\some dir\\some.jar", Py.getJarFileNameFromURL(url));
+            assertEquals("vfszip:/C:/some%20dir/some.jar" + classPart, url.toString());
+            result = Py.getJarFileNameFromURL(url);
+            assertEquals("C:\\some dir\\some.jar", result);
             // jboss url with + to escape
-            file = "/C:/some+dir/some.jar/org/python/core/PySystemState.class";
+            file = "/C:/some+dir/some.jar" + classPart;
             url = new URL(protocol, host, port, file, handler);
-            assertEquals("vfszip:/C:/some+dir/some.jar/org/python/core/PySystemState.class", url.toString());
-            assertEquals("C:\\some+dir\\some.jar", Py.getJarFileNameFromURL(url));
+            assertEquals("vfszip:/C:/some+dir/some.jar" + classPart, url.toString());
+            result = Py.getJarFileNameFromURL(url);
+            assertEquals("C:\\some+dir\\some.jar", result);
+            // jboss url with challenging JAR name (assume will be provided RFC-2396 encoded)
+            file = "/C:/n%c3%a5gon/katalog/r%c3%a4tt.jar" + classPart;
+            url = new URL(protocol, host, port, file, handler);
+            assertEquals("vfszip:/C:/n%c3%a5gon/katalog/r%c3%a4tt.jar" + classPart, url.toString());
+            result = Py.getJarFileNameFromURL(url);
+            assertEquals("C:\\någon\\katalog\\rätt.jar", result);
         } else {
             // plain jboss url
-            file = "/some_dir/some.jar/org/python/core/PySystemState.class";
+            file = "/some_dir/some.jar" + classPart;
             url = new URL(protocol, host, port, file, handler);
-            assertEquals("vfszip:/some_dir/some.jar/org/python/core/PySystemState.class", url.toString());
-            assertEquals("/some_dir/some.jar", Py.getJarFileNameFromURL(url));
+            assertEquals("vfszip:/some_dir/some.jar" + classPart, url.toString());
+            String result = Py.getJarFileNameFromURL(url);
+            assertEquals("/some_dir/some.jar", result);
             // jboss url to decode
-            file = "/some%20dir/some.jar/org/python/core/PySystemState.class";
+            file = "/some dir/some.jar" + classPart;
             url = new URL(protocol, host, port, file, handler);
-            assertEquals("vfszip:/some%20dir/some.jar/org/python/core/PySystemState.class", url.toString());
-            assertEquals("/some dir/some.jar", Py.getJarFileNameFromURL(url));
+            assertEquals("vfszip:/some%20dir/some.jar" + classPart, url.toString());
+            result = Py.getJarFileNameFromURL(url);
+            assertEquals("/some dir/some.jar", result);
             // jboss url with + to escape
-            file = "/some+dir/some.jar/org/python/core/PySystemState.class";
+            file = "/some+dir/some.jar" + classPart;
             url = new URL(protocol, host, port, file, handler);
-            assertEquals("vfszip:/some+dir/some.jar/org/python/core/PySystemState.class", url.toString());
-            assertEquals("/some+dir/some.jar", Py.getJarFileNameFromURL(url));
+            assertEquals("vfszip:/some+dir/some.jar" + classPart, url.toString());
+            result = Py.getJarFileNameFromURL(url);
+            assertEquals("/some+dir/some.jar", result);
+            // jboss url with challenging JAR name (assume will be provided RFC-2396 encoded)
+            file = "/n%c3%a5gon/katalog/r%c3%a4tt.jar" + classPart;
+            url = new URL(protocol, host, port, file, handler);
+            assertEquals("vfszip:/n%c3%a5gon/katalog/r%c3%a4tt.jar" + classPart, url.toString());
+            result = Py.getJarFileNameFromURL(url);
+            assertEquals("/någon/katalog/rätt.jar", result);
         }
     }
 

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


More information about the Jython-checkins mailing list