Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 18 additions & 15 deletions jsonschema/_keywords.py
Original file line number Diff line number Diff line change
Expand Up @@ -169,21 +169,24 @@ def multipleOf(validator, dB, instance, schema):
return

if isinstance(dB, float):
quotient = instance / dB
try:
failed = int(quotient) != quotient
except OverflowError:
# When `instance` is large and `dB` is less than one,
# quotient can overflow to infinity; and then casting to int
# raises an error.
#
# In this case we fall back to Fraction logic, which is
# exact and cannot overflow. The performance is also
# acceptable: we try the fast all-float option first, and
# we know that fraction(dB) can have at most a few hundred
# digits in each part. The worst-case slowdown is therefore
# for already-slow enormous integers or Decimals.
failed = (Fraction(instance) / Fraction(dB)).denominator != 1
if dB.is_integer():
failed = instance % int(dB)
else:
quotient = instance / dB
try:
failed = int(quotient) != quotient
except OverflowError:
# When `instance` is large and `dB` is less than one,
# quotient can overflow to infinity; and then casting to int
# raises an error.
#
# In this case we fall back to Fraction logic, which is
# exact and cannot overflow. The performance is also
# acceptable: we try the fast all-float option first, and
# we know that fraction(dB) can have at most a few hundred
# digits in each part. The worst-case slowdown is therefore
# for already-slow enormous integers or Decimals.
failed = (Fraction(instance) / Fraction(dB)).denominator != 1
else:
failed = instance % dB

Expand Down
5 changes: 5 additions & 0 deletions jsonschema/tests/test_validators.py
Original file line number Diff line number Diff line change
Expand Up @@ -1667,6 +1667,11 @@ def test_invalid_instances_are_not_valid(self):
schema, instance = self.invalid
self.assertFalse(self.Validator(schema).is_valid(instance))

def test_large_integer_multiple_of_integer_valued_float(self):
schema = {"type": "integer", "multipleOf": 11.0}
instance = 9007199254740995
self.assertTrue(self.Validator(schema).is_valid(instance))

def test_non_existent_properties_are_ignored(self):
self.Validator({object(): object()}).validate(instance=object())

Expand Down
Loading