Added support for RFC 7159

* Min and max numbers are "configurable" (by overriding them)
* Enforcement can be disabled by setting flag to false
This commit is contained in:
Rafael Sierra 2019-05-27 20:48:01 +02:00
parent 10a0b42b74
commit 8d63adcff0
2 changed files with 32 additions and 0 deletions

View File

@ -19,6 +19,11 @@ class JSONEncoder(json.JSONEncoder):
JSONEncoder subclass that knows how to encode date/time/timedelta,
decimal types, generators and other basic python objects.
"""
enforce_rfc7159_numbers = True
rfc7159_min_number = -(2**53) + 1
rfc7159_max_number = (2**53) - 1
def default(self, obj):
# For Date Time string spec, see ECMA 262
# https://ecma-international.org/ecma-262/5.1/#sec-15.9.1.15
@ -63,4 +68,17 @@ class JSONEncoder(json.JSONEncoder):
pass
elif hasattr(obj, '__iter__'):
return tuple(item for item in obj)
elif isinstance(obj, int):
# If RFC-7159 is enforced, numbers must not be outside its range
if self.enforce_rfc7159_numbers and not (
self.rfc7159_min_number <= obj <= self.rfc7159_max_number
):
raise ValueError(
"Cannot render number {} as integer if RFC 7159 is enforced. "
"Value must be between {} and {}".format(
obj, self.rfc7159_min_number, self.rfc7159_max_number
)
)
else:
return obj
return super().default(obj)

View File

@ -93,3 +93,17 @@ class JSONEncoderTests(TestCase):
"""
foo = MockList()
assert self.encoder.default(foo) == [1, 2, 3]
def test_encode_int_outside_rfc7159_range(self):
# Values lower than minimum allowed must fail
with pytest.raises(ValueError):
self.encoder.default(self.encoder.rfc7159_min_number - 1)
# Values greater than maximum allowed must fail
with pytest.raises(ValueError):
self.encoder.default(self.encoder.rfc7159_max_number + 1)
# Values within RFC 7159 range are allowed
self.encoder.default(self.encoder.rfc7159_min_number) == self.encoder.rfc7159_min_number
self.encoder.default(self.encoder.rfc7159_max_number) == self.encoder.rfc7159_max_number
self.encoder.default(42) == 42