Skip to content

Commit

Permalink
AdditionalProperties free form nullable fix
Browse files Browse the repository at this point in the history
  • Loading branch information
p1c2u committed Dec 17, 2022
1 parent 027860e commit e7972fc
Show file tree
Hide file tree
Showing 3 changed files with 15 additions and 10 deletions.
4 changes: 2 additions & 2 deletions openapi_core/schema/schemas.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@
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()))

if "allOf" not in schema:
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
19 changes: 11 additions & 8 deletions openapi_core/unmarshalling/schemas/unmarshallers.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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

Expand Down
2 changes: 2 additions & 0 deletions tests/integration/validation/test_petstore.py
Original file line number Diff line number Diff line change
Expand Up @@ -752,6 +752,7 @@ def test_post_cats(self, spec, spec_dict):
"ears": {
"healthy": pet_healthy,
},
"extra": None,
}
data = json.dumps(data_json)
headers = {
Expand Down Expand Up @@ -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"
Expand Down

0 comments on commit e7972fc

Please sign in to comment.