From 05da0e45a8feb2c66815aa35850acf8efaa6747c Mon Sep 17 00:00:00 2001 From: p1c2u Date: Mon, 24 Apr 2023 12:14:43 +0100 Subject: [PATCH] multi types schema format unmarshal fix --- .../unmarshalling/schemas/unmarshallers.py | 16 +++++++++------- .../unmarshalling/test_unmarshallers.py | 19 +++++++++++++++++++ 2 files changed, 28 insertions(+), 7 deletions(-) diff --git a/openapi_core/unmarshalling/schemas/unmarshallers.py b/openapi_core/unmarshalling/schemas/unmarshallers.py index 27c63179..a97abb93 100644 --- a/openapi_core/unmarshalling/schemas/unmarshallers.py +++ b/openapi_core/unmarshalling/schemas/unmarshallers.py @@ -228,12 +228,10 @@ def unmarshal(self, schema_format: str, value: Any) -> Any: return value try: return format_unmarshaller(value) - except (ValueError, TypeError) as exc: - raise FormatUnmarshalError(value, schema_format, exc) + except (ValueError, TypeError): + return value - def get_unmarshaller( - self, schema_format: str - ) -> Optional[FormatUnmarshaller]: + def get_unmarshaller(self, schema_format: str) -> Optional[FormatUnmarshaller]: if schema_format in self.custom_formatters: formatter = self.custom_formatters[schema_format] return formatter.format @@ -316,8 +314,12 @@ def evolve(self, schema: Spec) -> "SchemaUnmarshaller": def find_format(self, value: Any) -> Optional[str]: for schema in self.iter_valid_schemas(value): - if "format" in schema: - return str(schema.getkey("format")) + if "format" not in schema: + continue + schema_validator = self.schema_validator.evolve(schema) + if not schema_validator.format_validator(value): + continue + return str(schema.getkey("format")) return None def iter_valid_schemas(self, value: Any) -> Iterator[Spec]: diff --git a/tests/integration/unmarshalling/test_unmarshallers.py b/tests/integration/unmarshalling/test_unmarshallers.py index 3040adda..e46246bb 100644 --- a/tests/integration/unmarshalling/test_unmarshallers.py +++ b/tests/integration/unmarshalling/test_unmarshallers.py @@ -2060,6 +2060,25 @@ def test_nultiple_types_invalid(self, unmarshallers_factory, types, value): assert len(exc_info.value.schema_errors) == 1 assert "is not of type" in exc_info.value.schema_errors[0].message + @pytest.mark.parametrize( + "types,format,value,expected", + [ + (["string", "null"], "date", None, None), + (["string", "null"], "date", "2018-12-13", date(2018, 12, 13)), + ], + ) + def test_multiple_types_format_valid(self, unmarshallers_factory, types, format, value, expected): + schema = { + "type": types, + "format": format, + } + spec = Spec.from_dict(schema, validator=None) + unmarshaller = unmarshallers_factory.create(spec) + + result = unmarshaller.unmarshal(value) + + assert result == expected + def test_any_null(self, unmarshallers_factory): schema = {} spec = Spec.from_dict(schema, validator=None)