python-jsonschema / jsonschema

An implementation of the JSON Schema specification for Python
https://python-jsonschema.readthedocs.io
MIT License
4.52k stars 574 forks source link

Enhancing the multipleOf Validator for Improved Decimal Handling in jsonschema #1239

Closed PaschalisDim closed 4 months ago

PaschalisDim commented 4 months ago

The current implementation of the multipleOf function within the jsonschema library is designed to determine if a given instance is a multiple of a specified value. This function checks if the instance is of type float and then proceeds with the division and comparison operations. However, this implementation does not account for decimal numbers explicitly, which can lead to inaccuracies when dealing with high-precision decimal calculations.

To address this issue, I propose enhancing the condition within the multipleOf function to include checks for instances of the decimal.Decimal type.

if isinstance(dB, float):
    quotient = instance / dB
    try:
        failed = int(quotient) != quotient
    except OverflowError:

        failed = (Fraction(instance) / Fraction(dB)).denominator != 1
else:
    failed = instance % dB

if failed:
    yield ValidationError(f"{instance!r} is not a multiple of {dB}")
Julian commented 4 months ago

Hi there. Please see previous issues on the topic -- no changes are needed in the library here to do this. If you care about precision, deserialize your JSON using decimal.Decimal or Fraction yourself, before handing it off here to this library, and then everything works as you'd like!

(And for everyone else who doesn't care or prefers floats for performance, they too can get what they want).