Skip to content

Commit 2d3fdf5

Browse files
committed
Support parameter casting in composite schemas
1 parent 99ebe28 commit 2d3fdf5

File tree

3 files changed

+50
-2
lines changed

3 files changed

+50
-2
lines changed

openapi_core/casting/schemas/__init__.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from collections import OrderedDict
22

3+
from openapi_core.casting.schemas.casters import AnyCaster
34
from openapi_core.casting.schemas.casters import ArrayCaster
45
from openapi_core.casting.schemas.casters import BooleanCaster
56
from openapi_core.casting.schemas.casters import IntegerCaster
@@ -43,11 +44,11 @@
4344

4445
oas30_types_caster = TypesCaster(
4546
oas30_casters_dict,
46-
PrimitiveCaster,
47+
AnyCaster,
4748
)
4849
oas31_types_caster = TypesCaster(
4950
oas31_casters_dict,
50-
PrimitiveCaster,
51+
AnyCaster,
5152
multi=PrimitiveCaster,
5253
)
5354
oas32_types_caster = oas31_types_caster

openapi_core/casting/schemas/casters.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,32 @@ def cast(self, value: Any) -> Any:
4040
return value
4141

4242

43+
class AnyCaster(PrimitiveCaster):
44+
def cast(self, value: Any) -> Any:
45+
if "allOf" in self.schema:
46+
for subschema in self.schema / "allOf":
47+
try:
48+
value = self.schema_caster.evolve(subschema).cast(value)
49+
except (ValueError, TypeError, CastError):
50+
pass
51+
52+
if "oneOf" in self.schema:
53+
for subschema in self.schema / "oneOf":
54+
try:
55+
return self.schema_caster.evolve(subschema).cast(value)
56+
except (ValueError, TypeError, CastError):
57+
pass
58+
59+
if "anyOf" in self.schema:
60+
for subschema in self.schema / "anyOf":
61+
try:
62+
return self.schema_caster.evolve(subschema).cast(value)
63+
except (ValueError, TypeError, CastError):
64+
pass
65+
66+
return value
67+
68+
4369
PrimitiveType = TypeVar("PrimitiveType")
4470

4571

tests/unit/casting/test_schema_casters.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,3 +66,24 @@ def test_array_invalid_value(self, value, caster_factory):
6666
CastError, match=f"Failed to cast value to array type: {value}"
6767
):
6868
caster_factory(schema).cast(value)
69+
70+
@pytest.mark.parametrize(
71+
"composite_type,schema_type,value,expected",
72+
[
73+
("allOf", "integer", "2", 2),
74+
("anyOf", "number", "3.14", 3.14),
75+
("oneOf", "boolean", "false", False),
76+
("oneOf", "boolean", "true", True),
77+
],
78+
)
79+
def test_composite_primitive(
80+
self, caster_factory, composite_type, schema_type, value, expected
81+
):
82+
spec = {
83+
composite_type: [{"type": schema_type}],
84+
}
85+
schema = SchemaPath.from_dict(spec)
86+
87+
result = caster_factory(schema).cast(value)
88+
89+
assert result == expected

0 commit comments

Comments
 (0)