This is an automated email from the ASF dual-hosted git repository.

xiazcy pushed a commit to branch py-bigdecimal-to-decimal
in repository https://gitbox.apache.org/repos/asf/tinkerpop.git

commit be11ef7baa8e77fee6aae49cc37e6c8a176d2c3b
Author: xiazcy <[email protected]>
AuthorDate: Thu Oct 30 15:43:14 2025 -0700

    Experiment with everything deserialized to decimal.Decimal, but keep 
statics.BigDecimal as utility class, with serializers for both Decimal and 
BigDecimal in gremlin-python
---
 .../src/main/python/gremlin_python/statics.py      |  3 +-
 .../gremlin_python/structure/io/graphbinaryV1.py   | 27 ++++++++++++++++-
 .../gremlin_python/structure/io/graphsonV2d0.py    | 35 ++++++++++++++++++++--
 .../gremlin_python/structure/io/graphsonV3d0.py    | 34 ++++++++++++++++++++-
 .../src/main/python/radish/feature_steps.py        |  5 ++--
 .../tests/structure/io/test_functionalityio.py     |  6 ++--
 .../tests/structure/io/test_graphbinaryV1.py       | 13 ++++++--
 .../python/tests/structure/io/test_graphsonV2d0.py |  9 +++---
 .../python/tests/structure/io/test_graphsonV3d0.py |  9 +++---
 9 files changed, 120 insertions(+), 21 deletions(-)

diff --git a/gremlin-python/src/main/python/gremlin_python/statics.py 
b/gremlin-python/src/main/python/gremlin_python/statics.py
index 8f791b0845..ed7e929bef 100644
--- a/gremlin-python/src/main/python/gremlin_python/statics.py
+++ b/gremlin-python/src/main/python/gremlin_python/statics.py
@@ -85,7 +85,8 @@ class GremlinType(object):
 
 class BigDecimal(object):
     """
-    Provides a way to represent a BigDecimal for Gremlin.
+    Provides a way to represent a BigDecimal in Gremlin for serialization of 
decimal.Decimal only. Not round-trippable,
+    use decimal.Decimal for proper representation and for serialization 
round-tripping.
     """
     def __init__(self, scale, unscaled_value):
         self.scale = scale
diff --git 
a/gremlin-python/src/main/python/gremlin_python/structure/io/graphbinaryV1.py 
b/gremlin-python/src/main/python/gremlin_python/structure/io/graphbinaryV1.py
index 4bfa71e43a..f8b50aef86 100644
--- 
a/gremlin-python/src/main/python/gremlin_python/structure/io/graphbinaryV1.py
+++ 
b/gremlin-python/src/main/python/gremlin_python/structure/io/graphbinaryV1.py
@@ -25,6 +25,7 @@ import io
 import struct
 from collections import OrderedDict
 import logging
+from decimal import Decimal
 
 from struct import pack, unpack
 from aenum import Enum
@@ -32,7 +33,7 @@ from datetime import timedelta
 from gremlin_python import statics
 from gremlin_python.statics import FloatType, BigDecimal, FunctionType, 
ShortType, IntType, LongType, BigIntType, \
                                    TypeType, DictType, ListType, SetType, 
SingleByte, ByteBufferType, GremlinType, \
-                                   SingleChar
+                                   SingleChar, bigdecimal
 from gremlin_python.process.traversal import Barrier, Binding, Bytecode, 
Cardinality, Column, Direction, DT, GType, \
                                              Merge,Operator, Order, Pick, Pop, 
P, Scope, TextP, Traversal, Traverser, \
                                              TraversalStrategy, T
@@ -479,6 +480,30 @@ class BigDecimalIO(_GraphBinaryTypeIO):
         return cls.is_null(buff, reader, lambda b, r: cls._read(b), nullable)
 
 
+class DecimalIO(_GraphBinaryTypeIO):
+
+    python_type = Decimal
+    graphbinary_type = DataType.bigdecimal
+
+    @classmethod
+    def dictify(cls, obj, writer, to_extend, as_value=False, nullable=True):
+        cls.prefix_bytes(cls.graphbinary_type, as_value, nullable, to_extend)
+        bd_obj = bigdecimal(obj)
+        to_extend.extend(int32_pack(bd_obj.scale))
+        return BigIntIO.write_bigint(bd_obj.unscaled_value, to_extend)
+
+    @classmethod
+    def _read(cls, buff):
+        scale = int32_unpack(buff.read(4))
+        unscaled_value = BigIntIO.read_bigint(buff)
+        bg_obj = BigDecimal(scale, unscaled_value)
+        return bg_obj.value
+
+    @classmethod
+    def objectify(cls, buff, reader, nullable=False):
+        return cls.is_null(buff, reader, lambda b, r: cls._read(b), nullable)
+
+
 class CharIO(_GraphBinaryTypeIO):
     python_type = SingleChar
     graphbinary_type = DataType.char
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 f08e8ab72d..57cd3e5e5f 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
@@ -454,12 +454,43 @@ class BigDecimalIO(_NumberIO):
 
     @classmethod
     def dictify(cls, n, writer):
-        print(n)
         return GraphSONUtil.typed_value(cls.graphson_base_type, str(n.value), 
"gx")
 
     @classmethod
     def objectify(cls, v, _):
-        return bigdecimal(v)
+        bd_v = bigdecimal(v)
+        return bd_v.value
+
+
+class DecimalIO(_NumberIO):
+    python_type = Decimal
+    graphson_type = "gx:BigDecimal"
+    graphson_base_type = "BigDecimal"
+
+    @classmethod
+    def dictify(cls, n, writer):
+        if isinstance(n, bool):  # because isinstance(False, int) and 
isinstance(True, int)
+            return n
+        elif math.isnan(n):
+            return GraphSONUtil.typed_value(cls.graphson_base_type, "NaN", 
"gx")
+        elif math.isinf(n) and n > 0:
+            return GraphSONUtil.typed_value(cls.graphson_base_type, 
"Infinity", "gx")
+        elif math.isinf(n) and n < 0:
+            return GraphSONUtil.typed_value(cls.graphson_base_type, 
"-Infinity", "gx")
+        else:
+            return GraphSONUtil.typed_value(cls.graphson_base_type, str(n), 
"gx")
+
+    @classmethod
+    def objectify(cls, v, _):
+        if isinstance(v, str):
+            if v == 'NaN':
+                return Decimal('nan')
+            elif v == "Infinity":
+                return Decimal('inf')
+            elif v == "-Infinity":
+                return Decimal('-inf')
+
+        return Decimal(v)
 
 
 class DoubleIO(FloatIO):
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 99ed150dae..7fc74d78ef 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
@@ -555,7 +555,39 @@ class BigDecimalIO(_NumberIO):
 
     @classmethod
     def objectify(cls, v, _):
-        return bigdecimal(v)
+        bd_v = bigdecimal(v)
+        return bd_v.value
+
+
+class DecimalIO(_NumberIO):
+    python_type = Decimal
+    graphson_type = "gx:BigDecimal"
+    graphson_base_type = "BigDecimal"
+
+    @classmethod
+    def dictify(cls, n, writer):
+        if isinstance(n, bool):  # because isinstance(False, int) and 
isinstance(True, int)
+            return n
+        elif math.isnan(n):
+            return GraphSONUtil.typed_value(cls.graphson_base_type, "NaN", 
"gx")
+        elif math.isinf(n) and n > 0:
+            return GraphSONUtil.typed_value(cls.graphson_base_type, 
"Infinity", "gx")
+        elif math.isinf(n) and n < 0:
+            return GraphSONUtil.typed_value(cls.graphson_base_type, 
"-Infinity", "gx")
+        else:
+            return GraphSONUtil.typed_value(cls.graphson_base_type, str(n), 
"gx")
+
+    @classmethod
+    def objectify(cls, v, _):
+        if isinstance(v, str):
+            if v == 'NaN':
+                return Decimal('nan')
+            elif v == "Infinity":
+                return Decimal('inf')
+            elif v == "-Infinity":
+                return Decimal('-inf')
+
+        return Decimal(v)
 
 
 class DoubleIO(FloatIO):
diff --git a/gremlin-python/src/main/python/radish/feature_steps.py 
b/gremlin-python/src/main/python/radish/feature_steps.py
index c8765d6da5..a68f773515 100644
--- a/gremlin-python/src/main/python/radish/feature_steps.py
+++ b/gremlin-python/src/main/python/radish/feature_steps.py
@@ -262,8 +262,9 @@ def _convert(val, ctx):
         return float("-inf")
     elif isinstance(val, str) and re.match(r"^d\[.*\]\.[bsilfdn]$", val):  # 
parse numeric
         return float(val[2:-3]) if val[2:-3].__contains__(".") else 
long(val[2:-3])
-    elif isinstance(val, str) and re.match(r"^d\[.*\]\.m$", val):  # parse 
bigDecimal
-        return bigdecimal(val[2:-3])
+    elif isinstance(val, str) and re.match(r"^d\[.*\]\.m$", val):  # parse 
BigDecimal (into decimal.Decimal)
+        bd_val = bigdecimal(val[2:-3])
+        return bd_val.value
     elif isinstance(val, str) and re.match(r"^v\[.*\]\.id$", val):  # parse 
vertex id
         return __find_cached_element(ctx, graph_name, val[2:-4], "v").id
     elif isinstance(val, str) and re.match(r"^v\[.*\]\.sid$", val):  # parse 
vertex id as string
diff --git 
a/gremlin-python/src/main/python/tests/structure/io/test_functionalityio.py 
b/gremlin-python/src/main/python/tests/structure/io/test_functionalityio.py
index d6effb4813..2ecee51b8b 100644
--- a/gremlin-python/src/main/python/tests/structure/io/test_functionalityio.py
+++ b/gremlin-python/src/main/python/tests/structure/io/test_functionalityio.py
@@ -19,6 +19,7 @@ under the License.
 
 import datetime
 import uuid
+from decimal import Decimal
 
 from gremlin_python.driver.serializer import GraphSONSerializersV2d0, 
GraphBinarySerializersV1
 from gremlin_python.process.anonymous_traversal import traversal
@@ -192,9 +193,8 @@ def test_bigdecimal(remote_connection):
     vid = resp[0].id
     try:
         bigdecimal_prop = g.V(vid).properties('bigdecimal').toList()[0]
-        assert isinstance(bigdecimal_prop.value, BigDecimal)
-        assert bigdecimal_prop.value.scale == bigdecimal.scale
-        assert bigdecimal_prop.value.unscaled_value == 
bigdecimal.unscaled_value
+        assert isinstance(bigdecimal_prop.value, Decimal)
+        assert bigdecimal_prop.value == bigdecimal.value
     finally:
         g.V(vid).drop().iterate()
 
diff --git 
a/gremlin-python/src/main/python/tests/structure/io/test_graphbinaryV1.py 
b/gremlin-python/src/main/python/tests/structure/io/test_graphbinaryV1.py
index 102be4997a..cb4de18ad9 100644
--- a/gremlin-python/src/main/python/tests/structure/io/test_graphbinaryV1.py
+++ b/gremlin-python/src/main/python/tests/structure/io/test_graphbinaryV1.py
@@ -21,7 +21,9 @@ import uuid
 import math
 
 from datetime import datetime, timedelta, timezone
-from gremlin_python.statics import long, bigint, BigDecimal, SingleByte, 
SingleChar, ByteBufferType, timestamp
+from decimal import Decimal
+
+from gremlin_python.statics import long, bigint, BigDecimal, SingleByte, 
SingleChar, ByteBufferType, timestamp, bigdecimal
 from gremlin_python.structure.graph import Vertex, Edge, Property, 
VertexProperty, Path
 from gremlin_python.structure.io.graphbinaryV1 import GraphBinaryWriter, 
GraphBinaryReader
 from gremlin_python.process.traversal import Barrier, Binding, Bytecode, 
Merge, Direction
@@ -79,8 +81,13 @@ class TestGraphBinaryWriter(object):
     def test_bigdecimal(self):
         x = BigDecimal(100, 234)
         output = 
self.graphbinary_reader.read_object(self.graphbinary_writer.write_object(x))
-        assert x.scale == output.scale
-        assert x.unscaled_value == output.unscaled_value
+        assert x.scale == bigdecimal(output).scale
+        assert x.unscaled_value == bigdecimal(output).unscaled_value
+
+    def test_decimal(self):
+        x = Decimal(100)
+        output = 
self.graphbinary_reader.read_object(self.graphbinary_writer.write_object(x))
+        assert x == output
 
     def test_date(self):
         x = datetime(2016, 12, 14, 16, 14, 36, 295000)
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 5eaad833a0..81932d58b8 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
@@ -107,15 +107,15 @@ class TestGraphSONReader:
             "@type": "gx:BigDecimal",
             "@value": 31.2
         }))
-        assert isinstance(x, BigDecimal)
-        assert bigdecimal(31.2) == x
+        assert isinstance(x, Decimal)
+        assert Decimal(31.2) == x
         ##
         x = self.graphson_reader.read_object(json.dumps({
             "@type": "gx:BigDecimal",
             "@value": 123456789987654321123456789987654321
         }))
-        assert isinstance(x, BigDecimal)
-        assert bigdecimal('123456789987654321123456789987654321') == x
+        assert isinstance(x, Decimal)
+        assert Decimal('123456789987654321123456789987654321') == x
         ##
         x = self.graphson_reader.read_object(json.dumps({
             "@type": "gx:BigInteger",
@@ -372,6 +372,7 @@ class TestGraphSONWriter:
         assert {"@type": "g:Double", "@value": "Infinity"} == 
json.loads(self.graphson_writer.write_object(float('inf')))
         assert {"@type": "g:Double", "@value": "-Infinity"} == 
json.loads(self.graphson_writer.write_object(float('-inf')))
         assert {"@type": "gx:BigDecimal", "@value": 
"123456789987654321123456789987654321"} == 
json.loads(self.graphson_writer.write_object(bigdecimal('123456789987654321123456789987654321')))
+        assert {"@type": "gx:BigDecimal", "@value": 
"123456789987654321123456789987654321"} == 
json.loads(self.graphson_writer.write_object(Decimal('123456789987654321123456789987654321')))
         assert {"@type": "gx:BigInteger", "@value": 
"123456789987654321123456789987654321"} == 
json.loads(self.graphson_writer.write_object(long(123456789987654321123456789987654321)))
         assert {"@type": "gx:BigInteger", "@value": 
"123456789987654321123456789987654321"} == 
json.loads(self.graphson_writer.write_object(123456789987654321123456789987654321))
         assert """true""" == self.graphson_writer.write_object(True)
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 e882f5ca67..6792678b31 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
@@ -152,15 +152,15 @@ class TestGraphSONReader:
             "@type": "gx:BigDecimal",
             "@value": 31.2
         }))
-        assert isinstance(x, BigDecimal)
-        assert bigdecimal(31.2) == x
+        assert isinstance(x, Decimal)
+        assert Decimal(31.2) == x
         ##
         x = self.graphson_reader.read_object(json.dumps({
             "@type": "gx:BigDecimal",
             "@value": 123456789987654321123456789987654321
         }))
-        assert isinstance(x, BigDecimal)
-        assert bigdecimal('123456789987654321123456789987654321') == x
+        assert isinstance(x, Decimal)
+        assert Decimal('123456789987654321123456789987654321') == x
         ##
         x = self.graphson_reader.read_object(json.dumps({
             "@type": "gx:BigInteger",
@@ -431,6 +431,7 @@ class TestGraphSONWriter:
         assert {"@type": "g:Double", "@value": "Infinity"} == 
json.loads(self.graphson_writer.write_object(float('inf')))
         assert {"@type": "g:Double", "@value": "-Infinity"} == 
json.loads(self.graphson_writer.write_object(float('-inf')))
         assert {"@type": "gx:BigDecimal", "@value": 
"123456789987654321123456789987654321"} == 
json.loads(self.graphson_writer.write_object(bigdecimal('123456789987654321123456789987654321')))
+        assert {"@type": "gx:BigDecimal", "@value": 
"123456789987654321123456789987654321"} == 
json.loads(self.graphson_writer.write_object(Decimal('123456789987654321123456789987654321')))
         assert {"@type": "gx:BigInteger", "@value": 
"123456789987654321123456789987654321"} == 
json.loads(self.graphson_writer.write_object(long(123456789987654321123456789987654321)))
         assert {"@type": "gx:BigInteger", "@value": 
"123456789987654321123456789987654321"} == 
json.loads(self.graphson_writer.write_object(123456789987654321123456789987654321))
         assert """true""" == self.graphson_writer.write_object(True)

Reply via email to