Skip to content

Commit aa978cb

Browse files
authored
Merge pull request #121 from ondratu/master
Object additionalProperties support
2 parents 964302d + cfaeb03 commit aa978cb

File tree

4 files changed

+39
-14
lines changed

4 files changed

+39
-14
lines changed

openapi_core/schema/schemas/factories.py

+4-3
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@ def create(self, schema_spec):
2828
deprecated = schema_deref.get('deprecated', False)
2929
all_of_spec = schema_deref.get('allOf', None)
3030
one_of_spec = schema_deref.get('oneOf', None)
31-
additional_properties_spec = schema_deref.get('additionalProperties')
31+
additional_properties_spec = schema_deref.get('additionalProperties',
32+
True)
3233
min_items = schema_deref.get('minItems', None)
3334
max_items = schema_deref.get('maxItems', None)
3435
min_length = schema_deref.get('minLength', None)
@@ -59,8 +60,8 @@ def create(self, schema_spec):
5960
if items_spec:
6061
items = self._create_items(items_spec)
6162

62-
additional_properties = None
63-
if additional_properties_spec:
63+
additional_properties = additional_properties_spec
64+
if isinstance(additional_properties_spec, dict):
6465
additional_properties = self.create(additional_properties_spec)
6566

6667
return Schema(

openapi_core/schema/schemas/models.py

+13-11
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ def __init__(
6565
self, schema_type=None, model=None, properties=None, items=None,
6666
schema_format=None, required=None, default=None, nullable=False,
6767
enum=None, deprecated=False, all_of=None, one_of=None,
68-
additional_properties=None, min_items=None, max_items=None,
68+
additional_properties=True, min_items=None, max_items=None,
6969
min_length=None, max_length=None, pattern=None, unique_items=False,
7070
minimum=None, maximum=None, multiple_of=None,
7171
exclusive_minimum=False, exclusive_maximum=False,
@@ -311,14 +311,15 @@ def _unmarshal_properties(self, value, one_of_schema=None,
311311

312312
value_props_names = value.keys()
313313
extra_props = set(value_props_names) - set(all_props_names)
314-
if extra_props and self.additional_properties is None:
314+
if extra_props and self.additional_properties is False:
315315
raise UndefinedSchemaProperty(extra_props)
316316

317317
properties = {}
318-
for prop_name in extra_props:
319-
prop_value = value[prop_name]
320-
properties[prop_name] = self.additional_properties.unmarshal(
321-
prop_value, custom_formatters=custom_formatters)
318+
if self.additional_properties is not True:
319+
for prop_name in extra_props:
320+
prop_value = value[prop_name]
321+
properties[prop_name] = self.additional_properties.unmarshal(
322+
prop_value, custom_formatters=custom_formatters)
322323

323324
for prop_name, prop in iteritems(all_props):
324325
try:
@@ -542,13 +543,14 @@ def _validate_properties(self, value, one_of_schema=None,
542543

543544
value_props_names = value.keys()
544545
extra_props = set(value_props_names) - set(all_props_names)
545-
if extra_props and self.additional_properties is None:
546+
if extra_props and self.additional_properties is False:
546547
raise UndefinedSchemaProperty(extra_props)
547548

548-
for prop_name in extra_props:
549-
prop_value = value[prop_name]
550-
self.additional_properties.validate(
551-
prop_value, custom_formatters=custom_formatters)
549+
if self.additional_properties is not True:
550+
for prop_name in extra_props:
551+
prop_value = value[prop_name]
552+
self.additional_properties.validate(
553+
prop_value, custom_formatters=custom_formatters)
552554

553555
for prop_name, prop in iteritems(all_props):
554556
try:

tests/integration/data/v3.0/petstore.yaml

+1
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,7 @@ components:
286286
$ref: "#/components/schemas/Utctime"
287287
name:
288288
type: string
289+
additionalProperties: false
289290
TagList:
290291
type: array
291292
items:

tests/unit/schema/test_schemas.py

+21
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
from openapi_core.extensions.models.models import Model
88
from openapi_core.schema.schemas.exceptions import (
99
InvalidSchemaValue, MultipleOneOfSchema, NoOneOfSchema, OpenAPISchemaError,
10+
UndefinedSchemaProperty
1011
)
1112
from openapi_core.schema.schemas.models import Schema
1213

@@ -777,6 +778,26 @@ def test_object_max_properties(self, value):
777778

778779
assert result == value
779780

781+
@pytest.mark.parametrize('value', [Model({'additional': 1}), ])
782+
def test_object_additional_propetries(self, value):
783+
schema = Schema('object')
784+
785+
schema.validate(value)
786+
787+
@pytest.mark.parametrize('value', [Model({'additional': 1}), ])
788+
def test_object_additional_propetries_false(self, value):
789+
schema = Schema('object', additional_properties=False)
790+
791+
with pytest.raises(UndefinedSchemaProperty):
792+
schema.validate(value)
793+
794+
@pytest.mark.parametrize('value', [Model({'additional': 1}), ])
795+
def test_object_additional_propetries_object(self, value):
796+
additional_properties = Schema('integer')
797+
schema = Schema('object', additional_properties=additional_properties)
798+
799+
schema.validate(value)
800+
780801
@pytest.mark.parametrize('value', [[], ])
781802
def test_list_min_items_invalid_schema(self, value):
782803
schema = Schema(

0 commit comments

Comments
 (0)