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)'