Skip to content

Commit 83b9c37

Browse files
author
Ondrej Tuma
committed
Object additionalProperties support
* Default is true like in specification * When is set false, it works like in past * Object with types works
1 parent 395f68b commit 83b9c37

File tree

5 files changed

+40
-15
lines changed

5 files changed

+40
-15
lines changed

openapi_core/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
__author__ = 'Artur Maciag'
88
__email__ = 'maciag.artur@gmail.com'
9-
__version__ = '0.8.0'
9+
__version__ = '0.8.1'
1010
__url__ = 'https://github.com/p1c2u/openapi-core'
1111
__license__ = 'BSD 3-Clause License'
1212

openapi_core/schema/schemas/factories.py

Lines changed: 4 additions & 3 deletions
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

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ def __init__(
6868
self, schema_type=None, model=None, properties=None, items=None,
6969
schema_format=None, required=None, default=None, nullable=False,
7070
enum=None, deprecated=False, all_of=None, one_of=None,
71-
additional_properties=None, min_items=None, max_items=None,
71+
additional_properties=True, min_items=None, max_items=None,
7272
min_length=None, max_length=None, pattern=None, unique_items=False,
7373
minimum=None, maximum=None, multiple_of=None,
7474
exclusive_minimum=False, exclusive_maximum=False,
@@ -284,14 +284,15 @@ def _unmarshal_properties(self, value, one_of_schema=None,
284284

285285
value_props_names = value.keys()
286286
extra_props = set(value_props_names) - set(all_props_names)
287-
if extra_props and self.additional_properties is None:
287+
if extra_props and self.additional_properties is False:
288288
raise UndefinedSchemaProperty(extra_props)
289289

290290
properties = {}
291-
for prop_name in extra_props:
292-
prop_value = value[prop_name]
293-
properties[prop_name] = self.additional_properties.unmarshal(
294-
prop_value, custom_formatters=custom_formatters)
291+
if self.additional_properties is not True:
292+
for prop_name in extra_props:
293+
prop_value = value[prop_name]
294+
properties[prop_name] = self.additional_properties.unmarshal(
295+
prop_value, custom_formatters=custom_formatters)
295296

296297
for prop_name, prop in iteritems(all_props):
297298
try:
@@ -515,13 +516,14 @@ def _validate_properties(self, value, one_of_schema=None,
515516

516517
value_props_names = value.keys()
517518
extra_props = set(value_props_names) - set(all_props_names)
518-
if extra_props and self.additional_properties is None:
519+
if extra_props and self.additional_properties is False:
519520
raise UndefinedSchemaProperty(extra_props)
520521

521-
for prop_name in extra_props:
522-
prop_value = value[prop_name]
523-
self.additional_properties.validate(
524-
prop_value, custom_formatters=custom_formatters)
522+
if self.additional_properties is not True:
523+
for prop_name in extra_props:
524+
prop_value = value[prop_name]
525+
self.additional_properties.validate(
526+
prop_value, custom_formatters=custom_formatters)
525527

526528
for prop_name, prop in iteritems(all_props):
527529
try:

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,7 @@ components:
295295
$ref: "#/components/schemas/Utctime"
296296
name:
297297
type: string
298+
additionalProperties: false
298299
TagList:
299300
type: array
300301
items:

tests/unit/schema/test_schemas.py

Lines changed: 21 additions & 0 deletions
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

@@ -697,6 +698,26 @@ def test_object_max_properties(self, value):
697698

698699
assert result == value
699700

701+
@pytest.mark.parametrize('value', [Model({'additional': 1}), ])
702+
def test_object_additional_propetries(self, value):
703+
schema = Schema('object')
704+
705+
schema.validate(value)
706+
707+
@pytest.mark.parametrize('value', [Model({'additional': 1}), ])
708+
def test_object_additional_propetries_false(self, value):
709+
schema = Schema('object', additional_properties=False)
710+
711+
with pytest.raises(UndefinedSchemaProperty):
712+
schema.validate(value)
713+
714+
@pytest.mark.parametrize('value', [Model({'additional': 1}), ])
715+
def test_object_additional_propetries_object(self, value):
716+
additional_properties = Schema('integer')
717+
schema = Schema('object', additional_properties=additional_properties)
718+
719+
schema.validate(value)
720+
700721
@pytest.mark.parametrize('value', [[], ])
701722
def test_list_min_items_invalid_schema(self, value):
702723
schema = Schema(

0 commit comments

Comments
 (0)