diff --git a/openapi_core/schema/schemas.py b/openapi_core/schema/schemas.py index 9cdc2e92..fd6631b1 100644 --- a/openapi_core/schema/schemas.py +++ b/openapi_core/schema/schemas.py @@ -4,7 +4,7 @@ from openapi_core.spec import Spec -def get_all_properties(schema: Spec) -> Dict[str, Any]: +def get_schema_properties(schema: Spec) -> Dict[str, Any]: properties = schema.get("properties", {}) properties_dict = dict(list(properties.items())) @@ -12,7 +12,7 @@ def get_all_properties(schema: Spec) -> Dict[str, Any]: return properties_dict for subschema in schema / "allOf": - subschema_props = get_all_properties(subschema) + subschema_props = get_schema_properties(subschema) properties_dict.update(subschema_props) return properties_dict diff --git a/openapi_core/unmarshalling/schemas/unmarshallers.py b/openapi_core/unmarshalling/schemas/unmarshallers.py index 941e28cb..f0d95f11 100644 --- a/openapi_core/unmarshalling/schemas/unmarshallers.py +++ b/openapi_core/unmarshalling/schemas/unmarshallers.py @@ -20,7 +20,7 @@ from openapi_schema_validator._types import is_string from openapi_core.extensions.models.factories import ModelPathFactory -from openapi_core.schema.schemas import get_all_properties +from openapi_core.schema.schemas import get_schema_properties from openapi_core.spec import Spec from openapi_core.unmarshalling.schemas.datatypes import FormattersDict from openapi_core.unmarshalling.schemas.enums import UnmarshalContext @@ -268,7 +268,9 @@ def _unmarshal_properties(self, value: Any) -> Any: else: properties.update(any_of_properties) - for prop_name, prop in get_all_properties(self.schema).items(): + # unmarshal schema properties + schema_properties = get_schema_properties(self.schema) + for prop_name, prop in schema_properties.items(): read_only = prop.getkey("readOnly", False) if self.context == UnmarshalContext.REQUEST and read_only: continue @@ -286,23 +288,24 @@ def _unmarshal_properties(self, value: Any) -> Any: prop_value ) + # unmarshal additional properties additional_properties = self.schema.getkey( "additionalProperties", True ) if additional_properties is not False: # free-form object if additional_properties is True: - additional_prop_schema = Spec.from_dict({}) + unmarshal_func = lambda x: x # defined schema else: additional_prop_schema = self.schema / "additionalProperties" - additional_prop_unmarshaler = self.unmarshallers_factory.create( - additional_prop_schema - ) + unmarshal_func = self.unmarshallers_factory.create( + additional_prop_schema + ) for prop_name, prop_value in value.items(): - if prop_name in properties: + if prop_name in schema_properties: continue - properties[prop_name] = additional_prop_unmarshaler(prop_value) + properties[prop_name] = unmarshal_func(prop_value) return properties diff --git a/tests/integration/validation/test_petstore.py b/tests/integration/validation/test_petstore.py index c52feeb3..6925bbf9 100644 --- a/tests/integration/validation/test_petstore.py +++ b/tests/integration/validation/test_petstore.py @@ -752,6 +752,7 @@ def test_post_cats(self, spec, spec_dict): "ears": { "healthy": pet_healthy, }, + "extra": None, } data = json.dumps(data_json) headers = { @@ -799,6 +800,7 @@ def test_post_cats(self, spec, spec_dict): assert result.body.address.street == pet_street assert result.body.address.city == pet_city assert result.body.healthy == pet_healthy + assert result.body.extra is None def test_post_cats_boolean_string(self, spec, spec_dict): host_url = "https://staging.gigantic-server.com/v1"
Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.
Alternative Proxies: