Skip to content

Commit 742d20d

Browse files
committed
Merge branch 'script-engine-eval'
This fixes the eval command to actually work. We no longer need to use a custom ScriptEngine -- yay!
2 parents c6f9b05 + 91ec0fd commit 742d20d

File tree

2 files changed

+46
-30
lines changed

2 files changed

+46
-30
lines changed

src/main/java/org/scijava/plugins/scripting/jython/JythonScriptLanguage.java

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@
4949
* An adapter of the Jython interpreter to the SciJava scripting interface.
5050
*
5151
* @author Johannes Schindelin
52-
* @author Mark Hiner <hinerm@gmail.com>
52+
* @author Mark Hiner
5353
* @see ScriptEngine
5454
*/
5555
@Plugin(type = ScriptLanguage.class, name = "Python")
@@ -62,15 +62,6 @@ public JythonScriptLanguage() {
6262
super("jython");
6363
}
6464

65-
@Override
66-
public ScriptEngine getScriptEngine() {
67-
// NB: recursive priorities can only be resolved via inter-service
68-
// dependencies. There is no way to make the ScriptService
69-
// depend on the JythonService because of the hierarchy
70-
// of components. So we have to get the JythonService indirectly.
71-
return context.service(JythonService.class).getScriptEngine();
72-
}
73-
7465
@Override
7566
public Object decode(final Object object) {
7667
if (object instanceof PyNone) return null;

src/test/java/org/scijava/plugins/scripting/jython/JythonTest.java

Lines changed: 45 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -36,14 +36,18 @@
3636
import static org.junit.Assert.assertSame;
3737

3838
import java.io.IOException;
39+
import java.math.BigInteger;
3940
import java.util.concurrent.ExecutionException;
4041

4142
import javax.script.Bindings;
4243
import javax.script.ScriptContext;
4344
import javax.script.ScriptEngine;
4445
import javax.script.ScriptException;
4546

47+
import org.junit.After;
48+
import org.junit.Before;
4649
import org.junit.Test;
50+
import org.python.jsr223.PyScriptEngine;
4751
import org.scijava.Context;
4852
import org.scijava.script.ScriptLanguage;
4953
import org.scijava.script.ScriptModule;
@@ -56,12 +60,24 @@
5660
*/
5761
public class JythonTest {
5862

63+
private Context context;
64+
private ScriptService scriptService;
65+
66+
@Before
67+
public void setUp() {
68+
context = new Context();
69+
scriptService = context.getService(ScriptService.class);
70+
}
71+
72+
@After
73+
public void tearDown() {
74+
context.dispose();
75+
}
76+
5977
@Test
6078
public void testBasic() throws InterruptedException, ExecutionException,
6179
IOException, ScriptException
6280
{
63-
final Context context = new Context();
64-
final ScriptService scriptService = context.getService(ScriptService.class);
6581
final String script = "1 + 2";
6682
final ScriptModule m = scriptService.run("add.py", script, true).get();
6783
final Object result = m.getLanguage().decode(m.getReturnValue());
@@ -71,12 +87,9 @@ public void testBasic() throws InterruptedException, ExecutionException,
7187

7288
@Test
7389
public void testLocals() throws ScriptException {
74-
final Context context = new Context();
75-
final ScriptService scriptService = context.getService(ScriptService.class);
76-
7790
final ScriptLanguage language = scriptService.getLanguageByExtension("py");
7891
final ScriptEngine engine = language.getScriptEngine();
79-
assertEquals(JythonScriptEngine.class, engine.getClass());
92+
assertEquals(PyScriptEngine.class, engine.getClass());
8093
engine.put("hello", 17);
8194
assertEquals(17, language.decode(engine.eval("hello")));
8295
assertEquals(17, language.decode(engine.get("hello")));
@@ -90,9 +103,6 @@ public void testLocals() throws ScriptException {
90103
public void testParameters() throws InterruptedException, ExecutionException,
91104
IOException, ScriptException
92105
{
93-
final Context context = new Context();
94-
final ScriptService scriptService = context.getService(ScriptService.class);
95-
96106
final String script = "" + //
97107
"# @ScriptService ss\n" + //
98108
"# @OUTPUT String language\n" + //
@@ -109,29 +119,26 @@ public void testParameters() throws InterruptedException, ExecutionException,
109119
* Tests that variables assigned a primitive long value have the expected
110120
* type.
111121
* <p>
112-
* There is a crazy bug in {@link org.python.jsr223.PyScriptEngine}, which
113-
* results in variables assigned a long primitive to somehow end up as (or
122+
* There was a crazy bug in {@link PyScriptEngine} version 2.5.3, which
123+
* resulted in variables assigned a long primitive to somehow end up as (or
114124
* appearing to end up as) {@link java.math.BigInteger} instances instead. See
115125
* <a href=
116126
* "http://sourceforge.net/p/jython/mailman/jython-users/thread/54370FE9.5010603%40farowl.co.uk/"
117127
* >this thread on the jython-users mailing list</a> for discussion.
118128
* </p>
119129
* <p>
120-
* This test ensures that that specific problem gets flagged if it occurs. As
121-
* long as we keep using our own Jython {@code ScriptEngine} implementation
122-
* (i.e.: {@link org.scijava.plugins.scripting.jython.JythonScriptEngine}),
123-
* the problem does not occur. But if we switch to the stock JSR-223 Jython
124-
* {@code ScriptEngine} (i.e.: {@link org.python.jsr223.PyScriptEngine}), the
125-
* problem manifests. See {@link JythonScriptLanguage#getScriptEngine()}.
130+
* This test ensures that that specific problem gets flagged if it recurs.
131+
* Previously, to avoid it, we used our own Jython {@code ScriptEngine}
132+
* implementation
133+
* ({@code org.scijava.plugins.scripting.jython.JythonScriptEngine}). But
134+
* since Jython 2.7.0, the stock JSR-223 Jython {@code ScriptEngine} (i.e.:
135+
* {@link org.python.jsr223.PyScriptEngine}) no longer has this issue.
126136
* </p>
127137
*/
128138
@Test
129139
public void testLongType() throws InterruptedException, ExecutionException,
130140
IOException, ScriptException
131141
{
132-
final Context context = new Context();
133-
final ScriptService scriptService = context.getService(ScriptService.class);
134-
135142
final String script = "" + //
136143
"# @OUTPUT String varType\n" + //
137144
"a = 10L\n" + //
@@ -142,4 +149,22 @@ public void testLongType() throws InterruptedException, ExecutionException,
142149
final String expected = "<type 'long'>";
143150
assertEquals(expected, actual);
144151
}
152+
153+
@Test
154+
public void testEval() throws ScriptException {
155+
final ScriptLanguage language = scriptService.getLanguageByExtension("py");
156+
final ScriptEngine engine = language.getScriptEngine();
157+
assertEquals(PyScriptEngine.class, engine.getClass());
158+
159+
final Object sum = engine.eval("2 + 3");
160+
assertEquals(5, sum);
161+
162+
final String n1 = "112233445566778899";
163+
final String n2 = "998877665544332211";
164+
final Object bigNum = engine.eval(n1 + "*" + n2);
165+
assertEquals(new BigInteger(n1).multiply(new BigInteger(n2)), bigNum);
166+
167+
final Object varAssign = engine.eval("a = 4 + 5");
168+
assertNull(varAssign);
169+
}
145170
}

0 commit comments

Comments
 (0)