Skip to content

Commit 7fe5740

Browse files
authored
Merge pull request #876 from python-openapi/fix/openapi-30-unarshalling-none-with-nullable-subschema-fix
Openapi 3.0 unmarshalling None with nullable subschema fix
2 parents 41c5085 + 4085e9a commit 7fe5740

File tree

3 files changed

+45
-0
lines changed

3 files changed

+45
-0
lines changed

openapi_core/unmarshalling/schemas/unmarshallers.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,9 @@ def _unmarshal_properties(
137137
class MultiTypeUnmarshaller(PrimitiveUnmarshaller):
138138
def __call__(self, value: Any) -> Any:
139139
primitive_type = self.schema_validator.get_primitive_type(value)
140+
# OpenAPI 3.0: handle no type for None
141+
if primitive_type is None:
142+
return None
140143
unmarshaller = self.schema_unmarshaller.get_type_unmarshaller(
141144
primitive_type
142145
)
@@ -247,6 +250,9 @@ def unmarshal(self, value: Any) -> Any:
247250
schema_type = self.schema.getkey("type")
248251
type_unmarshaller = self.get_type_unmarshaller(schema_type)
249252
typed = type_unmarshaller(value)
253+
# skip finding format for None
254+
if typed is None:
255+
return None
250256
schema_format = self.find_format(value)
251257
if schema_format is None:
252258
return typed

openapi_core/validation/schemas/validators.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ def get_primitive_type(self, value: Any) -> Optional[str]:
9494
continue
9595
assert isinstance(schema_type, (str, type(None)))
9696
return schema_type
97+
# OpenAPI 3.0: None is not a primitive type so None value will not find any type
9798
return None
9899

99100
def iter_valid_schemas(self, value: Any) -> Iterator[SchemaPath]:

tests/integration/unmarshalling/test_unmarshallers.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1840,6 +1840,25 @@ def test_object_property_nullable(self, unmarshallers_factory):
18401840

18411841
assert result == value
18421842

1843+
def test_subschema_nullable(self, unmarshallers_factory):
1844+
schema = {
1845+
"oneOf": [
1846+
{
1847+
"type": "integer",
1848+
},
1849+
{
1850+
"nullable": True,
1851+
},
1852+
]
1853+
}
1854+
spec = SchemaPath.from_dict(schema)
1855+
unmarshaller = unmarshallers_factory.create(spec)
1856+
value = None
1857+
1858+
result = unmarshaller.unmarshal(value)
1859+
1860+
assert result is None
1861+
18431862

18441863
class TestOAS30RequestSchemaUnmarshallersFactory(
18451864
BaseTestOASSchemaUnmarshallersFactoryCall,
@@ -2086,3 +2105,22 @@ def test_any_null(self, unmarshallers_factory):
20862105
result = unmarshaller.unmarshal(None)
20872106

20882107
assert result is None
2108+
2109+
def test_subschema_null(self, unmarshallers_factory):
2110+
schema = {
2111+
"oneOf": [
2112+
{
2113+
"type": "integer",
2114+
},
2115+
{
2116+
"type": "null",
2117+
},
2118+
]
2119+
}
2120+
spec = SchemaPath.from_dict(schema)
2121+
unmarshaller = unmarshallers_factory.create(spec)
2122+
value = None
2123+
2124+
result = unmarshaller.unmarshal(value)
2125+
2126+
assert result is None

0 commit comments

Comments
 (0)