@@ -38,9 +38,6 @@ class Schema(object):
3838 """Represents an OpenAPI Schema."""
3939
4040 DEFAULT_CAST_CALLABLE_GETTER = {
41- SchemaType .INTEGER : int ,
42- SchemaType .NUMBER : float ,
43- SchemaType .BOOLEAN : forcebool ,
4441 }
4542
4643 STRING_FORMAT_CALLABLE_GETTER = {
@@ -148,27 +145,31 @@ def get_all_required_properties_names(self):
148145
149146 return set (required )
150147
151- def get_cast_mapping (self , custom_formatters = None ):
148+ def get_cast_mapping (self , custom_formatters = None , strict = True ):
152149 pass_defaults = lambda f : functools .partial (
153- f , custom_formatters = custom_formatters )
150+ f , custom_formatters = custom_formatters , strict = strict )
154151 mapping = self .DEFAULT_CAST_CALLABLE_GETTER .copy ()
155152 mapping .update ({
156153 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 ),
157157 SchemaType .ANY : pass_defaults (self ._unmarshal_any ),
158158 SchemaType .ARRAY : pass_defaults (self ._unmarshal_collection ),
159159 SchemaType .OBJECT : pass_defaults (self ._unmarshal_object ),
160160 })
161161
162162 return defaultdict (lambda : lambda x : x , mapping )
163163
164- def cast (self , value , custom_formatters = None ):
164+ def cast (self , value , custom_formatters = None , strict = True ):
165165 """Cast value to schema type"""
166166 if value is None :
167167 if not self .nullable :
168168 raise InvalidSchemaValue ("Null value for non-nullable schema" , value , self .type )
169169 return self .default
170170
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 )
172173
173174 if self .type is not SchemaType .STRING and value == '' :
174175 return None
@@ -180,12 +181,12 @@ def cast(self, value, custom_formatters=None):
180181 raise InvalidSchemaValue (
181182 "Failed to cast value {value} to type {type}" , value , self .type )
182183
183- def unmarshal (self , value , custom_formatters = None ):
184+ def unmarshal (self , value , custom_formatters = None , strict = True ):
184185 """Unmarshal parameter from the value."""
185186 if self .deprecated :
186187 warnings .warn ("The schema is deprecated" , DeprecationWarning )
187188
188- casted = self .cast (value , custom_formatters = custom_formatters )
189+ casted = self .cast (value , custom_formatters = custom_formatters , strict = strict )
189190
190191 if casted is None and not self .required :
191192 return None
@@ -196,7 +197,10 @@ def unmarshal(self, value, custom_formatters=None):
196197
197198 return casted
198199
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+
200204 try :
201205 schema_format = SchemaFormat (self .format )
202206 except ValueError :
@@ -216,7 +220,25 @@ def _unmarshal_string(self, value, custom_formatters=None):
216220 raise InvalidCustomFormatSchemaValue (
217221 "Failed to format value {value} to format {type}: {exception}" , value , self .format , exc )
218222
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 ):
220242 types_resolve_order = [
221243 SchemaType .OBJECT , SchemaType .ARRAY , SchemaType .BOOLEAN ,
222244 SchemaType .INTEGER , SchemaType .NUMBER , SchemaType .STRING ,
@@ -232,16 +254,21 @@ def _unmarshal_any(self, value, custom_formatters=None):
232254
233255 raise NoValidSchema (value )
234256
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+
236261 if self .items is None :
237262 raise UndefinedItemsSchema (self .type )
238263
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+ )
241268 return list (map (f , value ))
242269
243270 def _unmarshal_object (self , value , model_factory = None ,
244- custom_formatters = None ):
271+ custom_formatters = None , strict = True ):
245272 if not isinstance (value , (dict , )):
246273 raise InvalidSchemaValue ("Value {value} is not of type {type}" , value , self .type )
247274
@@ -270,7 +297,7 @@ def _unmarshal_object(self, value, model_factory=None,
270297 return model_factory .create (properties , name = self .model )
271298
272299 def _unmarshal_properties (self , value , one_of_schema = None ,
273- custom_formatters = None ):
300+ custom_formatters = None , strict = True ):
274301 all_props = self .get_all_properties ()
275302 all_props_names = self .get_all_properties_names ()
276303 all_req_props_names = self .get_all_required_properties_names ()
0 commit comments