diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc index 454ea115587..4bd90644a84 100644 --- a/CHANGELOG.asciidoc +++ b/CHANGELOG.asciidoc @@ -280,6 +280,7 @@ image::https://raw.githubusercontent.com/apache/tinkerpop/master/docs/static/ima === TinkerPop 3.6.7 (NOT OFFICIALLY RELEASED YET) * Improved error message from `JavaTranslator` by including exception source. +* Added missing `short` serialization (`gx:Int16`) to GraphSONV2 and GraphSONV3 in `gremlin-python` * Added tests for error handling for GLV's if tx.commit() is called remotely for graphs without transactions support. * Introduced multi-architecture AMD64/ARM64 docker images for gremlin-console. * Fixed bug in `JavaTranslator` where `has(String, null)` could call `has(String, Traversal)` to generate an error. diff --git a/gremlin-python/src/main/python/gremlin_python/structure/io/graphsonV2d0.py b/gremlin-python/src/main/python/gremlin_python/structure/io/graphsonV2d0.py index 2442a7c6043..d4138b6c9d3 100644 --- a/gremlin-python/src/main/python/gremlin_python/structure/io/graphsonV2d0.py +++ b/gremlin-python/src/main/python/gremlin_python/structure/io/graphsonV2d0.py @@ -30,7 +30,7 @@ from isodate import parse_duration, duration_isoformat from gremlin_python import statics -from gremlin_python.statics import FloatType, FunctionType, IntType, LongType, TypeType, SingleByte, ByteBufferType, SingleChar +from gremlin_python.statics import FloatType, FunctionType, ShortType, IntType, LongType, TypeType, SingleByte, ByteBufferType, SingleChar from gremlin_python.process.traversal import Binding, Bytecode, P, TextP, Traversal, Traverser, TraversalStrategy from gremlin_python.structure.graph import Edge, Property, Vertex, VertexProperty, Path from gremlin_python.structure.io.util import SymbolUtil @@ -498,6 +498,30 @@ def dictify(cls, n, writer): return GraphSONUtil.typed_value(cls.graphson_base_type, n) +class Int16IO(Int64IO): + python_type = ShortType + graphson_type = "gx:Int16" + graphson_base_type = "Int16" + + @classmethod + def dictify(cls, n, writer): + # if we exceed Java int range then we need a long + if isinstance(n, bool): + return n + elif n < -9223372036854775808 or n > 9223372036854775807: + return GraphSONUtil.typed_value("BigInteger", str(n), "gx") + elif n < -2147483648 or n > 2147483647: + return GraphSONUtil.typed_value("Int64", n) + elif n < -32768 or n > 32767: + return GraphSONUtil.typed_value("Int32", n) + else: + return GraphSONUtil.typed_value(cls.graphson_base_type, n, "gx") + + @classmethod + def objectify(cls, v, _): + return int.__new__(ShortType, v) + + class ByteIO(_NumberIO): python_type = SingleByte graphson_type = "gx:Byte" diff --git a/gremlin-python/src/main/python/gremlin_python/structure/io/graphsonV3d0.py b/gremlin-python/src/main/python/gremlin_python/structure/io/graphsonV3d0.py index ba805bd7381..692e4d27b07 100644 --- a/gremlin-python/src/main/python/gremlin_python/structure/io/graphsonV3d0.py +++ b/gremlin-python/src/main/python/gremlin_python/structure/io/graphsonV3d0.py @@ -29,7 +29,7 @@ from isodate import parse_duration, duration_isoformat from gremlin_python import statics -from gremlin_python.statics import FloatType, FunctionType, IntType, LongType, TypeType, DictType, ListType, SetType, SingleByte, ByteBufferType, SingleChar +from gremlin_python.statics import FloatType, FunctionType, ShortType, IntType, LongType, TypeType, DictType, ListType, SetType, SingleByte, ByteBufferType, SingleChar from gremlin_python.process.traversal import Binding, Bytecode, Direction, P, TextP, Traversal, Traverser, TraversalStrategy, T from gremlin_python.structure.graph import Edge, Property, Vertex, VertexProperty, Path from gremlin_python.structure.io.util import HashableDict, SymbolUtil @@ -597,6 +597,31 @@ def dictify(cls, n, writer): else: return GraphSONUtil.typed_value(cls.graphson_base_type, n) + +class Int16IO(Int64IO): + python_type = ShortType + graphson_type = "gx:Int16" + graphson_base_type = "Int16" + + @classmethod + def dictify(cls, n, writer): + # if we exceed Java int range then we need a long + if isinstance(n, bool): + return n + elif n < -9223372036854775808 or n > 9223372036854775807: + return GraphSONUtil.typed_value("BigInteger", str(n), "gx") + elif n < -2147483648 or n > 2147483647: + return GraphSONUtil.typed_value("Int64", n) + elif n < -32768 or n > 32767: + return GraphSONUtil.typed_value("Int32", n) + else: + return GraphSONUtil.typed_value(cls.graphson_base_type, n, "gx") + + @classmethod + def objectify(cls, v, _): + return int.__new__(ShortType, v) + + class ByteIO(_NumberIO): python_type = SingleByte graphson_type = "gx:Byte" diff --git a/gremlin-python/src/main/python/tests/driver/test_client.py b/gremlin-python/src/main/python/tests/driver/test_client.py index 36782c94870..75048a647f7 100644 --- a/gremlin-python/src/main/python/tests/driver/test_client.py +++ b/gremlin-python/src/main/python/tests/driver/test_client.py @@ -297,6 +297,15 @@ def thread_run(tr, result_list): assert len(results[2][0]) == 6 assert results[3][0][0].object == 6 +def test_client_bytecode_with_short(client): + g = Graph().traversal() + t = g.V().has('age', short(16)).count() + message = RequestMessage('traversal', 'bytecode', {'gremlin': t.bytecode, 'aliases': {'g': 'gmodern'}}) + result_set = client.submit(message) + results = [] + for result in result_set: + results += result + assert len(results) == 1 def test_client_bytecode_with_long(client): g = Graph().traversal() diff --git a/gremlin-python/src/main/python/tests/structure/io/test_graphsonV2d0.py b/gremlin-python/src/main/python/tests/structure/io/test_graphsonV2d0.py index a36fbe92e6f..f89c84cc546 100644 --- a/gremlin-python/src/main/python/tests/structure/io/test_graphsonV2d0.py +++ b/gremlin-python/src/main/python/tests/structure/io/test_graphsonV2d0.py @@ -47,6 +47,12 @@ def test_number_input(self): })) assert isinstance(x, SingleByte) assert 1 == x + x = self.graphson_reader.read_object(json.dumps({ + "@type": "gx:Int16", + "@value": 16 + })) + assert isinstance(x, short) + assert 16 == x x = self.graphson_reader.read_object(json.dumps({ "@type": "g:Int32", "@value": 31 @@ -298,6 +304,8 @@ class TestGraphSONWriter(object): def test_numbers(self): assert {"@type": "gx:Byte", "@value": 1} == json.loads(self.graphson_writer.write_object(int.__new__(SingleByte, 1))) + assert {"@type": "gx:Int16", "@value": 16} == json.loads(self.graphson_writer.write_object(short(16))) + assert {"@type": "gx:Int16", "@value": -16} == json.loads(self.graphson_writer.write_object(short(-16))) assert {"@type": "g:Int64", "@value": 2} == json.loads(self.graphson_writer.write_object(long(2))) assert {"@type": "g:Int64", "@value": 851401972585122} == json.loads(self.graphson_writer.write_object(long(851401972585122))) assert {"@type": "g:Int64", "@value": -2} == json.loads(self.graphson_writer.write_object(long(-2))) diff --git a/gremlin-python/src/main/python/tests/structure/io/test_graphsonV3d0.py b/gremlin-python/src/main/python/tests/structure/io/test_graphsonV3d0.py index 250c70a0e1b..6b852fbf68f 100644 --- a/gremlin-python/src/main/python/tests/structure/io/test_graphsonV3d0.py +++ b/gremlin-python/src/main/python/tests/structure/io/test_graphsonV3d0.py @@ -93,6 +93,12 @@ def test_number_input(self): })) assert isinstance(x, SingleByte) assert 1 == x + x = self.graphson_reader.read_object(json.dumps({ + "@type": "gx:Int16", + "@value": 16 + })) + assert isinstance(x, short) + assert 16 == x x = self.graphson_reader.read_object(json.dumps({ "@type": "g:Int32", "@value": 31 @@ -357,6 +363,8 @@ def test_collections(self): def test_numbers(self): assert {"@type": "gx:Byte", "@value": 1} == json.loads(self.graphson_writer.write_object(int.__new__(SingleByte, 1))) + assert {"@type": "gx:Int16", "@value": 16} == json.loads(self.graphson_writer.write_object(short(16))) + assert {"@type": "gx:Int16", "@value": -16} == json.loads(self.graphson_writer.write_object(short(-16))) assert {"@type": "g:Int64", "@value": 2} == json.loads(self.graphson_writer.write_object(long(2))) assert {"@type": "g:Int64", "@value": 851401972585122} == json.loads(self.graphson_writer.write_object(long(851401972585122))) assert {"@type": "g:Int64", "@value": -2} == json.loads(self.graphson_writer.write_object(long(-2)))