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/27 16:12:51 UTC

[4/4] tinkerpop git commit: gremlin_python.py is now graph_traversal.py and traversal.py. Added statics.py which holds all statics and has nice load_statics() and unload_statics() methods. Converging on the pattern... Funny enough, the pattern is identic

gremlin_python.py is now graph_traversal.py and traversal.py. Added statics.py which holds all statics and has nice load_statics() and unload_statics() methods. Converging on the pattern... Funny enough, the pattern is identical to Gremlin-Java (this is a good thing).


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

Branch: refs/heads/TINKERPOP-1278
Commit: b41fa42ecb3dd5eed170e362dee701c5b1d5b71f
Parents: 099a33c
Author: Marko A. Rodriguez <ok...@gmail.com>
Authored: Mon Jun 27 10:12:45 2016 -0600
Committer: Marko A. Rodriguez <ok...@gmail.com>
Committed: Mon Jun 27 10:12:45 2016 -0600

----------------------------------------------------------------------
 gremlin-python/pom.xml                          |    3 +-
 .../python/GraphTraversalSourceGenerator.groovy |  187 ++
 .../python/GremlinPythonSourceGenerator.groovy  |  315 ---
 .../python/TraversalSourceGenerator.groovy      |  204 ++
 .../gremlin/python/GenerateGremlinPython.java   |   15 +-
 .../src/main/jython/gremlin_python/__init__.py  |   29 +-
 .../jython/gremlin_python/graph_traversal.py    | 1599 +++++++++++++++
 .../jython/gremlin_python/gremlin_python.py     | 1829 ------------------
 .../jython/gremlin_python/groovy_translator.py  |    6 +-
 .../jython/gremlin_python/jython_translator.py  |   12 +-
 .../src/main/jython/gremlin_python/statics.py   |   45 +
 .../main/jython/gremlin_python/translator.py    |    5 +-
 .../src/main/jython/gremlin_python/traversal.py |  262 +++
 .../translator/PythonTranslatorProvider.java    |   22 +
 .../groovy/PythonGroovyTranslatorProvider.java  |   24 +-
 .../jython/PythonJythonTranslatorProvider.java  |   21 +-
 .../python/driver/RESTRemoteConnectionTest.java |   21 +-
 .../python/jsr223/JythonScriptEngineSetup.java  |    7 +-
 18 files changed, 2385 insertions(+), 2221 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/b41fa42e/gremlin-python/pom.xml
----------------------------------------------------------------------
diff --git a/gremlin-python/pom.xml b/gremlin-python/pom.xml
index 8d23d9c..e54561f 100644
--- a/gremlin-python/pom.xml
+++ b/gremlin-python/pom.xml
@@ -101,7 +101,8 @@
                         <configuration>
                             <mainClass>org.apache.tinkerpop.gremlin.python.GenerateGremlinPython</mainClass>
                             <arguments>
-                                <argument>${basedir}/src/main/jython/gremlin_python/gremlin_python.py</argument>
+                                <argument>${basedir}/src/main/jython/gremlin_python/traversal.py</argument>
+                                <argument>${basedir}/src/main/jython/gremlin_python/graph_traversal.py</argument>
                             </arguments>
                         </configuration>
                     </execution>

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/b41fa42e/gremlin-python/src/main/groovy/org/apache/tinkerpop/gremlin/python/GraphTraversalSourceGenerator.groovy
----------------------------------------------------------------------
diff --git a/gremlin-python/src/main/groovy/org/apache/tinkerpop/gremlin/python/GraphTraversalSourceGenerator.groovy b/gremlin-python/src/main/groovy/org/apache/tinkerpop/gremlin/python/GraphTraversalSourceGenerator.groovy
new file mode 100644
index 0000000..39bdc10
--- /dev/null
+++ b/gremlin-python/src/main/groovy/org/apache/tinkerpop/gremlin/python/GraphTraversalSourceGenerator.groovy
@@ -0,0 +1,187 @@
+/*
+ *  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.python
+
+import org.apache.tinkerpop.gremlin.process.traversal.Traversal
+import org.apache.tinkerpop.gremlin.process.traversal.TraversalSource
+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.python.util.SymbolHelper
+
+import java.lang.reflect.Modifier
+
+/**
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ */
+class GraphTraversalSourceGenerator {
+
+    public static void create(final String graphTraversalSourceFile) {
+
+        final StringBuilder pythonClass = new StringBuilder()
+
+        pythonClass.append("""'''
+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.
+'''
+""")
+        pythonClass.append("from aenum import Enum\n")
+        pythonClass.append("from traversal import RawExpression\n")
+        pythonClass.append("from traversal import PythonTraversal\n")
+        pythonClass.append("from statics import add_static\n")
+        pythonClass.append("globalTranslator = None\n\n")
+
+//////////////////////////
+// GraphTraversalSource //
+//////////////////////////
+        pythonClass.append(
+                """class PythonGraphTraversalSource(object):
+  def __init__(self, translator, remote_connection=None):
+    global globalTranslator
+    self.translator = translator
+    globalTranslator = translator
+    self.remote_connection = remote_connection
+  def __repr__(self):
+    return "graphtraversalsource[" + str(self.remote_connection) + ", " + self.translator.traversal_script + "]"
+""")
+        GraphTraversalSource.getMethods()
+                .findAll { !it.name.equals("clone") }
+                .collect { it.name }
+                .unique()
+                .sort { a, b -> a <=> b }
+                .each { method ->
+            final Class<?> returnType = (GraphTraversalSource.getMethods() as Set).findAll {
+                it.name.equals(method)
+            }.collect {
+                it.returnType
+            }[0]
+            if (null != returnType) {
+                if (Traversal.isAssignableFrom(returnType)) {
+                    pythonClass.append(
+                            """  def ${method}(self, *args):
+    traversal = PythonGraphTraversal(self.translator, self.remote_connection)
+    traversal.translator.addSpawnStep(traversal, "${method}", *args)
+    for arg in args:
+      if isinstance(arg, tuple) and 2 == len(arg) and isinstance(arg[0], str):
+        self.bindings[arg[0]] = arg[1]
+      elif isinstance(arg, RawExpression):
+        self.bindings.update(arg.bindings)
+    return traversal
+""")
+                } else if (TraversalSource.isAssignableFrom(returnType)) {
+                    pythonClass.append(
+                            """  def ${method}(self, *args):
+    source = PythonGraphTraversalSource(self.translator, self.remote_connection)
+    source.translator.addSource(source, "${method}", *args)
+    for arg in args:
+      if isinstance(arg, tuple) and 2 == len(arg) and isinstance(arg[0], str):
+        self.bindings[arg[0]] = arg[1]
+      elif isinstance(arg, RawExpression):
+        self.bindings.update(arg.bindings)
+    return source
+""")
+                }
+            }
+        }
+        pythonClass.append("\n\n")
+
+////////////////////
+// GraphTraversal //
+////////////////////
+        pythonClass.append(
+                """class PythonGraphTraversal(PythonTraversal):
+  def __init__(self, translator, remote_connection=None):
+    PythonTraversal.__init__(self, translator, remote_connection)
+""")
+        GraphTraversal.getMethods()
+                .findAll { !it.name.equals("clone") }
+                .collect { SymbolHelper.toPython(it.name) }
+                .unique()
+                .sort { a, b -> a <=> b }
+                .each { method ->
+            final Class<?> returnType = (GraphTraversal.getMethods() as Set).findAll {
+                it.name.equals(SymbolHelper.toJava(method))
+            }.collect { it.returnType }[0]
+            if (null != returnType && Traversal.isAssignableFrom(returnType)) {
+                pythonClass.append(
+                        """  def ${method}(self, *args):
+    self.translator.addStep(self, "${method}", *args)
+    for arg in args:
+      if isinstance(arg, tuple) and 2 == len(arg) and isinstance(arg[0], str):
+        self.bindings[arg[0]] = arg[1]
+      elif isinstance(arg, RawExpression):
+        self.bindings.update(arg.bindings)
+    return self
+""")
+            }
+        };
+        pythonClass.append("\n\n")
+
+////////////////////////
+// AnonymousTraversal //
+////////////////////////
+        pythonClass.append("class __(object):\n");
+        __.getMethods()
+                .findAll { Traversal.isAssignableFrom(it.returnType) }
+                .collect { SymbolHelper.toPython(it.name) }
+                .unique()
+                .sort { a, b -> a <=> b }
+                .each { method ->
+            pythonClass.append(
+                    """  @staticmethod
+  def ${method}(*args):
+    return PythonGraphTraversal(globalTranslator.getAnonymousTraversalTranslator()).${method}(*args)
+""")
+        };
+        pythonClass.append("\n\n")
+
+        __.class.getMethods()
+                .findAll { Traversal.class.isAssignableFrom(it.getReturnType()) }
+                .findAll { Modifier.isStatic(it.getModifiers()) }
+                .findAll { !it.name.equals("__") }
+                .collect { SymbolHelper.toPython(it.name) }
+                .unique()
+                .sort { a, b -> a <=> b }
+                .forEach {
+            pythonClass.append("def ${it}(*args):\n").append("      return __.${it}(*args)\n\n")
+            pythonClass.append("add_static('${it}', ${it})\n")
+        }
+        pythonClass.append("\n\n")
+
+// save to a python file
+        final File file = new File(graphTraversalSourceFile);
+        file.delete()
+        pythonClass.eachLine { file.append(it + "\n") }
+    }
+}

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/b41fa42e/gremlin-python/src/main/groovy/org/apache/tinkerpop/gremlin/python/GremlinPythonSourceGenerator.groovy
----------------------------------------------------------------------
diff --git a/gremlin-python/src/main/groovy/org/apache/tinkerpop/gremlin/python/GremlinPythonSourceGenerator.groovy b/gremlin-python/src/main/groovy/org/apache/tinkerpop/gremlin/python/GremlinPythonSourceGenerator.groovy
deleted file mode 100644
index cece5df..0000000
--- a/gremlin-python/src/main/groovy/org/apache/tinkerpop/gremlin/python/GremlinPythonSourceGenerator.groovy
+++ /dev/null
@@ -1,315 +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.python
-
-import org.apache.tinkerpop.gremlin.process.traversal.P
-import org.apache.tinkerpop.gremlin.process.traversal.Traversal
-import org.apache.tinkerpop.gremlin.process.traversal.TraversalSource
-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.python.util.SymbolHelper
-import org.apache.tinkerpop.gremlin.util.CoreImports
-
-import java.lang.reflect.Modifier
-
-/**
- * @author Marko A. Rodriguez (http://markorodriguez.com)
- */
-class GremlinPythonSourceGenerator {
-
-    public static void create(final String gremlinPythonFile) {
-
-        final StringBuilder pythonClass = new StringBuilder()
-
-        pythonClass.append("""'''
-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.
-'''
-""")
-        pythonClass.append("from collections import OrderedDict\n")
-        pythonClass.append("from aenum import Enum\n")
-        pythonClass.append("statics = OrderedDict()\n\n")
-        pythonClass.append("""
-globalTranslator = None
-""").append("\n\n");
-
-//////////////////////////
-// GraphTraversalSource //
-//////////////////////////
-        pythonClass.append(
-                """class PythonGraphTraversalSource(object):
-  def __init__(self, translator, remote_connection=None):
-    global globalTranslator
-    self.translator = translator
-    globalTranslator = translator
-    self.remote_connection = remote_connection
-  def __repr__(self):
-    return "graphtraversalsource[" + str(self.remote_connection) + ", " + self.translator.traversal_script + "]"
-""")
-        GraphTraversalSource.getMethods()
-                .findAll { !it.name.equals("clone") }
-                .collect { it.name }
-                .unique()
-                .sort { a, b -> a <=> b }
-                .each { method ->
-            final Class<?> returnType = (GraphTraversalSource.getMethods() as Set).findAll {
-                it.name.equals(method)
-            }.collect {
-                it.returnType
-            }[0]
-            if (null != returnType) {
-                if (Traversal.isAssignableFrom(returnType)) {
-                    pythonClass.append(
-                            """  def ${method}(self, *args):
-    traversal = PythonGraphTraversal(self.translator, self.remote_connection)
-    traversal.translator.addSpawnStep(traversal, "${method}", *args)
-    for arg in args:
-      if isinstance(arg, tuple) and 2 == len(arg) and isinstance(arg[0], str):
-        self.bindings[arg[0]] = arg[1]
-      elif isinstance(arg, RawExpression):
-        self.bindings.update(arg.bindings)
-    return traversal
-""")
-                } else if (TraversalSource.isAssignableFrom(returnType)) {
-                    pythonClass.append(
-                            """  def ${method}(self, *args):
-    source = PythonGraphTraversalSource(self.translator, self.remote_connection)
-    source.translator.addSource(source, "${method}", *args)
-    for arg in args:
-      if isinstance(arg, tuple) and 2 == len(arg) and isinstance(arg[0], str):
-        self.bindings[arg[0]] = arg[1]
-      elif isinstance(arg, RawExpression):
-        self.bindings.update(arg.bindings)
-    return source
-""")
-                }
-            }
-        }
-        pythonClass.append("\n\n")
-
-////////////////////
-// GraphTraversal //
-////////////////////
-        pythonClass.append(
-                """class PythonGraphTraversal(object):
-  def __init__(self, translator, remote_connection=None):
-    self.translator = translator
-    self.remote_connection = remote_connection
-    self.results = None
-    self.last_traverser = None
-    self.bindings = {}
-  def __repr__(self):
-    return self.translator.traversal_script
-  def __getitem__(self,index):
-    if isinstance(index,int):
-      return self.range(index,index+1)
-    elif isinstance(index,slice):
-      return self.range(index.start,index.stop)
-    else:
-      raise TypeError("Index must be int or slice")
-  def __getattr__(self,key):
-    return self.values(key)
-  def __iter__(self):
-        return self
-  def __next__(self):
-     return self.next()
-  def toList(self):
-    return list(iter(self))
-  def toSet(self):
-    return set(iter(self))
-  def next(self,amount):
-    count = 0
-    tempList = []
-    while count < amount:
-      count = count + 1
-      temp = next(self,None)
-      if None == temp:
-        break
-      tempList.append(temp)
-    return tempList
-  def next(self):
-     if self.results is None:
-        self.results = self.remote_connection.submit(self.translator.target_language, self.translator.traversal_script, self.bindings)
-     if self.last_traverser is None:
-         self.last_traverser = next(self.results)
-     object = self.last_traverser.object
-     self.last_traverser.bulk = self.last_traverser.bulk - 1
-     if self.last_traverser.bulk <= 0:
-         self.last_traverser = None
-     return object
-""")
-        GraphTraversal.getMethods()
-                .findAll { !it.name.equals("clone") }
-                .collect { SymbolHelper.toPython(it.name) }
-                .unique()
-                .sort { a, b -> a <=> b }
-                .each { method ->
-            final Class<?> returnType = (GraphTraversal.getMethods() as Set).findAll {
-                it.name.equals(SymbolHelper.toJava(method))
-            }.collect { it.returnType }[0]
-            if (null != returnType && Traversal.isAssignableFrom(returnType)) {
-                pythonClass.append(
-                        """  def ${method}(self, *args):
-    self.translator.addStep(self, "${method}", *args)
-    for arg in args:
-      if isinstance(arg, tuple) and 2 == len(arg) and isinstance(arg[0], str):
-        self.bindings[arg[0]] = arg[1]
-      elif isinstance(arg, RawExpression):
-        self.bindings.update(arg.bindings)
-    return self
-""")
-            }
-        };
-        pythonClass.append("\n\n")
-
-////////////////////////
-// AnonymousTraversal //
-////////////////////////
-        pythonClass.append("class __(object):\n");
-        __.getMethods()
-                .findAll { Traversal.isAssignableFrom(it.returnType) }
-                .collect { SymbolHelper.toPython(it.name) }
-                .unique()
-                .sort { a, b -> a <=> b }
-                .each { method ->
-            pythonClass.append(
-                    """  @staticmethod
-  def ${method}(*args):
-    return PythonGraphTraversal(globalTranslator.getAnonymousTraversalTranslator()).${method}(*args)
-""")
-        };
-        pythonClass.append("\n\n")
-
-        __.class.getMethods()
-                .findAll { Traversal.class.isAssignableFrom(it.getReturnType()) }
-                .findAll { Modifier.isStatic(it.getModifiers()) }
-                .findAll { !it.name.equals("__") }
-                .collect { SymbolHelper.toPython(it.name) }
-                .unique()
-                .sort { a, b -> a <=> b }
-                .forEach {
-            pythonClass.append("def ${it}(*args):\n").append("      return __.${it}(*args)\n\n")
-            pythonClass.append("statics['${it}'] = ${it}\n")
-        }
-        pythonClass.append("\n\n")
-
-///////////
-// Enums //
-///////////
-        for (final Class<? extends Enum> enumClass : CoreImports.getClassImports()
-                .findAll { Enum.class.isAssignableFrom(it) }
-                .sort { a, b -> a.getSimpleName() <=> b.getSimpleName() }
-                .collect()) {
-            pythonClass.append("${enumClass.getSimpleName()} = Enum('${enumClass.getSimpleName()}', '");
-            enumClass.getEnumConstants()
-                    .sort { a, b -> a.name() <=> b.name() }
-                    .each { value -> pythonClass.append("${SymbolHelper.toPython(value.name())} "); }
-            pythonClass.deleteCharAt(pythonClass.length() - 1).append("')\n\n")
-            enumClass.getEnumConstants().each { value ->
-                pythonClass.append("statics['${SymbolHelper.toPython(value.name())}'] = ${value.getDeclaringClass().getSimpleName()}.${SymbolHelper.toPython(value.name())}\n");
-            }
-            pythonClass.append("\n");
-        }
-        //////////////
-
-        pythonClass.append("""class P(object):
-   def __init__(self, operator, value, other=None):
-      self.operator = operator
-      self.value = value
-      self.other = other
-""")
-        P.class.getMethods()
-                .findAll { Modifier.isStatic(it.getModifiers()) }
-                .findAll { P.class.isAssignableFrom(it.returnType) }
-                .collect { SymbolHelper.toPython(it.name) }
-                .unique()
-                .sort { a, b -> a <=> b }
-                .each { method ->
-            pythonClass.append(
-                    """   @staticmethod
-   def ${method}(*args):
-      return P("${SymbolHelper.toJava(method)}", *args)
-""")
-        };
-        pythonClass.append("""   def _and(self, arg):
-      return P("_and", arg, self)
-   def _or(self, arg):
-      return P("_or", arg, self)
-""")
-        pythonClass.append("\n")
-        P.class.getMethods()
-                .findAll { Modifier.isStatic(it.getModifiers()) }
-                .findAll { !it.name.equals("clone") }
-                .findAll { P.class.isAssignableFrom(it.getReturnType()) }
-                .collect { SymbolHelper.toPython(it.name) }
-                .unique()
-                .sort { a, b -> a <=> b }
-                .forEach {
-            pythonClass.append("def ${it}(*args):\n").append("      return P.${it}(*args)\n\n")
-            pythonClass.append("statics['${it}'] = ${it}\n")
-        }
-        pythonClass.append("\n")
-        //////////////
-
-        pythonClass.append("""class RawExpression(object):
-   def __init__(self, *args):
-      self.bindings = dict()
-      self.parts = [self._process_arg(arg) for arg in args]
-
-   def _process_arg(self, arg):
-      if isinstance(arg, tuple) and 2 == len(arg) and isinstance(arg[0], str):
-         self.bindings[arg[0]] = arg[1]
-         return Raw(arg[0])
-      else:
-         return Raw(arg)
-
-class Raw(object):
-   def __init__(self, value):
-      self.value = value
-
-   def __str__(self):
-      return str(self.value)
-
-""")
-        //////////////
-
-        pythonClass.append("statics = OrderedDict(reversed(list(statics.items())))\n")
-
-// save to a python file
-        final File file = new File(gremlinPythonFile);
-        file.delete()
-        pythonClass.eachLine { file.append(it + "\n") }
-    }
-}

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/b41fa42e/gremlin-python/src/main/groovy/org/apache/tinkerpop/gremlin/python/TraversalSourceGenerator.groovy
----------------------------------------------------------------------
diff --git a/gremlin-python/src/main/groovy/org/apache/tinkerpop/gremlin/python/TraversalSourceGenerator.groovy b/gremlin-python/src/main/groovy/org/apache/tinkerpop/gremlin/python/TraversalSourceGenerator.groovy
new file mode 100644
index 0000000..504d240
--- /dev/null
+++ b/gremlin-python/src/main/groovy/org/apache/tinkerpop/gremlin/python/TraversalSourceGenerator.groovy
@@ -0,0 +1,204 @@
+/*
+ *  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.python
+
+import org.apache.tinkerpop.gremlin.process.traversal.P
+import org.apache.tinkerpop.gremlin.python.util.SymbolHelper
+import org.apache.tinkerpop.gremlin.util.CoreImports
+
+import java.lang.reflect.Modifier
+
+/**
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ */
+class TraversalSourceGenerator {
+
+    public static void create(final String traversalSourceFile) {
+
+        final StringBuilder pythonClass = new StringBuilder()
+
+        pythonClass.append("""'''
+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.
+'''
+""")
+        pythonClass.append("from aenum import Enum\n")
+        pythonClass.append("from statics import add_static\n")
+
+        pythonClass.append("""
+class PythonTraversal(object):
+    def __init__(self, translator, remote_connection=None):
+        self.translator = translator
+        self.remote_connection = remote_connection
+        self.results = None
+        self.last_traverser = None
+        self.bindings = {}
+
+    def __repr__(self):
+        return self.translator.traversal_script
+
+    def __getitem__(self, index):
+        if isinstance(index, int):
+            return self.range(index, index + 1)
+        elif isinstance(index, slice):
+            return self.range(index.start, index.stop)
+        else:
+            raise TypeError("Index must be int or slice")
+
+    def __getattr__(self, key):
+        return self.values(key)
+
+    def __iter__(self):
+        return self
+
+    def __next__(self):
+        return self.next()
+
+    def toList(self):
+        return list(iter(self))
+
+    def toSet(self):
+        return set(iter(self))
+
+    def next(self, amount):
+        count = 0
+        tempList = []
+        while count < amount:
+            count = count + 1
+            temp = next(self, None)
+            if None == temp:
+                break
+            tempList.append(temp)
+        return tempList
+
+    def next(self):
+        if self.results is None:
+            self.results = self.remote_connection.submit(self.translator.target_language,
+                                                         self.translator.traversal_script, self.bindings)
+        if self.last_traverser is None:
+            self.last_traverser = next(self.results)
+        object = self.last_traverser.object
+        self.last_traverser.bulk = self.last_traverser.bulk - 1
+        if self.last_traverser.bulk <= 0:
+            self.last_traverser = None
+        return object
+
+""")
+
+///////////
+// Enums //
+///////////
+        for (final Class<? extends Enum> enumClass : CoreImports.getClassImports()
+                .findAll { Enum.class.isAssignableFrom(it) }
+                .sort { a, b -> a.getSimpleName() <=> b.getSimpleName() }
+                .collect()) {
+            pythonClass.append("${enumClass.getSimpleName()} = Enum('${enumClass.getSimpleName()}', '");
+            enumClass.getEnumConstants()
+                    .sort { a, b -> a.name() <=> b.name() }
+                    .each { value -> pythonClass.append("${SymbolHelper.toPython(value.name())} "); }
+            pythonClass.deleteCharAt(pythonClass.length() - 1).append("')\n\n")
+            enumClass.getEnumConstants().each { value ->
+                pythonClass.append("add_static('${SymbolHelper.toPython(value.name())}', ${value.getDeclaringClass().getSimpleName()}.${SymbolHelper.toPython(value.name())})\n");
+            }
+            pythonClass.append("\n");
+        }
+        //////////////
+
+        pythonClass.append("""class P(object):
+   def __init__(self, operator, value, other=None):
+      self.operator = operator
+      self.value = value
+      self.other = other
+""")
+        P.class.getMethods()
+                .findAll { Modifier.isStatic(it.getModifiers()) }
+                .findAll { P.class.isAssignableFrom(it.returnType) }
+                .collect { SymbolHelper.toPython(it.name) }
+                .unique()
+                .sort { a, b -> a <=> b }
+                .each { method ->
+            pythonClass.append(
+                    """   @staticmethod
+   def ${method}(*args):
+      return P("${SymbolHelper.toJava(method)}", *args)
+""")
+        };
+        pythonClass.append("""   def _and(self, arg):
+      return P("_and", arg, self)
+   def _or(self, arg):
+      return P("_or", arg, self)
+""")
+        pythonClass.append("\n")
+        P.class.getMethods()
+                .findAll { Modifier.isStatic(it.getModifiers()) }
+                .findAll { !it.name.equals("clone") }
+                .findAll { P.class.isAssignableFrom(it.getReturnType()) }
+                .collect { SymbolHelper.toPython(it.name) }
+                .unique()
+                .sort { a, b -> a <=> b }
+                .forEach {
+            pythonClass.append("def ${it}(*args):\n").append("      return P.${it}(*args)\n\n")
+            pythonClass.append("add_static('${it}',${it})\n")
+        }
+        pythonClass.append("\n")
+        //////////////
+
+        pythonClass.append("""class RawExpression(object):
+   def __init__(self, *args):
+      self.bindings = dict()
+      self.parts = [self._process_arg(arg) for arg in args]
+
+   def _process_arg(self, arg):
+      if isinstance(arg, tuple) and 2 == len(arg) and isinstance(arg[0], str):
+         self.bindings[arg[0]] = arg[1]
+         return Raw(arg[0])
+      else:
+         return Raw(arg)
+
+class Raw(object):
+   def __init__(self, value):
+      self.value = value
+
+   def __str__(self):
+      return str(self.value)
+
+""")
+        //////////////
+
+        // save to a python file
+        final File file = new File(traversalSourceFile);
+        file.delete()
+        pythonClass.eachLine { file.append(it + "\n") }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/b41fa42e/gremlin-python/src/main/java/org/apache/tinkerpop/gremlin/python/GenerateGremlinPython.java
----------------------------------------------------------------------
diff --git a/gremlin-python/src/main/java/org/apache/tinkerpop/gremlin/python/GenerateGremlinPython.java b/gremlin-python/src/main/java/org/apache/tinkerpop/gremlin/python/GenerateGremlinPython.java
index 53dec75..6d8f04d 100644
--- a/gremlin-python/src/main/java/org/apache/tinkerpop/gremlin/python/GenerateGremlinPython.java
+++ b/gremlin-python/src/main/java/org/apache/tinkerpop/gremlin/python/GenerateGremlinPython.java
@@ -20,14 +20,13 @@
 package org.apache.tinkerpop.gremlin.python;
 
 public class GenerateGremlinPython {
+
+    private GenerateGremlinPython() {
+        // just need the main method
+    }
+
     public static void main(String[] args) {
-        String dest;
-        if (args.length > 0) {
-            dest = args[0];
-        } else {
-            System.out.println("Usage: java GenerateGremlinPython <path/to/dest>");
-            return;
-        }
-        GremlinPythonSourceGenerator.create(dest);
+        TraversalSourceGenerator.create(args[0]);
+        GraphTraversalSourceGenerator.create(args[1]);
     }
 }

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/b41fa42e/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 62a5ddd..bbeba19 100644
--- a/gremlin-python/src/main/jython/gremlin_python/__init__.py
+++ b/gremlin-python/src/main/jython/gremlin_python/__init__.py
@@ -16,21 +16,22 @@ KIND, either express or implied.  See the License for the
 specific language governing permissions and limitations
 under the License.
 '''
-from gremlin_python import Barrier
-from gremlin_python import Cardinality
-from gremlin_python import Column
-from gremlin_python import Direction
-from gremlin_python import Operator
-from gremlin_python import Order
-from gremlin_python import P
-from gremlin_python import Pop
-from gremlin_python import PythonGraphTraversal
-from gremlin_python import PythonGraphTraversalSource
-from gremlin_python import Scope
-from gremlin_python import T
-from gremlin_python import __
-from gremlin_python import statics
+import statics
+from graph_traversal import PythonGraphTraversal
+from graph_traversal import PythonGraphTraversalSource
+from graph_traversal import __
 from groovy_translator import GroovyTranslator
 from jython_translator import JythonTranslator
+from traversal import Barrier
+from traversal import Cardinality
+from traversal import Column
+from traversal import Direction
+from traversal import Operator
+from traversal import Order
+from traversal import P
+from traversal import Pop
+from traversal import PythonTraversal
+from traversal import Scope
+from traversal import T
 
 __author__ = 'Marko A. Rodriguez (http://markorodriguez.com)'