Skip to content

Commit

Permalink
Discriminated union schemas use oneOf instead of anyOf (#4335)
Browse files Browse the repository at this point in the history
  • Loading branch information
MaxwellPayne committed Aug 11, 2022
1 parent 149c05b commit 4cb58cf
Show file tree
Hide file tree
Showing 5 changed files with 18 additions and 16 deletions.
1 change: 1 addition & 0 deletions changes/4335-MaxwellPayne.md
@@ -0,0 +1 @@
Discriminated union models now use `oneOf` instead of `anyOf` when generating OpenAPI schema definitions.
11 changes: 6 additions & 5 deletions pydantic/schema.py
Expand Up @@ -705,7 +705,8 @@ def field_singleton_sub_fields_schema(
else:
s: Dict[str, Any] = {}
# https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#discriminator-object
if field.discriminator_key is not None:
field_has_discriminator: bool = field.discriminator_key is not None
if field_has_discriminator:
assert field.sub_fields_mapping is not None

discriminator_models_refs: Dict[str, Union[str, Dict[str, Any]]] = {}
Expand Down Expand Up @@ -748,16 +749,16 @@ def field_singleton_sub_fields_schema(
definitions.update(sub_definitions)
if schema_overrides and 'allOf' in sub_schema:
# if the sub_field is a referenced schema we only need the referenced
# object. Otherwise we will end up with several allOf inside anyOf.
# object. Otherwise we will end up with several allOf inside anyOf/oneOf.
# See https://github.com/pydantic/pydantic/issues/1209
sub_schema = sub_schema['allOf'][0]

if sub_schema.keys() == {'discriminator', 'anyOf'}:
# we don't want discriminator information inside anyOf choices, this is dealt with elsewhere
if sub_schema.keys() == {'discriminator', 'oneOf'}:
# we don't want discriminator information inside oneOf choices, this is dealt with elsewhere
sub_schema.pop('discriminator')
sub_field_schemas.append(sub_schema)
nested_models.update(sub_nested_models)
s['anyOf'] = sub_field_schemas
s['oneOf' if field_has_discriminator else 'anyOf'] = sub_field_schemas
return s, definitions, nested_models


Expand Down
4 changes: 2 additions & 2 deletions tests/test_dataclasses.py
Expand Up @@ -1201,7 +1201,7 @@ class Users(BaseModel):
}


def test_discrimated_union_basemodel_instance_value():
def test_discriminated_union_basemodel_instance_value():
@pydantic.dataclasses.dataclass
class A:
l: Literal['a']
Expand All @@ -1223,7 +1223,7 @@ class Top:
'sub': {
'title': 'Sub',
'discriminator': {'propertyName': 'l', 'mapping': {'a': '#/definitions/A', 'b': '#/definitions/B'}},
'anyOf': [{'$ref': '#/definitions/A'}, {'$ref': '#/definitions/B'}],
'oneOf': [{'$ref': '#/definitions/A'}, {'$ref': '#/definitions/B'}],
}
},
'required': ['sub'],
Expand Down
2 changes: 1 addition & 1 deletion tests/test_forward_ref.py
Expand Up @@ -588,7 +588,7 @@ class Dog(BaseModel):
assert module.Pet.schema() == {
'title': 'Pet',
'discriminator': {'propertyName': 'type', 'mapping': {'cat': '#/definitions/Cat', 'dog': '#/definitions/Dog'}},
'anyOf': [{'$ref': '#/definitions/Cat'}, {'$ref': '#/definitions/Dog'}],
'oneOf': [{'$ref': '#/definitions/Cat'}, {'$ref': '#/definitions/Dog'}],
'definitions': {
'Cat': {
'title': 'Cat',
Expand Down
16 changes: 8 additions & 8 deletions tests/test_schema.py
Expand Up @@ -2675,7 +2675,7 @@ class Model(BaseModel):
'lizard': '#/definitions/Lizard',
},
},
'anyOf': [
'oneOf': [
{'$ref': '#/definitions/Cat'},
{'$ref': '#/definitions/Dog'},
{'$ref': '#/definitions/Lizard'},
Expand Down Expand Up @@ -2708,7 +2708,7 @@ class Model(BaseModel):
'propertyName': 'color',
'mapping': {'black': '#/definitions/BlackCat', 'white': '#/definitions/WhiteCat'},
},
'anyOf': [{'$ref': '#/definitions/BlackCat'}, {'$ref': '#/definitions/WhiteCat'}],
'oneOf': [{'$ref': '#/definitions/BlackCat'}, {'$ref': '#/definitions/WhiteCat'}],
},
'Dog': {
'title': 'Dog',
Expand Down Expand Up @@ -2775,11 +2775,11 @@ class Model(BaseModel):
'dog': '#/definitions/Dog',
},
},
'anyOf': [
'oneOf': [
{
'anyOf': [
'oneOf': [
{
'anyOf': [
'oneOf': [
{'$ref': '#/definitions/BlackCatWithHeight'},
{'$ref': '#/definitions/BlackCatWithWeight'},
]
Expand Down Expand Up @@ -2858,7 +2858,7 @@ class Model(BaseModel):
'properties': {
'number': {'title': 'Number', 'type': 'integer'},
'pet': {
'anyOf': [{'$ref': '#/definitions/Cat'}, {'$ref': '#/definitions/Dog'}],
'oneOf': [{'$ref': '#/definitions/Cat'}, {'$ref': '#/definitions/Dog'}],
'discriminator': {
'mapping': {'cat': '#/definitions/Cat', 'dog': '#/definitions/Dog'},
'propertyName': 'typeOfPet',
Expand Down Expand Up @@ -2960,9 +2960,9 @@ class Model(BaseModel):
'dog': '#/definitions/Dog',
},
},
'anyOf': [
'oneOf': [
{
'anyOf': [
'oneOf': [
{'$ref': '#/definitions/BlackCat'},
{'$ref': '#/definitions/WhiteCat'},
],
Expand Down

0 comments on commit 4cb58cf

Please sign in to comment.