mirror of
https://github.com/encode/django-rest-framework.git
synced 2025-07-31 10:30:01 +03:00
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:
parent
10a0b42b74
commit
8d63adcff0
|
@ -19,6 +19,11 @@ class JSONEncoder(json.JSONEncoder):
|
||||||
JSONEncoder subclass that knows how to encode date/time/timedelta,
|
JSONEncoder subclass that knows how to encode date/time/timedelta,
|
||||||
decimal types, generators and other basic python objects.
|
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):
|
def default(self, obj):
|
||||||
# For Date Time string spec, see ECMA 262
|
# For Date Time string spec, see ECMA 262
|
||||||
# https://ecma-international.org/ecma-262/5.1/#sec-15.9.1.15
|
# https://ecma-international.org/ecma-262/5.1/#sec-15.9.1.15
|
||||||
|
@ -63,4 +68,17 @@ class JSONEncoder(json.JSONEncoder):
|
||||||
pass
|
pass
|
||||||
elif hasattr(obj, '__iter__'):
|
elif hasattr(obj, '__iter__'):
|
||||||
return tuple(item for item in obj)
|
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)
|
return super().default(obj)
|
||||||
|
|
|
@ -93,3 +93,17 @@ class JSONEncoderTests(TestCase):
|
||||||
"""
|
"""
|
||||||
foo = MockList()
|
foo = MockList()
|
||||||
assert self.encoder.default(foo) == [1, 2, 3]
|
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
|
||||||
|
|
Loading…
Reference in New Issue
Block a user