You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tinkerpop.apache.org by ok...@apache.org on 2016/06/23 21:47:18 UTC

[2/2] tinkerpop git commit: Okay, this is massive. We now have groovy_translator.py and jython_translator.py. One is targed for GremlinGroovyScriptEngine from Python and the other is targeted for GremlinJythonScriptEngine from Python. I had to redo the w

Okay, this is massive. We now have groovy_translator.py and jython_translator.py. One is targed for GremlinGroovyScriptEngine from Python and the other is targeted for GremlinJythonScriptEngine from Python. I had to redo the way in which we test translators as now we can have multiple translators from Python. It took me a long time to wrap my head arond having to version of 'Jython' -- one is simulating CPython and the other is GremlinJython. So when we have a test translator like PythonJythonTranslator, it goes Java->CPython->Jython...its nutz. Almost have it so that CPython lambdas are simply Jython lambdas but python lambdas don't coerce to Java8 functions (yet -- I have an idea to try). Anywho, very complex stuff, but this is turning out to be a really powerful model --- Gremlin language variants are for real.


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

Branch: refs/heads/TINKERPOP-1278
Commit: 6acb89366aa161608fee1dc416ae2a7044f0cda9
Parents: 07964b2
Author: Marko A. Rodriguez <ok...@gmail.com>
Authored: Thu Jun 23 15:47:09 2016 -0600
Committer: Marko A. Rodriguez <ok...@gmail.com>
Committed: Thu Jun 23 15:47:09 2016 -0600

----------------------------------------------------------------------
 .../strategy/creation/TranslationStrategy.java  |   2 +
 gremlin-python/pom.xml                          |  18 ++-
 .../java/translator/PythonTranslator.java       |  21 +--
 .../gremlin/python/util/SymbolHelper.java       |   4 +-
 .../src/main/jython/gremlin_python/__init__.py  |   1 +
 .../jython/gremlin_python/gremlin_python.py     |  58 +++----
 .../jython/gremlin_python/jython_translator.py  | 106 +++++++++++++
 gremlin-python/src/main/jython/setup.py         |   6 +-
 .../java/translator/PythonBypassTranslator.java |  88 -----------
 .../translator/PythonTranslatorProvider.java    | 136 +++++++++++++++++
 .../java/translator/PythonTranslatorTest.java   |  93 ------------
 ...erGraphPythonTranslatorComputerProvider.java |  37 -----
 ...raphPythonTranslatorProcessComputerTest.java |  34 -----
 ...raphPythonTranslatorProcessStandardTest.java |  34 -----
 .../TinkerGraphPythonTranslatorProvider.java    | 150 -------------------
 .../groovy/PythonGroovyTranslator.java          |  89 +++++++++++
 .../PythonGroovyTranslatorComputerProvider.java |  37 +++++
 ...thonGroovyTranslatorProcessComputerTest.java |  34 +++++
 ...thonGroovyTranslatorProcessStandardTest.java |  34 +++++
 .../groovy/PythonGroovyTranslatorProvider.java  |  51 +++++++
 .../groovy/PythonGroovyTranslatorTest.java      |  96 ++++++++++++
 .../jython/PythonJythonTranslator.java          |  89 +++++++++++
 .../PythonJythonTranslatorComputerProvider.java |  37 +++++
 ...thonJythonTranslatorProcessComputerTest.java |  34 +++++
 ...thonJythonTranslatorProcessStandardTest.java |  34 +++++
 .../jython/PythonJythonTranslatorProvider.java  |  52 +++++++
 .../jython/PythonJythonTranslatorTest.java      |  97 ++++++++++++
 .../python/driver/RESTRemoteConnectionTest.java |   6 +-
 .../jsr223/GremlinJythonScriptEngineSetup.java  |  46 ------
 .../jsr223/GremlinJythonScriptEngineTest.java   |  10 ++
 .../python/jsr223/JythonScriptEngineSetup.java  |  47 ++++++
 31 files changed, 1042 insertions(+), 539 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/6acb8936/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/creation/TranslationStrategy.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/creation/TranslationStrategy.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/creation/TranslationStrategy.java
index 2fbdc80..3da4327 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/creation/TranslationStrategy.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/creation/TranslationStrategy.java
@@ -31,6 +31,7 @@ import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalHelper;
 import org.apache.tinkerpop.gremlin.util.ScriptEngineCache;
 
 import javax.script.Bindings;
+import javax.script.ScriptContext;
 import javax.script.ScriptEngine;
 import java.lang.reflect.InvocationTargetException;
 import java.util.function.Function;
@@ -67,6 +68,7 @@ public class TranslationStrategy extends AbstractTraversalStrategy<TraversalStra
             // translate the traversal and add its steps to this traversal
             final ScriptEngine scriptEngine = ScriptEngineCache.get(this.translator.getTargetLanguage());
             final Bindings bindings = scriptEngine.createBindings();
+            scriptEngine.getContext().getBindings(ScriptContext.ENGINE_SCOPE).forEach(bindings::put);
             bindings.put(this.translator.getAlias(), this.traversalSource);
             final Traversal.Admin<?, ?> translatedTraversal = (Traversal.Admin<?, ?>) scriptEngine.eval(this.translator.getTraversalScript(), bindings);
             assert !translatedTraversal.isLocked();

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/6acb8936/gremlin-python/pom.xml
----------------------------------------------------------------------
diff --git a/gremlin-python/pom.xml b/gremlin-python/pom.xml
index 0929939..8d23d9c 100644
--- a/gremlin-python/pom.xml
+++ b/gremlin-python/pom.xml
@@ -115,7 +115,8 @@
                             <executable>python</executable>
                             <async>true</async>
                             <workingDirectory>${basedir}/src/main/jython</workingDirectory>
-                            <commandlineArgs>setup.py build --build-lib ${project.build.testOutputDirectory}/Lib</commandlineArgs>
+                            <commandlineArgs>setup.py build --build-lib ${project.build.testOutputDirectory}/Lib
+                            </commandlineArgs>
                         </configuration>
                     </execution>
                 </executions>
@@ -261,7 +262,8 @@
                                         <copy todir="${project.build.directory}/py">
                                             <fileset dir="src/main/jython"/>
                                         </copy>
-                                        <exec dir="${project.build.directory}/py" executable="virtualenv" failonerror="true">
+                                        <exec dir="${project.build.directory}/py" executable="virtualenv"
+                                              failonerror="true">
                                             <arg line="env"/>
                                         </exec>
                                     </tasks>
@@ -280,11 +282,13 @@
                                 <phase>package</phase>
                                 <configuration>
                                     <tasks>
-                                        <exec dir="${project.build.directory}/py" executable="env/bin/python" failonerror="true">
+                                        <exec dir="${project.build.directory}/py" executable="env/bin/python"
+                                              failonerror="true">
                                             <env key="VERSION" value="${project.version}"/>
                                             <arg line="setup.py sdist"/>
                                         </exec>
-                                        <exec dir="${project.build.directory}/py" executable="env/bin/python" failonerror="true">
+                                        <exec dir="${project.build.directory}/py" executable="env/bin/python"
+                                              failonerror="true">
                                             <env key="VERSION" value="${project.version}"/>
                                             <arg line="setup.py bdist_wheel"/>
                                         </exec>
@@ -301,10 +305,12 @@
                                 <phase>deploy</phase>
                                 <configuration>
                                     <tasks>
-                                        <exec dir="${project.build.directory}/py" executable="env/bin/pip" failonerror="true">
+                                        <exec dir="${project.build.directory}/py" executable="env/bin/pip"
+                                              failonerror="true">
                                             <arg line="install twine"/>
                                         </exec>
-                                        <exec dir="${project.build.directory}/py" executable="env/bin/twine" failonerror="true">
+                                        <exec dir="${project.build.directory}/py" executable="env/bin/twine"
+                                              failonerror="true">
                                             <arg line="upload dist/* -r pypitest"/>
                                         </exec>
                                     </tasks>

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/6acb8936/gremlin-python/src/main/java/org/apache/tinkerpop/gremlin/java/translator/PythonTranslator.java
----------------------------------------------------------------------
diff --git a/gremlin-python/src/main/java/org/apache/tinkerpop/gremlin/java/translator/PythonTranslator.java b/gremlin-python/src/main/java/org/apache/tinkerpop/gremlin/java/translator/PythonTranslator.java
index b1007a6..02240b0 100644
--- a/gremlin-python/src/main/java/org/apache/tinkerpop/gremlin/java/translator/PythonTranslator.java
+++ b/gremlin-python/src/main/java/org/apache/tinkerpop/gremlin/java/translator/PythonTranslator.java
@@ -32,6 +32,7 @@ import org.apache.tinkerpop.gremlin.process.traversal.util.EmptyTraversal;
 import org.apache.tinkerpop.gremlin.process.traversal.util.OrP;
 import org.apache.tinkerpop.gremlin.process.traversal.util.Translator;
 import org.apache.tinkerpop.gremlin.process.traversal.util.TranslatorHelper;
+import org.apache.tinkerpop.gremlin.python.util.SymbolHelper;
 import org.apache.tinkerpop.gremlin.structure.Element;
 import org.apache.tinkerpop.gremlin.structure.T;
 import org.apache.tinkerpop.gremlin.structure.VertexProperty;
@@ -55,7 +56,6 @@ import java.util.stream.Stream;
 public class PythonTranslator implements Translator {
 
     private static final Set<String> STEP_NAMES = Stream.of(GraphTraversal.class.getMethods()).filter(method -> Traversal.class.isAssignableFrom(method.getReturnType())).map(Method::getName).collect(Collectors.toSet());
-    private static final Set<String> PREFIX_NAMES = new HashSet<>(Arrays.asList("as", "in", "and", "or", "is", "not", "from", "global"));
     private static final Set<String> NO_STATIC = Stream.of(T.values(), Operator.values())
             .flatMap(arg -> IteratorUtils.stream(new ArrayIterator<>(arg)))
             .map(arg -> ((Enum) arg).name())
@@ -65,7 +65,7 @@ public class PythonTranslator implements Translator {
     protected String alias;
     protected final boolean importStatics;
 
-    PythonTranslator(final String alias, final boolean importStatics) {
+    protected PythonTranslator(final String alias, final boolean importStatics) {
         this.alias = alias;
         this.traversalScript = new StringBuilder(this.alias);
         this.importStatics = importStatics;
@@ -91,7 +91,7 @@ public class PythonTranslator implements Translator {
 
     @Override
     public String getTargetLanguage() {
-        return "gremlin-jython";
+        return "jython";
     }
 
     @Override
@@ -113,7 +113,7 @@ public class PythonTranslator implements Translator {
         final List<Object> objects = TranslatorHelper.flattenArguments(arguments);
         final int size = objects.size();
         if (0 == size)
-            this.traversalScript.append(".").append(convertStepName(stepName)).append("()");
+            this.traversalScript.append(".").append(SymbolHelper.toPython(stepName)).append("()");
         else if (stepName.equals("range") && 2 == size)
             this.traversalScript.append("[").append(objects.get(0)).append(":").append(objects.get(1)).append("]");
         else if (stepName.equals("limit") && 1 == size)
@@ -122,7 +122,7 @@ public class PythonTranslator implements Translator {
             this.traversalScript.append(".").append(objects.get(0));
         else {
             this.traversalScript.append(".");
-            String temp = convertStepName(stepName) + "(";
+            String temp = SymbolHelper.toPython(stepName) + "(";
             for (final Object object : objects) {
                 temp = temp + convertToString(object) + ",";
             }
@@ -131,7 +131,7 @@ public class PythonTranslator implements Translator {
 
         // clip off __.
         if (this.importStatics && this.traversalScript.substring(0, 3).startsWith("__.")
-                && !NO_STATIC.stream().filter(name -> this.traversalScript.substring(3).startsWith(convertStepName(name))).findAny().isPresent()) {
+                && !NO_STATIC.stream().filter(name -> this.traversalScript.substring(3).startsWith(SymbolHelper.toPython(name))).findAny().isPresent()) {
             this.traversalScript.delete(0, 3);
         }
     }
@@ -174,7 +174,7 @@ public class PythonTranslator implements Translator {
         else if (object instanceof SackFunctions.Barrier)
             return "Barrier." + object.toString();
         else if (object instanceof Enum)
-            return convertStatic(((Enum) object).getDeclaringClass().getSimpleName() + ".") + convertStepName(object.toString());
+            return convertStatic(((Enum) object).getDeclaringClass().getSimpleName() + ".") + SymbolHelper.toPython(object.toString());
         else if (object instanceof P)
             return convertPToString((P) object, new StringBuilder()).toString();
         else if (object instanceof Element)
@@ -194,13 +194,6 @@ public class PythonTranslator implements Translator {
         return this.importStatics ? "" : name;
     }
 
-    private String convertStepName(final String stepName) {
-        if (PREFIX_NAMES.contains(stepName))
-            return "_" + stepName;
-        else
-            return stepName;
-    }
-
     private StringBuilder convertPToString(final P p, final StringBuilder current) {
         if (p instanceof ConnectiveP) {
             final List<P<?>> list = ((ConnectiveP) p).getPredicates();

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/6acb8936/gremlin-python/src/main/java/org/apache/tinkerpop/gremlin/python/util/SymbolHelper.java
----------------------------------------------------------------------
diff --git a/gremlin-python/src/main/java/org/apache/tinkerpop/gremlin/python/util/SymbolHelper.java b/gremlin-python/src/main/java/org/apache/tinkerpop/gremlin/python/util/SymbolHelper.java
index da97245..ca4d6ed 100644
--- a/gremlin-python/src/main/java/org/apache/tinkerpop/gremlin/python/util/SymbolHelper.java
+++ b/gremlin-python/src/main/java/org/apache/tinkerpop/gremlin/python/util/SymbolHelper.java
@@ -51,8 +51,8 @@ public final class SymbolHelper {
         return TO_PYTHON_MAP.getOrDefault(symbol, symbol);
     }
 
-    public static String toJava(final String pythonSymbol) {
-        return FROM_PYTHON_MAP.getOrDefault(pythonSymbol, pythonSymbol);
+    public static String toJava(final String symbol) {
+        return FROM_PYTHON_MAP.getOrDefault(symbol, symbol);
     }
 
 }

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/6acb8936/gremlin-python/src/main/jython/gremlin_python/__init__.py
----------------------------------------------------------------------
diff --git a/gremlin-python/src/main/jython/gremlin_python/__init__.py b/gremlin-python/src/main/jython/gremlin_python/__init__.py
index 8f4fc49..62a5ddd 100644
--- a/gremlin-python/src/main/jython/gremlin_python/__init__.py
+++ b/gremlin-python/src/main/jython/gremlin_python/__init__.py
@@ -31,5 +31,6 @@ from gremlin_python import T
 from gremlin_python import __
 from gremlin_python import statics
 from groovy_translator import GroovyTranslator
+from jython_translator import JythonTranslator
 
 __author__ = 'Marko A. Rodriguez (http://markorodriguez.com)'

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/6acb8936/gremlin-python/src/main/jython/gremlin_python/gremlin_python.py
----------------------------------------------------------------------
diff --git a/gremlin-python/src/main/jython/gremlin_python/gremlin_python.py b/gremlin-python/src/main/jython/gremlin_python/gremlin_python.py
index 1ecca2b..99f9304 100644
--- a/gremlin-python/src/main/jython/gremlin_python/gremlin_python.py
+++ b/gremlin-python/src/main/jython/gremlin_python/gremlin_python.py
@@ -1642,16 +1642,31 @@ def where(*args):
 statics['where'] = where
 
 
-Barrier = Enum('Barrier', 'normSack')
-
-statics['normSack'] = Barrier.normSack
-
 Pop = Enum('Pop', 'first last all')
 
 statics['first'] = Pop.first
 statics['last'] = Pop.last
 statics['all'] = Pop.all
 
+Scope = Enum('Scope', '_global local')
+
+statics['_global'] = Scope._global
+statics['local'] = Scope.local
+
+Order = Enum('Order', 'incr decr keyIncr valueIncr keyDecr valueDecr shuffle')
+
+statics['incr'] = Order.incr
+statics['decr'] = Order.decr
+statics['keyIncr'] = Order.keyIncr
+statics['valueIncr'] = Order.valueIncr
+statics['keyDecr'] = Order.keyDecr
+statics['valueDecr'] = Order.valueDecr
+statics['shuffle'] = Order.shuffle
+
+Barrier = Enum('Barrier', 'normSack')
+
+statics['normSack'] = Barrier.normSack
+
 Operator = Enum('Operator', 'sum minus mult div min max assign _and _or addAll sumLong')
 
 statics['sum'] = Operator.sum
@@ -1666,18 +1681,6 @@ statics['_or'] = Operator._or
 statics['addAll'] = Operator.addAll
 statics['sumLong'] = Operator.sumLong
 
-Cardinality = Enum('Cardinality', 'single list set')
-
-statics['single'] = Cardinality.single
-statics['list'] = Cardinality.list
-statics['set'] = Cardinality.set
-
-Direction = Enum('Direction', 'OUT IN BOTH')
-
-statics['OUT'] = Direction.OUT
-statics['IN'] = Direction.IN
-statics['BOTH'] = Direction.BOTH
-
 T = Enum('T', 'label id key value')
 
 statics['label'] = T.label
@@ -1685,26 +1688,23 @@ statics['id'] = T.id
 statics['key'] = T.key
 statics['value'] = T.value
 
-Order = Enum('Order', 'incr decr keyIncr valueIncr keyDecr valueDecr shuffle')
-
-statics['incr'] = Order.incr
-statics['decr'] = Order.decr
-statics['keyIncr'] = Order.keyIncr
-statics['valueIncr'] = Order.valueIncr
-statics['keyDecr'] = Order.keyDecr
-statics['valueDecr'] = Order.valueDecr
-statics['shuffle'] = Order.shuffle
-
-Scope = Enum('Scope', '_global local')
+Cardinality = Enum('Cardinality', 'single list set')
 
-statics['_global'] = Scope._global
-statics['local'] = Scope.local
+statics['single'] = Cardinality.single
+statics['list'] = Cardinality.list
+statics['set'] = Cardinality.set
 
 Column = Enum('Column', 'keys values')
 
 statics['keys'] = Column.keys
 statics['values'] = Column.values
 
+Direction = Enum('Direction', 'OUT IN BOTH')
+
+statics['OUT'] = Direction.OUT
+statics['IN'] = Direction.IN
+statics['BOTH'] = Direction.BOTH
+
 class RawExpression(object):
    def __init__(self, *args):
       self.bindings = dict()

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/6acb8936/gremlin-python/src/main/jython/gremlin_python/jython_translator.py
----------------------------------------------------------------------
diff --git a/gremlin-python/src/main/jython/gremlin_python/jython_translator.py b/gremlin-python/src/main/jython/gremlin_python/jython_translator.py
new file mode 100644
index 0000000..45884a5
--- /dev/null
+++ b/gremlin-python/src/main/jython/gremlin_python/jython_translator.py
@@ -0,0 +1,106 @@
+'''
+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.
+'''
+
+import sys
+from aenum import Enum
+
+from gremlin_python import Barrier
+from gremlin_python import Cardinality
+from gremlin_python import Column
+from gremlin_python import P
+from gremlin_python import Raw
+from gremlin_python import RawExpression
+from translator import SymbolHelper
+from translator import Translator
+
+if sys.version_info.major > 2:
+    long = int
+
+__author__ = 'Marko A. Rodriguez (http://markorodriguez.com)'
+
+
+class JythonTranslator(Translator):
+    def __init__(self, alias, source_language="python", target_language="gremlin-jython"):
+        Translator.__init__(self, alias, source_language, target_language)
+
+    def addStep(self, traversal, step_name, *args):
+        self.traversal_script = self.traversal_script + "." + SymbolHelper.toJava(
+            step_name) + "(" + JythonTranslator.stringify(*args) + ")"
+
+    def addSpawnStep(self, traversal, step_name, *args):
+        newTranslator = JythonTranslator(self.alias, self.source_language)
+        newTranslator.traversal_script = self.traversal_script
+        newTranslator.traversal_script = newTranslator.traversal_script + "." + SymbolHelper.toJava(
+            step_name) + "(" + JythonTranslator.stringify(*args) + ")"
+        traversal.translator = newTranslator
+
+    def addSource(self, traversal_source, source_name, *args):
+        newTranslator = JythonTranslator(self.alias, self.source_language)
+        newTranslator.traversal_script = self.traversal_script
+        newTranslator.traversal_script = newTranslator.traversal_script + "." + SymbolHelper.toJava(
+            source_name) + "(" + JythonTranslator.stringify(*args) + ")"
+        traversal_source.translator = newTranslator
+
+    def getAnonymousTraversalTranslator(self):
+        return JythonTranslator("__", self.source_language)
+
+    @staticmethod
+    def stringOrObject(arg):
+        if isinstance(arg, str):
+            return "\"" + arg + "\""
+        elif isinstance(arg, long):
+            return str(arg) + "L"
+        elif isinstance(arg, Barrier):
+            return "Barrier" + "." + SymbolHelper.toJava(str(arg.name))
+        elif isinstance(arg, Column):
+            return "Column.valueOf('" + SymbolHelper.toJava(str(arg.name)) + "')"
+        elif isinstance(arg, Cardinality):
+            return "Cardinality" + "." + SymbolHelper.toJava(str(arg.name))
+        elif isinstance(arg, Enum):  # Order, Direction, Scope, T, etc.
+            return SymbolHelper.toJava(type(arg).__name__) + "." + SymbolHelper.toJava(str(arg.name))
+        elif isinstance(arg, P):
+            if arg.other is None:
+                return "P." + SymbolHelper.toJava(arg.operator) + "(" + JythonTranslator.stringOrObject(
+                    arg.value) + ")"
+            else:
+                return JythonTranslator.stringOrObject(arg.other) + "." + SymbolHelper.toJava(
+                    arg.operator) + "(" + JythonTranslator.stringOrObject(arg.value) + ")"
+        elif callable(arg):  # lambdas
+            lambdaString = arg().strip()
+            if lambdaString.startswith("lambda"):
+                return lambdaString
+            else:
+                return "lambda: " + lambdaString
+        elif isinstance(arg, tuple) and 2 == len(arg) and isinstance(arg[0], str):  # bindings
+            return arg[0]
+        elif isinstance(arg, RawExpression):
+            return "".join(JythonTranslator.stringOrObject(i) for i in arg.parts)
+        elif isinstance(arg, Raw):
+            return str(arg)
+        else:
+            return str(arg)
+
+    @staticmethod
+    def stringify(*args):
+        if len(args) == 0:
+            return ""
+        elif len(args) == 1:
+            return JythonTranslator.stringOrObject(args[0])
+        else:
+            return ", ".join(JythonTranslator.stringOrObject(i) for i in args)

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/6acb8936/gremlin-python/src/main/jython/setup.py
----------------------------------------------------------------------
diff --git a/gremlin-python/src/main/jython/setup.py b/gremlin-python/src/main/jython/setup.py
index 05f1dc3..0cd8b7d 100644
--- a/gremlin-python/src/main/jython/setup.py
+++ b/gremlin-python/src/main/jython/setup.py
@@ -16,10 +16,9 @@ KIND, either express or implied.  See the License for the
 specific language governing permissions and limitations
 under the License.
 '''
+import codecs
 import os
 import time
-import codecs
-
 from setuptools import setup
 
 # Folder containing the setup.py
@@ -41,12 +40,13 @@ if not os.path.exists(os.path.join(root, 'PKG-INFO')):
     fd.close()
 # Load version
 import __version__
+
 version = __version__.version
 
 setup(
     name='gremlinpython',
     version=version,
-    packages=['gremlin_driver','gremlin_python', 'gremlin_rest_driver'],
+    packages=['gremlin_driver', 'gremlin_python', 'gremlin_rest_driver'],
     license='Apache 2',
     url='http://tinkerpop.apache.org',
     description='Gremlin Language Variant for Apache TinkerPop - Gremlin',

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/6acb8936/gremlin-python/src/test/java/org/apache/tinkerpop/gremlin/java/translator/PythonBypassTranslator.java
----------------------------------------------------------------------
diff --git a/gremlin-python/src/test/java/org/apache/tinkerpop/gremlin/java/translator/PythonBypassTranslator.java b/gremlin-python/src/test/java/org/apache/tinkerpop/gremlin/java/translator/PythonBypassTranslator.java
deleted file mode 100644
index 0bbde96..0000000
--- a/gremlin-python/src/test/java/org/apache/tinkerpop/gremlin/java/translator/PythonBypassTranslator.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- *  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.
- */
-
-package org.apache.tinkerpop.gremlin.java.translator;
-
-import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
-import org.apache.tinkerpop.gremlin.process.traversal.util.Translator;
-import org.apache.tinkerpop.gremlin.structure.util.StringFactory;
-import org.apache.tinkerpop.gremlin.util.ScriptEngineCache;
-
-import javax.script.Bindings;
-import javax.script.ScriptContext;
-import javax.script.ScriptEngine;
-import javax.script.ScriptException;
-import javax.script.SimpleBindings;
-
-/**
- * @author Marko A. Rodriguez (http://markorodriguez.com)
- */
-class PythonBypassTranslator extends PythonTranslator {
-
-    private PythonBypassTranslator(final String alias, final boolean importStatics) {
-        super(alias, importStatics);
-    }
-
-    public static PythonBypassTranslator of(final String alias) {
-        return new PythonBypassTranslator(alias, false);
-    }
-
-    public static PythonBypassTranslator of(final String alias, final boolean importStatics) {
-        return new PythonBypassTranslator(alias, importStatics);
-    }
-
-    @Override
-    public void addStep(final Traversal.Admin<?, ?> traversal, final String stepName, final Object... arguments) {
-        super.addStep(traversal, stepName, arguments);
-        if (!this.importStatics)
-            assert this.traversalScript.toString().startsWith(this.alias + ".");
-    }
-
-    @Override
-    public Translator getAnonymousTraversalTranslator() {
-        return new PythonBypassTranslator("__", this.importStatics);
-    }
-
-    @Override
-    public String getTargetLanguage() {
-        return "gremlin-groovy";
-    }
-
-    @Override
-    public String getTraversalScript() {
-        final String traversal = super.getTraversalScript();
-        if (!this.alias.equals("__")) {
-            try {
-                final ScriptEngine jythonEngine = ScriptEngineCache.get("gremlin-jython");
-                final Bindings jythonBindings = new SimpleBindings();
-                jythonBindings.put(this.alias, jythonEngine.eval("PythonGraphTraversalSource(GroovyTranslator(\"" + this.alias + "\"))"));
-                jythonEngine.getContext().setBindings(jythonBindings, ScriptContext.GLOBAL_SCOPE);
-                return jythonEngine.eval(traversal).toString();
-            } catch (final ScriptException e) {
-                throw new IllegalArgumentException(e.getMessage(), e);
-            }
-        } else
-            return traversal;
-    }
-
-    @Override
-    public String toString() {
-        return StringFactory.translatorString(this);
-    }
-}

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/6acb8936/gremlin-python/src/test/java/org/apache/tinkerpop/gremlin/java/translator/PythonTranslatorProvider.java
----------------------------------------------------------------------
diff --git a/gremlin-python/src/test/java/org/apache/tinkerpop/gremlin/java/translator/PythonTranslatorProvider.java b/gremlin-python/src/test/java/org/apache/tinkerpop/gremlin/java/translator/PythonTranslatorProvider.java
new file mode 100644
index 0000000..c1061d9
--- /dev/null
+++ b/gremlin-python/src/test/java/org/apache/tinkerpop/gremlin/java/translator/PythonTranslatorProvider.java
@@ -0,0 +1,136 @@
+/*
+ *  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.
+ */
+
+package org.apache.tinkerpop.gremlin.java.translator;
+
+import org.apache.commons.configuration.Configuration;
+import org.apache.tinkerpop.gremlin.AbstractGraphProvider;
+import org.apache.tinkerpop.gremlin.LoadGraphWith;
+import org.apache.tinkerpop.gremlin.process.traversal.TraversalInterruptionComputerTest;
+import org.apache.tinkerpop.gremlin.process.traversal.TraversalInterruptionTest;
+import org.apache.tinkerpop.gremlin.process.traversal.step.map.ProgramTest;
+import org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration.ElementIdStrategyProcessTest;
+import org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration.EventStrategyProcessTest;
+import org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration.PartitionStrategyProcessTest;
+import org.apache.tinkerpop.gremlin.python.jsr223.JythonScriptEngineSetup;
+import org.apache.tinkerpop.gremlin.structure.Graph;
+import org.apache.tinkerpop.gremlin.structure.VertexProperty;
+import org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerEdge;
+import org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerElement;
+import org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerGraph;
+import org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerGraphVariables;
+import org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerProperty;
+import org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerVertex;
+import org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerVertexProperty;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ */
+public abstract class PythonTranslatorProvider extends AbstractGraphProvider {
+
+    protected static final boolean IMPORT_STATICS = false;//new Random().nextBoolean();
+
+    static {
+        JythonScriptEngineSetup.setup();
+    }
+
+    private static Set<String> SKIP_TESTS = new HashSet<>(Arrays.asList(
+            "testProfileStrategyCallback",
+            "testProfileStrategyCallbackSideEffect",
+            "g_V_branchXlabelX_optionXperson__ageX_optionXsoftware__langX_optionXsoftware__nameX",
+            "g_V_chooseXout_countX_optionX2L__nameX_optionX3L__valueMapX",
+            "g_withSideEffectXa_setX_V_both_name_storeXaX_capXaX",
+            "g_V_both_hasLabelXpersonX_order_byXage_decrX_name",
+            "g_VX1X_out_injectXv2X_name",
+            "g_addVXpersonX_propertyXsingle_name_stephenX_propertyXsingle_name_stephenmX",
+            "g_addVXpersonX_propertyXsingle_name_stephenX_propertyXsingle_name_stephenm_since_2010X",
+            "shouldSupportGraphFilter",
+            "shouldNeverPropagateANoBulkTraverser",
+            "shouldNeverPropagateANullValuedTraverser",
+            "shouldTraversalResetProperly",
+            "shouldHidePartitionKeyForValues",
+            "shouldAddStartsProperly",
+            ProgramTest.Traversals.class.getCanonicalName(),
+            TraversalInterruptionTest.class.getCanonicalName(),
+            TraversalInterruptionComputerTest.class.getCanonicalName(),
+            ElementIdStrategyProcessTest.class.getCanonicalName(),
+            EventStrategyProcessTest.class.getCanonicalName(),
+            PartitionStrategyProcessTest.class.getCanonicalName()));
+
+    private static final Set<Class> IMPLEMENTATION = new HashSet<Class>() {{
+        add(TinkerEdge.class);
+        add(TinkerElement.class);
+        add(TinkerGraph.class);
+        add(TinkerGraphVariables.class);
+        add(TinkerProperty.class);
+        add(TinkerVertex.class);
+        add(TinkerVertexProperty.class);
+    }};
+
+    @Override
+    public Map<String, Object> getBaseConfiguration(final String graphName, final Class<?> test, final String testMethodName,
+                                                    final LoadGraphWith.GraphData loadGraphWith) {
+
+        final TinkerGraph.DefaultIdManager idManager = selectIdMakerFromGraphData(loadGraphWith);
+        final String idMaker = (idManager.equals(TinkerGraph.DefaultIdManager.ANY) ? selectIdMakerFromGraphData(loadGraphWith) : idManager).name();
+        return new HashMap<String, Object>() {{
+            put(Graph.GRAPH, TinkerGraph.class.getName());
+            put(TinkerGraph.GREMLIN_TINKERGRAPH_VERTEX_ID_MANAGER, idMaker);
+            put(TinkerGraph.GREMLIN_TINKERGRAPH_EDGE_ID_MANAGER, idMaker);
+            put(TinkerGraph.GREMLIN_TINKERGRAPH_VERTEX_PROPERTY_ID_MANAGER, idMaker);
+            put("skipTest", SKIP_TESTS.contains(testMethodName) || SKIP_TESTS.contains(test.getCanonicalName()));
+            if (loadGraphWith == LoadGraphWith.GraphData.CREW)
+                put(TinkerGraph.GREMLIN_TINKERGRAPH_DEFAULT_VERTEX_PROPERTY_CARDINALITY, VertexProperty.Cardinality.list.name());
+        }};
+    }
+
+    @Override
+    public void clear(final Graph graph, final Configuration configuration) throws Exception {
+        if (graph != null) graph.close();
+    }
+
+    @Override
+    public Set<Class> getImplementations() {
+        return IMPLEMENTATION;
+    }
+
+    /**
+     * Test that load with specific graph data can be configured with a specific id manager as the data type to
+     * be used in the test for that graph is known.
+     */
+    protected TinkerGraph.DefaultIdManager selectIdMakerFromGraphData(final LoadGraphWith.GraphData loadGraphWith) {
+        if (null == loadGraphWith) return TinkerGraph.DefaultIdManager.ANY;
+        if (loadGraphWith.equals(LoadGraphWith.GraphData.CLASSIC))
+            return TinkerGraph.DefaultIdManager.INTEGER;
+        else if (loadGraphWith.equals(LoadGraphWith.GraphData.MODERN))
+            return TinkerGraph.DefaultIdManager.INTEGER;
+        else if (loadGraphWith.equals(LoadGraphWith.GraphData.CREW))
+            return TinkerGraph.DefaultIdManager.INTEGER;
+        else if (loadGraphWith.equals(LoadGraphWith.GraphData.GRATEFUL))
+            return TinkerGraph.DefaultIdManager.INTEGER;
+        else
+            throw new IllegalStateException(String.format("Need to define a new %s for %s", TinkerGraph.IdManager.class.getName(), loadGraphWith.name()));
+    }
+}

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/6acb8936/gremlin-python/src/test/java/org/apache/tinkerpop/gremlin/java/translator/PythonTranslatorTest.java
----------------------------------------------------------------------
diff --git a/gremlin-python/src/test/java/org/apache/tinkerpop/gremlin/java/translator/PythonTranslatorTest.java b/gremlin-python/src/test/java/org/apache/tinkerpop/gremlin/java/translator/PythonTranslatorTest.java
deleted file mode 100644
index adce9ee..0000000
--- a/gremlin-python/src/test/java/org/apache/tinkerpop/gremlin/java/translator/PythonTranslatorTest.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- *  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.
- */
-
-package org.apache.tinkerpop.gremlin.java.translator;
-
-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.python.jsr223.GremlinJythonScriptEngineSetup;
-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.Test;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-
-/**
- * @author Marko A. Rodriguez (http://markorodriguez.com)
- */
-public class PythonTranslatorTest {
-
-    static {
-        GremlinJythonScriptEngineSetup.setup();
-    }
-
-    @Test
-    public void shouldSupportStringSupplierLambdas() throws Exception {
-        final GraphTraversalSource g = TinkerFactory.createModern().traversal().withTranslator(PythonBypassTranslator.of("g", true));
-        GraphTraversal.Admin<Vertex, Integer> t = g.withSideEffect("lengthSum", 0).withSack(1)
-                .V()
-                .filter(Lambda.predicate("lambda: \"it.get().label().equals('person')\""))
-                .flatMap(Lambda.<Traverser<Vertex>, Iterator<Vertex>>function("it.get().vertices(Direction.OUT)"))
-                .map(Lambda.<Traverser<Vertex>, Integer>function("it.get().value('name').length()"))
-                .sideEffect(Lambda.consumer("x -> x.sideEffects('lengthSum', x.<Integer>sideEffects('lengthSum') + x.get())"))
-                .order().by(Lambda.comparator("a,b -> a <=> b"))
-                .sack(Lambda.biFunction("lambda : \"a,b -> a + b\""))
-                .asAdmin();
-        final List<Integer> sacks = new ArrayList<>();
-        final List<Integer> lengths = new ArrayList<>();
-        while (t.hasNext()) {
-            final Traverser.Admin<Integer> traverser = t.getEndStep().next();
-            sacks.add(traverser.sack());
-            lengths.add(traverser.get());
-        }
-        assertFalse(t.hasNext());
-        //
-        assertEquals(6, lengths.size());
-        assertEquals(3, lengths.get(0).intValue());
-        assertEquals(3, lengths.get(1).intValue());
-        assertEquals(3, lengths.get(2).intValue());
-        assertEquals(4, lengths.get(3).intValue());
-        assertEquals(5, lengths.get(4).intValue());
-        assertEquals(6, lengths.get(5).intValue());
-        ///
-        assertEquals(6, sacks.size());
-        assertEquals(4, sacks.get(0).intValue());
-        assertEquals(4, sacks.get(1).intValue());
-        assertEquals(4, sacks.get(2).intValue());
-        assertEquals(5, sacks.get(3).intValue());
-        assertEquals(6, sacks.get(4).intValue());
-        assertEquals(7, sacks.get(5).intValue());
-        //
-        assertEquals(24, t.getSideEffects().<Number>get("lengthSum").intValue());
-    }
-
-    @Test
-    public void shouldHaveValidToString() {
-        assertEquals("translator[h:gremlin-java->gremlin-jython]", PythonTranslator.of("h").toString());
-        assertEquals("translator[h:gremlin-java->gremlin-groovy]", PythonBypassTranslator.of("h").toString());
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/6acb8936/gremlin-python/src/test/java/org/apache/tinkerpop/gremlin/java/translator/TinkerGraphPythonTranslatorComputerProvider.java
----------------------------------------------------------------------
diff --git a/gremlin-python/src/test/java/org/apache/tinkerpop/gremlin/java/translator/TinkerGraphPythonTranslatorComputerProvider.java b/gremlin-python/src/test/java/org/apache/tinkerpop/gremlin/java/translator/TinkerGraphPythonTranslatorComputerProvider.java
deleted file mode 100644
index 6dcf40b..0000000
--- a/gremlin-python/src/test/java/org/apache/tinkerpop/gremlin/java/translator/TinkerGraphPythonTranslatorComputerProvider.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- *  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.
- */
-
-package org.apache.tinkerpop.gremlin.java.translator;
-
-import org.apache.tinkerpop.gremlin.GraphProvider;
-import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource;
-import org.apache.tinkerpop.gremlin.structure.Graph;
-import org.apache.tinkerpop.gremlin.tinkergraph.process.computer.TinkerGraphComputer;
-
-/**
- * @author Marko A. Rodriguez (http://markorodriguez.com)
- */
-@GraphProvider.Descriptor(computer = TinkerGraphComputer.class)
-public class TinkerGraphPythonTranslatorComputerProvider extends TinkerGraphPythonTranslatorProvider {
-
-    @Override
-    public GraphTraversalSource traversal(final Graph graph) {
-        return super.traversal(graph).withComputer();
-    }
-}

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/6acb8936/gremlin-python/src/test/java/org/apache/tinkerpop/gremlin/java/translator/TinkerGraphPythonTranslatorProcessComputerTest.java
----------------------------------------------------------------------
diff --git a/gremlin-python/src/test/java/org/apache/tinkerpop/gremlin/java/translator/TinkerGraphPythonTranslatorProcessComputerTest.java b/gremlin-python/src/test/java/org/apache/tinkerpop/gremlin/java/translator/TinkerGraphPythonTranslatorProcessComputerTest.java
deleted file mode 100644
index 2abf94a..0000000
--- a/gremlin-python/src/test/java/org/apache/tinkerpop/gremlin/java/translator/TinkerGraphPythonTranslatorProcessComputerTest.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- *  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.
- */
-
-package org.apache.tinkerpop.gremlin.java.translator;
-
-import org.apache.tinkerpop.gremlin.GraphProviderClass;
-import org.apache.tinkerpop.gremlin.process.ProcessComputerSuite;
-import org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerGraph;
-import org.junit.runner.RunWith;
-
-/**
- * @author Marko A. Rodriguez (http://markorodriguez.com)
- */
-@RunWith(ProcessComputerSuite.class)
-@GraphProviderClass(provider = TinkerGraphPythonTranslatorComputerProvider.class, graph = TinkerGraph.class)
-public class TinkerGraphPythonTranslatorProcessComputerTest {
-
-}

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/6acb8936/gremlin-python/src/test/java/org/apache/tinkerpop/gremlin/java/translator/TinkerGraphPythonTranslatorProcessStandardTest.java
----------------------------------------------------------------------
diff --git a/gremlin-python/src/test/java/org/apache/tinkerpop/gremlin/java/translator/TinkerGraphPythonTranslatorProcessStandardTest.java b/gremlin-python/src/test/java/org/apache/tinkerpop/gremlin/java/translator/TinkerGraphPythonTranslatorProcessStandardTest.java
deleted file mode 100644
index e393d88..0000000
--- a/gremlin-python/src/test/java/org/apache/tinkerpop/gremlin/java/translator/TinkerGraphPythonTranslatorProcessStandardTest.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- *  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.
- */
-
-package org.apache.tinkerpop.gremlin.java.translator;
-
-import org.apache.tinkerpop.gremlin.GraphProviderClass;
-import org.apache.tinkerpop.gremlin.process.ProcessStandardSuite;
-import org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerGraph;
-import org.junit.runner.RunWith;
-
-/**
- * @author Marko A. Rodriguez (http://markorodriguez.com)
- */
-@RunWith(ProcessStandardSuite.class)
-@GraphProviderClass(provider = TinkerGraphPythonTranslatorProvider.class, graph = TinkerGraph.class)
-public class TinkerGraphPythonTranslatorProcessStandardTest {
-
-}

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/6acb8936/gremlin-python/src/test/java/org/apache/tinkerpop/gremlin/java/translator/TinkerGraphPythonTranslatorProvider.java
----------------------------------------------------------------------
diff --git a/gremlin-python/src/test/java/org/apache/tinkerpop/gremlin/java/translator/TinkerGraphPythonTranslatorProvider.java b/gremlin-python/src/test/java/org/apache/tinkerpop/gremlin/java/translator/TinkerGraphPythonTranslatorProvider.java
deleted file mode 100644
index 507b7c3..0000000
--- a/gremlin-python/src/test/java/org/apache/tinkerpop/gremlin/java/translator/TinkerGraphPythonTranslatorProvider.java
+++ /dev/null
@@ -1,150 +0,0 @@
-/*
- *  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.
- */
-
-package org.apache.tinkerpop.gremlin.java.translator;
-
-import org.apache.commons.configuration.Configuration;
-import org.apache.tinkerpop.gremlin.AbstractGraphProvider;
-import org.apache.tinkerpop.gremlin.LoadGraphWith;
-import org.apache.tinkerpop.gremlin.process.traversal.TraversalInterruptionComputerTest;
-import org.apache.tinkerpop.gremlin.process.traversal.TraversalInterruptionTest;
-import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource;
-import org.apache.tinkerpop.gremlin.process.traversal.step.map.ProgramTest;
-import org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration.ElementIdStrategyProcessTest;
-import org.apache.tinkerpop.gremlin.python.jsr223.GremlinJythonScriptEngineSetup;
-import org.apache.tinkerpop.gremlin.structure.Graph;
-import org.apache.tinkerpop.gremlin.structure.VertexProperty;
-import org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerEdge;
-import org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerElement;
-import org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerGraph;
-import org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerGraphVariables;
-import org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerProperty;
-import org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerVertex;
-import org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerVertexProperty;
-import org.apache.tinkerpop.gremlin.util.ScriptEngineCache;
-
-import javax.script.ScriptException;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Random;
-import java.util.Set;
-
-/**
- * @author Marko A. Rodriguez (http://markorodriguez.com)
- */
-public class TinkerGraphPythonTranslatorProvider extends AbstractGraphProvider {
-
-    private static final boolean IMPORT_STATICS = new Random().nextBoolean();
-
-    static {
-        GremlinJythonScriptEngineSetup.setup();
-    }
-
-    private static Set<String> SKIP_TESTS = new HashSet<>(Arrays.asList(
-            "testProfileStrategyCallback",
-            "testProfileStrategyCallbackSideEffect",
-            "g_withSideEffectXa_setX_V_both_name_storeXaX_capXaX",
-            "g_V_both_hasLabelXpersonX_order_byXage_decrX_name",
-            "g_VX1X_out_injectXv2X_name",
-            "shouldSupportGraphFilter",
-            "shouldNeverPropagateANoBulkTraverser",
-            "shouldNeverPropagateANullValuedTraverser",
-            "shouldTraversalResetProperly",
-            "shouldHidePartitionKeyForValues",
-            ProgramTest.Traversals.class.getCanonicalName(),
-            TraversalInterruptionTest.class.getCanonicalName(),
-            TraversalInterruptionComputerTest.class.getCanonicalName(),
-            ElementIdStrategyProcessTest.class.getCanonicalName()));
-
-    private static final Set<Class> IMPLEMENTATION = new HashSet<Class>() {{
-        add(TinkerEdge.class);
-        add(TinkerElement.class);
-        add(TinkerGraph.class);
-        add(TinkerGraphVariables.class);
-        add(TinkerProperty.class);
-        add(TinkerVertex.class);
-        add(TinkerVertexProperty.class);
-    }};
-
-    @Override
-    public Map<String, Object> getBaseConfiguration(final String graphName, final Class<?> test, final String testMethodName,
-                                                    final LoadGraphWith.GraphData loadGraphWith) {
-
-        final TinkerGraph.DefaultIdManager idManager = selectIdMakerFromGraphData(loadGraphWith);
-        final String idMaker = (idManager.equals(TinkerGraph.DefaultIdManager.ANY) ? selectIdMakerFromGraphData(loadGraphWith) : idManager).name();
-        return new HashMap<String, Object>() {{
-            put(Graph.GRAPH, TinkerGraph.class.getName());
-            put(TinkerGraph.GREMLIN_TINKERGRAPH_VERTEX_ID_MANAGER, idMaker);
-            put(TinkerGraph.GREMLIN_TINKERGRAPH_EDGE_ID_MANAGER, idMaker);
-            put(TinkerGraph.GREMLIN_TINKERGRAPH_VERTEX_PROPERTY_ID_MANAGER, idMaker);
-            put("skipTest", SKIP_TESTS.contains(testMethodName) || SKIP_TESTS.contains(test.getCanonicalName()));
-            if (loadGraphWith == LoadGraphWith.GraphData.CREW)
-                put(TinkerGraph.GREMLIN_TINKERGRAPH_DEFAULT_VERTEX_PROPERTY_CARDINALITY, VertexProperty.Cardinality.list.name());
-        }};
-    }
-
-    @Override
-    public void clear(final Graph graph, final Configuration configuration) throws Exception {
-        if (graph != null) graph.close();
-    }
-
-    @Override
-    public Set<Class> getImplementations() {
-        return IMPLEMENTATION;
-    }
-
-    /**
-     * Test that load with specific graph data can be configured with a specific id manager as the data type to
-     * be used in the test for that graph is known.
-     */
-    protected TinkerGraph.DefaultIdManager selectIdMakerFromGraphData(final LoadGraphWith.GraphData loadGraphWith) {
-        if (null == loadGraphWith) return TinkerGraph.DefaultIdManager.ANY;
-        if (loadGraphWith.equals(LoadGraphWith.GraphData.CLASSIC))
-            return TinkerGraph.DefaultIdManager.INTEGER;
-        else if (loadGraphWith.equals(LoadGraphWith.GraphData.MODERN))
-            return TinkerGraph.DefaultIdManager.INTEGER;
-        else if (loadGraphWith.equals(LoadGraphWith.GraphData.CREW))
-            return TinkerGraph.DefaultIdManager.INTEGER;
-        else if (loadGraphWith.equals(LoadGraphWith.GraphData.GRATEFUL))
-            return TinkerGraph.DefaultIdManager.INTEGER;
-        else
-            throw new IllegalStateException(String.format("Need to define a new %s for %s", TinkerGraph.IdManager.class.getName(), loadGraphWith.name()));
-    }
-
-    @Override
-    public GraphTraversalSource traversal(final Graph graph) {
-        if ((Boolean) graph.configuration().getProperty("skipTest"))
-            return graph.traversal();
-            //throw new VerificationException("This test current does not work with Gremlin-Python", EmptyTraversal.instance());
-        else {
-            try {
-                if (IMPORT_STATICS)
-                    ScriptEngineCache.get("gremlin-jython").eval("for k in statics:\n  globals()[k] = statics[k]");
-                else
-                    ScriptEngineCache.get("gremlin-jython").eval("for k in statics:\n  if k in globals():\n    del globals()[k]");
-            } catch (final ScriptException e) {
-                throw new IllegalStateException(e.getMessage(), e);
-            }
-            return graph.traversal().withTranslator(PythonBypassTranslator.of("g", IMPORT_STATICS)); // the bypass translator will ensure that gremlin-groovy is ultimately used
-        }
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/6acb8936/gremlin-python/src/test/java/org/apache/tinkerpop/gremlin/java/translator/groovy/PythonGroovyTranslator.java
----------------------------------------------------------------------
diff --git a/gremlin-python/src/test/java/org/apache/tinkerpop/gremlin/java/translator/groovy/PythonGroovyTranslator.java b/gremlin-python/src/test/java/org/apache/tinkerpop/gremlin/java/translator/groovy/PythonGroovyTranslator.java
new file mode 100644
index 0000000..0911e5b
--- /dev/null
+++ b/gremlin-python/src/test/java/org/apache/tinkerpop/gremlin/java/translator/groovy/PythonGroovyTranslator.java
@@ -0,0 +1,89 @@
+/*
+ *  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.
+ */
+
+package org.apache.tinkerpop.gremlin.java.translator.groovy;
+
+import org.apache.tinkerpop.gremlin.java.translator.PythonTranslator;
+import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
+import org.apache.tinkerpop.gremlin.process.traversal.util.Translator;
+import org.apache.tinkerpop.gremlin.structure.util.StringFactory;
+import org.apache.tinkerpop.gremlin.util.ScriptEngineCache;
+
+import javax.script.Bindings;
+import javax.script.ScriptContext;
+import javax.script.ScriptEngine;
+import javax.script.ScriptException;
+import javax.script.SimpleBindings;
+
+/**
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ */
+public class PythonGroovyTranslator extends PythonTranslator {
+
+    private PythonGroovyTranslator(final String alias, final boolean importStatics) {
+        super(alias, importStatics);
+    }
+
+    public static PythonGroovyTranslator of(final String alias) {
+        return new PythonGroovyTranslator(alias, false);
+    }
+
+    public static PythonGroovyTranslator of(final String alias, final boolean importStatics) {
+        return new PythonGroovyTranslator(alias, importStatics);
+    }
+
+    @Override
+    public void addStep(final Traversal.Admin<?, ?> traversal, final String stepName, final Object... arguments) {
+        super.addStep(traversal, stepName, arguments);
+        if (!this.importStatics)
+            assert this.traversalScript.toString().startsWith(this.alias + ".");
+    }
+
+    @Override
+    public Translator getAnonymousTraversalTranslator() {
+        return new PythonGroovyTranslator("__", this.importStatics);
+    }
+
+    @Override
+    public String getTargetLanguage() {
+        return "gremlin-groovy";
+    }
+
+    @Override
+    public String getTraversalScript() {
+        final String traversal = super.getTraversalScript();
+        if (!this.alias.equals("__")) {
+            try {
+                final ScriptEngine jythonEngine = ScriptEngineCache.get("jython");
+                final Bindings jythonBindings = new SimpleBindings();
+                jythonBindings.put(this.alias, jythonEngine.eval("PythonGraphTraversalSource(GroovyTranslator(\"" + this.alias + "\"))"));
+                jythonEngine.getContext().setBindings(jythonBindings, ScriptContext.GLOBAL_SCOPE);
+                return jythonEngine.eval(traversal).toString();
+            } catch (final ScriptException e) {
+                throw new IllegalArgumentException(e.getMessage(), e);
+            }
+        } else
+            return traversal;
+    }
+
+    @Override
+    public String toString() {
+        return StringFactory.translatorString(this);
+    }
+}

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/6acb8936/gremlin-python/src/test/java/org/apache/tinkerpop/gremlin/java/translator/groovy/PythonGroovyTranslatorComputerProvider.java
----------------------------------------------------------------------
diff --git a/gremlin-python/src/test/java/org/apache/tinkerpop/gremlin/java/translator/groovy/PythonGroovyTranslatorComputerProvider.java b/gremlin-python/src/test/java/org/apache/tinkerpop/gremlin/java/translator/groovy/PythonGroovyTranslatorComputerProvider.java
new file mode 100644
index 0000000..8fe6a5b
--- /dev/null
+++ b/gremlin-python/src/test/java/org/apache/tinkerpop/gremlin/java/translator/groovy/PythonGroovyTranslatorComputerProvider.java
@@ -0,0 +1,37 @@
+/*
+ *  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.
+ */
+
+package org.apache.tinkerpop.gremlin.java.translator.groovy;
+
+import org.apache.tinkerpop.gremlin.GraphProvider;
+import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource;
+import org.apache.tinkerpop.gremlin.structure.Graph;
+import org.apache.tinkerpop.gremlin.tinkergraph.process.computer.TinkerGraphComputer;
+
+/**
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ */
+@GraphProvider.Descriptor(computer = TinkerGraphComputer.class)
+public class PythonGroovyTranslatorComputerProvider extends PythonGroovyTranslatorProvider {
+
+    @Override
+    public GraphTraversalSource traversal(final Graph graph) {
+        return super.traversal(graph).withComputer();
+    }
+}

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/6acb8936/gremlin-python/src/test/java/org/apache/tinkerpop/gremlin/java/translator/groovy/PythonGroovyTranslatorProcessComputerTest.java
----------------------------------------------------------------------
diff --git a/gremlin-python/src/test/java/org/apache/tinkerpop/gremlin/java/translator/groovy/PythonGroovyTranslatorProcessComputerTest.java b/gremlin-python/src/test/java/org/apache/tinkerpop/gremlin/java/translator/groovy/PythonGroovyTranslatorProcessComputerTest.java
new file mode 100644
index 0000000..eef5968
--- /dev/null
+++ b/gremlin-python/src/test/java/org/apache/tinkerpop/gremlin/java/translator/groovy/PythonGroovyTranslatorProcessComputerTest.java
@@ -0,0 +1,34 @@
+/*
+ *  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.
+ */
+
+package org.apache.tinkerpop.gremlin.java.translator.groovy;
+
+import org.apache.tinkerpop.gremlin.GraphProviderClass;
+import org.apache.tinkerpop.gremlin.process.ProcessComputerSuite;
+import org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerGraph;
+import org.junit.runner.RunWith;
+
+/**
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ */
+@RunWith(ProcessComputerSuite.class)
+@GraphProviderClass(provider = PythonGroovyTranslatorComputerProvider.class, graph = TinkerGraph.class)
+public class PythonGroovyTranslatorProcessComputerTest {
+
+}

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/6acb8936/gremlin-python/src/test/java/org/apache/tinkerpop/gremlin/java/translator/groovy/PythonGroovyTranslatorProcessStandardTest.java
----------------------------------------------------------------------
diff --git a/gremlin-python/src/test/java/org/apache/tinkerpop/gremlin/java/translator/groovy/PythonGroovyTranslatorProcessStandardTest.java b/gremlin-python/src/test/java/org/apache/tinkerpop/gremlin/java/translator/groovy/PythonGroovyTranslatorProcessStandardTest.java
new file mode 100644
index 0000000..3a5b59c
--- /dev/null
+++ b/gremlin-python/src/test/java/org/apache/tinkerpop/gremlin/java/translator/groovy/PythonGroovyTranslatorProcessStandardTest.java
@@ -0,0 +1,34 @@
+/*
+ *  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.
+ */
+
+package org.apache.tinkerpop.gremlin.java.translator.groovy;
+
+import org.apache.tinkerpop.gremlin.GraphProviderClass;
+import org.apache.tinkerpop.gremlin.process.ProcessStandardSuite;
+import org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerGraph;
+import org.junit.runner.RunWith;
+
+/**
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ */
+@RunWith(ProcessStandardSuite.class)
+@GraphProviderClass(provider = PythonGroovyTranslatorProvider.class, graph = TinkerGraph.class)
+public class PythonGroovyTranslatorProcessStandardTest {
+
+}

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/6acb8936/gremlin-python/src/test/java/org/apache/tinkerpop/gremlin/java/translator/groovy/PythonGroovyTranslatorProvider.java
----------------------------------------------------------------------
diff --git a/gremlin-python/src/test/java/org/apache/tinkerpop/gremlin/java/translator/groovy/PythonGroovyTranslatorProvider.java b/gremlin-python/src/test/java/org/apache/tinkerpop/gremlin/java/translator/groovy/PythonGroovyTranslatorProvider.java
new file mode 100644
index 0000000..8d38d30
--- /dev/null
+++ b/gremlin-python/src/test/java/org/apache/tinkerpop/gremlin/java/translator/groovy/PythonGroovyTranslatorProvider.java
@@ -0,0 +1,51 @@
+/*
+ *  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.
+ */
+
+package org.apache.tinkerpop.gremlin.java.translator.groovy;
+
+import org.apache.tinkerpop.gremlin.java.translator.PythonTranslatorProvider;
+import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource;
+import org.apache.tinkerpop.gremlin.structure.Graph;
+import org.apache.tinkerpop.gremlin.util.ScriptEngineCache;
+
+import javax.script.ScriptException;
+
+/**
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ */
+public class PythonGroovyTranslatorProvider extends PythonTranslatorProvider {
+    @Override
+    public GraphTraversalSource traversal(final Graph graph) {
+        if ((Boolean) graph.configuration().getProperty("skipTest"))
+            return graph.traversal();
+            //throw new VerificationException("This test current does not work with Gremlin-Python", EmptyTraversal.instance());
+        else {
+            try {
+                if (IMPORT_STATICS)
+                    ScriptEngineCache.get("jython").eval("for k in statics:\n  globals()[k] = statics[k]");
+                else
+                    ScriptEngineCache.get("jython").eval("for k in statics:\n  if k in globals():\n    del globals()[k]");
+            } catch (final ScriptException e) {
+                throw new IllegalStateException(e.getMessage(), e);
+            }
+            return graph.traversal().withTranslator(PythonGroovyTranslator.of("g", IMPORT_STATICS)); // the bypass translator will ensure that gremlin-groovy is ultimately used
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/6acb8936/gremlin-python/src/test/java/org/apache/tinkerpop/gremlin/java/translator/groovy/PythonGroovyTranslatorTest.java
----------------------------------------------------------------------
diff --git a/gremlin-python/src/test/java/org/apache/tinkerpop/gremlin/java/translator/groovy/PythonGroovyTranslatorTest.java b/gremlin-python/src/test/java/org/apache/tinkerpop/gremlin/java/translator/groovy/PythonGroovyTranslatorTest.java
new file mode 100644
index 0000000..e6ee06e
--- /dev/null
+++ b/gremlin-python/src/test/java/org/apache/tinkerpop/gremlin/java/translator/groovy/PythonGroovyTranslatorTest.java
@@ -0,0 +1,96 @@
+/*
+ *  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.
+ */
+
+package org.apache.tinkerpop.gremlin.java.translator.groovy;
+
+import org.apache.tinkerpop.gremlin.java.translator.PythonTranslator;
+import org.apache.tinkerpop.gremlin.java.translator.groovy.PythonGroovyTranslator;
+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.python.jsr223.JythonScriptEngineSetup;
+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.Assert;
+import org.junit.Test;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+
+/**
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ */
+public class PythonGroovyTranslatorTest {
+
+    static {
+        JythonScriptEngineSetup.setup();
+    }
+
+    @Test
+    public void shouldSupportStringSupplierLambdas() throws Exception {
+        final GraphTraversalSource g = TinkerFactory.createModern().traversal().withTranslator(PythonGroovyTranslator.of("g", true));
+        GraphTraversal.Admin<Vertex, Integer> t = g.withSideEffect("lengthSum", 0).withSack(1)
+                .V()
+                .filter(Lambda.predicate("lambda: \"it.get().label().equals('person')\""))
+                .flatMap(Lambda.<Traverser<Vertex>, Iterator<Vertex>>function("it.get().vertices(Direction.OUT)"))
+                .map(Lambda.<Traverser<Vertex>, Integer>function("it.get().value('name').length()"))
+                .sideEffect(Lambda.consumer("x -> x.sideEffects('lengthSum', x.<Integer>sideEffects('lengthSum') + x.get())"))
+                .order().by(Lambda.comparator("a,b -> a <=> b"))
+                .sack(Lambda.biFunction("lambda : \"a,b -> a + b\""))
+                .asAdmin();
+        final List<Integer> sacks = new ArrayList<>();
+        final List<Integer> lengths = new ArrayList<>();
+        while (t.hasNext()) {
+            final Traverser.Admin<Integer> traverser = t.getEndStep().next();
+            sacks.add(traverser.sack());
+            lengths.add(traverser.get());
+        }
+        assertFalse(t.hasNext());
+        //
+        assertEquals(6, lengths.size());
+        assertEquals(3, lengths.get(0).intValue());
+        assertEquals(3, lengths.get(1).intValue());
+        assertEquals(3, lengths.get(2).intValue());
+        assertEquals(4, lengths.get(3).intValue());
+        assertEquals(5, lengths.get(4).intValue());
+        assertEquals(6, lengths.get(5).intValue());
+        ///
+        assertEquals(6, sacks.size());
+        assertEquals(4, sacks.get(0).intValue());
+        assertEquals(4, sacks.get(1).intValue());
+        assertEquals(4, sacks.get(2).intValue());
+        assertEquals(5, sacks.get(3).intValue());
+        assertEquals(6, sacks.get(4).intValue());
+        assertEquals(7, sacks.get(5).intValue());
+        //
+        assertEquals(24, t.getSideEffects().<Number>get("lengthSum").intValue());
+    }
+
+    @Test
+    public void shouldHaveValidToString() {
+        Assert.assertEquals("translator[h:gremlin-java->jython]", PythonTranslator.of("h").toString());
+        assertEquals("translator[h:gremlin-java->gremlin-groovy]", PythonGroovyTranslator.of("h").toString());
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/6acb8936/gremlin-python/src/test/java/org/apache/tinkerpop/gremlin/java/translator/jython/PythonJythonTranslator.java
----------------------------------------------------------------------
diff --git a/gremlin-python/src/test/java/org/apache/tinkerpop/gremlin/java/translator/jython/PythonJythonTranslator.java b/gremlin-python/src/test/java/org/apache/tinkerpop/gremlin/java/translator/jython/PythonJythonTranslator.java
new file mode 100644
index 0000000..d1cee14
--- /dev/null
+++ b/gremlin-python/src/test/java/org/apache/tinkerpop/gremlin/java/translator/jython/PythonJythonTranslator.java
@@ -0,0 +1,89 @@
+/*
+ *  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.
+ */
+
+package org.apache.tinkerpop.gremlin.java.translator.jython;
+
+import org.apache.tinkerpop.gremlin.java.translator.PythonTranslator;
+import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
+import org.apache.tinkerpop.gremlin.process.traversal.util.Translator;
+import org.apache.tinkerpop.gremlin.structure.util.StringFactory;
+import org.apache.tinkerpop.gremlin.util.ScriptEngineCache;
+
+import javax.script.Bindings;
+import javax.script.ScriptContext;
+import javax.script.ScriptEngine;
+import javax.script.ScriptException;
+import javax.script.SimpleBindings;
+
+/**
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ */
+public class PythonJythonTranslator extends PythonTranslator {
+
+    private PythonJythonTranslator(final String alias, final boolean importStatics) {
+        super(alias, importStatics);
+    }
+
+    public static PythonJythonTranslator of(final String alias) {
+        return new PythonJythonTranslator(alias, false);
+    }
+
+    public static PythonJythonTranslator of(final String alias, final boolean importStatics) {
+        return new PythonJythonTranslator(alias, importStatics);
+    }
+
+    @Override
+    public void addStep(final Traversal.Admin<?, ?> traversal, final String stepName, final Object... arguments) {
+        super.addStep(traversal, stepName, arguments);
+        if (!this.importStatics)
+            assert this.traversalScript.toString().startsWith(this.alias + ".");
+    }
+
+    @Override
+    public Translator getAnonymousTraversalTranslator() {
+        return new PythonJythonTranslator("__", this.importStatics);
+    }
+
+    @Override
+    public String getTargetLanguage() {
+        return "gremlin-jython";
+    }
+
+    @Override
+    public String getTraversalScript() {
+        final String traversal = super.getTraversalScript();
+        if (!this.alias.equals("__")) {
+            try {
+                final ScriptEngine jythonEngine = ScriptEngineCache.get("jython");
+                final Bindings jythonBindings = new SimpleBindings();
+                jythonBindings.put(this.alias, jythonEngine.eval("PythonGraphTraversalSource(JythonTranslator(\"" + this.alias + "\"))"));
+                jythonEngine.getContext().setBindings(jythonBindings, ScriptContext.GLOBAL_SCOPE);
+                return jythonEngine.eval(traversal).toString();
+            } catch (final ScriptException e) {
+                throw new IllegalArgumentException(e.getMessage(), e);
+            }
+        } else
+            return traversal;
+    }
+
+    @Override
+    public String toString() {
+        return StringFactory.translatorString(this);
+    }
+}

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/6acb8936/gremlin-python/src/test/java/org/apache/tinkerpop/gremlin/java/translator/jython/PythonJythonTranslatorComputerProvider.java
----------------------------------------------------------------------
diff --git a/gremlin-python/src/test/java/org/apache/tinkerpop/gremlin/java/translator/jython/PythonJythonTranslatorComputerProvider.java b/gremlin-python/src/test/java/org/apache/tinkerpop/gremlin/java/translator/jython/PythonJythonTranslatorComputerProvider.java
new file mode 100644
index 0000000..f151c6d
--- /dev/null
+++ b/gremlin-python/src/test/java/org/apache/tinkerpop/gremlin/java/translator/jython/PythonJythonTranslatorComputerProvider.java
@@ -0,0 +1,37 @@
+/*
+ *  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.
+ */
+
+package org.apache.tinkerpop.gremlin.java.translator.jython;
+
+import org.apache.tinkerpop.gremlin.GraphProvider;
+import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource;
+import org.apache.tinkerpop.gremlin.structure.Graph;
+import org.apache.tinkerpop.gremlin.tinkergraph.process.computer.TinkerGraphComputer;
+
+/**
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ */
+@GraphProvider.Descriptor(computer = TinkerGraphComputer.class)
+public class PythonJythonTranslatorComputerProvider extends PythonJythonTranslatorProvider {
+
+    @Override
+    public GraphTraversalSource traversal(final Graph graph) {
+        return super.traversal(graph).withComputer();
+    }
+}

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/6acb8936/gremlin-python/src/test/java/org/apache/tinkerpop/gremlin/java/translator/jython/PythonJythonTranslatorProcessComputerTest.java
----------------------------------------------------------------------
diff --git a/gremlin-python/src/test/java/org/apache/tinkerpop/gremlin/java/translator/jython/PythonJythonTranslatorProcessComputerTest.java b/gremlin-python/src/test/java/org/apache/tinkerpop/gremlin/java/translator/jython/PythonJythonTranslatorProcessComputerTest.java
new file mode 100644
index 0000000..0c7a941
--- /dev/null
+++ b/gremlin-python/src/test/java/org/apache/tinkerpop/gremlin/java/translator/jython/PythonJythonTranslatorProcessComputerTest.java
@@ -0,0 +1,34 @@
+/*
+ *  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.
+ */
+
+package org.apache.tinkerpop.gremlin.java.translator.jython;
+
+import org.apache.tinkerpop.gremlin.GraphProviderClass;
+import org.apache.tinkerpop.gremlin.process.ProcessComputerSuite;
+import org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerGraph;
+import org.junit.runner.RunWith;
+
+/**
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ */
+@RunWith(ProcessComputerSuite.class)
+@GraphProviderClass(provider = PythonJythonTranslatorComputerProvider.class, graph = TinkerGraph.class)
+public class PythonJythonTranslatorProcessComputerTest {
+
+}

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/6acb8936/gremlin-python/src/test/java/org/apache/tinkerpop/gremlin/java/translator/jython/PythonJythonTranslatorProcessStandardTest.java
----------------------------------------------------------------------
diff --git a/gremlin-python/src/test/java/org/apache/tinkerpop/gremlin/java/translator/jython/PythonJythonTranslatorProcessStandardTest.java b/gremlin-python/src/test/java/org/apache/tinkerpop/gremlin/java/translator/jython/PythonJythonTranslatorProcessStandardTest.java
new file mode 100644
index 0000000..bf176fc
--- /dev/null
+++ b/gremlin-python/src/test/java/org/apache/tinkerpop/gremlin/java/translator/jython/PythonJythonTranslatorProcessStandardTest.java
@@ -0,0 +1,34 @@
+/*
+ *  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.
+ */
+
+package org.apache.tinkerpop.gremlin.java.translator.jython;
+
+import org.apache.tinkerpop.gremlin.GraphProviderClass;
+import org.apache.tinkerpop.gremlin.process.ProcessStandardSuite;
+import org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerGraph;
+import org.junit.runner.RunWith;
+
+/**
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ */
+@RunWith(ProcessStandardSuite.class)
+@GraphProviderClass(provider = PythonJythonTranslatorProvider.class, graph = TinkerGraph.class)
+public class PythonJythonTranslatorProcessStandardTest {
+
+}

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/6acb8936/gremlin-python/src/test/java/org/apache/tinkerpop/gremlin/java/translator/jython/PythonJythonTranslatorProvider.java
----------------------------------------------------------------------
diff --git a/gremlin-python/src/test/java/org/apache/tinkerpop/gremlin/java/translator/jython/PythonJythonTranslatorProvider.java b/gremlin-python/src/test/java/org/apache/tinkerpop/gremlin/java/translator/jython/PythonJythonTranslatorProvider.java
new file mode 100644
index 0000000..b972ec1
--- /dev/null
+++ b/gremlin-python/src/test/java/org/apache/tinkerpop/gremlin/java/translator/jython/PythonJythonTranslatorProvider.java
@@ -0,0 +1,52 @@
+/*
+ *  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.
+ */
+
+package org.apache.tinkerpop.gremlin.java.translator.jython;
+
+import org.apache.tinkerpop.gremlin.java.translator.PythonTranslatorProvider;
+import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource;
+import org.apache.tinkerpop.gremlin.structure.Graph;
+import org.apache.tinkerpop.gremlin.util.ScriptEngineCache;
+
+import javax.script.ScriptException;
+
+/**
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ */
+public class PythonJythonTranslatorProvider extends PythonTranslatorProvider {
+
+    @Override
+    public GraphTraversalSource traversal(final Graph graph) {
+        if ((Boolean) graph.configuration().getProperty("skipTest"))
+            return graph.traversal();
+            //throw new VerificationException("This test current does not work with Gremlin-Python", EmptyTraversal.instance());
+        else {
+            try {
+                if (IMPORT_STATICS)
+                    ScriptEngineCache.get("jython").eval("for k in statics:\n  globals()[k] = statics[k]");
+                else
+                    ScriptEngineCache.get("jython").eval("for k in statics:\n  if k in globals():\n    del globals()[k]");
+            } catch (final ScriptException e) {
+                throw new IllegalStateException(e.getMessage(), e);
+            }
+            return graph.traversal().withTranslator(PythonJythonTranslator.of("g", IMPORT_STATICS)); // the bypass translator will ensure that gremlin-groovy is ultimately used
+        }
+    }
+
+}