Closed qhelix7 closed 2 years ago
@qhelix7 -
The eval
portion of the deserializer is quite an old bit of code - some of the first ever written for this library. I'm more than happy to try another approach, as it has its drawbacks, which you so clearly illustrate here!
If you have a PR with a proposed solution that solves these cases you mention here then I would love for you to submit it. I'll keep an eye out for your submission 👍
Description
I am looking for a Python library that simplifies serialization between CSV / JSON data and dataclasses. I really like the approach you have taken with Typical, however, I am having trouble with Decimal data because it gets coerced to float.
In my experience, when I use a Decimal type it is because float is unacceptable -- not less-than-ideal, but actually unusable:
Decimal (BigInteger, BigNumber, Numeric, etc.) values are usually serialized to strings for these reasons -- at least for human-readable formats such as JSON and CSV. Some sort of binary representation could be used, but casting to traditional primitive types like float, double, int64, etc. defeats the purposes of using Decimal.
What I Did
When deserializing floating-point numbers to Decimal, rounding errors are to be expected, but this also happens when the input data is a string:
Deserialization works for big numbers without a decimal point, but breaks for serialization due to internal float coercion:
The main issue is that the generated code is doing an eval for string values which causes Python to interpret them as int or float literals before the code has a chance to convert them to Decimal.
The eval also makes it problematic to try to do something like define a custom type that subclasses Decimal.
I have a pull request to address these issues. Let me know what you think.