@@ -38,9 +38,6 @@ class Schema(object):
38
38
"""Represents an OpenAPI Schema."""
39
39
40
40
DEFAULT_CAST_CALLABLE_GETTER = {
41
- SchemaType .INTEGER : int ,
42
- SchemaType .NUMBER : float ,
43
- SchemaType .BOOLEAN : forcebool ,
44
41
}
45
42
46
43
STRING_FORMAT_CALLABLE_GETTER = {
@@ -148,27 +145,31 @@ def get_all_required_properties_names(self):
148
145
149
146
return set (required )
150
147
151
- def get_cast_mapping (self , custom_formatters = None ):
148
+ def get_cast_mapping (self , custom_formatters = None , strict = True ):
152
149
pass_defaults = lambda f : functools .partial (
153
- f , custom_formatters = custom_formatters )
150
+ f , custom_formatters = custom_formatters , strict = strict )
154
151
mapping = self .DEFAULT_CAST_CALLABLE_GETTER .copy ()
155
152
mapping .update ({
156
153
SchemaType .STRING : pass_defaults (self ._unmarshal_string ),
154
+ SchemaType .BOOLEAN : pass_defaults (self ._unmarshal_boolean ),
155
+ SchemaType .INTEGER : pass_defaults (self ._unmarshal_integer ),
156
+ SchemaType .NUMBER : pass_defaults (self ._unmarshal_number ),
157
157
SchemaType .ANY : pass_defaults (self ._unmarshal_any ),
158
158
SchemaType .ARRAY : pass_defaults (self ._unmarshal_collection ),
159
159
SchemaType .OBJECT : pass_defaults (self ._unmarshal_object ),
160
160
})
161
161
162
162
return defaultdict (lambda : lambda x : x , mapping )
163
163
164
- def cast (self , value , custom_formatters = None ):
164
+ def cast (self , value , custom_formatters = None , strict = True ):
165
165
"""Cast value to schema type"""
166
166
if value is None :
167
167
if not self .nullable :
168
168
raise InvalidSchemaValue ("Null value for non-nullable schema" , value , self .type )
169
169
return self .default
170
170
171
- cast_mapping = self .get_cast_mapping (custom_formatters = custom_formatters )
171
+ cast_mapping = self .get_cast_mapping (
172
+ custom_formatters = custom_formatters , strict = strict )
172
173
173
174
if self .type is not SchemaType .STRING and value == '' :
174
175
return None
@@ -180,12 +181,12 @@ def cast(self, value, custom_formatters=None):
180
181
raise InvalidSchemaValue (
181
182
"Failed to cast value {value} to type {type}" , value , self .type )
182
183
183
- def unmarshal (self , value , custom_formatters = None ):
184
+ def unmarshal (self , value , custom_formatters = None , strict = True ):
184
185
"""Unmarshal parameter from the value."""
185
186
if self .deprecated :
186
187
warnings .warn ("The schema is deprecated" , DeprecationWarning )
187
188
188
- casted = self .cast (value , custom_formatters = custom_formatters )
189
+ casted = self .cast (value , custom_formatters = custom_formatters , strict = strict )
189
190
190
191
if casted is None and not self .required :
191
192
return None
@@ -196,7 +197,10 @@ def unmarshal(self, value, custom_formatters=None):
196
197
197
198
return casted
198
199
199
- def _unmarshal_string (self , value , custom_formatters = None ):
200
+ def _unmarshal_string (self , value , custom_formatters = None , strict = True ):
201
+ if strict and not isinstance (value , (text_type , binary_type )):
202
+ raise InvalidSchemaValue ("Value {value} is not of type {type}" , value , self .type )
203
+
200
204
try :
201
205
schema_format = SchemaFormat (self .format )
202
206
except ValueError :
@@ -216,7 +220,25 @@ def _unmarshal_string(self, value, custom_formatters=None):
216
220
raise InvalidCustomFormatSchemaValue (
217
221
"Failed to format value {value} to format {type}: {exception}" , value , self .format , exc )
218
222
219
- def _unmarshal_any (self , value , custom_formatters = None ):
223
+ def _unmarshal_integer (self , value , custom_formatters = None , strict = True ):
224
+ if strict and not isinstance (value , (integer_types , )):
225
+ raise InvalidSchemaValue ("Value {value} is not of type {type}" , value , self .type )
226
+
227
+ return int (value )
228
+
229
+ def _unmarshal_number (self , value , custom_formatters = None , strict = True ):
230
+ if strict and not isinstance (value , (float , )):
231
+ raise InvalidSchemaValue ("Value {value} is not of type {type}" , value , self .type )
232
+
233
+ return float (value )
234
+
235
+ def _unmarshal_boolean (self , value , custom_formatters = None , strict = True ):
236
+ if strict and not isinstance (value , (bool , )):
237
+ raise InvalidSchemaValue ("Value {value} is not of type {type}" , value , self .type )
238
+
239
+ return forcebool (value )
240
+
241
+ def _unmarshal_any (self , value , custom_formatters = None , strict = True ):
220
242
types_resolve_order = [
221
243
SchemaType .OBJECT , SchemaType .ARRAY , SchemaType .BOOLEAN ,
222
244
SchemaType .INTEGER , SchemaType .NUMBER , SchemaType .STRING ,
@@ -232,16 +254,21 @@ def _unmarshal_any(self, value, custom_formatters=None):
232
254
233
255
raise NoValidSchema (value )
234
256
235
- def _unmarshal_collection (self , value , custom_formatters = None ):
257
+ def _unmarshal_collection (self , value , custom_formatters = None , strict = True ):
258
+ if not isinstance (value , (list , tuple )):
259
+ raise InvalidSchemaValue ("Value {value} is not of type {type}" , value , self .type )
260
+
236
261
if self .items is None :
237
262
raise UndefinedItemsSchema (self .type )
238
263
239
- f = functools .partial (self .items .unmarshal ,
240
- custom_formatters = custom_formatters )
264
+ f = functools .partial (
265
+ self .items .unmarshal ,
266
+ custom_formatters = custom_formatters , strict = strict ,
267
+ )
241
268
return list (map (f , value ))
242
269
243
270
def _unmarshal_object (self , value , model_factory = None ,
244
- custom_formatters = None ):
271
+ custom_formatters = None , strict = True ):
245
272
if not isinstance (value , (dict , )):
246
273
raise InvalidSchemaValue ("Value {value} is not of type {type}" , value , self .type )
247
274
@@ -270,7 +297,7 @@ def _unmarshal_object(self, value, model_factory=None,
270
297
return model_factory .create (properties , name = self .model )
271
298
272
299
def _unmarshal_properties (self , value , one_of_schema = None ,
273
- custom_formatters = None ):
300
+ custom_formatters = None , strict = True ):
274
301
all_props = self .get_all_properties ()
275
302
all_props_names = self .get_all_properties_names ()
276
303
all_req_props_names = self .get_all_required_properties_names ()
0 commit comments