summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulian Berman <Julian@GrayVines.com>2020-10-04 20:04:22 -0400
committerGitHub <noreply@github.com>2020-10-04 20:04:22 -0400
commite48d56cbd2b6c25d4a9483f53f79ec537b9a4a34 (patch)
tree455dc97d7269efcbd24c4d831ce5fccaafa34d13
parent58259e7a9fc1d8ef0602c06060bba4607c99bd90 (diff)
parent46db62a373ccc3d75fefd36f97a5fa8fcafedac4 (diff)
downloadjsonschema-e48d56cbd2b6c25d4a9483f53f79ec537b9a4a34.tar.gz
Merge pull request #746 from Zac-HD/multipleOf-overflow
Handle `multipleOf` overflow
-rw-r--r--jsonschema/_validators.py14
-rw-r--r--jsonschema/tests/test_jsonschema_test_suite.py39
2 files changed, 13 insertions, 40 deletions
diff --git a/jsonschema/_validators.py b/jsonschema/_validators.py
index d7097ff..7e8c95a 100644
--- a/jsonschema/_validators.py
+++ b/jsonschema/_validators.py
@@ -1,3 +1,4 @@
+from fractions import Fraction
import re
from jsonschema._utils import (
@@ -166,7 +167,18 @@ def multipleOf(validator, dB, instance, schema):
if isinstance(dB, float):
quotient = instance / dB
- failed = int(quotient) != quotient
+ 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
diff --git a/jsonschema/tests/test_jsonschema_test_suite.py b/jsonschema/tests/test_jsonschema_test_suite.py
index d6721b5..0f9698a 100644
--- a/jsonschema/tests/test_jsonschema_test_suite.py
+++ b/jsonschema/tests/test_jsonschema_test_suite.py
@@ -161,7 +161,6 @@ TestDraft4 = DRAFT4.to_unittest_testcase(
DRAFT4.tests(),
DRAFT4.format_tests(),
DRAFT4.optional_tests_of(name="bignum"),
- DRAFT4.optional_tests_of(name="float-overflow"),
DRAFT4.optional_tests_of(name="non-bmp-regex"),
DRAFT4.optional_tests_of(name="zeroTerminatedFloats"),
Validator=Draft4Validator,
@@ -235,18 +234,6 @@ TestDraft4 = DRAFT4.to_unittest_testcase(
subject="uniqueItems",
description='{"a": true} and {"a": 1} are unique',
)(test)
- or skip(
- message=bug(743),
- subject="float-overflow",
- )(test)
- or skip(
- message=bug(743),
- subject="multipleOf",
- description=(
- "always invalid, but naive implementations "
- "may raise an overflow error"
- ),
- )(test)
),
)
@@ -255,7 +242,6 @@ TestDraft6 = DRAFT6.to_unittest_testcase(
DRAFT6.tests(),
DRAFT6.format_tests(),
DRAFT6.optional_tests_of(name="bignum"),
- DRAFT6.optional_tests_of(name="float-overflow"),
DRAFT6.optional_tests_of(name="non-bmp-regex"),
Validator=Draft6Validator,
format_checker=draft6_format_checker,
@@ -348,18 +334,6 @@ TestDraft6 = DRAFT6.to_unittest_testcase(
subject="const",
case_description='const with {"a": true} does not match {"a": 1}',
)(test)
- or skip(
- message=bug(743),
- subject="float-overflow",
- )(test)
- or skip(
- message=bug(743),
- subject="multipleOf",
- description=(
- "always invalid, but naive implementations "
- "may raise an overflow error"
- ),
- )(test)
),
)
@@ -368,7 +342,6 @@ TestDraft7 = DRAFT7.to_unittest_testcase(
DRAFT7.tests(),
DRAFT7.format_tests(),
DRAFT7.optional_tests_of(name="bignum"),
- DRAFT7.optional_tests_of(name="float-overflow"),
DRAFT7.optional_tests_of(name="content"),
DRAFT7.optional_tests_of(name="non-bmp-regex"),
Validator=Draft7Validator,
@@ -484,18 +457,6 @@ TestDraft7 = DRAFT7.to_unittest_testcase(
subject="const",
case_description='const with {"a": true} does not match {"a": 1}',
)(test)
- or skip(
- message=bug(743),
- subject="float-overflow",
- )(test)
- or skip(
- message=bug(743),
- subject="multipleOf",
- description=(
- "always invalid, but naive implementations "
- "may raise an overflow error"
- ),
- )(test)
),
)