From 21ad0fed8629c1d774d54771627066e7a1afbe63 Mon Sep 17 00:00:00 2001 From: Sigurd Spieckermann Date: Fri, 28 May 2021 15:15:30 +0200 Subject: [PATCH] Unmarshal "allOf" with "oneOf/anyOf/allOf" sub-schemas --- src/oas/schema/unmarshalers.py | 6 +++--- tests/schema/test_unmarshalers.py | 30 ++++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+), 3 deletions(-) diff --git a/src/oas/schema/unmarshalers.py b/src/oas/schema/unmarshalers.py index 2104f17..e11908b 100644 --- a/src/oas/schema/unmarshalers.py +++ b/src/oas/schema/unmarshalers.py @@ -42,9 +42,9 @@ def _unmarshal(self, instance, schema): if 'allOf' in schema: sub_schemas = iter(schema['allOf']) result = self._unmarshal(instance, next(sub_schemas)) - # If the first sub-schema of ``allOf`` specifies an object, also - # unmarshal the remaining sub-schemas and merge the results. - if schema['allOf'][0].get('type', 'object') == 'object': + # If ``result`` is a dict, then the sub-schema specify objects, so + # also unmarshal the remaining sub-schemas and merge the results. + if isinstance(result, dict): for sub_schema in sub_schemas: for k, v in iteritems( self._unmarshal(instance, sub_schema) diff --git a/tests/schema/test_unmarshalers.py b/tests/schema/test_unmarshalers.py index d160a9f..c844e1a 100644 --- a/tests/schema/test_unmarshalers.py +++ b/tests/schema/test_unmarshalers.py @@ -245,6 +245,36 @@ def test_unmarshal_all_of_primitive_string_enum(): assert unmarshaled == instance +@pytest.mark.parametrize('schema_type', ['oneOf', 'anyOf']) +def test_unmarshal_all_of_one_of_or_any_of(schema_type): + schema = { + 'allOf': [ + {schema_type: [{'type': 'string'}, {'type': 'number'}]}, + {'type': 'string'}, + ] + } + instance = 'a' + unmarshaled = SchemaUnmarshaler().unmarshal(instance, schema) + assert unmarshaled == instance + + +def test_unmarshal_all_of_all_of(): + schema = { + 'allOf': [ + { + 'allOf': [ + {'type': 'string'}, + {'type': 'string', 'enum': ['a', 'b']}, + ] + }, + {'type': 'string', 'enum': ['a']}, + ] + } + instance = 'a' + unmarshaled = SchemaUnmarshaler().unmarshal(instance, schema) + assert unmarshaled == instance + + @pytest.mark.parametrize('schema_type', ['oneOf', 'anyOf']) def test_unmarshal_one_of_or_any_of(schema_type): schema = {