99import warnings
1010
1111from six import iteritems , integer_types , binary_type , text_type
12+ from jsonschema .exceptions import ValidationError
1213
1314from openapi_core .extensions .models .factories import ModelFactory
15+ from openapi_core .schema .schemas ._format import oas30_format_checker
1416from openapi_core .schema .schemas .enums import SchemaFormat , SchemaType
1517from openapi_core .schema .schemas .exceptions import (
1618 InvalidSchemaValue , UndefinedSchemaProperty , MissingSchemaProperty ,
2325 format_number ,
2426)
2527from openapi_core .schema .schemas .validators import (
26- TypeValidator , AttributeValidator ,
28+ TypeValidator , AttributeValidator , OAS30Validator ,
2729)
2830
2931log = logging .getLogger (__name__ )
@@ -85,7 +87,7 @@ def __init__(
8587 min_length = None , max_length = None , pattern = None , unique_items = False ,
8688 minimum = None , maximum = None , multiple_of = None ,
8789 exclusive_minimum = False , exclusive_maximum = False ,
88- min_properties = None , max_properties = None ):
90+ min_properties = None , max_properties = None , _source = None ):
8991 self .type = SchemaType (schema_type )
9092 self .model = model
9193 self .properties = properties and dict (properties ) or {}
@@ -119,6 +121,8 @@ def __init__(
119121 self ._all_required_properties_cache = None
120122 self ._all_optional_properties_cache = None
121123
124+ self ._source = _source
125+
122126 def __getitem__ (self , name ):
123127 return self .properties [name ]
124128
@@ -214,6 +218,18 @@ def get_unmarshal_mapping(self, custom_formatters=None, strict=True):
214218
215219 return defaultdict (lambda : lambda x : x , mapping )
216220
221+ def get_validator (self , resolver = None ):
222+ return OAS30Validator (
223+ self ._source , resolver = resolver , format_checker = oas30_format_checker )
224+
225+ def validate (self , value , resolver = None ):
226+ validator = self .get_validator (resolver = resolver )
227+ try :
228+ return validator .validate (value )
229+ except ValidationError :
230+ # TODO: pass validation errors
231+ raise InvalidSchemaValue ("Value not valid for schema" , value , self .type )
232+
217233 def unmarshal (self , value , custom_formatters = None , strict = True ):
218234 """Unmarshal parameter from the value."""
219235 if self .deprecated :
@@ -241,10 +257,7 @@ def unmarshal(self, value, custom_formatters=None, strict=True):
241257 "Value {value} is not of type {type}" , value , self .type )
242258 except ValueError :
243259 raise InvalidSchemaValue (
244- "Failed to cast value {value} to type {type}" , value , self .type )
245-
246- if unmarshalled is None and not self .required :
247- return None
260+ "Failed to unmarshal value {value} to type {type}" , value , self .type )
248261
249262 return unmarshalled
250263
@@ -297,8 +310,7 @@ def _unmarshal_any(self, value, custom_formatters=None, strict=True):
297310 return unmarshal_callable (value )
298311 except UnmarshallerStrictTypeError :
299312 continue
300- # @todo: remove ValueError when validation separated
301- except (OpenAPISchemaError , TypeError , ValueError ):
313+ except (OpenAPISchemaError , TypeError ):
302314 continue
303315
304316 raise NoValidSchema (value )
@@ -307,9 +319,6 @@ def _unmarshal_collection(self, value, custom_formatters=None, strict=True):
307319 if not isinstance (value , (list , tuple )):
308320 raise InvalidSchemaValue ("Value {value} is not of type {type}" , value , self .type )
309321
310- if self .items is None :
311- raise UndefinedItemsSchema (self .type )
312-
313322 f = functools .partial (
314323 self .items .unmarshal ,
315324 custom_formatters = custom_formatters , strict = strict ,
0 commit comments