You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I have a problem when I use msgspec and Decimal. One popular solution to using Decimal is to not round the data as part of the algorithm execution and domain layer. The rounding happens during demarshaling at the API endpoints. Decimal is the native type, so it's not possible to create an Encoder that can handle this.
Is it possible to change the behaviour for Decimal and allow interception in enc_hook?
Example:
fromdecimalimportROUND_HALF_UP, DecimalfromtypingimportAnyimportmsgspecdefenc_hook(obj: Any) ->Any:
ifisinstance(obj, Decimal):
returnstr(obj.quantize(Decimal("0.0001"), rounding=ROUND_HALF_UP))
else:
raiseNotImplementedError(f"Objects of type {type(obj)} are not supported")
classPrice(msgspec.Struct):
primecost: Decimalenc=msgspec.json.Encoder(enc_hook=enc_hook)
price=Price(primecost=Decimal("1.1234444"))
buf=enc.encode(price)
# b'{"primecost":"1.1234"}'
Creating a custom Decimal MyDecimal looks like a workaround.
Activity
[-]Decimal should be handled as a custom type during demarshaling.[/-][+]Decimal is a custom type[/+][-]Decimal is a custom type[/-][+]`Decimal` is a custom type[/+]JimDabell commentedon Aug 4, 2025
See also #829 and #849.
Add callable support for `decimal_format` option (msgspec#978)