Skip to content

Commit 63f3ffb

Browse files
committed
Number format added
1 parent 3339e13 commit 63f3ffb

File tree

3 files changed

+60
-4
lines changed

3 files changed

+60
-4
lines changed

openapi_core/schema/schemas/models.py

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
)
2121
from openapi_core.schema.schemas.util import (
2222
forcebool, format_date, format_datetime, format_byte, format_uuid,
23+
format_number,
2324
)
2425
from openapi_core.schema.schemas.validators import (
2526
TypeValidator, AttributeValidator,
@@ -50,11 +51,19 @@ class Schema(object):
5051
SchemaFormat.BYTE: Format(format_byte, TypeValidator(text_type)),
5152
}
5253

54+
NUMBER_FORMAT_CALLABLE_GETTER = {
55+
SchemaFormat.NONE: Format(format_number, TypeValidator(
56+
integer_types + (float, ), exclude=bool)),
57+
SchemaFormat.FLOAT: Format(float, TypeValidator(float)),
58+
SchemaFormat.DOUBLE: Format(float, TypeValidator(float)),
59+
}
60+
5361
TYPE_VALIDATOR_CALLABLE_GETTER = {
5462
SchemaType.ANY: lambda x: True,
5563
SchemaType.BOOLEAN: TypeValidator(bool),
5664
SchemaType.INTEGER: TypeValidator(integer_types, exclude=bool),
57-
SchemaType.NUMBER: TypeValidator(integer_types + (float, ), exclude=bool),
65+
SchemaType.NUMBER: TypeValidator(
66+
integer_types + (float, ), exclude=bool),
5867
SchemaType.STRING: TypeValidator(
5968
text_type, date, datetime, binary_type, UUID),
6069
SchemaType.ARRAY: TypeValidator(list, tuple),
@@ -237,7 +246,24 @@ def _unmarshal_number(self, value, custom_formatters=None, strict=True):
237246
if strict and not isinstance(value, (float, ) + integer_types):
238247
raise InvalidSchemaValue("Value {value} is not of type {type}", value, self.type)
239248

240-
return value
249+
try:
250+
schema_format = SchemaFormat(self.format)
251+
except ValueError:
252+
msg = "Unsupported format {type} unmarshalling for value {value}"
253+
if custom_formatters is not None:
254+
formatnumber = custom_formatters.get(self.format)
255+
if formatnumber is None:
256+
raise InvalidSchemaValue(msg, value, self.format)
257+
else:
258+
raise InvalidSchemaValue(msg, value, self.format)
259+
else:
260+
formatnumber = self.NUMBER_FORMAT_CALLABLE_GETTER[schema_format]
261+
262+
try:
263+
return formatnumber.unmarshal(value)
264+
except ValueError as exc:
265+
raise InvalidCustomFormatSchemaValue(
266+
"Failed to format value {value} to format {type}: {exception}", value, self.format, exc)
241267

242268
def _unmarshal_boolean(self, value, custom_formatters=None, strict=True):
243269
if strict and not isinstance(value, (bool, )):

openapi_core/schema/schemas/util.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import datetime
44
from distutils.util import strtobool
55
from json import dumps
6-
from six import string_types, text_type
6+
from six import string_types, text_type, integer_types
77
import strict_rfc3339
88
from uuid import UUID
99

@@ -36,3 +36,10 @@ def format_uuid(value):
3636

3737
def format_byte(value, encoding='utf8'):
3838
return text_type(b64decode(value), encoding)
39+
40+
41+
def format_number(value):
42+
if isinstance(value, integer_types + (float, )):
43+
return value
44+
45+
return float(value)

tests/unit/schema/test_schemas.py

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -267,7 +267,30 @@ def test_number_int(self):
267267
value = 1
268268
result = schema.unmarshal(value)
269269

270-
assert result == value
270+
assert result == 1
271+
assert type(result) == int
272+
273+
def test_number_float(self):
274+
schema = Schema('number')
275+
value = 1.2
276+
result = schema.unmarshal(value)
277+
278+
assert result == 1.2
279+
assert type(result) == float
280+
281+
def test_number_format_float(self):
282+
schema = Schema('number', schema_format='float')
283+
value = 1.2
284+
result = schema.unmarshal(value)
285+
286+
assert result == 1.2
287+
288+
def test_number_format_double(self):
289+
schema = Schema('number', schema_format='double')
290+
value = 1.2
291+
result = schema.unmarshal(value)
292+
293+
assert result == 1.2
271294

272295

273296
class TestSchemaValidate(object):

0 commit comments

Comments
 (0)