Return-Path: X-Original-To: archive-asf-public-internal@cust-asf2.ponee.io Delivered-To: archive-asf-public-internal@cust-asf2.ponee.io Received: from cust-asf.ponee.io (cust-asf.ponee.io [163.172.22.183]) by cust-asf2.ponee.io (Postfix) with ESMTP id 0A321200CC4 for ; Thu, 13 Jul 2017 19:24:56 +0200 (CEST) Received: by cust-asf.ponee.io (Postfix) id 0943016C6FA; Thu, 13 Jul 2017 17:24:56 +0000 (UTC) Delivered-To: archive-asf-public@cust-asf.ponee.io Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by cust-asf.ponee.io (Postfix) with SMTP id 89F9B16C701 for ; Thu, 13 Jul 2017 19:24:51 +0200 (CEST) Received: (qmail 4058 invoked by uid 500); 13 Jul 2017 17:24:50 -0000 Mailing-List: contact commits-help@tinkerpop.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@tinkerpop.apache.org Delivered-To: mailing list commits@tinkerpop.apache.org Received: (qmail 3867 invoked by uid 99); 13 Jul 2017 17:24:50 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 13 Jul 2017 17:24:50 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id 3D079F5542; Thu, 13 Jul 2017 17:24:50 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: spmallette@apache.org To: commits@tinkerpop.apache.org Date: Thu, 13 Jul 2017 17:25:30 -0000 Message-Id: <560f696e6f1f44dda83c7c27a46ebd0d@git.apache.org> In-Reply-To: References: X-Mailer: ASF-Git Admin Mailer Subject: [42/50] [abbrv] tinkerpop git commit: 99 percent complete GraphSON 3.0 working with Gremlin-Python. Extended test suite to support both GraphSON 2.0 and GraphSON 3.0 testing. There is one last requirement to do on the code -- a version flag on GraphSONMe archived-at: Thu, 13 Jul 2017 17:24:56 -0000 99 percent complete GraphSON 3.0 working with Gremlin-Python. Extended test suite to support both GraphSON 2.0 and GraphSON 3.0 testing. There is one last requirement to do on the code -- a version flag on GraphSONMessageSerializer. However, for some reason application/gremlin-v3.0 mime type stuff doesn't work for the Python->GremlinServer tests... Committing what I have so far as I think the issue might be an easy .yaml file fix or something. Dunno. Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/34827047 Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/34827047 Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/34827047 Branch: refs/heads/TINKERPOP-1427 Commit: 34827047b3aa3dcb1992ec27e8bcbcc23056b1ac Parents: ec5d377 Author: Marko A. Rodriguez Authored: Thu Jul 6 15:56:46 2017 -0600 Committer: Stephen Mallette Committed: Thu Jul 13 13:01:35 2017 -0400 ---------------------------------------------------------------------- .../io/graphson/TraversalSerializersV3d0.java | 14 +- .../jython/gremlin_python/driver/serializer.py | 32 +- .../src/main/jython/gremlin_python/statics.py | 6 + .../gremlin_python/structure/io/graphson.py | 400 ---------------- .../gremlin_python/structure/io/graphsonV2d0.py | 400 ++++++++++++++++ .../gremlin_python/structure/io/graphsonV3d0.py | 466 +++++++++++++++++++ .../jython/tests/structure/io/test_graphson.py | 271 ----------- .../tests/structure/io/test_graphsonV2d0.py | 273 +++++++++++ .../tests/structure/io/test_graphsonV3d0.py | 287 ++++++++++++ .../python/jsr223/JythonScriptEngineSetup.java | 9 +- .../jsr223/PythonGraphSONJavaTranslator.java | 29 +- .../gremlin/python/jsr223/PythonProvider.java | 9 +- .../io/graphson/GraphSONReaderTest.java | 149 +++--- .../io/graphson/GraphSONWriterTest.java | 142 +++--- 14 files changed, 1667 insertions(+), 820 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/34827047/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/TraversalSerializersV3d0.java ---------------------------------------------------------------------- diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/TraversalSerializersV3d0.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/TraversalSerializersV3d0.java index 57b6736..c629b3f 100644 --- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/TraversalSerializersV3d0.java +++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/TraversalSerializersV3d0.java @@ -38,7 +38,6 @@ import org.apache.tinkerpop.shaded.jackson.core.JsonProcessingException; import org.apache.tinkerpop.shaded.jackson.core.JsonToken; import org.apache.tinkerpop.shaded.jackson.databind.DeserializationContext; import org.apache.tinkerpop.shaded.jackson.databind.JavaType; -import org.apache.tinkerpop.shaded.jackson.databind.JsonNode; import org.apache.tinkerpop.shaded.jackson.databind.SerializerProvider; import org.apache.tinkerpop.shaded.jackson.databind.deser.std.StdDeserializer; import org.apache.tinkerpop.shaded.jackson.databind.jsontype.TypeSerializer; @@ -160,16 +159,9 @@ final class TraversalSerializersV3d0 { jsonGenerator.writeObject(predicate); } jsonGenerator.writeEndArray(); - } else { - if (p.getValue() instanceof Collection) { - jsonGenerator.writeArrayFieldStart(GraphSONTokens.VALUE); - for (final Object object : (Collection) p.getValue()) { - jsonGenerator.writeObject(object); - } - jsonGenerator.writeEndArray(); - } else - jsonGenerator.writeObjectField(GraphSONTokens.VALUE, p.getValue()); - } + } else + jsonGenerator.writeObjectField(GraphSONTokens.VALUE, p.getValue()); + jsonGenerator.writeEndObject(); } http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/34827047/gremlin-python/src/main/jython/gremlin_python/driver/serializer.py ---------------------------------------------------------------------- diff --git a/gremlin-python/src/main/jython/gremlin_python/driver/serializer.py b/gremlin-python/src/main/jython/gremlin_python/driver/serializer.py index a29d4dc..3248b4e 100644 --- a/gremlin-python/src/main/jython/gremlin_python/driver/serializer.py +++ b/gremlin-python/src/main/jython/gremlin_python/driver/serializer.py @@ -21,7 +21,8 @@ try: except ImportError: import json -from gremlin_python.structure.io import graphson +from gremlin_python.structure.io import graphsonV2d0 +from gremlin_python.structure.io import graphsonV3d0 __author__ = 'David M. Brown (davebshow@gmail.com)' @@ -85,10 +86,10 @@ class GraphSONMessageSerializer: def __init__(self, reader=None, writer=None): if not reader: - reader = graphson.GraphSONReader() + reader = graphsonV2d0.GraphSONReader() self._graphson_reader = reader if not writer: - writer = graphson.GraphSONWriter() + writer = graphsonV2d0.GraphSONWriter() self.standard = Standard(writer) self.traversal = Traversal(writer) @@ -127,3 +128,28 @@ class GraphSONMessageSerializer: def deserialize_message(self, message): return self._graphson_reader.toObject(message) + +class GraphSONSerializersV2d0(GraphSONMessageSerializer): + """Message serializer for GraphSON 2.0""" + + def __init__(self, reader=None, writer=None): + GraphSONMessageSerializer.__init__(self, reader, writer, "2.0") + if not reader: + self._graphson_reader = graphsonV2d0.GraphSONReader() + if not writer: + self._graphson_writer = graphsonV2d0.GraphSONWriter() + self.standard = Standard(self._graphson_writer) + self.traversal = Traversal(self._graphson_writer) + + +class GraphSONSerializersV3d0(GraphSONMessageSerializer): + """Message serializer for GraphSON 3.0""" + + def __init__(self, reader=None, writer=None): + GraphSONMessageSerializer.__init__(self, reader, writer, "3.0") + if not reader: + self._graphson_reader = graphsonV3d0.GraphSONReader() + if not writer: + self._graphson_writer = graphsonV3d0.GraphSONWriter() + self.standard = Standard(self._graphson_writer) + self.traversal = Traversal(self._graphson_writer) \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/34827047/gremlin-python/src/main/jython/gremlin_python/statics.py ---------------------------------------------------------------------- diff --git a/gremlin-python/src/main/jython/gremlin_python/statics.py b/gremlin-python/src/main/jython/gremlin_python/statics.py index a1abf8e..28cae14 100644 --- a/gremlin-python/src/main/jython/gremlin_python/statics.py +++ b/gremlin-python/src/main/jython/gremlin_python/statics.py @@ -29,12 +29,18 @@ if six.PY3: IntType = int LongType = long TypeType = type + ListType = list + DictType = dict + SetType = set else: long = long + SetType = set from types import FloatType from types import IntType from types import LongType from types import TypeType + from types import ListType + from types import DictType staticMethods = {} staticEnums = {} http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/34827047/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 deleted file mode 100644 index 5c7ccdb..0000000 --- a/gremlin-python/src/main/jython/gremlin_python/structure/io/graphson.py +++ /dev/null @@ -1,400 +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. -''' -from aenum import Enum -import json -import six - -from gremlin_python import statics -from gremlin_python.statics import FloatType, FunctionType, IntType, LongType, TypeType -from gremlin_python.process.traversal import Binding, Bytecode, P, Traversal, Traverser, TraversalStrategy -from gremlin_python.structure.graph import Edge, Property, Vertex, VertexProperty, Path - -_serializers = {} -_deserializers = {} - - -class GraphSONTypeType(type): - def __new__(mcs, name, bases, dct): - cls = super(GraphSONTypeType, mcs).__new__(mcs, name, bases, dct) - if not name.startswith('_'): - if cls.python_type: - _serializers[cls.python_type] = cls - if cls.graphson_type: - _deserializers[cls.graphson_type] = cls - return cls - - -class GraphSONUtil(object): - TYPE_KEY = "@type" - VALUE_KEY = "@value" - - @classmethod - def typedValue(cls, type_name, value, prefix="g"): - out = {cls.TYPE_KEY: cls.formatType(prefix, type_name)} - if value is not None: - out[cls.VALUE_KEY] = value - return out - - @classmethod - def formatType(cls, prefix, type_name): - return "%s:%s" % (prefix, type_name) - - -# Read/Write classes split to follow precedence of the Java API -class GraphSONWriter(object): - def __init__(self, serializer_map=None): - """ - :param serializer_map: map from Python type to serializer instance implementing `dictify` - """ - self.serializers = _serializers.copy() - if serializer_map: - self.serializers.update(serializer_map) - - def writeObject(self, objectData): - # to JSON - return json.dumps(self.toDict(objectData), separators=(',', ':')) - - def toDict(self, obj): - """ - Encodes python objects in GraphSON type-tagged dict values - """ - try: - return self.serializers[type(obj)].dictify(obj, self) - except KeyError: - for key, serializer in self.serializers.items(): - if isinstance(obj, key): - return serializer.dictify(obj, self) - - # list and map are treated as normal json objs (could be isolated serializers) - if isinstance(obj, (list, set)): - return [self.toDict(o) for o in obj] - elif isinstance(obj, dict): - return dict((self.toDict(k), self.toDict(v)) for k, v in obj.items()) - else: - return obj - - -class GraphSONReader(object): - def __init__(self, deserializer_map=None): - """ - :param deserializer_map: map from GraphSON type tag to deserializer instance implementing `objectify` - """ - self.deserializers = _deserializers.copy() - if deserializer_map: - self.deserializers.update(deserializer_map) - - def readObject(self, jsonData): - # from JSON - return self.toObject(json.loads(jsonData)) - - def toObject(self, obj): - """ - Unpacks GraphSON type-tagged dict values into objects mapped in self.deserializers - """ - if isinstance(obj, dict): - try: - return self.deserializers[obj[GraphSONUtil.TYPE_KEY]].objectify(obj[GraphSONUtil.VALUE_KEY], self) - except KeyError: - pass - # list and map are treated as normal json objs (could be isolated deserializers) - return dict((self.toObject(k), self.toObject(v)) for k, v in obj.items()) - elif isinstance(obj, list): - return [self.toObject(o) for o in obj] - else: - return obj - - -@six.add_metaclass(GraphSONTypeType) -class _GraphSONTypeIO(object): - python_type = None - graphson_type = None - - symbolMap = {"global_": "global", "as_": "as", "in_": "in", "and_": "and", - "or_": "or", "is_": "is", "not_": "not", "from_": "from", - "set_": "set", "list_": "list", "all_": "all"} - - @classmethod - def unmangleKeyword(cls, symbol): - return cls.symbolMap.get(symbol, symbol) - - def dictify(self, obj, writer): - raise NotImplementedError() - - def objectify(self, d, reader): - raise NotImplementedError() - - -class _BytecodeSerializer(_GraphSONTypeIO): - @classmethod - def _dictify_instructions(cls, instructions, writer): - out = [] - for instruction in instructions: - inst = [instruction[0]] - inst.extend(writer.toDict(arg) for arg in instruction[1:]) - out.append(inst) - return out - - @classmethod - def dictify(cls, bytecode, writer): - if isinstance(bytecode, Traversal): - bytecode = bytecode.bytecode - out = {} - if bytecode.source_instructions: - out["source"] = cls._dictify_instructions(bytecode.source_instructions, writer) - if bytecode.step_instructions: - out["step"] = cls._dictify_instructions(bytecode.step_instructions, writer) - return GraphSONUtil.typedValue("Bytecode", out) - - -class TraversalSerializer(_BytecodeSerializer): - python_type = Traversal - - -class BytecodeSerializer(_BytecodeSerializer): - python_type = Bytecode - - -class VertexSerializer(_GraphSONTypeIO): - python_type = Vertex - graphson_type = "g:Vertex" - - @classmethod - def dictify(cls, vertex, writer): - return GraphSONUtil.typedValue("Vertex", {"id": writer.toDict(vertex.id), - "label": writer.toDict(vertex.label)}) - - -class EdgeSerializer(_GraphSONTypeIO): - python_type = Edge - graphson_type = "g:Edge" - - @classmethod - def dictify(cls, edge, writer): - return GraphSONUtil.typedValue("Edge", {"id": writer.toDict(edge.id), - "outV": writer.toDict(edge.outV.id), - "outVLabel": writer.toDict(edge.outV.label), - "label": writer.toDict(edge.label), - "inV": writer.toDict(edge.inV.id), - "inVLabel": writer.toDict(edge.inV.label)}) - - -class VertexPropertySerializer(_GraphSONTypeIO): - python_type = VertexProperty - graphson_type = "g:VertexProperty" - - @classmethod - def dictify(cls, vertex_property, writer): - return GraphSONUtil.typedValue("VertexProperty", {"id": writer.toDict(vertex_property.id), - "label": writer.toDict(vertex_property.label), - "value": writer.toDict(vertex_property.value), - "vertex": writer.toDict(vertex_property.vertex.id)}) - - -class PropertySerializer(_GraphSONTypeIO): - python_type = Property - graphson_type = "g:Property" - - @classmethod - def dictify(cls, property, writer): - elementDict = writer.toDict(property.element) - if elementDict is not None: - valueDict = elementDict["@value"] - if "outVLabel" in valueDict: - del valueDict["outVLabel"] - if "inVLabel" in valueDict: - del valueDict["inVLabel"] - if "properties" in valueDict: - del valueDict["properties"] - if "value" in valueDict: - del valueDict["value"] - return GraphSONUtil.typedValue("Property", {"key": writer.toDict(property.key), - "value": writer.toDict(property.value), - "element": elementDict}) - - -class TraversalStrategySerializer(_GraphSONTypeIO): - python_type = TraversalStrategy - - @classmethod - def dictify(cls, strategy, writer): - return GraphSONUtil.typedValue(strategy.strategy_name, writer.toDict(strategy.configuration)) - - -class TraverserIO(_GraphSONTypeIO): - python_type = Traverser - graphson_type = "g:Traverser" - - @classmethod - def dictify(cls, traverser, writer): - return GraphSONUtil.typedValue("Traverser", {"value": writer.toDict(traverser.object), - "bulk": writer.toDict(traverser.bulk)}) - - @classmethod - def objectify(cls, d, reader): - return Traverser(reader.toObject(d["value"]), - reader.toObject(d["bulk"])) - - -class EnumSerializer(_GraphSONTypeIO): - python_type = Enum - - @classmethod - def dictify(cls, enum, _): - return GraphSONUtil.typedValue(cls.unmangleKeyword(type(enum).__name__), - cls.unmangleKeyword(str(enum.name))) - - -class PSerializer(_GraphSONTypeIO): - python_type = P - - @classmethod - def dictify(cls, p, writer): - out = {"predicate": p.operator, - "value": [writer.toDict(p.value), writer.toDict(p.other)] if p.other is not None else - writer.toDict(p.value)} - return GraphSONUtil.typedValue("P", out) - - -class BindingSerializer(_GraphSONTypeIO): - python_type = Binding - - @classmethod - def dictify(cls, binding, writer): - out = {"key": binding.key, - "value": writer.toDict(binding.value)} - return GraphSONUtil.typedValue("Binding", out) - - -class LambdaSerializer(_GraphSONTypeIO): - python_type = FunctionType - - @classmethod - def dictify(cls, lambda_object, writer): - lambda_result = lambda_object() - script = lambda_result if isinstance(lambda_result, str) else lambda_result[0] - language = statics.default_lambda_language if isinstance(lambda_result, str) else lambda_result[1] - out = {"script": script, - "language": language} - if language == "gremlin-jython" or language == "gremlin-python": - if not script.strip().startswith("lambda"): - script = "lambda " + script - out["script"] = script - out["arguments"] = six.get_function_code(eval(out["script"])).co_argcount - else: - out["arguments"] = -1 - return GraphSONUtil.typedValue("Lambda", out) - - -class TypeSerializer(_GraphSONTypeIO): - python_type = TypeType - - @classmethod - def dictify(cls, typ, writer): - return writer.toDict(typ()) - - -class _NumberIO(_GraphSONTypeIO): - @classmethod - def dictify(cls, n, writer): - if isinstance(n, bool): # because isinstance(False, int) and isinstance(True, int) - return n - return GraphSONUtil.typedValue(cls.graphson_base_type, n) - - @classmethod - def objectify(cls, v, _): - return cls.python_type(v) - - -class FloatIO(_NumberIO): - python_type = FloatType - graphson_type = "g:Float" - graphson_base_type = "Float" - - -class DoubleIO(FloatIO): - graphson_type = "g:Double" - graphson_base_type = "Double" - - -class Int64IO(_NumberIO): - python_type = LongType - graphson_type = "g:Int64" - graphson_base_type = "Int64" - - -class Int32IO(_NumberIO): - python_type = IntType - graphson_type = "g:Int32" - graphson_base_type = "Int32" - - @classmethod - def dictify(cls, n, writer): - if isinstance(n, bool): - return n - return GraphSONUtil.typedValue(cls.graphson_base_type, n) - - -class VertexDeserializer(_GraphSONTypeIO): - graphson_type = "g:Vertex" - - @classmethod - def objectify(cls, d, reader): - return Vertex(reader.toObject(d["id"]), d.get("label", "vertex")) - - -class EdgeDeserializer(_GraphSONTypeIO): - graphson_type = "g:Edge" - - @classmethod - def objectify(cls, d, reader): - return Edge(reader.toObject(d["id"]), - Vertex(reader.toObject(d["outV"]), d.get("outVLabel", "vertex")), - d.get("label", "edge"), - Vertex(reader.toObject(d["inV"]), d.get("inVLabel", "vertex"))) - - -class VertexPropertyDeserializer(_GraphSONTypeIO): - graphson_type = "g:VertexProperty" - - @classmethod - def objectify(cls, d, reader): - vertex = Vertex(reader.toObject(d.get("vertex"))) if "vertex" in d else None - return VertexProperty(reader.toObject(d["id"]), - d["label"], - reader.toObject(d["value"]), - vertex) - - -class PropertyDeserializer(_GraphSONTypeIO): - graphson_type = "g:Property" - - @classmethod - def objectify(cls, d, reader): - element = reader.toObject(d["element"]) if "element" in d else None - return Property(d["key"], reader.toObject(d["value"]), element) - - -class PathDeserializer(_GraphSONTypeIO): - graphson_type = "g:Path" - - @classmethod - def objectify(cls, d, reader): - labels = [set(label) for label in d["labels"]] - objects = [reader.toObject(o) for o in d["objects"]] - return Path(labels, objects) http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/34827047/gremlin-python/src/main/jython/gremlin_python/structure/io/graphsonV2d0.py ---------------------------------------------------------------------- diff --git a/gremlin-python/src/main/jython/gremlin_python/structure/io/graphsonV2d0.py b/gremlin-python/src/main/jython/gremlin_python/structure/io/graphsonV2d0.py new file mode 100644 index 0000000..5c7ccdb --- /dev/null +++ b/gremlin-python/src/main/jython/gremlin_python/structure/io/graphsonV2d0.py @@ -0,0 +1,400 @@ +''' +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 aenum import Enum +import json +import six + +from gremlin_python import statics +from gremlin_python.statics import FloatType, FunctionType, IntType, LongType, TypeType +from gremlin_python.process.traversal import Binding, Bytecode, P, Traversal, Traverser, TraversalStrategy +from gremlin_python.structure.graph import Edge, Property, Vertex, VertexProperty, Path + +_serializers = {} +_deserializers = {} + + +class GraphSONTypeType(type): + def __new__(mcs, name, bases, dct): + cls = super(GraphSONTypeType, mcs).__new__(mcs, name, bases, dct) + if not name.startswith('_'): + if cls.python_type: + _serializers[cls.python_type] = cls + if cls.graphson_type: + _deserializers[cls.graphson_type] = cls + return cls + + +class GraphSONUtil(object): + TYPE_KEY = "@type" + VALUE_KEY = "@value" + + @classmethod + def typedValue(cls, type_name, value, prefix="g"): + out = {cls.TYPE_KEY: cls.formatType(prefix, type_name)} + if value is not None: + out[cls.VALUE_KEY] = value + return out + + @classmethod + def formatType(cls, prefix, type_name): + return "%s:%s" % (prefix, type_name) + + +# Read/Write classes split to follow precedence of the Java API +class GraphSONWriter(object): + def __init__(self, serializer_map=None): + """ + :param serializer_map: map from Python type to serializer instance implementing `dictify` + """ + self.serializers = _serializers.copy() + if serializer_map: + self.serializers.update(serializer_map) + + def writeObject(self, objectData): + # to JSON + return json.dumps(self.toDict(objectData), separators=(',', ':')) + + def toDict(self, obj): + """ + Encodes python objects in GraphSON type-tagged dict values + """ + try: + return self.serializers[type(obj)].dictify(obj, self) + except KeyError: + for key, serializer in self.serializers.items(): + if isinstance(obj, key): + return serializer.dictify(obj, self) + + # list and map are treated as normal json objs (could be isolated serializers) + if isinstance(obj, (list, set)): + return [self.toDict(o) for o in obj] + elif isinstance(obj, dict): + return dict((self.toDict(k), self.toDict(v)) for k, v in obj.items()) + else: + return obj + + +class GraphSONReader(object): + def __init__(self, deserializer_map=None): + """ + :param deserializer_map: map from GraphSON type tag to deserializer instance implementing `objectify` + """ + self.deserializers = _deserializers.copy() + if deserializer_map: + self.deserializers.update(deserializer_map) + + def readObject(self, jsonData): + # from JSON + return self.toObject(json.loads(jsonData)) + + def toObject(self, obj): + """ + Unpacks GraphSON type-tagged dict values into objects mapped in self.deserializers + """ + if isinstance(obj, dict): + try: + return self.deserializers[obj[GraphSONUtil.TYPE_KEY]].objectify(obj[GraphSONUtil.VALUE_KEY], self) + except KeyError: + pass + # list and map are treated as normal json objs (could be isolated deserializers) + return dict((self.toObject(k), self.toObject(v)) for k, v in obj.items()) + elif isinstance(obj, list): + return [self.toObject(o) for o in obj] + else: + return obj + + +@six.add_metaclass(GraphSONTypeType) +class _GraphSONTypeIO(object): + python_type = None + graphson_type = None + + symbolMap = {"global_": "global", "as_": "as", "in_": "in", "and_": "and", + "or_": "or", "is_": "is", "not_": "not", "from_": "from", + "set_": "set", "list_": "list", "all_": "all"} + + @classmethod + def unmangleKeyword(cls, symbol): + return cls.symbolMap.get(symbol, symbol) + + def dictify(self, obj, writer): + raise NotImplementedError() + + def objectify(self, d, reader): + raise NotImplementedError() + + +class _BytecodeSerializer(_GraphSONTypeIO): + @classmethod + def _dictify_instructions(cls, instructions, writer): + out = [] + for instruction in instructions: + inst = [instruction[0]] + inst.extend(writer.toDict(arg) for arg in instruction[1:]) + out.append(inst) + return out + + @classmethod + def dictify(cls, bytecode, writer): + if isinstance(bytecode, Traversal): + bytecode = bytecode.bytecode + out = {} + if bytecode.source_instructions: + out["source"] = cls._dictify_instructions(bytecode.source_instructions, writer) + if bytecode.step_instructions: + out["step"] = cls._dictify_instructions(bytecode.step_instructions, writer) + return GraphSONUtil.typedValue("Bytecode", out) + + +class TraversalSerializer(_BytecodeSerializer): + python_type = Traversal + + +class BytecodeSerializer(_BytecodeSerializer): + python_type = Bytecode + + +class VertexSerializer(_GraphSONTypeIO): + python_type = Vertex + graphson_type = "g:Vertex" + + @classmethod + def dictify(cls, vertex, writer): + return GraphSONUtil.typedValue("Vertex", {"id": writer.toDict(vertex.id), + "label": writer.toDict(vertex.label)}) + + +class EdgeSerializer(_GraphSONTypeIO): + python_type = Edge + graphson_type = "g:Edge" + + @classmethod + def dictify(cls, edge, writer): + return GraphSONUtil.typedValue("Edge", {"id": writer.toDict(edge.id), + "outV": writer.toDict(edge.outV.id), + "outVLabel": writer.toDict(edge.outV.label), + "label": writer.toDict(edge.label), + "inV": writer.toDict(edge.inV.id), + "inVLabel": writer.toDict(edge.inV.label)}) + + +class VertexPropertySerializer(_GraphSONTypeIO): + python_type = VertexProperty + graphson_type = "g:VertexProperty" + + @classmethod + def dictify(cls, vertex_property, writer): + return GraphSONUtil.typedValue("VertexProperty", {"id": writer.toDict(vertex_property.id), + "label": writer.toDict(vertex_property.label), + "value": writer.toDict(vertex_property.value), + "vertex": writer.toDict(vertex_property.vertex.id)}) + + +class PropertySerializer(_GraphSONTypeIO): + python_type = Property + graphson_type = "g:Property" + + @classmethod + def dictify(cls, property, writer): + elementDict = writer.toDict(property.element) + if elementDict is not None: + valueDict = elementDict["@value"] + if "outVLabel" in valueDict: + del valueDict["outVLabel"] + if "inVLabel" in valueDict: + del valueDict["inVLabel"] + if "properties" in valueDict: + del valueDict["properties"] + if "value" in valueDict: + del valueDict["value"] + return GraphSONUtil.typedValue("Property", {"key": writer.toDict(property.key), + "value": writer.toDict(property.value), + "element": elementDict}) + + +class TraversalStrategySerializer(_GraphSONTypeIO): + python_type = TraversalStrategy + + @classmethod + def dictify(cls, strategy, writer): + return GraphSONUtil.typedValue(strategy.strategy_name, writer.toDict(strategy.configuration)) + + +class TraverserIO(_GraphSONTypeIO): + python_type = Traverser + graphson_type = "g:Traverser" + + @classmethod + def dictify(cls, traverser, writer): + return GraphSONUtil.typedValue("Traverser", {"value": writer.toDict(traverser.object), + "bulk": writer.toDict(traverser.bulk)}) + + @classmethod + def objectify(cls, d, reader): + return Traverser(reader.toObject(d["value"]), + reader.toObject(d["bulk"])) + + +class EnumSerializer(_GraphSONTypeIO): + python_type = Enum + + @classmethod + def dictify(cls, enum, _): + return GraphSONUtil.typedValue(cls.unmangleKeyword(type(enum).__name__), + cls.unmangleKeyword(str(enum.name))) + + +class PSerializer(_GraphSONTypeIO): + python_type = P + + @classmethod + def dictify(cls, p, writer): + out = {"predicate": p.operator, + "value": [writer.toDict(p.value), writer.toDict(p.other)] if p.other is not None else + writer.toDict(p.value)} + return GraphSONUtil.typedValue("P", out) + + +class BindingSerializer(_GraphSONTypeIO): + python_type = Binding + + @classmethod + def dictify(cls, binding, writer): + out = {"key": binding.key, + "value": writer.toDict(binding.value)} + return GraphSONUtil.typedValue("Binding", out) + + +class LambdaSerializer(_GraphSONTypeIO): + python_type = FunctionType + + @classmethod + def dictify(cls, lambda_object, writer): + lambda_result = lambda_object() + script = lambda_result if isinstance(lambda_result, str) else lambda_result[0] + language = statics.default_lambda_language if isinstance(lambda_result, str) else lambda_result[1] + out = {"script": script, + "language": language} + if language == "gremlin-jython" or language == "gremlin-python": + if not script.strip().startswith("lambda"): + script = "lambda " + script + out["script"] = script + out["arguments"] = six.get_function_code(eval(out["script"])).co_argcount + else: + out["arguments"] = -1 + return GraphSONUtil.typedValue("Lambda", out) + + +class TypeSerializer(_GraphSONTypeIO): + python_type = TypeType + + @classmethod + def dictify(cls, typ, writer): + return writer.toDict(typ()) + + +class _NumberIO(_GraphSONTypeIO): + @classmethod + def dictify(cls, n, writer): + if isinstance(n, bool): # because isinstance(False, int) and isinstance(True, int) + return n + return GraphSONUtil.typedValue(cls.graphson_base_type, n) + + @classmethod + def objectify(cls, v, _): + return cls.python_type(v) + + +class FloatIO(_NumberIO): + python_type = FloatType + graphson_type = "g:Float" + graphson_base_type = "Float" + + +class DoubleIO(FloatIO): + graphson_type = "g:Double" + graphson_base_type = "Double" + + +class Int64IO(_NumberIO): + python_type = LongType + graphson_type = "g:Int64" + graphson_base_type = "Int64" + + +class Int32IO(_NumberIO): + python_type = IntType + graphson_type = "g:Int32" + graphson_base_type = "Int32" + + @classmethod + def dictify(cls, n, writer): + if isinstance(n, bool): + return n + return GraphSONUtil.typedValue(cls.graphson_base_type, n) + + +class VertexDeserializer(_GraphSONTypeIO): + graphson_type = "g:Vertex" + + @classmethod + def objectify(cls, d, reader): + return Vertex(reader.toObject(d["id"]), d.get("label", "vertex")) + + +class EdgeDeserializer(_GraphSONTypeIO): + graphson_type = "g:Edge" + + @classmethod + def objectify(cls, d, reader): + return Edge(reader.toObject(d["id"]), + Vertex(reader.toObject(d["outV"]), d.get("outVLabel", "vertex")), + d.get("label", "edge"), + Vertex(reader.toObject(d["inV"]), d.get("inVLabel", "vertex"))) + + +class VertexPropertyDeserializer(_GraphSONTypeIO): + graphson_type = "g:VertexProperty" + + @classmethod + def objectify(cls, d, reader): + vertex = Vertex(reader.toObject(d.get("vertex"))) if "vertex" in d else None + return VertexProperty(reader.toObject(d["id"]), + d["label"], + reader.toObject(d["value"]), + vertex) + + +class PropertyDeserializer(_GraphSONTypeIO): + graphson_type = "g:Property" + + @classmethod + def objectify(cls, d, reader): + element = reader.toObject(d["element"]) if "element" in d else None + return Property(d["key"], reader.toObject(d["value"]), element) + + +class PathDeserializer(_GraphSONTypeIO): + graphson_type = "g:Path" + + @classmethod + def objectify(cls, d, reader): + labels = [set(label) for label in d["labels"]] + objects = [reader.toObject(o) for o in d["objects"]] + return Path(labels, objects) http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/34827047/gremlin-python/src/main/jython/gremlin_python/structure/io/graphsonV3d0.py ---------------------------------------------------------------------- diff --git a/gremlin-python/src/main/jython/gremlin_python/structure/io/graphsonV3d0.py b/gremlin-python/src/main/jython/gremlin_python/structure/io/graphsonV3d0.py new file mode 100644 index 0000000..1818df7 --- /dev/null +++ b/gremlin-python/src/main/jython/gremlin_python/structure/io/graphsonV3d0.py @@ -0,0 +1,466 @@ +''' +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 aenum import Enum +import json +import six + +from gremlin_python import statics +from gremlin_python.statics import FloatType, FunctionType, IntType, LongType, TypeType, DictType, ListType, SetType +from gremlin_python.process.traversal import Binding, Bytecode, P, Traversal, Traverser, TraversalStrategy +from gremlin_python.structure.graph import Edge, Property, Vertex, VertexProperty, Path + +_serializers = {} +_deserializers = {} + + +class GraphSONTypeType(type): + def __new__(mcs, name, bases, dct): + cls = super(GraphSONTypeType, mcs).__new__(mcs, name, bases, dct) + if not name.startswith('_'): + if cls.python_type: + _serializers[cls.python_type] = cls + if cls.graphson_type: + _deserializers[cls.graphson_type] = cls + return cls + + +class GraphSONUtil(object): + TYPE_KEY = "@type" + VALUE_KEY = "@value" + + @classmethod + def typedValue(cls, type_name, value, prefix="g"): + out = {cls.TYPE_KEY: cls.formatType(prefix, type_name)} + if value is not None: + out[cls.VALUE_KEY] = value + return out + + @classmethod + def formatType(cls, prefix, type_name): + return "%s:%s" % (prefix, type_name) + + +# Read/Write classes split to follow precedence of the Java API +class GraphSONWriter(object): + def __init__(self, serializer_map=None): + """ + :param serializer_map: map from Python type to serializer instance implementing `dictify` + """ + self.serializers = _serializers.copy() + if serializer_map: + self.serializers.update(serializer_map) + + def writeObject(self, objectData): + # to JSON + return json.dumps(self.toDict(objectData), separators=(',', ':')) + + def toDict(self, obj): + """ + Encodes python objects in GraphSON type-tagged dict values + """ + try: + return self.serializers[type(obj)].dictify(obj, self) + except KeyError: + for key, serializer in self.serializers.items(): + if isinstance(obj, key): + return serializer.dictify(obj, self) + + if isinstance(obj, dict): + return dict((self.toDict(k), self.toDict(v)) for k, v in obj.items()) + elif isinstance(obj, set): + return set([self.toDict(o) for o in obj]) + elif isinstance(obj, list): + return [self.toDict(o) for o in obj] + else: + return obj + + +class GraphSONReader(object): + def __init__(self, deserializer_map=None): + """ + :param deserializer_map: map from GraphSON type tag to deserializer instance implementing `objectify` + """ + self.deserializers = _deserializers.copy() + if deserializer_map: + self.deserializers.update(deserializer_map) + + def readObject(self, jsonData): + # from JSON + return self.toObject(json.loads(jsonData)) + + def toObject(self, obj): + """ + Unpacks GraphSON type-tagged dict values into objects mapped in self.deserializers + """ + if isinstance(obj, dict): + try: + return self.deserializers[obj[GraphSONUtil.TYPE_KEY]].objectify(obj[GraphSONUtil.VALUE_KEY], self) + except KeyError: + pass + return dict((self.toObject(k), self.toObject(v)) for k, v in obj.items()) + elif isinstance(obj, set): + return set([self.toObject(o) for o in obj]) + elif isinstance(obj, list): + return [self.toObject(o) for o in obj] + else: + return obj + + +@six.add_metaclass(GraphSONTypeType) +class _GraphSONTypeIO(object): + python_type = None + graphson_type = None + + symbolMap = {"global_": "global", "as_": "as", "in_": "in", "and_": "and", + "or_": "or", "is_": "is", "not_": "not", "from_": "from", + "set_": "set", "list_": "list", "all_": "all"} + + @classmethod + def unmangleKeyword(cls, symbol): + return cls.symbolMap.get(symbol, symbol) + + def dictify(self, obj, writer): + raise NotImplementedError() + + def objectify(self, d, reader): + raise NotImplementedError() + + +class _BytecodeSerializer(_GraphSONTypeIO): + @classmethod + def _dictify_instructions(cls, instructions, writer): + out = [] + for instruction in instructions: + inst = [instruction[0]] + inst.extend(writer.toDict(arg) for arg in instruction[1:]) + out.append(inst) + return out + + @classmethod + def dictify(cls, bytecode, writer): + if isinstance(bytecode, Traversal): + bytecode = bytecode.bytecode + out = {} + if bytecode.source_instructions: + out["source"] = cls._dictify_instructions(bytecode.source_instructions, writer) + if bytecode.step_instructions: + out["step"] = cls._dictify_instructions(bytecode.step_instructions, writer) + return GraphSONUtil.typedValue("Bytecode", out) + + +class TraversalSerializer(_BytecodeSerializer): + python_type = Traversal + + +class BytecodeSerializer(_BytecodeSerializer): + python_type = Bytecode + + +class VertexSerializer(_GraphSONTypeIO): + python_type = Vertex + graphson_type = "g:Vertex" + + @classmethod + def dictify(cls, vertex, writer): + return GraphSONUtil.typedValue("Vertex", {"id": writer.toDict(vertex.id), + "label": writer.toDict(vertex.label)}) + + +class EdgeSerializer(_GraphSONTypeIO): + python_type = Edge + graphson_type = "g:Edge" + + @classmethod + def dictify(cls, edge, writer): + return GraphSONUtil.typedValue("Edge", {"id": writer.toDict(edge.id), + "outV": writer.toDict(edge.outV.id), + "outVLabel": writer.toDict(edge.outV.label), + "label": writer.toDict(edge.label), + "inV": writer.toDict(edge.inV.id), + "inVLabel": writer.toDict(edge.inV.label)}) + + +class VertexPropertySerializer(_GraphSONTypeIO): + python_type = VertexProperty + graphson_type = "g:VertexProperty" + + @classmethod + def dictify(cls, vertex_property, writer): + return GraphSONUtil.typedValue("VertexProperty", {"id": writer.toDict(vertex_property.id), + "label": writer.toDict(vertex_property.label), + "value": writer.toDict(vertex_property.value), + "vertex": writer.toDict(vertex_property.vertex.id)}) + + +class PropertySerializer(_GraphSONTypeIO): + python_type = Property + graphson_type = "g:Property" + + @classmethod + def dictify(cls, property, writer): + elementDict = writer.toDict(property.element) + if elementDict is not None: + valueDict = elementDict["@value"] + if "outVLabel" in valueDict: + del valueDict["outVLabel"] + if "inVLabel" in valueDict: + del valueDict["inVLabel"] + if "properties" in valueDict: + del valueDict["properties"] + if "value" in valueDict: + del valueDict["value"] + return GraphSONUtil.typedValue("Property", {"key": writer.toDict(property.key), + "value": writer.toDict(property.value), + "element": elementDict}) + + +class TraversalStrategySerializer(_GraphSONTypeIO): + python_type = TraversalStrategy + + @classmethod + def dictify(cls, strategy, writer): + configuration = {} + for key in strategy.configuration: + configuration[key] = writer.toDict(strategy.configuration[key]) + return GraphSONUtil.typedValue(strategy.strategy_name, configuration) + + +class TraverserIO(_GraphSONTypeIO): + python_type = Traverser + graphson_type = "g:Traverser" + + @classmethod + def dictify(cls, traverser, writer): + return GraphSONUtil.typedValue("Traverser", {"value": writer.toDict(traverser.object), + "bulk": writer.toDict(traverser.bulk)}) + + @classmethod + def objectify(cls, d, reader): + return Traverser(reader.toObject(d["value"]), + reader.toObject(d["bulk"])) + + +class EnumSerializer(_GraphSONTypeIO): + python_type = Enum + + @classmethod + def dictify(cls, enum, _): + return GraphSONUtil.typedValue(cls.unmangleKeyword(type(enum).__name__), + cls.unmangleKeyword(str(enum.name))) + + +class PSerializer(_GraphSONTypeIO): + python_type = P + + @classmethod + def dictify(cls, p, writer): + out = {"predicate": p.operator, + "value": [writer.toDict(p.value), writer.toDict(p.other)] if p.other is not None else + writer.toDict(p.value)} + return GraphSONUtil.typedValue("P", out) + + +class BindingSerializer(_GraphSONTypeIO): + python_type = Binding + + @classmethod + def dictify(cls, binding, writer): + out = {"key": binding.key, + "value": writer.toDict(binding.value)} + return GraphSONUtil.typedValue("Binding", out) + + +class LambdaSerializer(_GraphSONTypeIO): + python_type = FunctionType + + @classmethod + def dictify(cls, lambda_object, writer): + lambda_result = lambda_object() + script = lambda_result if isinstance(lambda_result, str) else lambda_result[0] + language = statics.default_lambda_language if isinstance(lambda_result, str) else lambda_result[1] + out = {"script": script, + "language": language} + if language == "gremlin-jython" or language == "gremlin-python": + if not script.strip().startswith("lambda"): + script = "lambda " + script + out["script"] = script + out["arguments"] = six.get_function_code(eval(out["script"])).co_argcount + else: + out["arguments"] = -1 + return GraphSONUtil.typedValue("Lambda", out) + + +class TypeSerializer(_GraphSONTypeIO): + python_type = TypeType + + @classmethod + def dictify(cls, typ, writer): + return writer.toDict(typ()) + + +class _NumberIO(_GraphSONTypeIO): + @classmethod + def dictify(cls, n, writer): + if isinstance(n, bool): # because isinstance(False, int) and isinstance(True, int) + return n + return GraphSONUtil.typedValue(cls.graphson_base_type, n) + + @classmethod + def objectify(cls, v, _): + return cls.python_type(v) + + +class ListIO(_GraphSONTypeIO): + python_type = ListType + graphson_type = "g:List" + + @classmethod + def dictify(cls, l, writer): + new_list = [] + for obj in l: + new_list.append(writer.toDict(obj)) + return GraphSONUtil.typedValue("List", new_list) + + @classmethod + def objectify(cls, l, reader): + new_list = [] + for obj in l: + new_list.append(reader.toObject(obj)) + return new_list + + +class SetIO(_GraphSONTypeIO): + python_type = SetType + graphson_type = "g:Set" + + @classmethod + def dictify(cls, s, writer): + new_list = [] + for obj in s: + new_list.append(writer.toDict(obj)) + return GraphSONUtil.typedValue("Set", new_list) + + @classmethod + def objectify(cls, s, reader): + new_set = set() + for obj in s: + new_set.add(reader.toObject(obj)) + return new_set + + +class MapType(_GraphSONTypeIO): + python_type = DictType + graphson_type = "g:Map" + + @classmethod + def dictify(cls, d, writer): + l = [] + for key in d: + l.append(writer.toDict(key)) + l.append(writer.toDict(d[key])) + return GraphSONUtil.typedValue("Map", l) + + @classmethod + def objectify(cls, l, reader): + new_dict = {} + if len(l) > 0: + x = 0 + while x < len(l): + new_dict[reader.toObject(l[x])] = reader.toObject(l[x + 1]) + x = x + 2 + return new_dict + + +class FloatIO(_NumberIO): + python_type = FloatType + graphson_type = "g:Float" + graphson_base_type = "Float" + + +class DoubleIO(FloatIO): + graphson_type = "g:Double" + graphson_base_type = "Double" + + +class Int64IO(_NumberIO): + python_type = LongType + graphson_type = "g:Int64" + graphson_base_type = "Int64" + + +class Int32IO(_NumberIO): + python_type = IntType + graphson_type = "g:Int32" + graphson_base_type = "Int32" + + @classmethod + def dictify(cls, n, writer): + if isinstance(n, bool): + return n + return GraphSONUtil.typedValue(cls.graphson_base_type, n) + + +class VertexDeserializer(_GraphSONTypeIO): + graphson_type = "g:Vertex" + + @classmethod + def objectify(cls, d, reader): + return Vertex(reader.toObject(d["id"]), d.get("label", "vertex")) + + +class EdgeDeserializer(_GraphSONTypeIO): + graphson_type = "g:Edge" + + @classmethod + def objectify(cls, d, reader): + return Edge(reader.toObject(d["id"]), + Vertex(reader.toObject(d["outV"]), d.get("outVLabel", "vertex")), + d.get("label", "edge"), + Vertex(reader.toObject(d["inV"]), d.get("inVLabel", "vertex"))) + + +class VertexPropertyDeserializer(_GraphSONTypeIO): + graphson_type = "g:VertexProperty" + + @classmethod + def objectify(cls, d, reader): + vertex = Vertex(reader.toObject(d.get("vertex"))) if "vertex" in d else None + return VertexProperty(reader.toObject(d["id"]), + d["label"], + reader.toObject(d["value"]), + vertex) + + +class PropertyDeserializer(_GraphSONTypeIO): + graphson_type = "g:Property" + + @classmethod + def objectify(cls, d, reader): + element = reader.toObject(d["element"]) if "element" in d else None + return Property(d["key"], reader.toObject(d["value"]), element) + + +class PathDeserializer(_GraphSONTypeIO): + graphson_type = "g:Path" + + @classmethod + def objectify(cls, d, reader): + labels = [set(label) for label in d["labels"]] + objects = [reader.toObject(o) for o in d["objects"]] + return Path(labels, objects) http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/34827047/gremlin-python/src/main/jython/tests/structure/io/test_graphson.py ---------------------------------------------------------------------- diff --git a/gremlin-python/src/main/jython/tests/structure/io/test_graphson.py b/gremlin-python/src/main/jython/tests/structure/io/test_graphson.py deleted file mode 100644 index 719550b..0000000 --- a/gremlin-python/src/main/jython/tests/structure/io/test_graphson.py +++ /dev/null @@ -1,271 +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. -''' - -__author__ = 'Marko A. Rodriguez (http://markorodriguez.com)' - -import sys -import json -from mock import Mock - -import six - -from gremlin_python.statics import * -from gremlin_python.structure.graph import Vertex, Edge, Property, VertexProperty -from gremlin_python.structure.graph import Path -from gremlin_python.structure.io.graphson import GraphSONWriter, GraphSONReader, GraphSONUtil -import gremlin_python.structure.io.graphson -from gremlin_python.process.traversal import P -from gremlin_python.process.strategies import SubgraphStrategy -from gremlin_python.process.graph_traversal import __ - - -class TestGraphSONReader(object): - graphson_reader = GraphSONReader() - - def test_number_input(self): - x = self.graphson_reader.readObject(json.dumps({ - "@type": "g:Int32", - "@value": 31 - })) - assert isinstance(x, int) - assert 31 == x - ## - x = self.graphson_reader.readObject(json.dumps({ - "@type": "g:Int64", - "@value": 31 - })) - assert isinstance(x, long) - assert long(31) == x - ## - x = self.graphson_reader.readObject(json.dumps({ - "@type": "g:Float", - "@value": 31.3 - })) - assert isinstance(x, float) - assert 31.3 == x - ## - x = self.graphson_reader.readObject(json.dumps({ - "@type": "g:Double", - "@value": 31.2 - })) - assert isinstance(x, float) - assert 31.2 == x - - def test_graph(self): - vertex = self.graphson_reader.readObject(""" - {"@type":"g:Vertex", "@value":{"id":{"@type":"g:Int32","@value":1},"label":"person","outE":{"created":[{"id":{"@type":"g:Int32","@value":9},"inV":{"@type":"g:Int32","@value":3},"properties":{"weight":{"@type":"g:Double","@value":0.4}}}],"knows":[{"id":{"@type":"g:Int32","@value":7},"inV":{"@type":"g:Int32","@value":2},"properties":{"weight":{"@type":"g:Double","@value":0.5}}},{"id":{"@type":"g:Int32","@value":8},"inV":{"@type":"g:Int32","@value":4},"properties":{"weight":{"@type":"g:Double","@value":1.0}}}]},"properties":{"name":[{"id":{"@type":"g:Int64","@value":0},"value":"marko"}],"age":[{"id":{"@type":"g:Int64","@value":1},"value":{"@type":"g:Int32","@value":29}}]}}}""") - assert isinstance(vertex, Vertex) - assert "person" == vertex.label - assert 1 == vertex.id - assert isinstance(vertex.id, int) - assert vertex == Vertex(1) - ## - vertex = self.graphson_reader.readObject(""" - {"@type":"g:Vertex", "@value":{"id":{"@type":"g:Float","@value":45.23}}}""") - assert isinstance(vertex, Vertex) - assert 45.23 == vertex.id - assert isinstance(vertex.id, FloatType) - assert "vertex" == vertex.label - assert vertex == Vertex(45.23) - ## - vertex_property = self.graphson_reader.readObject(""" - {"@type":"g:VertexProperty", "@value":{"id":"anId","label":"aKey","value":true,"vertex":{"@type":"g:Int32","@value":9}}}""") - assert isinstance(vertex_property, VertexProperty) - assert "anId" == vertex_property.id - assert "aKey" == vertex_property.label - assert vertex_property.value - assert vertex_property.vertex == Vertex(9) - ## - vertex_property = self.graphson_reader.readObject(""" - {"@type":"g:VertexProperty", "@value":{"id":{"@type":"g:Int32","@value":1},"label":"name","value":"marko"}}""") - assert isinstance(vertex_property, VertexProperty) - assert 1 == vertex_property.id - assert "name" == vertex_property.label - assert "marko" == vertex_property.value - assert vertex_property.vertex is None - ## - edge = self.graphson_reader.readObject(""" - {"@type":"g:Edge", "@value":{"id":{"@type":"g:Int64","@value":17},"label":"knows","inV":"x","outV":"y","inVLabel":"xLab","properties":{"aKey":"aValue","bKey":true}}}""") - # print edge - assert isinstance(edge, Edge) - assert 17 == edge.id - assert "knows" == edge.label - assert edge.inV == Vertex("x", "xLabel") - assert edge.outV == Vertex("y", "vertex") - ## - property = self.graphson_reader.readObject(""" - {"@type":"g:Property", "@value":{"key":"aKey","value":{"@type":"g:Int64","@value":17},"element":{"@type":"g:Edge","@value":{"id":{"@type":"g:Int64","@value":122},"label":"knows","inV":"x","outV":"y","inVLabel":"xLab"}}}}""") - # print property - assert isinstance(property, Property) - assert "aKey" == property.key - assert 17 == property.value - assert Edge(122, Vertex("x"), "knows", Vertex("y")) == property.element - - def test_path(self): - path = self.graphson_reader.readObject( - """{"@type":"g:Path","@value":{"labels":[["a"],["b","c"],[]],"objects":[{"@type":"g:Vertex","@value":{"id":{"@type":"g:Int32","@value":1},"label":"person","properties":{"name":[{"@type":"g:VertexProperty","@value":{"id":{"@type":"g:Int64","@value":0},"value":"marko","label":"name"}}],"age":[{"@type":"g:VertexProperty","@value":{"id":{"@type":"g:Int64","@value":1},"value":{"@type":"g:Int32","@value":29},"label":"age"}}]}}},{"@type":"g:Vertex","@value":{"id":{"@type":"g:Int32","@value":3},"label":"software","properties":{"name":[{"@type":"g:VertexProperty","@value":{"id":{"@type":"g:Int64","@value":4},"value":"lop","label":"name"}}],"lang":[{"@type":"g:VertexProperty","@value":{"id":{"@type":"g:Int64","@value":5},"value":"java","label":"lang"}}]}}},"lop"]}}""" - ) - assert isinstance(path, Path) - if six.PY3: - assert "[v[1], v[3], 'lop']" == str(path) - else: - assert "[v[1], v[3], u'lop']" == str(path) - assert Vertex(1) == path[0] - assert Vertex(1) == path["a"] - assert "lop" == path[2] - assert 3 == len(path) - - def test_custom_mapping(self): - - # extended mapping - class X(object): - pass - - type_string = "test:Xtype" - override_string = "g:Int64" - serdes = Mock() - - reader = GraphSONReader(deserializer_map={type_string: serdes}) - assert type_string in reader.deserializers - - # base dicts are not modified - assert type_string not in gremlin_python.structure.io.graphson._deserializers - - x = X() - o = reader.toObject({GraphSONUtil.TYPE_KEY: type_string, GraphSONUtil.VALUE_KEY: x}) - serdes.objectify.assert_called_once_with(x, reader) - assert o is serdes.objectify() - - # overridden mapping - type_string = "g:Int64" - serdes = Mock() - reader = GraphSONReader(deserializer_map={type_string: serdes, override_string: serdes}) - assert gremlin_python.structure.io.graphson._deserializers[type_string] is not reader.deserializers[type_string] - - value = 3 - o = reader.toObject({GraphSONUtil.TYPE_KEY: type_string, GraphSONUtil.VALUE_KEY: value}) - serdes.objectify.assert_called_once_with(value, reader) - assert o is serdes.objectify() - - -class TestGraphSONWriter(object): - - graphson_writer = GraphSONWriter() - - def test_number_output(self): - assert {"@type": "g:Int64", "@value": 2} == json.loads(self.graphson_writer.writeObject(long(2))) - assert {"@type": "g:Int32", "@value": 1} == json.loads(self.graphson_writer.writeObject(1)) - assert {"@type": "g:Double", "@value": 3.2} == json.loads(self.graphson_writer.writeObject(3.2)) - assert """true""" == self.graphson_writer.writeObject(True) - - def test_numbers(self): - assert {"@type": "g:Int64", "@value": 2} == json.loads(self.graphson_writer.writeObject(long(2))) - assert {"@type": "g:Int32", "@value": 1} == json.loads(self.graphson_writer.writeObject(1)) - assert {"@type": "g:Double", "@value": 3.2} == json.loads(self.graphson_writer.writeObject(3.2)) - assert """true""" == self.graphson_writer.writeObject(True) - - def test_P(self): - result = {'@type': 'g:P', - '@value': { - 'predicate': 'and', - 'value': [{ - '@type': 'g:P', - '@value': { - 'predicate': 'or', - 'value': [{ - '@type': 'g:P', - '@value': {'predicate': 'lt', 'value': 'b'} - }, - {'@type': 'g:P', '@value': {'predicate': 'gt', 'value': 'c'}} - ] - } - }, - {'@type': 'g:P', '@value': {'predicate': 'neq', 'value': 'd'}}]}} - - assert result == json.loads( - self.graphson_writer.writeObject(P.lt("b").or_(P.gt("c")).and_(P.neq("d")))) - - def test_strategies(self): - # we have a proxy model for now given that we don't want to have to have g:XXX all registered on the Gremlin traversal machine (yet) - assert {"@type": "g:SubgraphStrategy", "@value": {}} == json.loads( - self.graphson_writer.writeObject(SubgraphStrategy)) - assert {"@type": "g:SubgraphStrategy", "@value": { - "vertices": {"@type": "g:Bytecode", "@value": {"step": [["has", "name", "marko"]]}}}} == json.loads( - self.graphson_writer.writeObject(SubgraphStrategy(vertices=__.has("name", "marko")))) - - def test_graph(self): - # TODO: this assert is not compatible with python 3 and now that we test with both 2 and 3 it fails - assert {"@type": "g:Vertex", "@value": {"id": {"@type": "g:Int64", "@value": 12}, "label": "person"}} == json.loads(self.graphson_writer.writeObject(Vertex(long(12), "person"))) - - assert {"@type": "g:Edge", "@value": {"id": {"@type": "g:Int32", "@value": 7}, - "outV": {"@type": "g:Int32", "@value": 0}, - "outVLabel": "person", - "label": "knows", - "inV": {"@type": "g:Int32", "@value": 1}, - "inVLabel": "dog"}} == json.loads( - self.graphson_writer.writeObject(Edge(7, Vertex(0, "person"), "knows", Vertex(1, "dog")))) - assert {"@type": "g:VertexProperty", "@value": {"id": "blah", "label": "keyA", "value": True, - "vertex": "stephen"}} == json.loads( - self.graphson_writer.writeObject(VertexProperty("blah", "keyA", True, Vertex("stephen")))) - - assert {"@type": "g:Property", - "@value": {"key": "name", "value": "marko", "element": {"@type": "g:VertexProperty", - "@value": { - "vertex": "vertexId", - "id": {"@type": "g:Int32", "@value": 1234}, - "label": "aKey"}}}} == json.loads( - self.graphson_writer.writeObject( - Property("name", "marko", VertexProperty(1234, "aKey", 21345, Vertex("vertexId"))))) - - def test_custom_mapping(self): - # extended mapping - class X(object): - pass - - serdes = Mock() - writer = GraphSONWriter(serializer_map={X: serdes}) - assert X in writer.serializers - - # base dicts are not modified - assert X not in gremlin_python.structure.io.graphson._serializers - - obj = X() - d = writer.toDict(obj) - serdes.dictify.assert_called_once_with(obj, writer) - assert d is serdes.dictify() - - # overridden mapping - serdes = Mock() - writer = GraphSONWriter(serializer_map={int: serdes}) - assert gremlin_python.structure.io.graphson._serializers[int] is not writer.serializers[int] - - value = 3 - d = writer.toDict(value) - serdes.dictify.assert_called_once_with(value, writer) - assert d is serdes.dictify() - - def test_write_long(self): - - mapping = self.graphson_writer.toDict(1) - assert mapping['@type'] == 'g:Int32' - assert mapping['@value'] == 1 - - mapping = self.graphson_writer.toDict(long(1)) - assert mapping['@type'] == 'g:Int64' - assert mapping['@value'] == 1 http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/34827047/gremlin-python/src/main/jython/tests/structure/io/test_graphsonV2d0.py ---------------------------------------------------------------------- diff --git a/gremlin-python/src/main/jython/tests/structure/io/test_graphsonV2d0.py b/gremlin-python/src/main/jython/tests/structure/io/test_graphsonV2d0.py new file mode 100644 index 0000000..6bc5097 --- /dev/null +++ b/gremlin-python/src/main/jython/tests/structure/io/test_graphsonV2d0.py @@ -0,0 +1,273 @@ +''' +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. +''' + +__author__ = 'Marko A. Rodriguez (http://markorodriguez.com)' + +import sys +import json +from mock import Mock + +import six + +from gremlin_python.statics import * +from gremlin_python.structure.graph import Vertex, Edge, Property, VertexProperty +from gremlin_python.structure.graph import Path +from gremlin_python.structure.io.graphsonV2d0 import GraphSONWriter, GraphSONReader, GraphSONUtil +import gremlin_python.structure.io.graphsonV2d0 +from gremlin_python.process.traversal import P +from gremlin_python.process.strategies import SubgraphStrategy +from gremlin_python.process.graph_traversal import __ + + +class TestGraphSONReader(object): + graphson_reader = GraphSONReader() + + def test_number_input(self): + x = self.graphson_reader.readObject(json.dumps({ + "@type": "g:Int32", + "@value": 31 + })) + assert isinstance(x, int) + assert 31 == x + ## + x = self.graphson_reader.readObject(json.dumps({ + "@type": "g:Int64", + "@value": 31 + })) + assert isinstance(x, long) + assert long(31) == x + ## + x = self.graphson_reader.readObject(json.dumps({ + "@type": "g:Float", + "@value": 31.3 + })) + assert isinstance(x, float) + assert 31.3 == x + ## + x = self.graphson_reader.readObject(json.dumps({ + "@type": "g:Double", + "@value": 31.2 + })) + assert isinstance(x, float) + assert 31.2 == x + + def test_graph(self): + vertex = self.graphson_reader.readObject(""" + {"@type":"g:Vertex", "@value":{"id":{"@type":"g:Int32","@value":1},"label":"person","outE":{"created":[{"id":{"@type":"g:Int32","@value":9},"inV":{"@type":"g:Int32","@value":3},"properties":{"weight":{"@type":"g:Double","@value":0.4}}}],"knows":[{"id":{"@type":"g:Int32","@value":7},"inV":{"@type":"g:Int32","@value":2},"properties":{"weight":{"@type":"g:Double","@value":0.5}}},{"id":{"@type":"g:Int32","@value":8},"inV":{"@type":"g:Int32","@value":4},"properties":{"weight":{"@type":"g:Double","@value":1.0}}}]},"properties":{"name":[{"id":{"@type":"g:Int64","@value":0},"value":"marko"}],"age":[{"id":{"@type":"g:Int64","@value":1},"value":{"@type":"g:Int32","@value":29}}]}}}""") + assert isinstance(vertex, Vertex) + assert "person" == vertex.label + assert 1 == vertex.id + assert isinstance(vertex.id, int) + assert vertex == Vertex(1) + ## + vertex = self.graphson_reader.readObject(""" + {"@type":"g:Vertex", "@value":{"id":{"@type":"g:Float","@value":45.23}}}""") + assert isinstance(vertex, Vertex) + assert 45.23 == vertex.id + assert isinstance(vertex.id, FloatType) + assert "vertex" == vertex.label + assert vertex == Vertex(45.23) + ## + vertex_property = self.graphson_reader.readObject(""" + {"@type":"g:VertexProperty", "@value":{"id":"anId","label":"aKey","value":true,"vertex":{"@type":"g:Int32","@value":9}}}""") + assert isinstance(vertex_property, VertexProperty) + assert "anId" == vertex_property.id + assert "aKey" == vertex_property.label + assert vertex_property.value + assert vertex_property.vertex == Vertex(9) + ## + vertex_property = self.graphson_reader.readObject(""" + {"@type":"g:VertexProperty", "@value":{"id":{"@type":"g:Int32","@value":1},"label":"name","value":"marko"}}""") + assert isinstance(vertex_property, VertexProperty) + assert 1 == vertex_property.id + assert "name" == vertex_property.label + assert "marko" == vertex_property.value + assert vertex_property.vertex is None + ## + edge = self.graphson_reader.readObject(""" + {"@type":"g:Edge", "@value":{"id":{"@type":"g:Int64","@value":17},"label":"knows","inV":"x","outV":"y","inVLabel":"xLab","properties":{"aKey":"aValue","bKey":true}}}""") + # print edge + assert isinstance(edge, Edge) + assert 17 == edge.id + assert "knows" == edge.label + assert edge.inV == Vertex("x", "xLabel") + assert edge.outV == Vertex("y", "vertex") + ## + property = self.graphson_reader.readObject(""" + {"@type":"g:Property", "@value":{"key":"aKey","value":{"@type":"g:Int64","@value":17},"element":{"@type":"g:Edge","@value":{"id":{"@type":"g:Int64","@value":122},"label":"knows","inV":"x","outV":"y","inVLabel":"xLab"}}}}""") + # print property + assert isinstance(property, Property) + assert "aKey" == property.key + assert 17 == property.value + assert Edge(122, Vertex("x"), "knows", Vertex("y")) == property.element + + def test_path(self): + path = self.graphson_reader.readObject( + """{"@type":"g:Path","@value":{"labels":[["a"],["b","c"],[]],"objects":[{"@type":"g:Vertex","@value":{"id":{"@type":"g:Int32","@value":1},"label":"person","properties":{"name":[{"@type":"g:VertexProperty","@value":{"id":{"@type":"g:Int64","@value":0},"value":"marko","label":"name"}}],"age":[{"@type":"g:VertexProperty","@value":{"id":{"@type":"g:Int64","@value":1},"value":{"@type":"g:Int32","@value":29},"label":"age"}}]}}},{"@type":"g:Vertex","@value":{"id":{"@type":"g:Int32","@value":3},"label":"software","properties":{"name":[{"@type":"g:VertexProperty","@value":{"id":{"@type":"g:Int64","@value":4},"value":"lop","label":"name"}}],"lang":[{"@type":"g:VertexProperty","@value":{"id":{"@type":"g:Int64","@value":5},"value":"java","label":"lang"}}]}}},"lop"]}}""" + ) + assert isinstance(path, Path) + if six.PY3: + assert "[v[1], v[3], 'lop']" == str(path) + else: + assert "[v[1], v[3], u'lop']" == str(path) + assert Vertex(1) == path[0] + assert Vertex(1) == path["a"] + assert "lop" == path[2] + assert 3 == len(path) + + def test_custom_mapping(self): + + # extended mapping + class X(object): + pass + + type_string = "test:Xtype" + override_string = "g:Int64" + serdes = Mock() + + reader = GraphSONReader(deserializer_map={type_string: serdes}) + assert type_string in reader.deserializers + + # base dicts are not modified + assert type_string not in gremlin_python.structure.io.graphsonV2d0._deserializers + + x = X() + o = reader.toObject({GraphSONUtil.TYPE_KEY: type_string, GraphSONUtil.VALUE_KEY: x}) + serdes.objectify.assert_called_once_with(x, reader) + assert o is serdes.objectify() + + # overridden mapping + type_string = "g:Int64" + serdes = Mock() + reader = GraphSONReader(deserializer_map={type_string: serdes, override_string: serdes}) + assert gremlin_python.structure.io.graphsonV2d0._deserializers[type_string] is not reader.deserializers[type_string] + + value = 3 + o = reader.toObject({GraphSONUtil.TYPE_KEY: type_string, GraphSONUtil.VALUE_KEY: value}) + serdes.objectify.assert_called_once_with(value, reader) + assert o is serdes.objectify() + +class TestGraphSONWriter(object): + + graphson_writer = GraphSONWriter() + + def test_number_output(self): + assert {"@type": "g:Int64", "@value": 2} == json.loads(self.graphson_writer.writeObject(long(2))) + assert {"@type": "g:Int32", "@value": 1} == json.loads(self.graphson_writer.writeObject(1)) + assert {"@type": "g:Double", "@value": 3.2} == json.loads(self.graphson_writer.writeObject(3.2)) + assert """true""" == self.graphson_writer.writeObject(True) + + def test_numbers(self): + assert {"@type": "g:Int64", "@value": 2} == json.loads(self.graphson_writer.writeObject(long(2))) + assert {"@type": "g:Int32", "@value": 1} == json.loads(self.graphson_writer.writeObject(1)) + assert {"@type": "g:Double", "@value": 3.2} == json.loads(self.graphson_writer.writeObject(3.2)) + assert """true""" == self.graphson_writer.writeObject(True) + + def test_P(self): + result = {'@type': 'g:P', + '@value': { + 'predicate': 'and', + 'value': [{ + '@type': 'g:P', + '@value': { + 'predicate': 'or', + 'value': [{ + '@type': 'g:P', + '@value': {'predicate': 'lt', 'value': 'b'} + }, + {'@type': 'g:P', '@value': {'predicate': 'gt', 'value': 'c'}} + ] + } + }, + {'@type': 'g:P', '@value': {'predicate': 'neq', 'value': 'd'}}]}} + + assert result == json.loads( + self.graphson_writer.writeObject(P.lt("b").or_(P.gt("c")).and_(P.neq("d")))) + + result = {'@type': 'g:P', '@value': {'predicate':'within','value': [{"@type": "g:Int32", "@value": 1},{"@type": "g:Int32", "@value": 2}]}} + assert result == json.loads(self.graphson_writer.writeObject(P.within([1,2]))) + + def test_strategies(self): + # we have a proxy model for now given that we don't want to have to have g:XXX all registered on the Gremlin traversal machine (yet) + assert {"@type": "g:SubgraphStrategy", "@value": {}} == json.loads( + self.graphson_writer.writeObject(SubgraphStrategy)) + assert {"@type": "g:SubgraphStrategy", "@value": { + "vertices": {"@type": "g:Bytecode", "@value": {"step": [["has", "name", "marko"]]}}}} == json.loads( + self.graphson_writer.writeObject(SubgraphStrategy(vertices=__.has("name", "marko")))) + + def test_graph(self): + # TODO: this assert is not compatible with python 3 and now that we test with both 2 and 3 it fails + assert {"@type": "g:Vertex", "@value": {"id": {"@type": "g:Int64", "@value": 12}, "label": "person"}} == json.loads(self.graphson_writer.writeObject(Vertex(long(12), "person"))) + + assert {"@type": "g:Edge", "@value": {"id": {"@type": "g:Int32", "@value": 7}, + "outV": {"@type": "g:Int32", "@value": 0}, + "outVLabel": "person", + "label": "knows", + "inV": {"@type": "g:Int32", "@value": 1}, + "inVLabel": "dog"}} == json.loads( + self.graphson_writer.writeObject(Edge(7, Vertex(0, "person"), "knows", Vertex(1, "dog")))) + assert {"@type": "g:VertexProperty", "@value": {"id": "blah", "label": "keyA", "value": True, + "vertex": "stephen"}} == json.loads( + self.graphson_writer.writeObject(VertexProperty("blah", "keyA", True, Vertex("stephen")))) + + assert {"@type": "g:Property", + "@value": {"key": "name", "value": "marko", "element": {"@type": "g:VertexProperty", + "@value": { + "vertex": "vertexId", + "id": {"@type": "g:Int32", "@value": 1234}, + "label": "aKey"}}}} == json.loads( + self.graphson_writer.writeObject( + Property("name", "marko", VertexProperty(1234, "aKey", 21345, Vertex("vertexId"))))) + + def test_custom_mapping(self): + # extended mapping + class X(object): + pass + + serdes = Mock() + writer = GraphSONWriter(serializer_map={X: serdes}) + assert X in writer.serializers + + # base dicts are not modified + assert X not in gremlin_python.structure.io.graphsonV2d0._serializers + + obj = X() + d = writer.toDict(obj) + serdes.dictify.assert_called_once_with(obj, writer) + assert d is serdes.dictify() + + # overridden mapping + serdes = Mock() + writer = GraphSONWriter(serializer_map={int: serdes}) + assert gremlin_python.structure.io.graphsonV2d0._serializers[int] is not writer.serializers[int] + + value = 3 + d = writer.toDict(value) + serdes.dictify.assert_called_once_with(value, writer) + assert d is serdes.dictify() + + def test_write_long(self): + + mapping = self.graphson_writer.toDict(1) + assert mapping['@type'] == 'g:Int32' + assert mapping['@value'] == 1 + + mapping = self.graphson_writer.toDict(long(1)) + assert mapping['@type'] == 'g:Int64' + assert mapping['@value'] == 1 \ No newline at end of file