tinkerpop-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ok...@apache.org
Subject [04/13] incubator-tinkerpop git commit: more work on Gremlin-Jython. This is a really cool tutorial.
Date Thu, 21 Apr 2016 13:20:02 GMT
more work on Gremlin-Jython. This is a really cool tutorial.


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

Branch: refs/heads/TINKERPOP-1232
Commit: d5a06d99f3df520ad5cecf2fb21c7ac8ad223592
Parents: 7e2833c
Author: Marko A. Rodriguez <okrammarko@gmail.com>
Authored: Wed Apr 20 09:28:33 2016 -0600
Committer: Marko A. Rodriguez <okrammarko@gmail.com>
Committed: Wed Apr 20 09:28:33 2016 -0600

----------------------------------------------------------------------
 .../gremlin-language-variants/index.asciidoc    |  94 ++-
 docs/static/resources/gremlin-jython.py         | 590 ++++++++++---------
 2 files changed, 363 insertions(+), 321 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/d5a06d99/docs/src/tutorials/gremlin-language-variants/index.asciidoc
----------------------------------------------------------------------
diff --git a/docs/src/tutorials/gremlin-language-variants/index.asciidoc b/docs/src/tutorials/gremlin-language-variants/index.asciidoc
index d341093..a768190 100644
--- a/docs/src/tutorials/gremlin-language-variants/index.asciidoc
+++ b/docs/src/tutorials/gremlin-language-variants/index.asciidoc
@@ -98,8 +98,8 @@ class that mimics Gremlin-Java's `GraphTraversal` API. With each method
calls of
 string is constructed (e.g. Gremlin-Groovy). Ultimately, that constructed traversal (represented
behind the
 scenes as a string) is submitted to a Gremlin-Server compliant graph system for evaluation.
 
-IMPORTANT: Gremlin-Java is considered the idiomatic, standard implementation of Gremlin.
Any language variant, regardless
-of the model it uses above, **must** do its best (within the constraints of the host language)
to be in 1-to-1
+IMPORTANT: Gremlin-Java is considered the idiomatic, standard implementation of Gremlin.
Any Gremlin language variant,
+regardless of the implementation model chosen, **must**, within the constraints of the host
language, be in 1-to-1
 correspondence with Gremlin-Java.
 
 Implementation Requirements
@@ -118,7 +118,16 @@ Every language variant implementation, regardless of the model used above,
will
 4. `__`: The anonymous traversal class that is used for nested traversals. An example includes
`repeat(__.out())`.
 
 Historically, many Gremlin language variants have failed to make these distinction clear
and in doing so, either
-complicate their implementations or yield variants that are not in 1-to-1 correspondence
with Gremlin-Java.
+complicate their implementations or yield variants that are not in 1-to-1 correspondence
with Gremlin-Java. Note that most
+variants will only have to consider `GraphTraversalSource`, `GraphTraversal`, and `__`.
+
+NOTE: `GraphTraversal` is a particular Gremlin domain-specific language (link:https://en.wikipedia.org/wiki/Domain-specific_language[DSL]),
+albeit the most popular and foundational DSL. If another DSL is created, then the same techniques
discussed for `GraphTraversal`
+apply to `XXXTraversal`.
+
+IMPORTANT: The term "Gremlin-Java" denotes the language that is defined by `GraphTraversalSource`,
`GraphTraversal`,
+and `__`. These three classes exist in `org.apache.tinkerpop.gremlin.process.traversal.dsl.graph`
and form the definitive
+representation of the Gremlin traversal language.
 
 [[using-jython-and-the-jvm]]
 Using Jython and the JVM
@@ -126,9 +135,9 @@ Using Jython and the JVM
 
 link:http://www.jython.org/[Jython] is a link:https://www.jcp.org/en/jsr/detail?id=223[JSR-223]
implementation that allows
 for the evaluation of Python on the link:https://en.wikipedia.org/wiki/Java_virtual_machine[Java
virtual machine].
-Jython's virtual machine is not the standard link:https://wiki.python.org/moin/CPython[CPython]
reference implementation
-distributed with most operating systems, but instead the JVM. The benefit of Jython is that
it is simple to interact
-with the Java API and any Java packages from Python. This makes a Gremlin language variant
"implementation" trivial.
+In other words, Jython's virtual machine is not the standard link:https://wiki.python.org/moin/CPython[CPython]
reference implementation
+distributed with most operating systems, but instead the JVM. The benefit of Jython is that
Python code and classes can interact
+with the Java API and any Java packages on the `CLASSPATH`. This makes any JSR-224 Gremlin
language variant "implementation" trivial.
 
 [source,python]
 ----
@@ -148,7 +157,7 @@ with the Java API and any Java packages from Python. This makes a Gremlin
langua
 # The Jython shell does not automatically iterate Iterators like the Gremlin Console
 >>> g.V().hasLabel("person").out("knows").out("created")
 [GraphStep(vertex,[]), HasStep([~label.eq(person)]), VertexStep(OUT,[knows],vertex), VertexStep(OUT,[created],vertex)]
-# toList() will do the iteration and result the results as a list
+# toList() will do the iteration and return the results as a list
 >>> g.V().hasLabel("person").out("knows").out("created").toList()
 [v[5], v[3]]
 >>> g.V().repeat(__.out()).times(2).values("name").toList()
@@ -161,25 +170,26 @@ u'RIP'
 >>>
 ----
 
-Most every JSR-223 `ScriptEngine` language will allow the developer to immediately interact
with Gremlin-Java. The benefit
-of this model is that nearly every major programming language has a respective `ScriptEngine`:
JavaScript
-(link:https://en.wikipedia.org/wiki/Nashorn_(JavaScript_engine)[Nashorn]), link:http://groovy-lang.org/[Groovy],
-link:http://www.scala-lang.org/[Scala], Lisp (link:https://clojure.org/[Clojure]), link:http://jruby.org/[Ruby],
etc.
+Most every JSR-223 `ScriptEngine` language will allow the developer to immediately interact
with `GraphTraversal`.
+The benefit of this model is that nearly every major programming language has a respective
`ScriptEngine`:
+link:https://en.wikipedia.org/wiki/Nashorn_(JavaScript_engine)[JavaScript], link:http://groovy-lang.org/[Groovy],
+link:http://www.scala-lang.org/[Scala], Lisp (link:https://clojure.org/[Clojure]), link:http://jruby.org/[Ruby],
etc. A
+list of implementations is provided link:https://en.wikipedia.org/wiki/List_of_JVM_languages[here].
 
 Traversal Wrappers
 ~~~~~~~~~~~~~~~~~~
 
 While it is possible to simply interact with Java classes in a `ScriptEngine` implementation,
such Gremlin language variants
 will not leverage the unique features of the host language. It is for this reason that link:https://github.com/mpollmeier/gremlin-scala[Gremlin-Scala]
-exists at all. Gremlin-Scala "wraps" `GraphTraversal` to provide Scala-idiomatic extensions.
Note that Apache TinkerPop's
-Gremlin-Groovy does the same for the link:http://tinkerpop.apache.org/docs/x.y.z/reference/#sugar-plugin[Sugar
plugin],
+was developed. Scala provides many syntax niceties not available in Java. To leverage these
niceties, Gremlin-Scala "wraps"
+`GraphTraversal` in order to provide Scala-idiomatic extensions. Another example is Apache
TinkerPop's
+Gremlin-Groovy which does the same via the link:http://tinkerpop.apache.org/docs/x.y.z/reference/#sugar-plugin[Sugar
plugin],
 but uses link:http://groovy-lang.org/metaprogramming.html[meta-programming] instead of object
wrapping.
-This tutorial will use wrapping to extend `GraphTraversal` with Python idiomatic extensions.
 
 The Python (via Jython) classes below wrap `GraphTraversalSource` and `GraphTraversal`. In
doing so, they add methods
-that apply Python-specific constructs to Gremlin. In particular `__getitem__` and `__getattr__`
"magic methods." It is
-important to note that the classes below are **not complete** and only contain enough functionality
to demonstrate the
-example at hand.
+that apply Python-specific constructs to Gremlin. In particular, `__getitem__` and `__getattr__`
"magic methods" are leveraged.
+It is important to note that the classes below are **not complete** and only provide enough
functionality to demonstrate this
+sub-sections tutorial material.
 
 [source,python]
 ----
@@ -243,15 +253,18 @@ language variant **must** provide all the same functionality (methods)
as `Graph
 with host language specific constructs. This means that the extensions **must** compile to
`GraphTraversal`-specific
 steps. A Gremlin language variant **should not** add steps/methods that do not exist in `GraphTraversal`.
If such an extension
 is desired, the language variant designer should submit a proposal to link:http://tinkerpop.apache.org[Apache
TinkerPop]
-to have the extension added to a future version of Gremlin.
+to have the extension added to a future release of Gremlin.
 
-Auto-Generated Wrappers
-~~~~~~~~~~~~~~~~~~~~~~~
+Auto-Generated Traversal Wrappers
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 In the previous example, only a subset of the `GraphTraversalSource` and `GraphTraversal`
methods were implemented in the
 corresponding Jython-based Python classes. Unfortunately, adding the near 200 `GraphTraversal`
methods to a wrapper is
 both tedious and error-prone. To alleviate this pain, Python classes can be dynamically created
using Groovy and
-Java reflection.
+link:https://en.wikipedia.org/wiki/Reflection_(computer_programming)#Java[Java reflection].
+The Groovy code for constructing the `JythonGraphTraversal` class source is reviewed below.
By simply executing this code
+in the link:http://tinkerpop.apache.org/docs/x.y.z/reference/#gremlin-console[Gremlin Console],
the `gremlin-jython.py` file
+is generated and can be used by Jython.
 
 [source,groovy]
 ----
@@ -294,10 +307,9 @@ pythonClass.append("\n\n")
 ////////////////////
 // GraphTraversal //
 ////////////////////
-methodMap = [as:"_as",in:"_in",and:"_and",or:"_or",is:"_is",not:"_not",from:"_from"].withDefault{
it }
+methodMap = [as:"_as",in:"_in",and:"_and",or:"_or",is:"_is",not:"_not",from:"_from"].withDefault{
it }  <1>
 invertedMethodMap = [_as:"as",_in:"in",_and:"and",_or:"or",_is:"is",_not:"not",_from:"from"].withDefault{
it }
-methods = GraphTraversal.getMethods().collect{methodMap[it.name]} as Set; []
-pythonClass.append(
+pythonClass.append(                                                           <2>
 """class JythonGraphTraversal(object):
   def __init__(self, traversal):
     self.traversal = traversal
@@ -314,16 +326,17 @@ pythonClass.append(
   def __getattr__(self,key):
     return self.values(key)
 """)
+methods = GraphTraversal.getMethods().collect{methodMap[it.name]} as Set; []  <3>
 methods.each{ method ->
   returnType = (GraphTraversal.getMethods() as Set).findAll{it.name.equals(method)}.collect{it.returnType}[0]
-  if(null != returnType && Traversal.isAssignableFrom(returnType)) {
+  if(null != returnType && Traversal.isAssignableFrom(returnType)) {          <4>
   pythonClass.append(
 """  def ${method}(self, *args):
     self.traversal = self.traversal.${invertedMethodMap[method]}(*args)
     return self
 """)
   } else {
-  pythonClass.append(
+  pythonClass.append(                                                         <5>
 """  def ${method}(self, *args):
     return self.traversal.${invertedMethodMap[method]}(*args)
 """)
@@ -339,30 +352,36 @@ pythonClass.append("class __(object):\n");
 methods.each{ method ->
   pythonClass.append(
 """  @staticmethod
-  def ${method}(self, *args):
+  def ${method}(*args):
     return anon.${invertedMethodMap[method]}(*args)
 """)
 }; []
 pythonClass.append("\n\n")
 
 // save to a python file
-file = new File("/Users/marko/Desktop/JYTHON-TUTORIAL/gremlin-jython.py")
+file = new File("/usr/local/apache-gremlin-console-x.y.z-standalone/lib/gremlin-jython.py")
 file.delete()
 pythonClass.eachLine{ file.append(it + "\n") }
 ----
 
-Then, from the Jython console, `gremlin-jython.py` is loaded and a complete Gremlin language
variant is born: **Gremlin-Jython**.
+<1> There are numerous `GraphTraversal` step names that are reserved words in Python.
Prefixing these steps with `_` is the chosen workaround.
+<2> Add Gremlin-Jython specific methods to `JythonGraphTraversal`. These methods are
idiomatic Python extensions, not step additions.
+<3> Use Java reflection to get all the methods of `GraphTraversal`.
+<4> If the method is a fluent traversal-method, then mutate the underlying/wrapped
`GraphTraversal` instance accordingly.
+<5> If the method is not a fluent traversal-method, return the result of applying the
method.
+
+From the Jython console, `gremlin-jython.py` is loaded and a complete Gremlin language variant
is born: **Gremlin-Jython**.
 The generated file is available at link:../../resources/gremlin-jython.py[gremlin-jython.py].
 
 [source,python]
 ----
 >>> execfile("/usr/local/apache-gremlin-console-x.y.z-standalone/lib/gremlin-jython.py")
+>>> graph = TinkerFactory.createModern()
 >>> g = JythonGraphTraversalSource(graph.traversal())
->>> g.V().repeat(__.both("created")).times(2).name[1:2].toList()
-[[marko, josh, ripple], [marko, josh, lop]]
-# using the Gremlin-Jython __getattr__ and __getitem__ extensions
+# using the Gremlin-Jython __getattr__ and __getitem__ extensions and anonymous traversals
 >>> g.V().repeat(__.both("created")).times(2).name[1:3].path().toList()
 [[v[1], v[3], v[4], josh], [v[1], v[3], v[6], peter]]
+# JythonGraphTraversalSource works as expected -- an example using Gremlin-Jython w/ OLAP
 >>> g = g.withComputer()
 >>> g
 graphtraversalsource[tinkergraph[vertices:6 edges:6], graphcomputer]
@@ -371,6 +390,17 @@ graphtraversalsource[tinkergraph[vertices:6 edges:6], graphcomputer]
 >>>
 ----
 
+Gremlin-Jython was simple to create. Unfortunately, this simplicity is not without problems.
These problems are itemized below.
+However, for the sake of this tutorial, the simple application of the technique was chosen.
+
+* The Gremlin-Jython API is non-informative as all methods take a tuple reference (`*args`).
+** The Gremlin-Java link:http://tinkerpop.apache.org/javadocs/x.y.z/full/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html[JavaDoc]
would be a sufficient guide to Gremlin-Jython (minus the extensions).
+* Lambdas are not supported with, for example, `map(lambda x: x.get())` throwing an exception.
+** Type introspection with a typecast to a `java.util.function.Function` lambda wrapper would
solve this problem.
+* `__` is always required for anonymous traversals.
+** By placing the `@staticmethods` outside of the `__` Jython class, the methods would be
globally scoped (analogous to `import static` in Java).
+
+
 [[using-python-and-jni]]
 Using Python and JNI
 --------------------

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/d5a06d99/docs/static/resources/gremlin-jython.py
----------------------------------------------------------------------
diff --git a/docs/static/resources/gremlin-jython.py b/docs/static/resources/gremlin-jython.py
index c74248f..c04b411 100644
--- a/docs/static/resources/gremlin-jython.py
+++ b/docs/static/resources/gremlin-jython.py
@@ -26,7 +26,7 @@ class JythonGraphTraversalSource(object):
     return self.traversalSource.toString(*args)
   def clone(self, *args):
     self.traversalSource = self.traversalSource.clone(*args)
-    return self 
+    return self
   def V(self, *args):
     return JythonGraphTraversal(self.traversalSource.V(*args))
   def E(self, *args):
@@ -39,27 +39,27 @@ class JythonGraphTraversalSource(object):
     return self.traversalSource.getGraph(*args)
   def withSack(self, *args):
     self.traversalSource = self.traversalSource.withSack(*args)
-    return self 
+    return self
   def computer(self, *args):
     return self.traversalSource.computer(*args)
   def withComputer(self, *args):
     self.traversalSource = self.traversalSource.withComputer(*args)
-    return self 
+    return self
   def withStrategies(self, *args):
     self.traversalSource = self.traversalSource.withStrategies(*args)
-    return self 
+    return self
   def withoutStrategies(self, *args):
     self.traversalSource = self.traversalSource.withoutStrategies(*args)
-    return self 
+    return self
   def withSideEffect(self, *args):
     self.traversalSource = self.traversalSource.withSideEffect(*args)
-    return self 
+    return self
   def withBulk(self, *args):
     self.traversalSource = self.traversalSource.withBulk(*args)
-    return self 
+    return self
   def withPath(self, *args):
     self.traversalSource = self.traversalSource.withPath(*args)
-    return self 
+    return self
   def standard(self, *args):
     return self.traversalSource.standard(*args)
   def build(self, *args):
@@ -99,295 +99,295 @@ class JythonGraphTraversal(object):
     return self.values(key)
   def group(self, *args):
     self.traversal = self.traversal.group(*args)
-    return self 
+    return self
   def limit(self, *args):
     self.traversal = self.traversal.limit(*args)
-    return self 
+    return self
   def value(self, *args):
     self.traversal = self.traversal.value(*args)
-    return self 
+    return self
   def count(self, *args):
     self.traversal = self.traversal.count(*args)
-    return self 
+    return self
   def profile(self, *args):
     self.traversal = self.traversal.profile(*args)
-    return self 
+    return self
   def values(self, *args):
     self.traversal = self.traversal.values(*args)
-    return self 
+    return self
   def min(self, *args):
     self.traversal = self.traversal.min(*args)
-    return self 
+    return self
   def max(self, *args):
     self.traversal = self.traversal.max(*args)
-    return self 
+    return self
   def V(self, *args):
     self.traversal = self.traversal.V(*args)
-    return self 
+    return self
   def identity(self, *args):
     self.traversal = self.traversal.identity(*args)
-    return self 
+    return self
   def _in(self, *args):
     return self.traversal.in(*args)
   def out(self, *args):
     self.traversal = self.traversal.out(*args)
-    return self 
+    return self
   def key(self, *args):
     self.traversal = self.traversal.key(*args)
-    return self 
+    return self
   def store(self, *args):
     self.traversal = self.traversal.store(*args)
-    return self 
+    return self
   def path(self, *args):
     self.traversal = self.traversal.path(*args)
-    return self 
+    return self
   def sum(self, *args):
     self.traversal = self.traversal.sum(*args)
-    return self 
+    return self
   def toV(self, *args):
     self.traversal = self.traversal.toV(*args)
-    return self 
+    return self
   def filter(self, *args):
     self.traversal = self.traversal.filter(*args)
-    return self 
+    return self
   def tree(self, *args):
     self.traversal = self.traversal.tree(*args)
-    return self 
+    return self
   def match(self, *args):
     self.traversal = self.traversal.match(*args)
-    return self 
+    return self
   def range(self, *args):
     self.traversal = self.traversal.range(*args)
-    return self 
+    return self
   def order(self, *args):
     self.traversal = self.traversal.order(*args)
-    return self 
+    return self
   def map(self, *args):
     self.traversal = self.traversal.map(*args)
-    return self 
+    return self
   def tail(self, *args):
     self.traversal = self.traversal.tail(*args)
-    return self 
+    return self
   def _and(self, *args):
     return self.traversal.and(*args)
   def _or(self, *args):
     return self.traversal.or(*args)
   def id(self, *args):
     self.traversal = self.traversal.id(*args)
-    return self 
+    return self
   def label(self, *args):
     self.traversal = self.traversal.label(*args)
-    return self 
+    return self
   def has(self, *args):
     self.traversal = self.traversal.has(*args)
-    return self 
+    return self
   def union(self, *args):
     self.traversal = self.traversal.union(*args)
-    return self 
+    return self
   def groupCount(self, *args):
     self.traversal = self.traversal.groupCount(*args)
-    return self 
+    return self
   def flatMap(self, *args):
     self.traversal = self.traversal.flatMap(*args)
-    return self 
+    return self
   def iterate(self, *args):
     self.traversal = self.traversal.iterate(*args)
-    return self 
+    return self
   def until(self, *args):
     self.traversal = self.traversal.until(*args)
-    return self 
+    return self
   def asAdmin(self, *args):
     self.traversal = self.traversal.asAdmin(*args)
-    return self 
+    return self
   def choose(self, *args):
     self.traversal = self.traversal.choose(*args)
-    return self 
+    return self
   def program(self, *args):
     self.traversal = self.traversal.program(*args)
-    return self 
+    return self
   def both(self, *args):
     self.traversal = self.traversal.both(*args)
-    return self 
+    return self
   def toE(self, *args):
     self.traversal = self.traversal.toE(*args)
-    return self 
+    return self
   def outE(self, *args):
     self.traversal = self.traversal.outE(*args)
-    return self 
+    return self
   def inE(self, *args):
     self.traversal = self.traversal.inE(*args)
-    return self 
+    return self
   def bothE(self, *args):
     self.traversal = self.traversal.bothE(*args)
-    return self 
+    return self
   def inV(self, *args):
     self.traversal = self.traversal.inV(*args)
-    return self 
+    return self
   def outV(self, *args):
     self.traversal = self.traversal.outV(*args)
-    return self 
+    return self
   def bothV(self, *args):
     self.traversal = self.traversal.bothV(*args)
-    return self 
+    return self
   def otherV(self, *args):
     self.traversal = self.traversal.otherV(*args)
-    return self 
+    return self
   def valueMap(self, *args):
     self.traversal = self.traversal.valueMap(*args)
-    return self 
+    return self
   def mapValues(self, *args):
     self.traversal = self.traversal.mapValues(*args)
-    return self 
+    return self
   def mapKeys(self, *args):
     self.traversal = self.traversal.mapKeys(*args)
-    return self 
+    return self
   def sack(self, *args):
     self.traversal = self.traversal.sack(*args)
-    return self 
+    return self
   def loops(self, *args):
     self.traversal = self.traversal.loops(*args)
-    return self 
+    return self
   def project(self, *args):
     self.traversal = self.traversal.project(*args)
-    return self 
+    return self
   def unfold(self, *args):
     self.traversal = self.traversal.unfold(*args)
-    return self 
+    return self
   def fold(self, *args):
     self.traversal = self.traversal.fold(*args)
-    return self 
+    return self
   def mean(self, *args):
     self.traversal = self.traversal.mean(*args)
-    return self 
+    return self
   def groupV3d0(self, *args):
     self.traversal = self.traversal.groupV3d0(*args)
-    return self 
+    return self
   def addV(self, *args):
     self.traversal = self.traversal.addV(*args)
-    return self 
+    return self
   def addE(self, *args):
     self.traversal = self.traversal.addE(*args)
-    return self 
+    return self
   def addOutE(self, *args):
     self.traversal = self.traversal.addOutE(*args)
-    return self 
+    return self
   def addInE(self, *args):
     self.traversal = self.traversal.addInE(*args)
-    return self 
+    return self
   def dedup(self, *args):
     self.traversal = self.traversal.dedup(*args)
-    return self 
+    return self
   def where(self, *args):
     self.traversal = self.traversal.where(*args)
-    return self 
+    return self
   def hasNot(self, *args):
     self.traversal = self.traversal.hasNot(*args)
-    return self 
+    return self
   def hasLabel(self, *args):
     self.traversal = self.traversal.hasLabel(*args)
-    return self 
+    return self
   def hasId(self, *args):
     self.traversal = self.traversal.hasId(*args)
-    return self 
+    return self
   def hasKey(self, *args):
     self.traversal = self.traversal.hasKey(*args)
-    return self 
+    return self
   def hasValue(self, *args):
     self.traversal = self.traversal.hasValue(*args)
-    return self 
+    return self
   def coin(self, *args):
     self.traversal = self.traversal.coin(*args)
-    return self 
+    return self
   def timeLimit(self, *args):
     self.traversal = self.traversal.timeLimit(*args)
-    return self 
+    return self
   def simplePath(self, *args):
     self.traversal = self.traversal.simplePath(*args)
-    return self 
+    return self
   def cyclicPath(self, *args):
     self.traversal = self.traversal.cyclicPath(*args)
-    return self 
+    return self
   def sample(self, *args):
     self.traversal = self.traversal.sample(*args)
-    return self 
+    return self
   def sideEffect(self, *args):
     self.traversal = self.traversal.sideEffect(*args)
-    return self 
+    return self
   def subgraph(self, *args):
     self.traversal = self.traversal.subgraph(*args)
-    return self 
+    return self
   def aggregate(self, *args):
     self.traversal = self.traversal.aggregate(*args)
-    return self 
+    return self
   def branch(self, *args):
     self.traversal = self.traversal.branch(*args)
-    return self 
+    return self
   def optional(self, *args):
     self.traversal = self.traversal.optional(*args)
-    return self 
+    return self
   def coalesce(self, *args):
     self.traversal = self.traversal.coalesce(*args)
-    return self 
+    return self
   def repeat(self, *args):
     self.traversal = self.traversal.repeat(*args)
-    return self 
+    return self
   def emit(self, *args):
     self.traversal = self.traversal.emit(*args)
-    return self 
+    return self
   def local(self, *args):
     self.traversal = self.traversal.local(*args)
-    return self 
+    return self
   def pageRank(self, *args):
     self.traversal = self.traversal.pageRank(*args)
-    return self 
+    return self
   def peerPressure(self, *args):
     self.traversal = self.traversal.peerPressure(*args)
-    return self 
+    return self
   def barrier(self, *args):
     self.traversal = self.traversal.barrier(*args)
-    return self 
+    return self
   def by(self, *args):
     self.traversal = self.traversal.by(*args)
-    return self 
+    return self
   def propertyMap(self, *args):
     self.traversal = self.traversal.propertyMap(*args)
-    return self 
+    return self
   def select(self, *args):
     self.traversal = self.traversal.select(*args)
-    return self 
+    return self
   def _as(self, *args):
     return self.traversal.as(*args)
   def property(self, *args):
     self.traversal = self.traversal.property(*args)
-    return self 
+    return self
   def inject(self, *args):
     self.traversal = self.traversal.inject(*args)
-    return self 
+    return self
   def drop(self, *args):
     self.traversal = self.traversal.drop(*args)
-    return self 
+    return self
   def times(self, *args):
     self.traversal = self.traversal.times(*args)
-    return self 
+    return self
   def option(self, *args):
     self.traversal = self.traversal.option(*args)
-    return self 
+    return self
   def cap(self, *args):
     self.traversal = self.traversal.cap(*args)
-    return self 
+    return self
   def _is(self, *args):
     return self.traversal.is(*args)
   def _not(self, *args):
     return self.traversal.not(*args)
   def constant(self, *args):
     self.traversal = self.traversal.constant(*args)
-    return self 
+    return self
   def properties(self, *args):
     self.traversal = self.traversal.properties(*args)
-    return self 
+    return self
   def to(self, *args):
     self.traversal = self.traversal.to(*args)
-    return self 
+    return self
   def _from(self, *args):
     return self.traversal.from(*args)
   def next(self, *args):
@@ -415,292 +415,304 @@ class JythonGraphTraversal(object):
 
 
 class __(object):
-  @staticmethod  
-  def group(self, *args):
+  @staticmethod
+  def group(*args):
     return anon.group(*args)
-  @staticmethod  
-  def limit(self, *args):
+  @staticmethod
+  def limit(*args):
     return anon.limit(*args)
-  @staticmethod  
-  def value(self, *args):
+  @staticmethod
+  def value(*args):
     return anon.value(*args)
-  @staticmethod  
-  def count(self, *args):
+  @staticmethod
+  def count(*args):
     return anon.count(*args)
-  @staticmethod  
-  def values(self, *args):
+  @staticmethod
+  def values(*args):
     return anon.values(*args)
-  @staticmethod  
-  def min(self, *args):
+  @staticmethod
+  def min(*args):
     return anon.min(*args)
-  @staticmethod  
-  def max(self, *args):
+  @staticmethod
+  def max(*args):
     return anon.max(*args)
-  @staticmethod  
-  def V(self, *args):
+  @staticmethod
+  def V(*args):
     return anon.V(*args)
-  @staticmethod  
-  def identity(self, *args):
+  @staticmethod
+  def identity(*args):
     return anon.identity(*args)
-  def _in(self, *args):
+  @staticmethod
+  def _in(*args):
     return anon.in(*args)
-  @staticmethod  
-  def out(self, *args):
+  @staticmethod
+  def out(*args):
     return anon.out(*args)
-  @staticmethod  
-  def key(self, *args):
+  @staticmethod
+  def key(*args):
     return anon.key(*args)
-  @staticmethod  
-  def start(self, *args):
+  @staticmethod
+  def start(*args):
     return anon.start(*args)
-  @staticmethod  
-  def store(self, *args):
+  @staticmethod
+  def store(*args):
     return anon.store(*args)
-  @staticmethod  
-  def path(self, *args):
+  @staticmethod
+  def path(*args):
     return anon.path(*args)
-  @staticmethod  
-  def sum(self, *args):
+  @staticmethod
+  def sum(*args):
     return anon.sum(*args)
-  @staticmethod  
-  def toV(self, *args):
+  @staticmethod
+  def toV(*args):
     return anon.toV(*args)
-  @staticmethod  
-  def filter(self, *args):
+  @staticmethod
+  def filter(*args):
     return anon.filter(*args)
-  @staticmethod  
-  def tree(self, *args):
+  @staticmethod
+  def tree(*args):
     return anon.tree(*args)
-  @staticmethod  
-  def match(self, *args):
+  @staticmethod
+  def match(*args):
     return anon.match(*args)
-  @staticmethod  
-  def range(self, *args):
+  @staticmethod
+  def range(*args):
     return anon.range(*args)
-  @staticmethod  
-  def order(self, *args):
+  @staticmethod
+  def order(*args):
     return anon.order(*args)
-  @staticmethod  
-  def map(self, *args):
+  @staticmethod
+  def map(*args):
     return anon.map(*args)
-  @staticmethod  
-  def tail(self, *args):
+  @staticmethod
+  def tail(*args):
     return anon.tail(*args)
-  def _and(self, *args):
+  @staticmethod
+  def _and(*args):
     return anon.and(*args)
-  def _or(self, *args):
+  @staticmethod
+  def _or(*args):
     return anon.or(*args)
-  @staticmethod  
-  def id(self, *args):
+  @staticmethod
+  def id(*args):
     return anon.id(*args)
-  @staticmethod  
-  def label(self, *args):
+  @staticmethod
+  def label(*args):
     return anon.label(*args)
-  @staticmethod  
-  def has(self, *args):
+  @staticmethod
+  def has(*args):
     return anon.has(*args)
-  @staticmethod  
-  def union(self, *args):
+  @staticmethod
+  def union(*args):
     return anon.union(*args)
-  @staticmethod  
-  def groupCount(self, *args):
+  @staticmethod
+  def groupCount(*args):
     return anon.groupCount(*args)
-  @staticmethod  
-  def flatMap(self, *args):
+  @staticmethod
+  def flatMap(*args):
     return anon.flatMap(*args)
-  @staticmethod  
-  def until(self, *args):
+  @staticmethod
+  def until(*args):
     return anon.until(*args)
-  @staticmethod  
-  def __(self, *args):
+  @staticmethod
+  def __(*args):
     return anon.__(*args)
-  @staticmethod  
-  def choose(self, *args):
+  @staticmethod
+  def choose(*args):
     return anon.choose(*args)
-  @staticmethod  
-  def both(self, *args):
+  @staticmethod
+  def both(*args):
     return anon.both(*args)
-  @staticmethod  
-  def toE(self, *args):
+  @staticmethod
+  def toE(*args):
     return anon.toE(*args)
-  @staticmethod  
-  def outE(self, *args):
+  @staticmethod
+  def outE(*args):
     return anon.outE(*args)
-  @staticmethod  
-  def inE(self, *args):
+  @staticmethod
+  def inE(*args):
     return anon.inE(*args)
-  @staticmethod  
-  def bothE(self, *args):
+  @staticmethod
+  def bothE(*args):
     return anon.bothE(*args)
-  @staticmethod  
-  def inV(self, *args):
+  @staticmethod
+  def inV(*args):
     return anon.inV(*args)
-  @staticmethod  
-  def outV(self, *args):
+  @staticmethod
+  def outV(*args):
     return anon.outV(*args)
-  @staticmethod  
-  def bothV(self, *args):
+  @staticmethod
+  def bothV(*args):
     return anon.bothV(*args)
-  @staticmethod  
-  def otherV(self, *args):
+  @staticmethod
+  def otherV(*args):
     return anon.otherV(*args)
-  @staticmethod  
-  def valueMap(self, *args):
+  @staticmethod
+  def valueMap(*args):
     return anon.valueMap(*args)
-  @staticmethod  
-  def mapValues(self, *args):
+  @staticmethod
+  def mapValues(*args):
     return anon.mapValues(*args)
-  @staticmethod  
-  def mapKeys(self, *args):
+  @staticmethod
+  def mapKeys(*args):
     return anon.mapKeys(*args)
-  @staticmethod  
-  def sack(self, *args):
+  @staticmethod
+  def sack(*args):
     return anon.sack(*args)
-  @staticmethod  
-  def loops(self, *args):
+  @staticmethod
+  def loops(*args):
     return anon.loops(*args)
-  @staticmethod  
-  def project(self, *args):
+  @staticmethod
+  def project(*args):
     return anon.project(*args)
-  @staticmethod  
-  def unfold(self, *args):
+  @staticmethod
+  def unfold(*args):
     return anon.unfold(*args)
-  @staticmethod  
-  def fold(self, *args):
+  @staticmethod
+  def fold(*args):
     return anon.fold(*args)
-  @staticmethod  
-  def mean(self, *args):
+  @staticmethod
+  def mean(*args):
     return anon.mean(*args)
-  @staticmethod  
-  def groupV3d0(self, *args):
+  @staticmethod
+  def groupV3d0(*args):
     return anon.groupV3d0(*args)
-  @staticmethod  
-  def addV(self, *args):
+  @staticmethod
+  def addV(*args):
     return anon.addV(*args)
-  @staticmethod  
-  def addE(self, *args):
+  @staticmethod
+  def addE(*args):
     return anon.addE(*args)
-  @staticmethod  
-  def addOutE(self, *args):
+  @staticmethod
+  def addOutE(*args):
     return anon.addOutE(*args)
-  @staticmethod  
-  def addInE(self, *args):
+  @staticmethod
+  def addInE(*args):
     return anon.addInE(*args)
-  @staticmethod  
-  def dedup(self, *args):
+  @staticmethod
+  def dedup(*args):
     return anon.dedup(*args)
-  @staticmethod  
-  def where(self, *args):
+  @staticmethod
+  def where(*args):
     return anon.where(*args)
-  @staticmethod  
-  def hasNot(self, *args):
+  @staticmethod
+  def hasNot(*args):
     return anon.hasNot(*args)
-  @staticmethod  
-  def hasLabel(self, *args):
+  @staticmethod
+  def hasLabel(*args):
     return anon.hasLabel(*args)
-  @staticmethod  
-  def hasId(self, *args):
+  @staticmethod
+  def hasId(*args):
     return anon.hasId(*args)
-  @staticmethod  
-  def hasKey(self, *args):
+  @staticmethod
+  def hasKey(*args):
     return anon.hasKey(*args)
-  @staticmethod  
-  def hasValue(self, *args):
+  @staticmethod
+  def hasValue(*args):
     return anon.hasValue(*args)
-  @staticmethod  
-  def coin(self, *args):
+  @staticmethod
+  def coin(*args):
     return anon.coin(*args)
-  @staticmethod  
-  def timeLimit(self, *args):
+  @staticmethod
+  def timeLimit(*args):
     return anon.timeLimit(*args)
-  @staticmethod  
-  def simplePath(self, *args):
+  @staticmethod
+  def simplePath(*args):
     return anon.simplePath(*args)
-  @staticmethod  
-  def cyclicPath(self, *args):
+  @staticmethod
+  def cyclicPath(*args):
     return anon.cyclicPath(*args)
-  @staticmethod  
-  def sample(self, *args):
+  @staticmethod
+  def sample(*args):
     return anon.sample(*args)
-  @staticmethod  
-  def sideEffect(self, *args):
+  @staticmethod
+  def sideEffect(*args):
     return anon.sideEffect(*args)
-  @staticmethod  
-  def subgraph(self, *args):
+  @staticmethod
+  def subgraph(*args):
     return anon.subgraph(*args)
-  @staticmethod  
-  def aggregate(self, *args):
+  @staticmethod
+  def aggregate(*args):
     return anon.aggregate(*args)
-  @staticmethod  
-  def branch(self, *args):
+  @staticmethod
+  def branch(*args):
     return anon.branch(*args)
-  @staticmethod  
-  def optional(self, *args):
+  @staticmethod
+  def optional(*args):
     return anon.optional(*args)
-  @staticmethod  
-  def coalesce(self, *args):
+  @staticmethod
+  def coalesce(*args):
     return anon.coalesce(*args)
-  @staticmethod  
-  def repeat(self, *args):
+  @staticmethod
+  def repeat(*args):
     return anon.repeat(*args)
-  @staticmethod  
-  def emit(self, *args):
+  @staticmethod
+  def emit(*args):
     return anon.emit(*args)
-  @staticmethod  
-  def local(self, *args):
+  @staticmethod
+  def local(*args):
     return anon.local(*args)
-  @staticmethod  
-  def barrier(self, *args):
+  @staticmethod
+  def barrier(*args):
     return anon.barrier(*args)
-  @staticmethod  
-  def propertyMap(self, *args):
+  @staticmethod
+  def propertyMap(*args):
     return anon.propertyMap(*args)
-  @staticmethod  
-  def select(self, *args):
+  @staticmethod
+  def select(*args):
     return anon.select(*args)
-  def _as(self, *args):
+  @staticmethod
+  def _as(*args):
     return anon.as(*args)
-  @staticmethod  
-  def property(self, *args):
+  @staticmethod
+  def property(*args):
     return anon.property(*args)
-  @staticmethod  
-  def inject(self, *args):
+  @staticmethod
+  def inject(*args):
     return anon.inject(*args)
-  @staticmethod  
-  def drop(self, *args):
+  @staticmethod
+  def drop(*args):
     return anon.drop(*args)
-  @staticmethod  
-  def times(self, *args):
+  @staticmethod
+  def times(*args):
     return anon.times(*args)
-  @staticmethod  
-  def cap(self, *args):
+  @staticmethod
+  def cap(*args):
     return anon.cap(*args)
-  def _is(self, *args):
+  @staticmethod
+  def _is(*args):
     return anon.is(*args)
-  def _not(self, *args):
+  @staticmethod
+  def _not(*args):
     return anon.not(*args)
-  @staticmethod  
-  def constant(self, *args):
+  @staticmethod
+  def constant(*args):
     return anon.constant(*args)
-  @staticmethod  
-  def properties(self, *args):
+  @staticmethod
+  def properties(*args):
     return anon.properties(*args)
-  @staticmethod  
-  def to(self, *args):
+  @staticmethod
+  def to(*args):
     return anon.to(*args)
-  def wait(self, *args):
+  @staticmethod
+  def wait(*args):
     return anon.wait(*args)
-  def equals(self, *args):
+  @staticmethod
+  def equals(*args):
     return anon.equals(*args)
-  def toString(self, *args):
+  @staticmethod
+  def toString(*args):
     return anon.toString(*args)
-  def hashCode(self, *args):
+  @staticmethod
+  def hashCode(*args):
     return anon.hashCode(*args)
-  def getClass(self, *args):
+  @staticmethod
+  def getClass(*args):
     return anon.getClass(*args)
-  def notify(self, *args):
+  @staticmethod
+  def notify(*args):
     return anon.notify(*args)
-  def notifyAll(self, *args):
+  @staticmethod
+  def notifyAll(*args):
     return anon.notifyAll(*args)
 
-



Mime
View raw message