TINKERPOP-1895 Fixed jython based evaluations of withStrategies

Similar to TINKERPOP-1896 in that a lambda would trigger a scriptengine 
evaluation with jython which would fail when withStrategies() was used as the 
JythonTranslator was actually producing Python valid code rather than Jython 
valid code.


Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/f3172bc5
Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/f3172bc5
Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/f3172bc5

Branch: refs/heads/TINKERPOP-1897
Commit: f3172bc55ef3e8f298dccfeb18c9fe6b4c27767c
Parents: 5feadbd
Author: Stephen Mallette <sp...@genoprime.com>
Authored: Fri Mar 9 09:38:35 2018 -0500
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Mon Mar 12 11:56:16 2018 -0400

----------------------------------------------------------------------
 CHANGELOG.asciidoc                               |  1 +
 .../gremlin/python/jsr223/JythonTranslator.java  | 19 +++++++++++++++++++
 .../gremlin/python/jsr223/PythonTranslator.java  | 14 ++++++++------
 .../python/jsr223/JythonTranslatorTest.java      | 13 +++++++++++++
 4 files changed, 41 insertions(+), 6 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/f3172bc5/CHANGELOG.asciidoc
----------------------------------------------------------------------
diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc
index a761003..350fce8 100644
--- a/CHANGELOG.asciidoc
+++ b/CHANGELOG.asciidoc
@@ -31,6 +31,7 @@ 
image::https://raw.githubusercontent.com/apache/tinkerpop/master/docs/static/ima
 * Bumped to Jackson 2.9.4.
 * Added `idleConnectionTimeout` and `keepAliveInterval` to Gremlin Server that 
enables a "ping" and auto-close for seemingly dead clients.
 * Fixed a bug where lambdas in `gremlin-python` would trigger a failure if 
steps using python-only symbols were present (such as `as_()`).
+* Fixed a bug where lambdas in `gremlin-python` would trigger a failure if 
`withStrategies()` was evaluated.
 * Fixed a bug in `NumberHelper` that led to wrong min/max results if numbers 
exceeded the Integer limits.
 * Delayed setting of the request identifier until `RequestMessage` 
construction by the builder.
 * Improved error messaging for failed serialization and deserialization of 
request/response messages.

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/f3172bc5/gremlin-python/src/main/java/org/apache/tinkerpop/gremlin/python/jsr223/JythonTranslator.java
----------------------------------------------------------------------
diff --git 
a/gremlin-python/src/main/java/org/apache/tinkerpop/gremlin/python/jsr223/JythonTranslator.java
 
b/gremlin-python/src/main/java/org/apache/tinkerpop/gremlin/python/jsr223/JythonTranslator.java
index f8a5bc3..3d7d9fe 100644
--- 
a/gremlin-python/src/main/java/org/apache/tinkerpop/gremlin/python/jsr223/JythonTranslator.java
+++ 
b/gremlin-python/src/main/java/org/apache/tinkerpop/gremlin/python/jsr223/JythonTranslator.java
@@ -19,8 +19,17 @@
 
 package org.apache.tinkerpop.gremlin.python.jsr223;
 
+import org.apache.commons.configuration.Configuration;
+import org.apache.commons.configuration.ConfigurationConverter;
+import org.apache.commons.configuration.MapConfiguration;
+import org.apache.tinkerpop.gremlin.process.traversal.TraversalStrategy;
+import 
org.apache.tinkerpop.gremlin.process.traversal.strategy.TraversalStrategyProxy;
 import org.apache.tinkerpop.gremlin.util.function.Lambda;
 
+import java.lang.reflect.InvocationTargetException;
+import java.util.HashMap;
+import java.util.Map;
+
 /**
  * @author Marko A. Rodriguez (http://markorodriguez.com)
  * @author Stephen Mallette (http://stephen.genoprime.com)
@@ -63,4 +72,14 @@ public final class JythonTranslator extends PythonTranslator 
{
         // jython one can just pass them through.
         return methodName;
     }
+
+    @Override
+    protected String resolveTraversalStrategyProxy(final 
TraversalStrategyProxy proxy) {
+        // since this is jython we don't need a traversal proxy here - we need 
the actual JVM version of the strategy
+        // since this script will be executed in Jython. 
+        if (proxy.getConfiguration().isEmpty())
+            return proxy.getStrategyClass().getCanonicalName() + ".instance()";
+        else
+            return proxy.getStrategyClass().getCanonicalName() + ".create(new 
org.apache.commons.configuration.MapConfiguration(" + 
convertToString(ConfigurationConverter.getMap(proxy.getConfiguration())) + "))";
+    }
 }

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/f3172bc5/gremlin-python/src/main/java/org/apache/tinkerpop/gremlin/python/jsr223/PythonTranslator.java
----------------------------------------------------------------------
diff --git 
a/gremlin-python/src/main/java/org/apache/tinkerpop/gremlin/python/jsr223/PythonTranslator.java
 
b/gremlin-python/src/main/java/org/apache/tinkerpop/gremlin/python/jsr223/PythonTranslator.java
index 7c74b85..d8c73f0 100644
--- 
a/gremlin-python/src/main/java/org/apache/tinkerpop/gremlin/python/jsr223/PythonTranslator.java
+++ 
b/gremlin-python/src/main/java/org/apache/tinkerpop/gremlin/python/jsr223/PythonTranslator.java
@@ -139,7 +139,7 @@ public class PythonTranslator implements 
Translator.ScriptTranslator {
         return traversalScript.toString();
     }
 
-    private String convertToString(final Object object) {
+    protected String convertToString(final Object object) {
         if (object instanceof Bytecode.Binding)
             return ((Bytecode.Binding) object).variable();
         else if (object instanceof Bytecode)
@@ -172,11 +172,7 @@ public class PythonTranslator implements 
Translator.ScriptTranslator {
         } else if (object instanceof Long)
             return object + "L";
         else if (object instanceof TraversalStrategyProxy) {
-            final TraversalStrategyProxy proxy = (TraversalStrategyProxy) 
object;
-            if (proxy.getConfiguration().isEmpty())
-                return "TraversalStrategy(\"" + 
proxy.getStrategyClass().getSimpleName() + "\")";
-            else
-                return "TraversalStrategy(\"" + 
proxy.getStrategyClass().getSimpleName() + "\"," + 
convertToString(ConfigurationConverter.getMap(proxy.getConfiguration())) + ")";
+            return resolveTraversalStrategyProxy((TraversalStrategyProxy) 
object);
         } else if (object instanceof TraversalStrategy) {
             return convertToString(new 
TraversalStrategyProxy((TraversalStrategy) object));
         } else if (object instanceof Boolean)
@@ -242,4 +238,10 @@ public class PythonTranslator implements 
Translator.ScriptTranslator {
         return SymbolHelper.toPython(methodName);
     }
 
+    protected String resolveTraversalStrategyProxy(final 
TraversalStrategyProxy proxy) {
+        if (proxy.getConfiguration().isEmpty())
+            return "TraversalStrategy(\"" + 
proxy.getStrategyClass().getSimpleName() + "\")";
+        else
+            return "TraversalStrategy(\"" + 
proxy.getStrategyClass().getSimpleName() + "\"," + 
convertToString(ConfigurationConverter.getMap(proxy.getConfiguration())) + ")";
+    }
 }

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/f3172bc5/gremlin-python/src/test/java/org/apache/tinkerpop/gremlin/python/jsr223/JythonTranslatorTest.java
----------------------------------------------------------------------
diff --git 
a/gremlin-python/src/test/java/org/apache/tinkerpop/gremlin/python/jsr223/JythonTranslatorTest.java
 
b/gremlin-python/src/test/java/org/apache/tinkerpop/gremlin/python/jsr223/JythonTranslatorTest.java
index 86e3b78..e35898b 100644
--- 
a/gremlin-python/src/test/java/org/apache/tinkerpop/gremlin/python/jsr223/JythonTranslatorTest.java
+++ 
b/gremlin-python/src/test/java/org/apache/tinkerpop/gremlin/python/jsr223/JythonTranslatorTest.java
@@ -24,6 +24,7 @@ import 
org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal;
 import 
org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource;
 import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__;
 import 
org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration.TranslationStrategy;
+import 
org.apache.tinkerpop.gremlin.process.traversal.strategy.verification.ReadOnlyStrategy;
 import org.apache.tinkerpop.gremlin.structure.Vertex;
 import org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerFactory;
 import org.apache.tinkerpop.gremlin.util.function.Lambda;
@@ -103,4 +104,16 @@ public class JythonTranslatorTest {
 
         assertEquals(6, o.size());
     }
+
+    @Test
+    public void shouldTranslateToJythonWhenUsingLambdasAndStrategies() throws 
Exception {
+        // the jython translation kicks in when you add a lambda so ensure 
that it translates when strategies are
+        // present
+        GraphTraversalSource g = TinkerFactory.createModern().traversal();
+        g = g.withStrategies(new TranslationStrategy(g, 
JythonTranslator.of("g")));
+        final List<Object> o = g.withStrategies(ReadOnlyStrategy.instance()).
+                V().has("name").map(Lambda.function("lambda x: 
type(x.get())")).toList();
+
+        assertEquals(6, o.size());
+    }
 }

Reply via email to