Skip to content

Commit 29ca150

Browse files
committed
copy JYTHONPATH to sys.path in Jython engine
extends feature request #112
1 parent 9fb0d6c commit 29ca150

File tree

3 files changed

+61
-16
lines changed

3 files changed

+61
-16
lines changed

build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,7 @@ tasks.register('testJSR223EnginePresent', Test) {
290290
useJUnitPlatform()
291291
jvmArgs JVM_ARGS
292292
systemProperty "python.import.site", false
293+
environment "JYTHONPATH", ["/foo/bar/jythonpath1", "/foo/bar/jythonpath2"].join(File.pathSeparator)
293294
scanForTestClasses = false
294295
include "org/openstreetmap/josm/plugins/scripting/jsr223/*.class"
295296
testLogging {

src/main/java/org/openstreetmap/josm/plugins/scripting/ui/ScriptExecutor.java

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,11 @@
1919
import java.awt.*;
2020
import java.io.*;
2121
import java.nio.charset.StandardCharsets;
22+
import java.util.Arrays;
2223
import java.util.Objects;
2324
import java.util.logging.Level;
2425
import java.util.logging.Logger;
26+
import java.util.stream.Collectors;
2527

2628
import static org.openstreetmap.josm.plugins.scripting.ui.SwingUtil.runOnSwingEDT;
2729
import static org.openstreetmap.josm.tools.I18n.tr;
@@ -101,17 +103,36 @@ public void runScriptWithPluggedEngine(
101103
}
102104
final Runnable task = () -> {
103105
final var bindings = engine.createBindings();
104-
// For a python script we initialize the bindings as follows:
105-
// __file__ = <full path to script file>
106-
// add the script's parent directory to sys.path
107106
if (desc.isJython()) {
107+
// For a python script we initialize the bindings as follows:
108+
// __file__ = <full path to script file>
108109
bindings.put("__file__", scriptFile.getPath());
110+
111+
// For a python script we initialize the Jython engine as follows:
112+
// add the script's parent directory to sys.path
113+
// add the paths in JYTHONPATH to sys.path
109114
final var sysPathStatement = format("import sys; sys.path.append(''{0}'')", scriptFile.getParent());
110115
try {
111116
engine.eval(sysPathStatement);
112117
} catch(ScriptException e) {
113118
logger.log(Level.WARNING, format("Failed to add ''{0}'' to sys.path", scriptFile.getParent()), e);
114119
}
120+
final var jythonPath = System.getenv("JYTHONPATH");
121+
if (jythonPath != null) {
122+
final var paths = jythonPath.split(File.pathSeparator);
123+
if (paths.length > 0) {
124+
final var script = "import sys; " +
125+
Arrays.stream(paths)
126+
.distinct()
127+
.map(path -> format("sys.path.append(''{0}'')", path))
128+
.collect(Collectors.joining("; "));
129+
try {
130+
engine.eval(script);
131+
} catch(ScriptException e) {
132+
logger.log(Level.WARNING, format("Failed to add JYTHONPATH ''{0}'' to sys.path", jythonPath), e);
133+
}
134+
}
135+
}
115136
}
116137
try {
117138
if (engine instanceof Compilable) {

src/test/unit/groovy/org/openstreetmap/josm/plugins/scripting/jsr223/JythonBindingsTest.groovy

Lines changed: 36 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,19 @@ class JythonBindingsTest extends JOSMFixtureBasedTest {
1414
public static String __file__holder = null
1515
public static boolean scriptPathInSysPath = false
1616
public static int sum = 0
17+
public static boolean jythonPathInSysPath = true
1718

18-
@Test
19-
void ensure__file__IsSet() {
20-
final jythonDesc = ScriptEngineMetaDataProvider
19+
static def getJythonDescriptor() {
20+
return ScriptEngineMetaDataProvider
2121
.getAvailablePluggedScriptEngines()
2222
.filter(desc -> desc.isJython())
2323
.findAny()
2424
.orElseThrow(() -> new IllegalStateException("No Jython scripting engine found"))
25+
}
26+
27+
@Test
28+
void ensure__file__IsSet() {
29+
final jythonDesc = jythonDescriptor
2530

2631
final executor = new ScriptExecutor(MainApplication.getMainFrame())
2732

@@ -38,11 +43,7 @@ JythonBindingsTest.__file__holder = __file__
3843

3944
@Test
4045
void ensureSysPathIsSet() {
41-
final jythonDesc = ScriptEngineMetaDataProvider
42-
.getAvailablePluggedScriptEngines()
43-
.filter(desc -> desc.isJython())
44-
.findAny()
45-
.orElseThrow(() -> new IllegalStateException("No Jython scripting engine found"))
46+
final jythonDesc = jythonDescriptor
4647

4748
final executor = new ScriptExecutor(MainApplication.getMainFrame())
4849

@@ -62,11 +63,7 @@ for path in sys.path:
6263

6364
@Test
6465
void ensureImportFromSysPathWorks() {
65-
final jythonDesc = ScriptEngineMetaDataProvider
66-
.getAvailablePluggedScriptEngines()
67-
.filter(desc -> desc.isJython())
68-
.findAny()
69-
.orElseThrow(() -> new IllegalStateException("No Jython scripting engine found"))
66+
final jythonDesc = jythonDescriptor
7067

7168
final executor = new ScriptExecutor(MainApplication.getMainFrame())
7269

@@ -91,4 +88,30 @@ JythonBindingsTest.sum = add(5,3)
9188
moduleFile.delete()
9289

9390
}
91+
92+
@Test
93+
void ensureJYTHONPATHinSysPath() {
94+
final jythonDesc = jythonDescriptor
95+
96+
final executor = new ScriptExecutor(MainApplication.getMainFrame())
97+
98+
// generate temporary script file
99+
final scriptFile = File.createTempFile("test-script", "")
100+
scriptFile.write("""
101+
import sys
102+
from java.lang import System
103+
from java.io import File
104+
from org.openstreetmap.josm.plugins.scripting.jsr223 import JythonBindingsTest
105+
jythonpath = System.getenv('JYTHONPATH')
106+
if jythonpath:
107+
paths = jythonpath.split(File.pathSeparator)
108+
result = True
109+
for path in paths:
110+
result = result and path in sys.path
111+
JythonBindingsTest.jythonPathInSysPath = result
112+
""")
113+
executor.runScriptWithPluggedEngine(jythonDesc, scriptFile)
114+
assertTrue(jythonPathInSysPath)
115+
scriptFile.delete()
116+
}
94117
}

0 commit comments

Comments
 (0)