You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tinkerpop.apache.org by fl...@apache.org on 2018/03/15 17:19:43 UTC

[1/9] tinkerpop git commit: TINKERPOP-1898 Can't seem to fix this in a consistent way given jython evaluation [Forced Update!]

Repository: tinkerpop
Updated Branches:
  refs/heads/TINKERPOP-1854 c7a82c6ed -> 11351a828 (forced update)


TINKERPOP-1898 Can't seem to fix this in a consistent way given jython evaluation

Jython seems to have problems with varargs that are not easily resolved. Nothing I've tried works consistently. Sometimes it works and other times not.


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

Branch: refs/heads/TINKERPOP-1854
Commit: c82d06e05cfcc05607dd2d84c0c2d1475f0a0ddf
Parents: c677a21
Author: Stephen Mallette <sp...@genoprime.com>
Authored: Mon Mar 12 11:53:57 2018 -0400
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Mon Mar 12 11:56:16 2018 -0400

----------------------------------------------------------------------
 .../tinkerpop/gremlin/python/jsr223/JythonTranslatorTest.java      | 2 ++
 1 file changed, 2 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/c82d06e0/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 343819c..3165df3 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
@@ -29,6 +29,7 @@ import org.apache.tinkerpop.gremlin.process.traversal.strategy.verification.Read
 import org.apache.tinkerpop.gremlin.structure.Vertex;
 import org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerFactory;
 import org.apache.tinkerpop.gremlin.util.function.Lambda;
+import org.junit.Ignore;
 import org.junit.Test;
 
 import java.util.ArrayList;
@@ -108,6 +109,7 @@ public class JythonTranslatorTest {
     }
 
     @Test
+    @Ignore("TINKERPOP-1898 - ultimately seems to be a problem with jython and varargs - doesn't act consistently")
     public void shouldTranslateToJythonWhenUsingLambdasAndStrategies() throws Exception {
         // the jython translation kicks in when you add a lambda so ensure that it translates when strategies are
         // present


[3/9] tinkerpop git commit: TINKERPOP-1895 Fixed jython based evaluations of withStrategies

Posted by fl...@apache.org.
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-1854
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());
+    }
 }


[9/9] tinkerpop git commit: TINKERPOP-1854 Make Lambda implementation internal

Posted by fl...@apache.org.
TINKERPOP-1854 Make Lambda implementation internal


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

Branch: refs/heads/TINKERPOP-1854
Commit: 11351a8284c7bac6c63f06152fb882d5e9faae34
Parents: 0cdaa3a
Author: Florian Hockmann <fh...@florian-hockmann.de>
Authored: Thu Mar 15 18:15:53 2018 +0100
Committer: Florian Hockmann <fh...@florian-hockmann.de>
Committed: Thu Mar 15 18:16:05 2018 +0100

----------------------------------------------------------------------
 .../src/Gremlin.Net/Process/Traversal/Lambda.cs | 45 +++++++-------------
 .../Process/Traversal/StringBasedLambda.cs      | 42 ++++++++++++++++++
 .../Structure/IO/GraphSON/GraphSONWriter.cs     |  2 +-
 .../Structure/IO/GraphSON/LambdaSerializer.cs   |  2 +-
 4 files changed, 60 insertions(+), 31 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/11351a82/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/Lambda.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/Lambda.cs b/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/Lambda.cs
index 21849ef..12eb016 100644
--- a/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/Lambda.cs
+++ b/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/Lambda.cs
@@ -26,47 +26,34 @@ namespace Gremlin.Net.Process.Traversal
     /// <summary>
     ///     Represents a lambda.
     /// </summary>
-    public class Lambda : IFunction, IBiFunction, IPredicate, IUnaryOperator, IBinaryOperator, IComparator, IConsumer,
-        ISupplier
+    public interface ILambda : IFunction, IBiFunction, IPredicate, IUnaryOperator, IBinaryOperator, IComparator,
+        IConsumer, ISupplier
     {
-        private const int DefaultArgument = -1;
-
-        private Lambda(string expression, string language)
-        {
-            LambdaExpression = expression;
-            Language = language;
-        }
-
-        /// <summary>
-        ///     Gets the lambda expression.
-        /// </summary>
-        public string LambdaExpression { get; }
-
-        /// <summary>
-        ///     Gets the language of this lambda.
-        /// </summary>
-        public string Language { get; }
-
-        internal object Arguments => DefaultArgument;
+    }
 
+    /// <summary>
+    ///     Provides methods to create lambdas.
+    /// </summary>
+    public static class Lambda
+    {
         /// <summary>
-        ///     Creates a new Groovy <see cref="Lambda"/>.
+        ///     Creates a new Groovy lambda.
         /// </summary>
         /// <param name="expression">The lambda expression.</param>
-        /// <returns>The created <see cref="Lambda"/>.</returns>
-        public static Lambda Groovy(string expression)
+        /// <returns>The created lambda.</returns>
+        public static ILambda Groovy(string expression)
         {
-            return new Lambda(expression, "gremlin-groovy");
+            return new StringBasedLambda(expression, "gremlin-groovy");
         }
 
         /// <summary>
-        ///     Creates a new Python <see cref="Lambda"/>.
+        ///     Creates a new Python lambda.
         /// </summary>
         /// <param name="expression">The lambda expression.</param>
-        /// <returns>The created <see cref="Lambda"/>.</returns>
-        public static Lambda Python(string expression)
+        /// <returns>The created lambda.</returns>
+        public static ILambda Python(string expression)
         {
-            return new Lambda(expression, "gremlin-python");
+            return new StringBasedLambda(expression, "gremlin-python");
         }
     }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/11351a82/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/StringBasedLambda.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/StringBasedLambda.cs b/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/StringBasedLambda.cs
new file mode 100644
index 0000000..e27b474
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/StringBasedLambda.cs
@@ -0,0 +1,42 @@
+#region License
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#endregion
+
+namespace Gremlin.Net.Process.Traversal
+{
+    internal class StringBasedLambda : ILambda
+    {
+        private const int DefaultArgument = -1;
+
+        public StringBasedLambda(string expression, string language)
+        {
+            LambdaExpression = expression;
+            Language = language;
+        }
+
+        public string LambdaExpression { get; }
+
+        public string Language { get; }
+
+        public object Arguments => DefaultArgument;
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/11351a82/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/GraphSONWriter.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/GraphSONWriter.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/GraphSONWriter.cs
index 826d608..7185868 100644
--- a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/GraphSONWriter.cs
+++ b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/GraphSONWriter.cs
@@ -60,7 +60,7 @@ namespace Gremlin.Net.Structure.IO.GraphSON
                 {typeof(Property), new PropertySerializer()},
                 {typeof(VertexProperty), new VertexPropertySerializer()},
                 {typeof(AbstractTraversalStrategy), new TraversalStrategySerializer()},
-                {typeof(Lambda), new LambdaSerializer()}
+                {typeof(ILambda), new LambdaSerializer()}
             };
 
         /// <summary>

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/11351a82/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/LambdaSerializer.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/LambdaSerializer.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/LambdaSerializer.cs
index fa739fd..180253e 100644
--- a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/LambdaSerializer.cs
+++ b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/LambdaSerializer.cs
@@ -30,7 +30,7 @@ namespace Gremlin.Net.Structure.IO.GraphSON
     {
         public Dictionary<string, dynamic> Dictify(dynamic objectData, GraphSONWriter writer)
         {
-            Lambda lambda = objectData;
+            StringBasedLambda lambda = objectData;
             var valueDict = new Dictionary<string, dynamic>
             {
                 {"script", lambda.LambdaExpression},


[4/9] tinkerpop git commit: TINKERPOP-1896 Fixed bug in lambda processing for python

Posted by fl...@apache.org.
TINKERPOP-1896 Fixed bug in lambda processing for python

When a lambda is in a traversal, the bytecode gets pushed to a scriptengine for evaluation. For python that means, using the JythonTranslator. Prior to this change the JythonTranslator largely relied on the PythonTranslator to convert bytecode to Jython-syntaxed Gremlin. The problem there is that in the JythonScriptEngine, the Traversal bindings are Java objects and so if translated to pure Python syntax, traversal steps like as() become as_() and thus not part of the Java API that is expected - and then errors. Not sure why this didn't come up sooner, but it really only ends up being an issue if you are using bytecode, use gremlin server, use jython in gremlin server and then submit a traversal with a lambda - so perhaps that hasn't been a common combination.


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

Branch: refs/heads/TINKERPOP-1854
Commit: 5feadbddba308a6999649dffb193cf7d31b4645c
Parents: f80a542
Author: Stephen Mallette <sp...@genoprime.com>
Authored: Thu Mar 8 17:15:34 2018 -0500
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Mon Mar 12 11:56:16 2018 -0400

----------------------------------------------------------------------
 CHANGELOG.asciidoc                              |  1 +
 .../jsr223/GremlinJythonScriptEngine.java       |  7 +--
 .../gremlin/python/jsr223/JythonTranslator.java |  9 ++++
 .../gremlin/python/jsr223/PythonTranslator.java | 19 +++++---
 .../python/jsr223/JythonTranslatorTest.java     | 47 +++++++++-----------
 5 files changed, 44 insertions(+), 39 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/5feadbdd/CHANGELOG.asciidoc
----------------------------------------------------------------------
diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc
index 66fbbb2..a761003 100644
--- a/CHANGELOG.asciidoc
+++ b/CHANGELOG.asciidoc
@@ -30,6 +30,7 @@ image::https://raw.githubusercontent.com/apache/tinkerpop/master/docs/static/ima
 * Fixed deserialization of `P.not()` for GraphSON.
 * 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 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/5feadbdd/gremlin-python/src/main/java/org/apache/tinkerpop/gremlin/python/jsr223/GremlinJythonScriptEngine.java
----------------------------------------------------------------------
diff --git a/gremlin-python/src/main/java/org/apache/tinkerpop/gremlin/python/jsr223/GremlinJythonScriptEngine.java b/gremlin-python/src/main/java/org/apache/tinkerpop/gremlin/python/jsr223/GremlinJythonScriptEngine.java
index 10f4790..a28a58f 100644
--- a/gremlin-python/src/main/java/org/apache/tinkerpop/gremlin/python/jsr223/GremlinJythonScriptEngine.java
+++ b/gremlin-python/src/main/java/org/apache/tinkerpop/gremlin/python/jsr223/GremlinJythonScriptEngine.java
@@ -41,11 +41,11 @@ import java.lang.reflect.Method;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
-import java.util.Map;
 import java.util.stream.Collectors;
 
 /**
  * @author Marko A. Rodriguez (http://markorodriguez.com)
+ * @author Stephen Mallette (http://stephen.genoprime.com)
  */
 public class GremlinJythonScriptEngine implements GremlinScriptEngine {
 
@@ -123,10 +123,7 @@ public class GremlinJythonScriptEngine implements GremlinScriptEngine {
         // extract the named traversalsource prior to that happening so that bytecode bindings can share the same
         // namespace as global bindings (e.g. traversalsources and graphs).
         if (traversalSource.equals(HIDDEN_G))
-            throw new IllegalArgumentException("The traversalSource cannot have the name " + HIDDEN_G+ " - it is reserved");
-
-        if (bindings.containsKey(HIDDEN_G))
-            throw new IllegalArgumentException("Bindings cannot include " + HIDDEN_G + " - it is reserved");
+            throw new IllegalArgumentException("The traversalSource cannot have the name " + HIDDEN_G + " - it is reserved");
 
         if (!bindings.containsKey(traversalSource))
             throw new IllegalArgumentException("The bindings available to the ScriptEngine do not contain a traversalSource named: " + traversalSource);

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/5feadbdd/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 0eb8961..f8a5bc3 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
@@ -23,6 +23,7 @@ import org.apache.tinkerpop.gremlin.util.function.Lambda;
 
 /**
  * @author Marko A. Rodriguez (http://markorodriguez.com)
+ * @author Stephen Mallette (http://stephen.genoprime.com)
  */
 public final class JythonTranslator extends PythonTranslator {
 
@@ -54,4 +55,12 @@ public final class JythonTranslator extends PythonTranslator {
         else
             return "JythonUnknownArgLambda(" + lambdaString + ")";
     }
+
+    @Override
+    protected String resolveSymbol(final String methodName) {
+        // since this is Jython we should expect the Gremlin to conform to the java classes to which the engine is
+        // bound - therefore, unlike the python engine which converts java names to python friendly ones, this
+        // jython one can just pass them through.
+        return methodName;
+    }
 }

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/5feadbdd/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 4af4578..7c74b85 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
@@ -56,6 +56,7 @@ import java.util.stream.Stream;
 
 /**
  * @author Marko A. Rodriguez (http://markorodriguez.com)
+ * @author Stephen Mallette (http://stephen.genoprime.com)
  */
 public class PythonTranslator implements Translator.ScriptTranslator {
 
@@ -114,7 +115,7 @@ public class PythonTranslator implements Translator.ScriptTranslator {
                     instruction.getArguments()[0].toString().contains("TranslationStrategy"))
                 continue;
             else if (0 == arguments.length)
-                traversalScript.append(".").append(SymbolHelper.toPython(methodName)).append("()");
+                traversalScript.append(".").append(resolveSymbol(methodName)).append("()");
             else if (methodName.equals("range") && 2 == arguments.length)
                 traversalScript.append("[").append(arguments[0]).append(":").append(arguments[1]).append("]");
             else if (methodName.equals("limit") && 1 == arguments.length)
@@ -123,7 +124,7 @@ public class PythonTranslator implements Translator.ScriptTranslator {
                 traversalScript.append(".").append(arguments[0]);
             else {
                 traversalScript.append(".");
-                String temp = SymbolHelper.toPython(methodName) + "(";
+                String temp = resolveSymbol(methodName) + "(";
                 for (final Object object : arguments) {
                     temp = temp + convertToString(object) + ",";
                 }
@@ -131,7 +132,7 @@ public class PythonTranslator implements Translator.ScriptTranslator {
             }
             // clip off __.
             if (this.importStatics && traversalScript.substring(0, 3).startsWith("__.")
-                    && !NO_STATIC.stream().filter(name -> traversalScript.substring(3).startsWith(SymbolHelper.toPython(name))).findAny().isPresent()) {
+                    && !NO_STATIC.stream().filter(name -> traversalScript.substring(3).startsWith(resolveSymbol(name))).findAny().isPresent()) {
                 traversalScript.delete(0, 3);
             }
         }
@@ -183,13 +184,13 @@ public class PythonTranslator implements Translator.ScriptTranslator {
         else if (object instanceof Class)
             return ((Class) object).getCanonicalName();
         else if (object instanceof VertexProperty.Cardinality)
-            return "Cardinality." + SymbolHelper.toPython(object.toString());
+            return "Cardinality." + resolveSymbol(object.toString());
         else if (object instanceof SackFunctions.Barrier)
-            return "Barrier." + SymbolHelper.toPython(object.toString());
+            return "Barrier." + resolveSymbol(object.toString());
         else if (object instanceof TraversalOptionParent.Pick)
-            return "Pick." + SymbolHelper.toPython(object.toString());
+            return "Pick." + resolveSymbol(object.toString());
         else if (object instanceof Enum)
-            return convertStatic(((Enum) object).getDeclaringClass().getSimpleName() + ".") + SymbolHelper.toPython(object.toString());
+            return convertStatic(((Enum) object).getDeclaringClass().getSimpleName() + ".") + resolveSymbol(object.toString());
         else if (object instanceof P)
             return convertPToString((P) object, new StringBuilder()).toString();
         else if (object instanceof Element) {
@@ -237,4 +238,8 @@ public class PythonTranslator implements Translator.ScriptTranslator {
         return lambdaString.startsWith("lambda") ? lambdaString : "lambda " + lambdaString;
     }
 
+    protected String resolveSymbol(final String methodName) {
+        return SymbolHelper.toPython(methodName);
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/5feadbdd/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 5165120..86e3b78 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
@@ -22,11 +22,11 @@ package org.apache.tinkerpop.gremlin.python.jsr223;
 import org.apache.tinkerpop.gremlin.process.traversal.Traverser;
 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.structure.Vertex;
 import org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerFactory;
 import org.apache.tinkerpop.gremlin.util.function.Lambda;
-import org.junit.Ignore;
 import org.junit.Test;
 
 import java.util.ArrayList;
@@ -37,39 +37,15 @@ import static org.junit.Assert.assertFalse;
 
 /**
  * @author Marko A. Rodriguez (http://markorodriguez.com)
+ * @author Stephen Mallette (http://stephen.genoprime.com)
  */
-@Ignore
 public class JythonTranslatorTest {
 
-    /*@Test
-    public void shouldHandleStrategies() throws Exception {
-        GraphTraversalSource g = TinkerFactory.createModern().traversal();
-        g = g.withStrategies(new HashMap<String, Object>() {{
-            put(SubgraphStrategy.STRATEGY, SubgraphStrategy.class.getCanonicalName());
-            put(SubgraphStrategy.VERTICES, __.has("name", "marko"));
-        }});
-        final Bindings bindings = new SimpleBindings();
-        bindings.put("g", g);
-        //System.out.println(JythonTranslator.of("g").translate(g.V().values("name").asAdmin().getBytecode()));
-        Traversal.Admin<Vertex, String> traversal = ((GremlinScriptEngine) ScriptEngineCache.get("gremlin-jython")).eval(g.V().values("name").asAdmin().getBytecode(), bindings);
-        assertEquals("marko", traversal.next());
-        assertFalse(traversal.hasNext());
-        //
-        g = g.withStrategies(new HashMap<String, Object>() {{
-            put(SubgraphStrategy.STRATEGY, SubgraphStrategy.class.getCanonicalName());
-            put(SubgraphStrategy.VERTICES, __.has("name", "marko"));
-        }}, Collections.singletonMap(ReadOnlyStrategy.STRATEGY, ReadOnlyStrategy.class.getCanonicalName()));
-        //System.out.println(JythonTranslator.of("g").translate(g.V().values("name").asAdmin().getBytecode()));
-        traversal = ((GremlinScriptEngine) ScriptEngineCache.get("gremlin-jython")).eval(g.V().values("name").asAdmin().getBytecode(), bindings);
-        assertEquals("marko", traversal.next());
-        assertFalse(traversal.hasNext());
-    }*/
-
     @Test
     public void shouldSupportStringSupplierLambdas() throws Exception {
         GraphTraversalSource g = TinkerFactory.createModern().traversal();
         g = g.withStrategies(new TranslationStrategy(g, JythonTranslator.of("g")));
-        GraphTraversal.Admin<Vertex, Integer> t = g.withSideEffect("lengthSum", 0).withSack(1)
+        final GraphTraversal.Admin<Vertex, Integer> t = g.withSideEffect("lengthSum", 0).withSack(1)
                 .V()
                 .filter(Lambda.predicate("x : x.get().label() == 'person'"))
                 .flatMap(Lambda.function("lambda x : x.get().vertices(Direction.OUT)"))
@@ -110,4 +86,21 @@ public class JythonTranslatorTest {
     public void shouldHaveValidToString() {
         assertEquals("translator[h:gremlin-jython]", JythonTranslator.of("h").toString());
     }
+
+    @Test
+    public void shouldTranslateToJythonAndNotPython() throws Exception {
+        // the jython translation bind "g" to java classes and thus does not require the strict python syntax which
+        // converts steps like as() to as_(). if those steps are converted then the traversal does not evaluate
+        // properly in the python engine. not much of an assertion here to worry about - just need to ensure that
+        // the traversal with such steps evaluates to success
+        GraphTraversalSource g = TinkerFactory.createModern().traversal();
+        g = g.withStrategies(new TranslationStrategy(g, JythonTranslator.of("g")));
+        final List<Object> o = g.V().has("name").
+                match(__.as("x").label().as("lbl"),
+                        __.as("x").id().as("id")).
+                select("lbl", "id").
+                                 map(Lambda.function("lambda x: type(x.get())")).toList();
+
+        assertEquals(6, o.size());
+    }
 }


[7/9] tinkerpop git commit: TINKERPOP-1922 P.Not() serialization is no longer an issue

Posted by fl...@apache.org.
TINKERPOP-1922 P.Not() serialization is no longer an issue

Resolved on a different issue - likely TINKERPOP-1894 CTR


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

Branch: refs/heads/TINKERPOP-1854
Commit: 0bf9b2f718f7db8344845d8fb5327ea16f1e9414
Parents: 1ea01ad
Author: Stephen Mallette <sp...@genoprime.com>
Authored: Thu Mar 15 10:33:45 2018 -0400
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Thu Mar 15 10:33:45 2018 -0400

----------------------------------------------------------------------
 .../Gherkin/GherkinTestRunner.cs                      | 14 +-------------
 1 file changed, 1 insertion(+), 13 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/0bf9b2f7/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/GherkinTestRunner.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/GherkinTestRunner.cs b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/GherkinTestRunner.cs
index c3819fe..e15a492 100644
--- a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/GherkinTestRunner.cs
+++ b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/GherkinTestRunner.cs
@@ -41,19 +41,7 @@ namespace Gremlin.Net.IntegrationTest.Gherkin
             new Dictionary<string, IgnoreReason>
             {
                 {"g_V_hasIdXwithinXemptyXX_count", IgnoreReason.PWithinWrapsArgumentsInArray},
-                {"g_VX1X_out_aggregateXxX_out_whereXnotXwithinXaXXX", IgnoreReason.PWithinWrapsArgumentsInArray},
-                {
-                    "g_V_asXaX_out_asXbX_whereXandXasXaX_outXknowsX_asXbX__orXasXbX_outXcreatedX_hasXname_rippleX__asXbX_inXknowsX_count_isXnotXeqX0XXXXX_selectXa_bX",
-                    IgnoreReason.PNotDeserializationProblem
-                },
-                {
-                    "g_V_hasLabelXpersonX_hasXage_notXlteX10X_andXnotXbetweenX11_20XXXX_andXltX29X_orXeqX35XXXX_name",
-                    IgnoreReason.PNotDeserializationProblem
-                },
-                {
-                    "g_V_asXaX_outXcreatedX_asXbX_inXcreatedX_asXcX_bothXknowsX_bothXknowsX_asXdX_whereXc__notXeqXaX_orXeqXdXXXX_selectXa_b_c_dX",
-                    IgnoreReason.PNotDeserializationProblem
-                }
+                {"g_VX1X_out_aggregateXxX_out_whereXnotXwithinXaXXX", IgnoreReason.PWithinWrapsArgumentsInArray}
             };
         
         private static class Keywords


[2/9] tinkerpop git commit: TINKERPOP-1898 Specifically tested SubgraphStrategy for jython evaluation

Posted by fl...@apache.org.
TINKERPOP-1898 Specifically tested SubgraphStrategy for jython evaluation


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

Branch: refs/heads/TINKERPOP-1854
Commit: c677a21d3fde73c496145915c66e7963c5290f69
Parents: f3172bc
Author: Stephen Mallette <sp...@genoprime.com>
Authored: Fri Mar 9 10:17:09 2018 -0500
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Mon Mar 12 11:56:16 2018 -0400

----------------------------------------------------------------------
 .../tinkerpop/gremlin/python/jsr223/JythonTranslator.java   | 2 +-
 .../gremlin/python/jsr223/JythonTranslatorTest.java         | 9 ++++++---
 2 files changed, 7 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/c677a21d/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 3d7d9fe..e043278 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
@@ -80,6 +80,6 @@ public final class JythonTranslator extends PythonTranslator {
         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())) + "))";
+            return proxy.getStrategyClass().getCanonicalName() + ".create(org.apache.commons.configuration.MapConfiguration(" + convertToString(ConfigurationConverter.getMap(proxy.getConfiguration())) + "))";
     }
 }

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/c677a21d/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 e35898b..343819c 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
@@ -23,6 +23,7 @@ import org.apache.tinkerpop.gremlin.process.traversal.Traverser;
 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.SubgraphStrategy;
 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;
@@ -33,6 +34,7 @@ import org.junit.Test;
 import java.util.ArrayList;
 import java.util.List;
 
+import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.hasLabel;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 
@@ -111,9 +113,10 @@ public class JythonTranslatorTest {
         // 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();
+        final List<Object> o = g.withStrategies(ReadOnlyStrategy.instance(),
+                                                SubgraphStrategy.build().checkAdjacentVertices(false).vertices(hasLabel("person")).create()).
+                                 V().has("name").map(Lambda.function("lambda x: type(x.get())")).toList();
 
-        assertEquals(6, o.size());
+        assertEquals(4, o.size());
     }
 }


[5/9] tinkerpop git commit: TINKERPOP-1896 Cleaned up changelog around TINKERPOP-1898/1895

Posted by fl...@apache.org.
TINKERPOP-1896 Cleaned up changelog around TINKERPOP-1898/1895


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

Branch: refs/heads/TINKERPOP-1854
Commit: 01ef6c110cc323643653c716fbb85fcf433dc418
Parents: c82d06e
Author: Stephen Mallette <sp...@genoprime.com>
Authored: Mon Mar 12 12:19:18 2018 -0400
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Mon Mar 12 12:19:18 2018 -0400

----------------------------------------------------------------------
 CHANGELOG.asciidoc | 1 -
 1 file changed, 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/01ef6c11/CHANGELOG.asciidoc
----------------------------------------------------------------------
diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc
index 350fce8..a761003 100644
--- a/CHANGELOG.asciidoc
+++ b/CHANGELOG.asciidoc
@@ -31,7 +31,6 @@ 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.


[8/9] tinkerpop git commit: TINKERPOP-1919 Add Lambda support to Gremlin.Net

Posted by fl...@apache.org.
TINKERPOP-1919 Add Lambda support to Gremlin.Net

This adds a Lambda class that can be used to construct Groovy or Python
lambdas. The Lambda class implements all interfaces that mirror Javas
functional interfaces like Function.


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

Branch: refs/heads/TINKERPOP-1854
Commit: 0cdaa3a2114670a34999aa56e0487a2e7ef998e1
Parents: 0bf9b2f
Author: Florian Hockmann <fh...@florian-hockmann.de>
Authored: Wed Mar 14 18:56:47 2018 +0100
Committer: Florian Hockmann <fh...@florian-hockmann.de>
Committed: Thu Mar 15 18:16:05 2018 +0100

----------------------------------------------------------------------
 CHANGELOG.asciidoc                              |  1 +
 docs/src/reference/gremlin-variants.asciidoc    | 29 ++++++--
 .../upgrade/release-3.2.x-incubating.asciidoc   |  7 ++
 gremlin-dotnet/glv/generate.groovy              |  4 +-
 .../Process/Traversal/GraphTraversalSource.cs   | 52 +++++++++++++-
 .../Gremlin.Net/Process/Traversal/ISupplier.cs  | 32 +++++++++
 .../Process/Traversal/IUnaryOperator.cs         | 33 +++++++++
 .../src/Gremlin.Net/Process/Traversal/Lambda.cs | 72 ++++++++++++++++++++
 .../Structure/IO/GraphSON/GraphSONWriter.cs     |  3 +-
 .../Structure/IO/GraphSON/LambdaSerializer.cs   | 43 ++++++++++++
 .../Gherkin/CommonSteps.cs                      |  2 +-
 .../Gherkin/IgnoreException.cs                  |  4 --
 .../TraversalEvaluation/TraversalParser.cs      |  2 +-
 .../IO/GraphSON/GraphSONWriterTests.cs          | 13 ++++
 14 files changed, 282 insertions(+), 15 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/0cdaa3a2/CHANGELOG.asciidoc
----------------------------------------------------------------------
diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc
index 94ee24f..8fcbe1a 100644
--- a/CHANGELOG.asciidoc
+++ b/CHANGELOG.asciidoc
@@ -23,6 +23,7 @@ image::https://raw.githubusercontent.com/apache/tinkerpop/master/docs/static/ima
 [[release-3-2-8]]
 === TinkerPop 3.2.8 (Release Date: NOT OFFICIALLY RELEASED YET)
 
+* Added a `Lambda` class to Gremlin.Net that makes it possible to use Groovy and Python lambdas with Gremlin.Net.
 * Enums are now represented as classes in Gremlin.Net which allows to use them as arguments in more steps.
 * Bumped to Groovy 2.4.14.
 * Added `checkAdjacentVertices` option to `SubgraphStrategy`.

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/0cdaa3a2/docs/src/reference/gremlin-variants.asciidoc
----------------------------------------------------------------------
diff --git a/docs/src/reference/gremlin-variants.asciidoc b/docs/src/reference/gremlin-variants.asciidoc
index ace8119..bf8c8b1 100644
--- a/docs/src/reference/gremlin-variants.asciidoc
+++ b/docs/src/reference/gremlin-variants.asciidoc
@@ -46,7 +46,7 @@ implementation of Gremlin and serves as the foundation by which all other Gremli
 === The Lambda Solution
 
 Supporting link:https://en.wikipedia.org/wiki/Anonymous_function[anonymous functions] across languages is difficult as
-most language do not support lambda introspection and thus, code analysis. In Gremlin-Java, Java8 lambdas can be leveraged.
+most languages do not support lambda introspection and thus, code analysis. In Gremlin-Java, Java8 lambdas can be leveraged.
 
 [source,java]
 g.V().out("knows").map(t -> t.get().value("name") + " is the friend name") <1>
@@ -281,7 +281,7 @@ re-construction machine-side.
 === The Lambda Solution
 
 Supporting link:https://en.wikipedia.org/wiki/Anonymous_function[anonymous functions] across languages is difficult as
-most language do not support lambda introspection and thus, code analysis. In Gremlin-Python,
+most languages do not support lambda introspection and thus, code analysis. In Gremlin-Python,
 a link:https://docs.python.org/2/reference/expressions.html#lambda[Python lambda] should be represented as a zero-arg callable
 that returns a string representation of a lambda. The default lambda language is `gremlin-python` and can be changed via
 `gremlin_python.statics.default_lambda_language`. When the lambda is represented in `Bytecode` its language is encoded
@@ -343,8 +343,10 @@ var g = graph.Traversal().WithRemote(new DriverRemoteConnection(new GremlinClien
 
 When a traversal from the `GraphTraversalSource` is iterated, the traversal’s `Bytecode` is sent over the wire via the registered
 `IRemoteConnection`. The bytecode is used to construct the equivalent traversal at the remote traversal source.
-Since Gremlin.Net currently doesn't support lambda expressions, all traversals can be translated to Gremlin-Java on the remote
-location (e.g. Gremlin Server).
+Moreover, typically the bytecode is analyzed to determine which language the bytecode should be translated to. If the traversal
+does not contain lambdas, the remote location (e.g. Gremlin Server) will typically
+use Gremlin-Java. If it has lambdas written in Groovy, it will use Gremlin-Groovy (e.g. `GremlinGroovyScriptEngine`).
+Likewise, if it has lambdas represented in Python, it will use Gremlin-Python (e.g. `GremlinJythonScriptEngine`).
 
 IMPORTANT: Gremlin.Net’s `ITraversal` interface supports the standard Gremlin methods such as `Next()`, `NextTraverser()`, `ToSet()`,
 `ToList()`, etc. Such "terminal" methods trigger the evaluation of the traversal.
@@ -433,6 +435,25 @@ NOTE: Many of the TraversalStrategy classes in Gremlin.Net are proxies to the re
 JVM-based Gremlin traversal machine. As such, their `Apply(ITraversal)` method does nothing. However, the strategy is
 encoded in the Gremlin.Net bytecode and transmitted to the Gremlin traversal machine for re-construction machine-side.
 
+=== The Lambda Solution
+
+Supporting link:https://en.wikipedia.org/wiki/Anonymous_function[anonymous functions] across languages is difficult as
+most languages do not support lambda introspection and thus, code analysis. While Gremlin.Net doesn't support C# lambdas, it
+is still able to represent lambdas in other languages. When the lambda is represented in `Bytecode` its language is encoded
+such that the remote connection host can infer which translator and ultimate execution engine to use.
+
+[source,csharp]
+----
+g.V().Out().Map<int>(Lambda.Groovy("it.get().value('name').length()")).Sum<int>().ToList();      <1>
+g.V().Out().Map<int>(Lambda.Python("lambda x: len(x.get().value('name'))")).Sum<int>().ToList(); <2>
+----
+
+<1> `Lambda.Groovy()` can be used to create a Groovy lambda. 
+<2> `Lambda.Python()` can be used to create a Python lambda.
+
+The `Lambda` class implements interfaces like `IFunction` and `IPredicate` that mirror their Java counterparts which makes it possible
+to use lambdas with Gremlin.Net for the same steps as in Gremlin-Java.
+
 [[gremlin-javascript]]
 == Gremlin-JavaScript
 

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/0cdaa3a2/docs/src/upgrade/release-3.2.x-incubating.asciidoc
----------------------------------------------------------------------
diff --git a/docs/src/upgrade/release-3.2.x-incubating.asciidoc b/docs/src/upgrade/release-3.2.x-incubating.asciidoc
index 0848843..edc7f79 100644
--- a/docs/src/upgrade/release-3.2.x-incubating.asciidoc
+++ b/docs/src/upgrade/release-3.2.x-incubating.asciidoc
@@ -42,6 +42,13 @@ by clients that might mysteriously disappear without properly closing their conn
 
 See: link:https://issues.apache.org/jira/browse/TINKERPOP-1726[TINKERPOP-1726]
 
+==== Gremlin.Net Lambdas
+
+Gremlin.Net now has a `Lambda` class that can be used to construct Groovy or Java lambdas which will be evaluated on the
+server.
+
+See: link:https://issues.apache.org/jira/browse/TINKERPOP-1854[TINKERPOP-1854], link:http://tinkerpop.apache.org/docs/3.2.8/reference/#_the_lambda_solution_3[Reference Documentation - Gremlin.Net - The Lambda Solution].
+
 ==== Gremlin.Net Tokens Improved
 
 The various Gremlin tokens (e.g. `T`, `Order`, `Operator`, etc.) that were implemented as Enums before in Gremlin.Net

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/0cdaa3a2/gremlin-dotnet/glv/generate.groovy
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/glv/generate.groovy b/gremlin-dotnet/glv/generate.groovy
index 5057ff8..10b1008 100644
--- a/gremlin-dotnet/glv/generate.groovy
+++ b/gremlin-dotnet/glv/generate.groovy
@@ -54,10 +54,10 @@ def toCSharpTypeMap = ["Long": "long",
                        "TraversalStrategy[]": "ITraversalStrategy[]",
                        "Function": "IFunction",
                        "BiFunction": "IBiFunction",
-                       "UnaryOperator": "object",
+                       "UnaryOperator": "IUnaryOperator",
                        "BinaryOperator": "IBinaryOperator",
                        "Consumer": "IConsumer",
-                       "Supplier": "object",
+                       "Supplier": "ISupplier",
                        "Comparator": "IComparator",
                        "VertexProgram": "object"]
 

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/0cdaa3a2/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/GraphTraversalSource.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/GraphTraversalSource.cs b/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/GraphTraversalSource.cs
index 9c32559..7115016 100644
--- a/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/GraphTraversalSource.cs
+++ b/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/GraphTraversalSource.cs
@@ -104,7 +104,7 @@ namespace Gremlin.Net.Process.Traversal
             return source;
         }
 
-        public GraphTraversalSource WithSack(object initialValue, object splitOperator)
+        public GraphTraversalSource WithSack(object initialValue, IUnaryOperator splitOperator)
         {
             var source = new GraphTraversalSource(new List<ITraversalStrategy>(TraversalStrategies),
                                                   new Bytecode(Bytecode));
@@ -112,7 +112,39 @@ namespace Gremlin.Net.Process.Traversal
             return source;
         }
 
-        public GraphTraversalSource WithSack(object initialValue, object splitOperator, IBinaryOperator mergeOperator)
+        public GraphTraversalSource WithSack(object initialValue, IUnaryOperator splitOperator, IBinaryOperator mergeOperator)
+        {
+            var source = new GraphTraversalSource(new List<ITraversalStrategy>(TraversalStrategies),
+                                                  new Bytecode(Bytecode));
+            source.Bytecode.AddSource("withSack", initialValue, splitOperator, mergeOperator);
+            return source;
+        }
+
+        public GraphTraversalSource WithSack(ISupplier initialValue)
+        {
+            var source = new GraphTraversalSource(new List<ITraversalStrategy>(TraversalStrategies),
+                                                  new Bytecode(Bytecode));
+            source.Bytecode.AddSource("withSack", initialValue);
+            return source;
+        }
+
+        public GraphTraversalSource WithSack(ISupplier initialValue, IBinaryOperator mergeOperator)
+        {
+            var source = new GraphTraversalSource(new List<ITraversalStrategy>(TraversalStrategies),
+                                                  new Bytecode(Bytecode));
+            source.Bytecode.AddSource("withSack", initialValue, mergeOperator);
+            return source;
+        }
+
+        public GraphTraversalSource WithSack(ISupplier initialValue, IUnaryOperator splitOperator)
+        {
+            var source = new GraphTraversalSource(new List<ITraversalStrategy>(TraversalStrategies),
+                                                  new Bytecode(Bytecode));
+            source.Bytecode.AddSource("withSack", initialValue, splitOperator);
+            return source;
+        }
+
+        public GraphTraversalSource WithSack(ISupplier initialValue, IUnaryOperator splitOperator, IBinaryOperator mergeOperator)
         {
             var source = new GraphTraversalSource(new List<ITraversalStrategy>(TraversalStrategies),
                                                   new Bytecode(Bytecode));
@@ -136,6 +168,22 @@ namespace Gremlin.Net.Process.Traversal
             return source;
         }
 
+        public GraphTraversalSource WithSideEffect(string key, ISupplier initialValue)
+        {
+            var source = new GraphTraversalSource(new List<ITraversalStrategy>(TraversalStrategies),
+                                                  new Bytecode(Bytecode));
+            source.Bytecode.AddSource("withSideEffect", key, initialValue);
+            return source;
+        }
+
+        public GraphTraversalSource WithSideEffect(string key, ISupplier initialValue, IBinaryOperator reducer)
+        {
+            var source = new GraphTraversalSource(new List<ITraversalStrategy>(TraversalStrategies),
+                                                  new Bytecode(Bytecode));
+            source.Bytecode.AddSource("withSideEffect", key, initialValue, reducer);
+            return source;
+        }
+
         public GraphTraversalSource WithStrategies(params ITraversalStrategy[] traversalStrategies)
         {
             var source = new GraphTraversalSource(new List<ITraversalStrategy>(TraversalStrategies),

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/0cdaa3a2/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/ISupplier.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/ISupplier.cs b/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/ISupplier.cs
new file mode 100644
index 0000000..b1dda13
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/ISupplier.cs
@@ -0,0 +1,32 @@
+#region License
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#endregion
+
+namespace Gremlin.Net.Process.Traversal
+{
+    /// <summary>
+    ///     Represents a supplier of results
+    /// </summary>
+    public interface ISupplier
+    {
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/0cdaa3a2/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/IUnaryOperator.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/IUnaryOperator.cs b/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/IUnaryOperator.cs
new file mode 100644
index 0000000..b57be02
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/IUnaryOperator.cs
@@ -0,0 +1,33 @@
+#region License
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#endregion
+
+namespace Gremlin.Net.Process.Traversal
+{
+    /// <summary>
+    ///     Represents an operation on a single operand that produces a result of the same type as its operand. This is a
+    ///     specialization of Function for the case where the operand and result are of the same type.
+    /// </summary>
+    public interface IUnaryOperator : IFunction
+    {
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/0cdaa3a2/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/Lambda.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/Lambda.cs b/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/Lambda.cs
new file mode 100644
index 0000000..21849ef
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/Lambda.cs
@@ -0,0 +1,72 @@
+#region License
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#endregion
+
+namespace Gremlin.Net.Process.Traversal
+{
+    /// <summary>
+    ///     Represents a lambda.
+    /// </summary>
+    public class Lambda : IFunction, IBiFunction, IPredicate, IUnaryOperator, IBinaryOperator, IComparator, IConsumer,
+        ISupplier
+    {
+        private const int DefaultArgument = -1;
+
+        private Lambda(string expression, string language)
+        {
+            LambdaExpression = expression;
+            Language = language;
+        }
+
+        /// <summary>
+        ///     Gets the lambda expression.
+        /// </summary>
+        public string LambdaExpression { get; }
+
+        /// <summary>
+        ///     Gets the language of this lambda.
+        /// </summary>
+        public string Language { get; }
+
+        internal object Arguments => DefaultArgument;
+
+        /// <summary>
+        ///     Creates a new Groovy <see cref="Lambda"/>.
+        /// </summary>
+        /// <param name="expression">The lambda expression.</param>
+        /// <returns>The created <see cref="Lambda"/>.</returns>
+        public static Lambda Groovy(string expression)
+        {
+            return new Lambda(expression, "gremlin-groovy");
+        }
+
+        /// <summary>
+        ///     Creates a new Python <see cref="Lambda"/>.
+        /// </summary>
+        /// <param name="expression">The lambda expression.</param>
+        /// <returns>The created <see cref="Lambda"/>.</returns>
+        public static Lambda Python(string expression)
+        {
+            return new Lambda(expression, "gremlin-python");
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/0cdaa3a2/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/GraphSONWriter.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/GraphSONWriter.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/GraphSONWriter.cs
index f23d80d..826d608 100644
--- a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/GraphSONWriter.cs
+++ b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/GraphSONWriter.cs
@@ -59,7 +59,8 @@ namespace Gremlin.Net.Structure.IO.GraphSON
                 {typeof(Edge), new EdgeSerializer()},
                 {typeof(Property), new PropertySerializer()},
                 {typeof(VertexProperty), new VertexPropertySerializer()},
-                {typeof(AbstractTraversalStrategy), new TraversalStrategySerializer()}
+                {typeof(AbstractTraversalStrategy), new TraversalStrategySerializer()},
+                {typeof(Lambda), new LambdaSerializer()}
             };
 
         /// <summary>

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/0cdaa3a2/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/LambdaSerializer.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/LambdaSerializer.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/LambdaSerializer.cs
new file mode 100644
index 0000000..fa739fd
--- /dev/null
+++ b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/LambdaSerializer.cs
@@ -0,0 +1,43 @@
+#region License
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#endregion
+
+using System.Collections.Generic;
+using Gremlin.Net.Process.Traversal;
+
+namespace Gremlin.Net.Structure.IO.GraphSON
+{
+    internal class LambdaSerializer : IGraphSONSerializer
+    {
+        public Dictionary<string, dynamic> Dictify(dynamic objectData, GraphSONWriter writer)
+        {
+            Lambda lambda = objectData;
+            var valueDict = new Dictionary<string, dynamic>
+            {
+                {"script", lambda.LambdaExpression},
+                {"language", lambda.Language},
+                {"arguments", lambda.Arguments}
+            };
+            return GraphSONUtil.ToTypedValue(nameof(Lambda), valueDict);
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/0cdaa3a2/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/CommonSteps.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/CommonSteps.cs b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/CommonSteps.cs
index 0abc247..dd96474 100644
--- a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/CommonSteps.cs
+++ b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/CommonSteps.cs
@@ -233,7 +233,7 @@ namespace Gremlin.Net.IntegrationTest.Gherkin
 
         private static object ToLambda(string stringLambda, string graphName)
         {
-            throw new IgnoreException(IgnoreReason.LambdaNotSupported);
+            return Lambda.Groovy(stringLambda);
         }
 
         private static object ToNumber(string stringNumber, string graphName)

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/0cdaa3a2/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/IgnoreException.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/IgnoreException.cs b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/IgnoreException.cs
index fd226bf..9aa5213 100644
--- a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/IgnoreException.cs
+++ b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/IgnoreException.cs
@@ -40,9 +40,6 @@ namespace Gremlin.Net.IntegrationTest.Gherkin
             string reasonSuffix = null;
             switch (reason)
             {
-                case IgnoreReason.LambdaNotSupported:
-                    reasonSuffix = " because lambdas are not supported in Gremlin.NET (TINKERPOP-1854)";
-                    break;
                 case IgnoreReason.PWithinWrapsArgumentsInArray:
                     reasonSuffix = " because P.Within() arguments are incorrectly wrapped in an array (TINKERPOP-1920)";
                     break;
@@ -56,7 +53,6 @@ namespace Gremlin.Net.IntegrationTest.Gherkin
     
     public enum IgnoreReason
     {
-        LambdaNotSupported,
         PWithinWrapsArgumentsInArray,
         PNotDeserializationProblem
     }

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/0cdaa3a2/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/TraversalParser.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/TraversalParser.cs b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/TraversalParser.cs
index 11145da..7e1486c 100644
--- a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/TraversalParser.cs
+++ b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/TraversalEvaluation/TraversalParser.cs
@@ -398,7 +398,7 @@ namespace Gremlin.Net.IntegrationTest.Gherkin.TraversalEvaluation
             {
                 return ParseNumber(text, ref i);
             }
-            if (text.Substring(i, 3).StartsWith("__."))
+            if (text.Length >= i + 3 && text.Substring(i, 3).StartsWith("__."))
             {
                 var startIndex = i;
                 var tokens = ParseTokens(text, ref i);

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/0cdaa3a2/gremlin-dotnet/test/Gremlin.Net.UnitTest/Structure/IO/GraphSON/GraphSONWriterTests.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/test/Gremlin.Net.UnitTest/Structure/IO/GraphSON/GraphSONWriterTests.cs b/gremlin-dotnet/test/Gremlin.Net.UnitTest/Structure/IO/GraphSON/GraphSONWriterTests.cs
index 3e2d307..54dc8f3 100644
--- a/gremlin-dotnet/test/Gremlin.Net.UnitTest/Structure/IO/GraphSON/GraphSONWriterTests.cs
+++ b/gremlin-dotnet/test/Gremlin.Net.UnitTest/Structure/IO/GraphSON/GraphSONWriterTests.cs
@@ -333,6 +333,19 @@ namespace Gremlin.Net.UnitTest.Structure.IO.GraphSON
             const string expected = "{\"@type\":\"g:SubgraphStrategy\",\"@value\":{}}";
             Assert.Equal(expected, graphSon);
         }
+
+        [Fact]
+        public void ShouldSerializeLambda()
+        {
+            var writer = CreateStandardGraphSONWriter();
+            var lambda = Lambda.Groovy("{ it.get() }");
+
+            var graphSon = writer.WriteObject(lambda);
+
+            const string expected =
+                "{\"@type\":\"g:Lambda\",\"@value\":{\"script\":\"{ it.get() }\",\"language\":\"gremlin-groovy\",\"arguments\":-1}}";
+            Assert.Equal(expected, graphSon);
+        }
     }
 
     internal class TestGraphSONSerializer : IGraphSONSerializer


[6/9] tinkerpop git commit: Merge branch 'TINKERPOP-1896' into tp32

Posted by fl...@apache.org.
Merge branch 'TINKERPOP-1896' into tp32


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

Branch: refs/heads/TINKERPOP-1854
Commit: 1ea01ad2e0748d400cc89d92d2dbfe07dd2cb6be
Parents: 5cf1cba 01ef6c1
Author: Stephen Mallette <sp...@genoprime.com>
Authored: Wed Mar 14 07:58:22 2018 -0400
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Wed Mar 14 07:58:22 2018 -0400

----------------------------------------------------------------------
 CHANGELOG.asciidoc                              |  1 +
 .../jsr223/GremlinJythonScriptEngine.java       |  7 +--
 .../gremlin/python/jsr223/JythonTranslator.java | 28 +++++++++
 .../gremlin/python/jsr223/PythonTranslator.java | 33 ++++++----
 .../python/jsr223/JythonTranslatorTest.java     | 63 ++++++++++++--------
 5 files changed, 88 insertions(+), 44 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/1ea01ad2/CHANGELOG.asciidoc
----------------------------------------------------------------------
diff --cc CHANGELOG.asciidoc
index 97b90a5,a761003..94ee24f
--- a/CHANGELOG.asciidoc
+++ b/CHANGELOG.asciidoc
@@@ -30,8 -29,8 +30,9 @@@ image::https://raw.githubusercontent.co
  * Added the "Kitchen Sink" test data set.
  * Fixed deserialization of `P.not()` for GraphSON.
  * Bumped to Jackson 2.9.4.
 +* Improved performance of `JavaTranslator` by caching reflected methods required for traversal construction.
  * 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 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.