Skip to content

Commit 3c71e8c

Browse files
authored
Merge pull request #279 from python-openapi/fix/oas31-discriminator-annotation-only
OAS 3.1/3.2 discriminator is annotation-only
2 parents 3c195a0 + 71249e7 commit 3c71e8c

File tree

2 files changed

+74
-3
lines changed

2 files changed

+74
-3
lines changed

openapi_schema_validator/validators.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -115,12 +115,10 @@ def _build_oas31_validator() -> Any:
115115
Draft202012Validator,
116116
{
117117
# adjusted to OAS
118-
"allOf": oas_keywords.allOf,
119-
"oneOf": oas_keywords.oneOf,
120-
"anyOf": oas_keywords.anyOf,
121118
"pattern": oas_keywords.pattern,
122119
"description": oas_keywords.not_implemented,
123120
# fixed OAS fields
121+
# discriminator is annotation-only in OAS 3.1+
124122
"discriminator": oas_keywords.not_implemented,
125123
"xml": oas_keywords.not_implemented,
126124
"externalDocs": oas_keywords.not_implemented,

tests/integration/test_validators.py

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1107,6 +1107,79 @@ def test_array_prefixitems_invalid(self, validator_class, value):
11071107
]
11081108
assert any(error in str(excinfo.value) for error in errors)
11091109

1110+
def test_discriminator_is_annotation_only(self, validator_class):
1111+
schema = {
1112+
"components": {
1113+
"schemas": {
1114+
"A": {
1115+
"type": "object",
1116+
"properties": {"kind": {"type": "string"}},
1117+
"required": ["kind"],
1118+
},
1119+
"B": {
1120+
"type": "object",
1121+
"properties": {
1122+
"kind": {"type": "string"},
1123+
"other": {"type": "string"},
1124+
},
1125+
"required": ["kind"],
1126+
},
1127+
}
1128+
},
1129+
"oneOf": [
1130+
{"$ref": "#/components/schemas/A"},
1131+
{"$ref": "#/components/schemas/B"},
1132+
],
1133+
"discriminator": {"propertyName": "kind"},
1134+
}
1135+
1136+
validator = validator_class(schema)
1137+
1138+
# A payload valid for both schemas A and B
1139+
instance = {"kind": "B"}
1140+
1141+
# oneOf fails because it matches BOTH A and B, discriminator does not restrict it
1142+
with pytest.raises(ValidationError):
1143+
validator.validate(instance)
1144+
1145+
@pytest.mark.parametrize(
1146+
"mapping_ref",
1147+
[
1148+
"#/components/schemas/Missing",
1149+
"#missing-anchor",
1150+
"#bad/frag",
1151+
],
1152+
)
1153+
def test_discriminator_unresolvable_reference_ignored(
1154+
self, validator_class, mapping_ref
1155+
):
1156+
schema = {
1157+
"oneOf": [{"$ref": "#/components/schemas/MountainHiking"}],
1158+
"discriminator": {
1159+
"propertyName": "discipline",
1160+
"mapping": {"mountain_hiking": mapping_ref},
1161+
},
1162+
"components": {
1163+
"schemas": {
1164+
"MountainHiking": {
1165+
"type": "object",
1166+
"properties": {
1167+
"discipline": {"type": "string"},
1168+
"length": {"type": "integer"},
1169+
},
1170+
"required": ["discipline", "length"],
1171+
},
1172+
},
1173+
},
1174+
}
1175+
1176+
validator = validator_class(schema)
1177+
1178+
# It should not raise any referencing errors because discriminator mapping is annotation-only
1179+
validator.validate(
1180+
{"discipline": "mountain_hiking", "length": 10},
1181+
)
1182+
11101183

11111184
class TestOAS32ValidatorValidate(TestOAS31ValidatorValidate):
11121185
"""OAS 3.2 uses the OAS 3.2 published dialect resources."""

0 commit comments

Comments
 (0)