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/08/24 14:35:24 UTC

tinkerpop git commit: added deserializers for Vertex, Edge, VertexProperty, Property, Long, Double, Float, Integer, and Traverser. This way the user gets the same look and feel as Gremlin-Java when getting back these types of objects. Cleaned up driver_r

Repository: tinkerpop
Updated Branches:
  refs/heads/TINKERPOP-1278 79120e543 -> 98efcef17


added deserializers for Vertex, Edge, VertexProperty, Property, Long, Double, Float, Integer, and Traverser. This way the user gets the same look and feel as Gremlin-Java when getting back these types of objects. Cleaned up driver_remote_connection a bit and made it so its results run through GraphSONReader to do the object deserialization. Moved graphson.py to structure.io package.


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

Branch: refs/heads/TINKERPOP-1278
Commit: 98efcef17945842b77001e95e19d45a462bd91e4
Parents: 79120e5
Author: Marko A. Rodriguez <ok...@gmail.com>
Authored: Wed Aug 24 08:35:03 2016 -0600
Committer: Marko A. Rodriguez <ok...@gmail.com>
Committed: Wed Aug 24 08:35:03 2016 -0600

----------------------------------------------------------------------
 .../jsr223/GremlinJythonScriptEngine.java       |   8 +-
 .../gremlin/python/jsr223/JythonTranslator.java |   8 +-
 .../driver/driver_remote_connection.py          |  12 +-
 .../jython/gremlin_python/process/__init__.py   |   4 +-
 .../jython/gremlin_python/process/graphson.py   | 164 ------------
 .../jython/gremlin_python/structure/__init__.py |   4 +
 .../jython/gremlin_python/structure/graph.py    |  39 +++
 .../gremlin_python/structure/io/__init__.py     |  25 ++
 .../gremlin_python/structure/io/graphson.py     | 263 +++++++++++++++++++
 gremlin-python/src/main/jython/setup.py         |   2 +-
 .../gremlin/python/GremlinPythonTest.java       |  37 +++
 .../python/jsr223/JythonScriptEngineSetup.java  |   2 +-
 12 files changed, 387 insertions(+), 181 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/98efcef1/gremlin-python/src/main/java/org/apache/tinkerpop/gremlin/python/jsr223/GremlinJythonScriptEngine.java
----------------------------------------------------------------------
diff --git a/gremlin-python/src/main/java/org/apache/tinkerpop/gremlin/python/jsr223/GremlinJythonScriptEngine.java b/gremlin-python/src/main/java/org/apache/tinkerpop/gremlin/python/jsr223/GremlinJythonScriptEngine.java
index 951b82a..4952803 100644
--- a/gremlin-python/src/main/java/org/apache/tinkerpop/gremlin/python/jsr223/GremlinJythonScriptEngine.java
+++ b/gremlin-python/src/main/java/org/apache/tinkerpop/gremlin/python/jsr223/GremlinJythonScriptEngine.java
@@ -78,14 +78,14 @@ public class GremlinJythonScriptEngine implements GremlinScriptEngine {
                     "from org.apache.tinkerpop.gremlin.util.function.Lambda import TwoArgLambda\n\n" +
 
                     "class JythonUnknownArgLambda(UnknownArgLambda):\n" +
-                    "  def __init__(self,func,script,lang='gremlin-jython'):\n" +
+                    "  def __init__(self,func,script='none',lang='gremlin-jython'):\n" +
                     "    UnknownArgLambda.__init__(self, script, lang, -1)\n" +
                     "    self.func = func\n" +
                     "  def __repr__(self):\n" +
                     "    return self.getLambdaScript()\n\n" +
 
                     "class JythonZeroArgLambda(ZeroArgLambda):\n" +
-                    "  def __init__(self,func,script,lang='gremlin-jython'):\n" +
+                    "  def __init__(self,func,script='none',lang='gremlin-jython'):\n" +
                     "    ZeroArgLambda.__init__(self, script, lang)\n" +
                     "    self.func = func\n" +
                     "  def __repr__(self):\n" +
@@ -94,7 +94,7 @@ public class GremlinJythonScriptEngine implements GremlinScriptEngine {
                     "    return self.func()\n\n" +
 
                     "class JythonOneArgLambda(OneArgLambda):\n" +
-                    "  def __init__(self,func,script,lang='gremlin-jython'):\n" +
+                    "  def __init__(self,func,script='none',lang='gremlin-jython'):\n" +
                     "    OneArgLambda.__init__(self, script, lang)\n" +
                     "    self.func = func\n" +
                     "  def __repr__(self):\n" +
@@ -109,7 +109,7 @@ public class GremlinJythonScriptEngine implements GremlinScriptEngine {
                     "    return self.func(a,b)\n\n" +
 
                     "class JythonTwoArgLambda(TwoArgLambda):\n" +
-                    "  def __init__(self,func,script,lang='gremlin-jython'):\n" +
+                    "  def __init__(self,func,script='none',lang='gremlin-jython'):\n" +
                     "    TwoArgLambda.__init__(self, script, lang)\n" +
                     "    self.func = func\n" +
                     "  def __repr__(self):\n" +

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/98efcef1/gremlin-python/src/main/java/org/apache/tinkerpop/gremlin/python/jsr223/JythonTranslator.java
----------------------------------------------------------------------
diff --git a/gremlin-python/src/main/java/org/apache/tinkerpop/gremlin/python/jsr223/JythonTranslator.java b/gremlin-python/src/main/java/org/apache/tinkerpop/gremlin/python/jsr223/JythonTranslator.java
index 8b21704..0eb8961 100644
--- a/gremlin-python/src/main/java/org/apache/tinkerpop/gremlin/python/jsr223/JythonTranslator.java
+++ b/gremlin-python/src/main/java/org/apache/tinkerpop/gremlin/python/jsr223/JythonTranslator.java
@@ -46,12 +46,12 @@ public final class JythonTranslator extends PythonTranslator {
                 lambdaString :
                 "lambda " + lambdaString;
         if (0 == lambda.getLambdaArguments())
-            return "JythonZeroArgLambda(" + lambdaString + ", \"" + lambdaString.replaceAll("\"","\\\\\"") + "\")";
+            return "JythonZeroArgLambda(" + lambdaString + ")";
         else if (1 == lambda.getLambdaArguments())
-            return "JythonOneArgLambda(" + lambdaString + ", \"" + lambdaString.replaceAll("\"","\\\\\"") + "\")";
+            return "JythonOneArgLambda(" + lambdaString + ")";
         else if (2 == lambda.getLambdaArguments())
-            return "JythonTwoArgLambda(" + lambdaString + ", \"" + lambdaString.replaceAll("\"","\\\\\"") + "\")";
+            return "JythonTwoArgLambda(" + lambdaString + ")";
         else
-            return "JythonUnknownArgLambda(" + lambdaString + ", \"" + lambdaString.replaceAll("\"","\\\\\"") + "\")";
+            return "JythonUnknownArgLambda(" + lambdaString + ")";
     }
 }

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/98efcef1/gremlin-python/src/main/jython/gremlin_python/driver/driver_remote_connection.py
----------------------------------------------------------------------
diff --git a/gremlin-python/src/main/jython/gremlin_python/driver/driver_remote_connection.py b/gremlin-python/src/main/jython/gremlin_python/driver/driver_remote_connection.py
index b5f99e9..f7e50ad 100644
--- a/gremlin-python/src/main/jython/gremlin_python/driver/driver_remote_connection.py
+++ b/gremlin-python/src/main/jython/gremlin_python/driver/driver_remote_connection.py
@@ -22,19 +22,23 @@ from tornado import gen
 from tornado import ioloop
 from tornado import websocket
 
+from gremlin_python.structure.io.graphson import GraphSONWriter
+from gremlin_python.structure.io.graphson import TraverserDeserializer
 from .remote_connection import RemoteConnection
 from .remote_connection import RemoteTraversal
 from .remote_connection import RemoteTraversalSideEffects
-from ..process.graphson import GraphSONWriter
-from ..process.traversal import Traverser
 
 
 class GremlinServerError(Exception):
     pass
 
 
-def parse_traverser(result):
-    return Traverser(result["@value"]["value"], result["@value"]["bulk"]["@value"])
+# when the object is known to be a traverser, just use a direct call to the deserializer
+__traverserDeserializer = TraverserDeserializer()
+
+
+def parse_traverser(traverser_dict):
+    return __traverserDeserializer._objectify(traverser_dict)
 
 
 def parse_side_effect(result):

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/98efcef1/gremlin-python/src/main/jython/gremlin_python/process/__init__.py
----------------------------------------------------------------------
diff --git a/gremlin-python/src/main/jython/gremlin_python/process/__init__.py b/gremlin-python/src/main/jython/gremlin_python/process/__init__.py
index 2a5e832..31af92d 100644
--- a/gremlin-python/src/main/jython/gremlin_python/process/__init__.py
+++ b/gremlin-python/src/main/jython/gremlin_python/process/__init__.py
@@ -20,9 +20,8 @@ under the License.
 from .graph_traversal import GraphTraversal
 from .graph_traversal import GraphTraversalSource
 from .graph_traversal import __
-from .graphson import GraphSONWriter
-from .graphson import serializers
 from .traversal import Barrier
+from .traversal import Bindings
 from .traversal import Bytecode
 from .traversal import Cardinality
 from .traversal import Column
@@ -34,6 +33,5 @@ from .traversal import Pop
 from .traversal import Scope
 from .traversal import T
 from .traversal import Traversal
-from .traversal import Bindings
 
 __author__ = 'Marko A. Rodriguez (http://markorodriguez.com)'

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/98efcef1/gremlin-python/src/main/jython/gremlin_python/process/graphson.py
----------------------------------------------------------------------
diff --git a/gremlin-python/src/main/jython/gremlin_python/process/graphson.py b/gremlin-python/src/main/jython/gremlin_python/process/graphson.py
deleted file mode 100644
index 80b1087..0000000
--- a/gremlin-python/src/main/jython/gremlin_python/process/graphson.py
+++ /dev/null
@@ -1,164 +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.
-'''
-
-import json
-from abc import abstractmethod
-from aenum import Enum
-from types import FunctionType
-from types import IntType
-from types import LongType
-
-from .traversal import Binding
-from .traversal import Bytecode
-from .traversal import P
-from .traversal import Traversal
-from .. import statics
-
-
-class GraphSONWriter(object):
-    @staticmethod
-    def _dictify(object):
-        for key in serializers:
-            if isinstance(object, key):
-                return serializers[key]._dictify(object)
-        return object
-
-    @staticmethod
-    def writeObject(object):
-        return json.dumps(GraphSONWriter._dictify(object))
-
-
-'''
-Serializers
-'''
-
-
-class GraphSONSerializer(object):
-    @abstractmethod
-    def _dictify(self, object):
-        return object
-
-
-class BytecodeSerializer(GraphSONSerializer):
-    def _dictify(self, bytecode):
-        if isinstance(bytecode, Traversal):
-            bytecode = bytecode.bytecode
-        dict = {}
-        sources = []
-        for instruction in bytecode.source_instructions:
-            inst = []
-            inst.append(instruction[0])
-            for arg in instruction[1:]:
-                inst.append(GraphSONWriter._dictify(arg))
-            sources.append(inst)
-        steps = []
-        for instruction in bytecode.step_instructions:
-            inst = []
-            inst.append(instruction[0])
-            for arg in instruction[1:]:
-                inst.append(GraphSONWriter._dictify(arg))
-            steps.append(inst)
-        if len(sources) > 0:
-            dict["source"] = sources
-        if len(steps) > 0:
-            dict["step"] = steps
-        return _SymbolHelper.objectify("bytecode", dict)
-
-
-class EnumSerializer(GraphSONSerializer):
-    def _dictify(self, enum):
-        return _SymbolHelper.objectify(_SymbolHelper.toGremlin(type(enum).__name__),
-                                       _SymbolHelper.toGremlin(str(enum.name)))
-
-
-class PSerializer(GraphSONSerializer):
-    def _dictify(self, p):
-        dict = {}
-        dict["predicate"] = p.operator
-        if p.other is None:
-            dict["value"] = GraphSONWriter._dictify(p.value)
-        else:
-            dict["value"] = [GraphSONWriter._dictify(p.value), GraphSONWriter._dictify(p.other)]
-        return _SymbolHelper.objectify("P", dict)
-
-
-class BindingSerializer(GraphSONSerializer):
-    def _dictify(self, binding):
-        dict = {}
-        dict["key"] = binding.key
-        dict["value"] = GraphSONWriter._dictify(binding.value)
-        return _SymbolHelper.objectify("binding", dict)
-
-
-class LambdaSerializer(GraphSONSerializer):
-    def _dictify(self, lambdaObject):
-        lambdaResult = lambdaObject()
-        dict = {}
-        script = lambdaResult if isinstance(lambdaResult, str) else lambdaResult[0]
-        language = statics.default_lambda_language if isinstance(lambdaResult, str) else lambdaResult[1]
-        dict["script"] = script
-        dict["language"] = language
-        if language == "gremlin-jython" or language == "gremlin-python":
-            if not script.strip().startswith("lambda"):
-                script = "lambda " + script
-                dict["value"] = script
-            dict["arguments"] = eval(dict["value"]).func_code.co_argcount
-        else:
-            dict["arguments"] = -1
-        return _SymbolHelper.objectify("lambda", dict)
-
-
-class NumberSerializer(GraphSONSerializer):
-    def _dictify(self, number):
-        if isinstance(number, bool): # python thinks that 0/1 integers are booleans
-            return number
-        elif isinstance(number, long):
-            return _SymbolHelper.objectify("int64", number)
-        elif isinstance(number, int):
-            return _SymbolHelper.objectify("int32", number)
-        else:
-            return number
-
-
-class _SymbolHelper(object):
-    symbolMap = {"_global": "global", "_as": "as", "_in": "in", "_and": "and",
-                 "_or": "or", "_is": "is", "_not": "not", "_from": "from"}
-
-    _TYPE = "@type"
-    _VALUE = "@value"
-
-    @staticmethod
-    def toGremlin(symbol):
-        return _SymbolHelper.symbolMap[symbol] if symbol in _SymbolHelper.symbolMap else symbol
-
-    @staticmethod
-    def objectify(type, value, prefix="gremlin"):
-        return {_SymbolHelper._TYPE: prefix + ":" + type, _SymbolHelper._VALUE: value}
-
-
-serializers = {
-    Traversal: BytecodeSerializer(),
-    Bytecode: BytecodeSerializer(),
-    Binding: BindingSerializer(),
-    P: PSerializer(),
-    Enum: EnumSerializer(),
-    FunctionType: LambdaSerializer(),
-    LongType: NumberSerializer(),
-    IntType: NumberSerializer()
-}

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/98efcef1/gremlin-python/src/main/jython/gremlin_python/structure/__init__.py
----------------------------------------------------------------------
diff --git a/gremlin-python/src/main/jython/gremlin_python/structure/__init__.py b/gremlin-python/src/main/jython/gremlin_python/structure/__init__.py
index cb2d3b6..99273c7 100644
--- a/gremlin-python/src/main/jython/gremlin_python/structure/__init__.py
+++ b/gremlin-python/src/main/jython/gremlin_python/structure/__init__.py
@@ -17,5 +17,9 @@ specific language governing permissions and limitations
 under the License.
 '''
 from .graph import Graph
+from .graph import Vertex
+from .graph import Edge
+from .graph import VertexProperty
+from .graph import Property
 
 __author__ = 'Marko A. Rodriguez (http://markorodriguez.com)'

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/98efcef1/gremlin-python/src/main/jython/gremlin_python/structure/graph.py
----------------------------------------------------------------------
diff --git a/gremlin-python/src/main/jython/gremlin_python/structure/graph.py b/gremlin-python/src/main/jython/gremlin_python/structure/graph.py
index ccddbe5..c0e3157 100644
--- a/gremlin-python/src/main/jython/gremlin_python/structure/graph.py
+++ b/gremlin-python/src/main/jython/gremlin_python/structure/graph.py
@@ -33,3 +33,42 @@ class Graph(object):
 
     def __repr__(self):
         return "graph[]"
+
+
+class Element(object):
+    def __init__(self, id, label):
+        self.id = id
+        self.label = label
+
+
+class Vertex(Element):
+    def __repr__(self):
+        return "v[" + str(self.id) + "]"
+
+
+class Edge(Element):
+    def __init__(self, id, outV, label, inV):
+        Element.__init__(self, id, label)
+        self.outV = outV
+        self.inV = inV
+
+    def __repr__(self):
+        return "e[" + str(self.id) + "][" + str(self.outV.id) + "-" + self.label + "->" + str(self.inV.id) + "]"
+
+
+class VertexProperty(Element):
+    def __init__(self, id, label, value):
+        Element.__init__(self, id, label)
+        self.value = value
+
+    def __repr__(self):
+        return "vp[" + str(self.label) + "->" + str(self.value)[0:20] + "]"
+
+
+class Property(object):
+    def __init__(self, key, value):
+        self.key = key
+        self.value = value
+
+    def __repr__(self):
+        return "p[" + str(self.key) + "->" + str(self.value)[0:20] + "]"

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/98efcef1/gremlin-python/src/main/jython/gremlin_python/structure/io/__init__.py
----------------------------------------------------------------------
diff --git a/gremlin-python/src/main/jython/gremlin_python/structure/io/__init__.py b/gremlin-python/src/main/jython/gremlin_python/structure/io/__init__.py
new file mode 100644
index 0000000..e9e5f01
--- /dev/null
+++ b/gremlin-python/src/main/jython/gremlin_python/structure/io/__init__.py
@@ -0,0 +1,25 @@
+'''
+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.
+'''
+
+from .graphson import GraphSONReader
+from .graphson import GraphSONWriter
+from .graphson import deserializers
+from .graphson import serializers
+
+__author__ = 'Marko A. Rodriguez (http://markorodriguez.com)'

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/98efcef1/gremlin-python/src/main/jython/gremlin_python/structure/io/graphson.py
----------------------------------------------------------------------
diff --git a/gremlin-python/src/main/jython/gremlin_python/structure/io/graphson.py b/gremlin-python/src/main/jython/gremlin_python/structure/io/graphson.py
new file mode 100644
index 0000000..7cce4a5
--- /dev/null
+++ b/gremlin-python/src/main/jython/gremlin_python/structure/io/graphson.py
@@ -0,0 +1,263 @@
+'''
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+'''
+
+import json
+from abc import abstractmethod
+from aenum import Enum
+from types import FunctionType
+from types import IntType
+from types import LongType
+
+from gremlin_python import statics
+from gremlin_python.process.traversal import Binding
+from gremlin_python.process.traversal import Bytecode
+from gremlin_python.process.traversal import P
+from gremlin_python.process.traversal import Traversal
+from gremlin_python.process.traversal import Traverser
+from gremlin_python.structure.graph import Edge
+from gremlin_python.structure.graph import Property
+from gremlin_python.structure.graph import Vertex
+from gremlin_python.structure.graph import VertexProperty
+
+
+class GraphSONWriter(object):
+    @staticmethod
+    def _dictify(object):
+        for key in serializers:
+            if isinstance(object, key):
+                return serializers[key]._dictify(object)
+        return object
+
+    @staticmethod
+    def writeObject(object):
+        return json.dumps(GraphSONWriter._dictify(object))
+
+
+class GraphSONReader(object):
+    @staticmethod
+    def _objectify(object):
+        if isinstance(object, dict):
+            if _SymbolHelper._TYPE in object:
+                type = object[_SymbolHelper._TYPE]
+                if type in deserializers:
+                    return deserializers[type]._objectify(object)
+            newDict = {}
+            for key in object:
+                newDict[GraphSONReader._objectify(key)] = GraphSONReader._objectify(object[key])
+            return newDict
+        elif isinstance(object, list):
+            newList = []
+            for item in object:
+                newList.append(GraphSONReader._objectify(item))
+            return newList
+        else:
+            return object
+
+    @staticmethod
+    def readObject(data):
+        return GraphSONReader._objectify(json.loads(data))
+
+
+'''
+SERIALIZERS
+'''
+
+
+class GraphSONSerializer(object):
+    @abstractmethod
+    def _dictify(self, object):
+        return object
+
+
+class BytecodeSerializer(GraphSONSerializer):
+    def _dictify(self, bytecode):
+        if isinstance(bytecode, Traversal):
+            bytecode = bytecode.bytecode
+        dict = {}
+        sources = []
+        for instruction in bytecode.source_instructions:
+            inst = []
+            inst.append(instruction[0])
+            for arg in instruction[1:]:
+                inst.append(GraphSONWriter._dictify(arg))
+            sources.append(inst)
+        steps = []
+        for instruction in bytecode.step_instructions:
+            inst = []
+            inst.append(instruction[0])
+            for arg in instruction[1:]:
+                inst.append(GraphSONWriter._dictify(arg))
+            steps.append(inst)
+        if len(sources) > 0:
+            dict["source"] = sources
+        if len(steps) > 0:
+            dict["step"] = steps
+        return _SymbolHelper.objectify("bytecode", dict)
+
+
+class EnumSerializer(GraphSONSerializer):
+    def _dictify(self, enum):
+        return _SymbolHelper.objectify(_SymbolHelper.toGremlin(type(enum).__name__),
+                                       _SymbolHelper.toGremlin(str(enum.name)))
+
+
+class PSerializer(GraphSONSerializer):
+    def _dictify(self, p):
+        dict = {}
+        dict["predicate"] = p.operator
+        if p.other is None:
+            dict["value"] = GraphSONWriter._dictify(p.value)
+        else:
+            dict["value"] = [GraphSONWriter._dictify(p.value), GraphSONWriter._dictify(p.other)]
+        return _SymbolHelper.objectify("P", dict)
+
+
+class BindingSerializer(GraphSONSerializer):
+    def _dictify(self, binding):
+        dict = {}
+        dict["key"] = binding.key
+        dict["value"] = GraphSONWriter._dictify(binding.value)
+        return _SymbolHelper.objectify("binding", dict)
+
+
+class LambdaSerializer(GraphSONSerializer):
+    def _dictify(self, lambdaObject):
+        lambdaResult = lambdaObject()
+        dict = {}
+        script = lambdaResult if isinstance(lambdaResult, str) else lambdaResult[0]
+        language = statics.default_lambda_language if isinstance(lambdaResult, str) else lambdaResult[1]
+        dict["script"] = script
+        dict["language"] = language
+        if language == "gremlin-jython" or language == "gremlin-python":
+            if not script.strip().startswith("lambda"):
+                script = "lambda " + script
+                dict["script"] = script
+            dict["arguments"] = eval(dict["script"]).func_code.co_argcount
+        else:
+            dict["arguments"] = -1
+        return _SymbolHelper.objectify("lambda", dict)
+
+
+class NumberSerializer(GraphSONSerializer):
+    def _dictify(self, number):
+        if isinstance(number, bool):  # python thinks that 0/1 integers are booleans
+            return number
+        elif isinstance(number, long):
+            return _SymbolHelper.objectify("int64", number)
+        elif isinstance(number, int):
+            return _SymbolHelper.objectify("int32", number)
+        else:
+            return number
+
+
+'''
+DESERIALIZERS
+'''
+
+
+class GraphSONDeserializer(object):
+    @abstractmethod
+    def _objectify(self, dict):
+        return dict
+
+
+class TraverserDeserializer(GraphSONDeserializer):
+    def _objectify(self, dict):
+        return Traverser(GraphSONReader._objectify(dict[_SymbolHelper._VALUE]["value"]),
+                         GraphSONReader._objectify(dict[_SymbolHelper._VALUE]["bulk"]))
+
+
+class NumberDeserializer(GraphSONDeserializer):
+    def _objectify(self, dict):
+        type = dict[_SymbolHelper._TYPE]
+        value = dict[_SymbolHelper._VALUE]
+        if type == "gremlin:int32":
+            return int(value)
+        elif type == "gremlin:int64":
+            return long(value)
+        else:
+            return float(value)
+
+
+class VertexDeserializer(GraphSONDeserializer):
+    def _objectify(self, dict):
+        value = dict[_SymbolHelper._VALUE]
+        return Vertex(GraphSONReader._objectify(value["id"]), value["label"] if "label" in value else "")
+
+
+class EdgeDeserializer(GraphSONDeserializer):
+    def _objectify(self, dict):
+        value = dict[_SymbolHelper._VALUE]
+        return Edge(GraphSONReader._objectify(value["id"]),
+                    Vertex(GraphSONReader._objectify(value["outV"]), ""),
+                    value["label"] if "label" in value else "vertex",
+                    Vertex(GraphSONReader._objectify(value["inV"]), ""))
+
+
+class VertexPropertyDeserializer(GraphSONDeserializer):
+    def _objectify(self, dict):
+        value = dict[_SymbolHelper._VALUE]
+        return VertexProperty(GraphSONReader._objectify(value["id"]), value["label"],
+                              GraphSONReader._objectify(value["value"]))
+
+
+class PropertyDeserializer(GraphSONDeserializer):
+    def _objectify(self, dict):
+        value = dict[_SymbolHelper._VALUE]
+        return Property(value["key"], GraphSONReader._objectify(value["value"]))
+
+
+class _SymbolHelper(object):
+    symbolMap = {"_global": "global", "_as": "as", "_in": "in", "_and": "and",
+                 "_or": "or", "_is": "is", "_not": "not", "_from": "from"}
+
+    _TYPE = "@type"
+    _VALUE = "@value"
+
+    @staticmethod
+    def toGremlin(symbol):
+        return _SymbolHelper.symbolMap[symbol] if symbol in _SymbolHelper.symbolMap else symbol
+
+    @staticmethod
+    def objectify(type, value, prefix="gremlin"):
+        return {_SymbolHelper._TYPE: prefix + ":" + type, _SymbolHelper._VALUE: value}
+
+
+serializers = {
+    Traversal: BytecodeSerializer(),
+    Bytecode: BytecodeSerializer(),
+    Binding: BindingSerializer(),
+    P: PSerializer(),
+    Enum: EnumSerializer(),
+    FunctionType: LambdaSerializer(),
+    LongType: NumberSerializer(),
+    IntType: NumberSerializer()
+}
+
+deserializers = {
+    "gremlin:traverser": TraverserDeserializer(),
+    "gremlin:int32": NumberDeserializer(),
+    "gremlin:int64": NumberDeserializer(),
+    "gremlin:float": NumberDeserializer(),
+    "gremlin:double": NumberDeserializer(),
+    "gremlin:vertex": VertexDeserializer(),
+    "gremlin:edge": EdgeDeserializer(),
+    "gremlin:vertexproperty": VertexPropertyDeserializer(),
+    "gremlin:property": PropertyDeserializer()
+}

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/98efcef1/gremlin-python/src/main/jython/setup.py
----------------------------------------------------------------------
diff --git a/gremlin-python/src/main/jython/setup.py b/gremlin-python/src/main/jython/setup.py
index 4d474ab..01521ed 100644
--- a/gremlin-python/src/main/jython/setup.py
+++ b/gremlin-python/src/main/jython/setup.py
@@ -46,7 +46,7 @@ version = __version__.version
 setup(
     name='gremlinpython',
     version=version,
-    packages=['gremlin_python', 'gremlin_python.driver', 'gremlin_python.process', 'gremlin_python.structure'],
+    packages=['gremlin_python', 'gremlin_python.driver', 'gremlin_python.process', 'gremlin_python.structure', 'gremlin_python.structure.io'],
     license='Apache 2',
     url='http://tinkerpop.apache.org',
     description='Gremlin-Python for Apache TinkerPop',

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/98efcef1/gremlin-python/src/test/java/org/apache/tinkerpop/gremlin/python/GremlinPythonTest.java
----------------------------------------------------------------------
diff --git a/gremlin-python/src/test/java/org/apache/tinkerpop/gremlin/python/GremlinPythonTest.java b/gremlin-python/src/test/java/org/apache/tinkerpop/gremlin/python/GremlinPythonTest.java
new file mode 100644
index 0000000..9eede82
--- /dev/null
+++ b/gremlin-python/src/test/java/org/apache/tinkerpop/gremlin/python/GremlinPythonTest.java
@@ -0,0 +1,37 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.tinkerpop.gremlin.python;
+
+import org.apache.tinkerpop.gremlin.python.jsr223.JythonScriptEngineSetup;
+import org.apache.tinkerpop.gremlin.util.ScriptEngineCache;
+
+import javax.script.ScriptEngine;
+
+/**
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ */
+public class GremlinPythonTest {
+
+    public static final ScriptEngine jythonEngine = ScriptEngineCache.get("jython");
+    static {
+        JythonScriptEngineSetup.setup();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/98efcef1/gremlin-python/src/test/java/org/apache/tinkerpop/gremlin/python/jsr223/JythonScriptEngineSetup.java
----------------------------------------------------------------------
diff --git a/gremlin-python/src/test/java/org/apache/tinkerpop/gremlin/python/jsr223/JythonScriptEngineSetup.java b/gremlin-python/src/test/java/org/apache/tinkerpop/gremlin/python/jsr223/JythonScriptEngineSetup.java
index f4bf61c..1698b30 100644
--- a/gremlin-python/src/test/java/org/apache/tinkerpop/gremlin/python/jsr223/JythonScriptEngineSetup.java
+++ b/gremlin-python/src/test/java/org/apache/tinkerpop/gremlin/python/jsr223/JythonScriptEngineSetup.java
@@ -46,7 +46,7 @@ public class JythonScriptEngineSetup {
             // jythonEngine.eval("from gremlin_python.driver.driver_remote_connection import DriverRemoteConnection");
             jythonEngine.eval("from gremlin_python.process.traversal import Bytecode");
             jythonEngine.eval("from gremlin_python.structure.graph import Graph");
-            jythonEngine.eval("from gremlin_python.process.graphson import GraphSONWriter");
+            jythonEngine.eval("from gremlin_python.structure.io.graphson import GraphSONWriter");
         } catch (final ScriptException e) {
             throw new IllegalStateException(e.getMessage(), e);
         }