Repository: strawberry-graphql/strawberry

Issue:
Decimal scalars aren't serialized as strings when passed as numbers
When using the `Decimal` scalar, if the value passed in is a floating point number, the value isn't serialized as a string, but as if it were still the floating point number which causes precision issues as can be seen in the working example below.


[Working example](https://la4de.github.io/strawberry-playground/#UEsDBAoAAAAAAFaAjFQgaUU4EgAAABIAAAAQAAAAcmVxdWlyZW1lbnRzLnR4dHN0cmF3YmVycnktZ3JhcGhxbFBLAwQKAAAAAABWgIxUj3TlatIAAADSAAAACQAAAHNjaGVtYS5weWltcG9ydCBzdHJhd2JlcnJ5CmZyb20gZGVjaW1hbCBpbXBvcnQgRGVjaW1hbAoKQHN0cmF3YmVycnkudHlwZQpjbGFzcyBRdWVyeToKICAgIEBzdHJhd2JlcnJ5LmZpZWxkCiAgICBkZWYgZGVjaW1hbChzZWxmLCB2YWx1ZTogRGVjaW1hbCkgLT4gRGVjaW1hbDoKICAgICAgICByZXR1cm4gdmFsdWUKCnNjaGVtYSA9IHN0cmF3YmVycnkuU2NoZW1hKHF1ZXJ5PVF1ZXJ5KVBLAwQKAAAAAABWgIxUERrh0UMAAABDAAAACQAAAHF1ZXJ5LmdxbHsKICBkZWNpbWFsKHZhbHVlOiAzLjE0KQogIGFub3RoZXJEZWNpbWFsOiBkZWNpbWFsKHZhbHVlOiAiMy4xNCIpCn1QSwMECgAAAAAAVoCMVKi7vnMDAAAAAwAAAA4AAAB2YXJpYWJsZXMuanNvbnsKfVBLAQIUAAoAAAAAAFaAjFQgaUU4EgAAABIAAAAQAAAAAAAAAAAAAAAAAAAAAAByZXF1aXJlbWVudHMudHh0UEsBAhQACgAAAAAAVoCMVI905WrSAAAA0gAAAAkAAAAAAAAAAAAAAAAAQAAAAHNjaGVtYS5weVBLAQIUAAoAAAAAAFaAjFQRGuHRQwAAAEMAAAAJAAAAAAAAAAAAAAAAADkBAABxdWVyeS5ncWxQSwECFAAKAAAAAABWgIxUqLu+cwMAAAADAAAADgAAAAAAAAAAAAAAAACjAQAAdmFyaWFibGVzLmpzb25QSwUGAAAAAAQABADoAAAA0gEAAAAA)

Actual output - `"3.140000000000000124344978758017532527446746826171875"`
Expected output - `"3.14"`

As text:

```
@strawberry.type
class DecimalResponse:
    value: Decimal


@strawberry.field
def decimals(
    dec_value: Decimal,
) -> DecimalResponse:
    return DecimalResponse(value=dec_value)
 ```
```
mutation decimals($dec_value: Decimal!) {
  decimals(
    decValue: $dec_value
  ) {
    ... on DecimalResponse {
      value
    }
  }
}
{
    "dec_value": 3.14
}
```



Discussion:

Resolving patch:
diff --git a/strawberry/schema/types/base_scalars.py b/strawberry/schema/types/base_scalars.py
--- a/strawberry/schema/types/base_scalars.py
+++ b/strawberry/schema/types/base_scalars.py
@@ -21,9 +21,9 @@ def inner(value: str):
     return inner
 
 
-def parse_decimal(value: str) -> decimal.Decimal:
+def parse_decimal(value: object) -> decimal.Decimal:
     try:
-        return decimal.Decimal(value)
+        return decimal.Decimal(str(value))
     except decimal.DecimalException:
         raise GraphQLError(f'Value cannot represent a Decimal: "{value}".')
 


Test patch:
diff --git a/tests/schema/test_scalars.py b/tests/schema/test_scalars.py
--- a/tests/schema/test_scalars.py
+++ b/tests/schema/test_scalars.py
@@ -1,4 +1,5 @@
 from datetime import datetime, timedelta, timezone
+from decimal import Decimal
 from textwrap import dedent
 from typing import Optional
 from uuid import UUID
@@ -383,3 +384,34 @@ def duration(self, value: timedelta) -> timedelta:
 
     assert not result.errors
     assert result.data == {"duration": 10}
+
+
+def test_decimal():
+    @strawberry.type
+    class Query:
+        @strawberry.field
+        def decimal(value: Decimal) -> Decimal:
+            return value
+
+    schema = strawberry.Schema(query=Query)
+
+    result = schema.execute_sync(
+        """
+        query {
+            floatDecimal: decimal(value: 3.14)
+            floatDecimal2: decimal(value: 3.14509999)
+            floatDecimal3: decimal(value: 0.000001)
+            stringDecimal: decimal(value: "3.14")
+            stringDecimal2: decimal(value: "3.1499999991")
+        }
+    """
+    )
+
+    assert not result.errors
+    assert result.data == {
+        "floatDecimal": "3.14",
+        "floatDecimal2": "3.14509999",
+        "floatDecimal3": "0.000001",
+        "stringDecimal": "3.14",
+        "stringDecimal2": "3.1499999991",
+    }