33from  typing  import  TYPE_CHECKING 
44from  typing  import  Any 
55from  typing  import  Iterable 
6+ from  typing  import  Iterator 
67from  typing  import  List 
78from  typing  import  Optional 
89from  typing  import  cast 
3132)
3233from  openapi_core .unmarshalling .schemas .exceptions  import  InvalidSchemaValue 
3334from  openapi_core .unmarshalling .schemas .exceptions  import  UnmarshalError 
35+ from  openapi_core .unmarshalling .schemas .exceptions  import  UnmarshallerError 
3436from  openapi_core .unmarshalling .schemas .exceptions  import  ValidateError 
3537from  openapi_core .unmarshalling .schemas .formatters  import  Formatter 
3638from  openapi_core .unmarshalling .schemas .util  import  format_byte 
@@ -61,24 +63,25 @@ def __init__(
6163    ):
6264        self .schema  =  schema 
6365        self .validator  =  validator 
64-         self .format  =  schema .getkey ("format" )
66+         self .schema_format  =  schema .getkey ("format" )
6567
6668        if  formatter  is  None :
67-             if  self .format  not  in self .FORMATTERS :
68-                 raise  FormatterNotFoundError (self .format )
69-             self .formatter  =  self .FORMATTERS [self .format ]
69+             if  self .schema_format  not  in self .FORMATTERS :
70+                 raise  FormatterNotFoundError (self .schema_format )
71+             self .formatter  =  self .FORMATTERS [self .schema_format ]
7072        else :
7173            self .formatter  =  formatter 
7274
7375    def  __call__ (self , value : Any ) ->  Any :
74-         if  value  is  None :
75-             return 
76- 
7776        self .validate (value )
7877
78+         # skip unmarshalling for nullable in OpenAPI 3.0 
79+         if  value  is  None  and  self .schema .getkey ("nullable" , False ):
80+             return  value 
81+ 
7982        return  self .unmarshal (value )
8083
81-     def  _formatter_validate (self , value : Any ) ->  None :
84+     def  _validate_format (self , value : Any ) ->  None :
8285        result  =  self .formatter .validate (value )
8386        if  not  result :
8487            schema_type  =  self .schema .getkey ("type" , "any" )
@@ -91,11 +94,14 @@ def validate(self, value: Any) -> None:
9194            schema_type  =  self .schema .getkey ("type" , "any" )
9295            raise  InvalidSchemaValue (value , schema_type , schema_errors = errors )
9396
94-     def  unmarshal (self , value : Any ) ->  Any :
97+     def  format (self , value : Any ) ->  Any :
9598        try :
96-             return  self .formatter .unmarshal (value )
97-         except  ValueError  as  exc :
98-             raise  InvalidSchemaFormatValue (value , self .format , exc )
99+             return  self .formatter .format (value )
100+         except  (ValueError , TypeError ) as  exc :
101+             raise  InvalidSchemaFormatValue (value , self .schema_format , exc )
102+ 
103+     def  unmarshal (self , value : Any ) ->  Any :
104+         return  self .format (value )
99105
100106
101107class  StringUnmarshaller (BaseSchemaUnmarshaller ):
@@ -192,10 +198,8 @@ def items_unmarshaller(self) -> "BaseSchemaUnmarshaller":
192198        items_schema  =  self .schema .get ("items" , Spec .from_dict ({}))
193199        return  self .unmarshallers_factory .create (items_schema )
194200
195-     def  __call__ (self , value : Any ) ->  Optional [List [Any ]]:
196-         value  =  super ().__call__ (value )
197-         if  value  is  None  and  self .schema .getkey ("nullable" , False ):
198-             return  None 
201+     def  unmarshal (self , value : Any ) ->  Optional [List [Any ]]:
202+         value  =  super ().unmarshal (value )
199203        return  list (map (self .items_unmarshaller , value ))
200204
201205
@@ -210,38 +214,31 @@ def object_class_factory(self) -> ModelPathFactory:
210214        return  ModelPathFactory ()
211215
212216    def  unmarshal (self , value : Any ) ->  Any :
213-         properties  =  self .unmarshal_raw (value )
217+         properties  =  self .format (value )
214218
215219        fields : Iterable [str ] =  properties  and  properties .keys () or  []
216220        object_class  =  self .object_class_factory .create (self .schema , fields )
217221
218222        return  object_class (** properties )
219223
220-     def  unmarshal_raw (self , value : Any ) ->  Any :
221-         try :
222-             value  =  self .formatter .unmarshal (value )
223-         except  ValueError  as  exc :
224-             schema_format  =  self .schema .getkey ("format" )
225-             raise  InvalidSchemaFormatValue (value , schema_format , exc )
226-         else :
227-             return  self ._unmarshal_object (value )
224+     def  format (self , value : Any ) ->  Any :
225+         formatted  =  super ().format (value )
226+         return  self ._unmarshal_properties (formatted )
228227
229228    def  _clone (self , schema : Spec ) ->  "ObjectUnmarshaller" :
230229        return  cast (
231230            "ObjectUnmarshaller" ,
232231            self .unmarshallers_factory .create (schema , "object" ),
233232        )
234233
235-     def  _unmarshal_object (self , value : Any ) ->  Any :
234+     def  _unmarshal_properties (self , value : Any ) ->  Any :
236235        properties  =  {}
237236
238237        if  "oneOf"  in  self .schema :
239238            one_of_properties  =  None 
240239            for  one_of_schema  in  self .schema  /  "oneOf" :
241240                try :
242-                     unmarshalled  =  self ._clone (one_of_schema ).unmarshal_raw (
243-                         value 
244-                     )
241+                     unmarshalled  =  self ._clone (one_of_schema ).format (value )
245242                except  (UnmarshalError , ValueError ):
246243                    pass 
247244                else :
@@ -259,9 +256,7 @@ def _unmarshal_object(self, value: Any) -> Any:
259256            any_of_properties  =  None 
260257            for  any_of_schema  in  self .schema  /  "anyOf" :
261258                try :
262-                     unmarshalled  =  self ._clone (any_of_schema ).unmarshal_raw (
263-                         value 
264-                     )
259+                     unmarshalled  =  self ._clone (any_of_schema ).format (value )
265260                except  (UnmarshalError , ValueError ):
266261                    pass 
267262                else :
@@ -319,21 +314,36 @@ def types_unmarshallers(self) -> List["BaseSchemaUnmarshaller"]:
319314        unmarshaller  =  partial (self .unmarshallers_factory .create , self .schema )
320315        return  list (map (unmarshaller , types ))
321316
322-     def  unmarshal (self , value : Any ) ->  Any :
323-         for  unmarshaller  in  self .types_unmarshallers :
317+     @property  
318+     def  type (self ) ->  List [str ]:
319+         types  =  self .schema .getkey ("type" , ["any" ])
320+         assert  isinstance (types , list )
321+         return  types 
322+ 
323+     def  _get_unmarshallers_iter (self ) ->  Iterator ["BaseSchemaUnmarshaller" ]:
324+         for  schema_type  in  self .type :
325+             yield  self .unmarshallers_factory .create (
326+                 self .schema , type_override = schema_type 
327+             )
328+ 
329+     def  _get_best_unmarshaller (self , value : Any ) ->  "BaseSchemaUnmarshaller" :
330+         for  unmarshaller  in  self ._get_unmarshallers_iter ():
324331            # validate with validator of formatter (usualy type validator) 
325332            try :
326-                 unmarshaller ._formatter_validate (value )
333+                 unmarshaller ._validate_format (value )
327334            except  ValidateError :
328335                continue 
329336            else :
330-                 return  unmarshaller ( value ) 
337+                 return  unmarshaller 
331338
332-         log .warning ("failed to unmarshal multi type" )
333-         return  value 
339+         raise  UnmarshallerError ("Unmarshaller not found for type(s)" )
340+ 
341+     def  unmarshal (self , value : Any ) ->  Any :
342+         unmarshaller  =  self ._get_best_unmarshaller (value )
343+         return  unmarshaller (value )
334344
335345
336- class  AnyUnmarshaller (ComplexUnmarshaller ):
346+ class  AnyUnmarshaller (MultiTypeUnmarshaller ):
337347
338348    SCHEMA_TYPES_ORDER  =  [
339349        "object" ,
@@ -344,6 +354,10 @@ class AnyUnmarshaller(ComplexUnmarshaller):
344354        "string" ,
345355    ]
346356
357+     @property  
358+     def  type (self ) ->  List [str ]:
359+         return  self .SCHEMA_TYPES_ORDER 
360+ 
347361    def  unmarshal (self , value : Any ) ->  Any :
348362        one_of_schema  =  self ._get_one_of_schema (value )
349363        if  one_of_schema :
@@ -357,20 +371,7 @@ def unmarshal(self, value: Any) -> Any:
357371        if  all_of_schema :
358372            return  self .unmarshallers_factory .create (all_of_schema )(value )
359373
360-         for  schema_type  in  self .SCHEMA_TYPES_ORDER :
361-             unmarshaller  =  self .unmarshallers_factory .create (
362-                 self .schema , type_override = schema_type 
363-             )
364-             # validate with validator of formatter (usualy type validator) 
365-             try :
366-                 unmarshaller ._formatter_validate (value )
367-             except  ValidateError :
368-                 continue 
369-             else :
370-                 return  unmarshaller (value )
371- 
372-         log .warning ("failed to unmarshal any type" )
373-         return  value 
374+         return  super ().unmarshal (value )
374375
375376    def  _get_one_of_schema (self , value : Any ) ->  Optional [Spec ]:
376377        if  "oneOf"  not  in self .schema :
0 commit comments