Skip to content

Commit

Permalink
fix[Decimal]: converting from float -> decimal resulted in inaccurate…
Browse files Browse the repository at this point in the history
… values

Example:-
Decimal(0.01) -> Decimal("0.01000000000000000020816681711721685132943093776702880859375")

Additional:
Decimal field now accepts string, int & float. Previously it was just string & int
  • Loading branch information
mak626 committed Feb 10, 2025
1 parent 8290326 commit 2da4618
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 9 deletions.
6 changes: 3 additions & 3 deletions graphene/types/decimal.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from decimal import Decimal as _Decimal

from graphql import Undefined
from graphql.language.ast import StringValueNode, IntValueNode
from graphql.language.ast import StringValueNode, IntValueNode, FloatValueNode

from .scalars import Scalar

Expand All @@ -22,13 +22,13 @@ def serialize(dec):

@classmethod
def parse_literal(cls, node, _variables=None):
if isinstance(node, (StringValueNode, IntValueNode)):
if isinstance(node, (StringValueNode, IntValueNode, FloatValueNode)):
return cls.parse_value(node.value)
return Undefined

@staticmethod
def parse_value(value):
try:
return _Decimal(value)
return _Decimal(str(value))
except Exception:
return Undefined
52 changes: 46 additions & 6 deletions graphene/types/tests/test_decimal.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,26 @@ def test_decimal_string_query():
assert decimal.Decimal(result.data["decimal"]) == decimal_value


def test_decimal_float_query():
float_value = 1969.1974
decimal_value = decimal.Decimal(str(float_value))
result = schema.execute("""{ decimal(input: %s) }""" % float_value)
assert not result.errors
assert not result.errors
assert result.data == {"decimal": str(decimal_value)}
assert decimal.Decimal(result.data["decimal"]) == decimal_value


def test_decimal_int_query():
int_value = 1234
decimal_value = decimal.Decimal(str(int_value))
result = schema.execute("""{ decimal(input: %s) }""" % int_value)
assert not result.errors
assert not result.errors
assert result.data == {"decimal": str(decimal_value)}
assert decimal.Decimal(result.data["decimal"]) == decimal_value


def test_decimal_string_query_variable():
decimal_value = decimal.Decimal("1969.1974")

Expand All @@ -35,6 +55,32 @@ def test_decimal_string_query_variable():
assert decimal.Decimal(result.data["decimal"]) == decimal_value


def test_decimal_float_query_variable():
float_value = 1969.1974
decimal_value = decimal.Decimal(str(float_value))

result = schema.execute(
"""query Test($decimal: Decimal){ decimal(input: $decimal) }""",
variables={"decimal": float_value},
)
assert not result.errors
assert result.data == {"decimal": str(decimal_value)}
assert decimal.Decimal(result.data["decimal"]) == decimal_value


def test_decimal_int_query_variable():
int_value = 1234
decimal_value = decimal.Decimal(str(int_value))

result = schema.execute(
"""query Test($decimal: Decimal){ decimal(input: $decimal) }""",
variables={"decimal": int_value},
)
assert not result.errors
assert result.data == {"decimal": str(decimal_value)}
assert decimal.Decimal(result.data["decimal"]) == decimal_value


def test_bad_decimal_query():
not_a_decimal = "Nobody expects the Spanish Inquisition!"

Expand All @@ -53,12 +99,6 @@ def test_bad_decimal_query():
assert result.data is None
assert result.errors[0].message == "Expected value of type 'Decimal', found true."

result = schema.execute("{ decimal(input: 1.2) }")
assert result.errors
assert len(result.errors) == 1
assert result.data is None
assert result.errors[0].message == "Expected value of type 'Decimal', found 1.2."


def test_decimal_string_query_integer():
decimal_value = 1
Expand Down

0 comments on commit 2da4618

Please sign in to comment.