Skip to content

Commit 7db11f4

Browse files
authored
Merge pull request #432 from stephenfin/null-unmarshaller
Add NullUnmarshaller
2 parents a2b31c9 + cd6996c commit 7db11f4

File tree

3 files changed

+47
-6
lines changed

3 files changed

+47
-6
lines changed

openapi_core/unmarshalling/schemas/factories.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
from openapi_core.unmarshalling.schemas.unmarshallers import (
3131
IntegerUnmarshaller,
3232
)
33+
from openapi_core.unmarshalling.schemas.unmarshallers import NullUnmarshaller
3334
from openapi_core.unmarshalling.schemas.unmarshallers import NumberUnmarshaller
3435
from openapi_core.unmarshalling.schemas.unmarshallers import ObjectUnmarshaller
3536
from openapi_core.unmarshalling.schemas.unmarshallers import StringUnmarshaller
@@ -45,6 +46,7 @@ class SchemaUnmarshallersFactory:
4546
"boolean": BooleanUnmarshaller,
4647
"array": ArrayUnmarshaller,
4748
"object": ObjectUnmarshaller,
49+
"null": NullUnmarshaller,
4850
"any": AnyUnmarshaller,
4951
}
5052

openapi_core/unmarshalling/schemas/unmarshallers.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
from functools import partial
33
from typing import TYPE_CHECKING
44
from typing import Any
5-
from typing import Dict
65
from typing import Iterable
76
from typing import List
87
from typing import Optional
@@ -12,6 +11,7 @@
1211
from jsonschema._types import is_array
1312
from jsonschema._types import is_bool
1413
from jsonschema._types import is_integer
14+
from jsonschema._types import is_null
1515
from jsonschema._types import is_number
1616
from jsonschema._types import is_object
1717
from jsonschema.protocols import Validator
@@ -159,6 +159,13 @@ class BooleanUnmarshaller(BaseSchemaUnmarshaller):
159159
}
160160

161161

162+
class NullUnmarshaller(BaseSchemaUnmarshaller):
163+
164+
FORMATTERS: FormattersDict = {
165+
None: Formatter.from_callables(partial(is_null, None), None),
166+
}
167+
168+
162169
class ComplexUnmarshaller(BaseSchemaUnmarshaller):
163170
def __init__(
164171
self,

tests/unit/unmarshalling/test_unmarshal.py

Lines changed: 37 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
import datetime
22
import uuid
3+
from functools import partial
34

45
import pytest
56
from isodate.tzinfo import UTC
67
from isodate.tzinfo import FixedOffset
78
from openapi_schema_validator import OAS30Validator
9+
from openapi_schema_validator import OAS31Validator
810

911
from openapi_core.spec.paths import Spec
1012
from openapi_core.unmarshalling.schemas.enums import UnmarshalContext
@@ -23,21 +25,25 @@
2325

2426

2527
@pytest.fixture
26-
def unmarshaller_factory():
28+
def schema_unmarshaller_factory():
2729
def create_unmarshaller(
28-
schema, custom_formatters=None, context=UnmarshalContext.REQUEST
30+
validator, schema, custom_formatters=None, context=None
2931
):
3032
custom_formatters = custom_formatters or {}
3133
return SchemaUnmarshallersFactory(
32-
OAS30Validator,
34+
validator,
3335
custom_formatters=custom_formatters,
3436
context=context,
3537
).create(schema)
3638

3739
return create_unmarshaller
3840

3941

40-
class TestUnmarshal:
42+
class TestOAS30SchemaUnmarshallerUnmarshal:
43+
@pytest.fixture
44+
def unmarshaller_factory(self, schema_unmarshaller_factory):
45+
return partial(schema_unmarshaller_factory, OAS30Validator)
46+
4147
def test_no_schema(self, unmarshaller_factory):
4248
spec = None
4349
value = "test"
@@ -79,7 +85,11 @@ def unmarshal(self, value):
7985
).unmarshal(value)
8086

8187

82-
class TestSchemaUnmarshallerCall:
88+
class TestOAS30SchemaUnmarshallerCall:
89+
@pytest.fixture
90+
def unmarshaller_factory(self, schema_unmarshaller_factory):
91+
return partial(schema_unmarshaller_factory, OAS30Validator)
92+
8393
def test_deprecated(self, unmarshaller_factory):
8494
schema = {
8595
"type": "string",
@@ -824,3 +834,25 @@ def test_additional_properties_list(self, unmarshaller_factory):
824834
assert result == {
825835
"user_ids": [1, 2, 3, 4],
826836
}
837+
838+
839+
class TestOAS31SchemaUnmarshallerCall:
840+
@pytest.fixture
841+
def unmarshaller_factory(self, schema_unmarshaller_factory):
842+
return partial(schema_unmarshaller_factory, OAS31Validator)
843+
844+
def test_null(self, unmarshaller_factory):
845+
schema = {"type": "null"}
846+
spec = Spec.from_dict(schema)
847+
848+
result = unmarshaller_factory(spec)(None)
849+
850+
assert result is None
851+
852+
@pytest.mark.parametrize("value", ["string", 2, 3.14, True, [1, 2], {}])
853+
def test_null_invalid(self, unmarshaller_factory, value):
854+
schema = {"type": "null"}
855+
spec = Spec.from_dict(schema)
856+
857+
with pytest.raises(InvalidSchemaValue):
858+
unmarshaller_factory(spec)(value)

0 commit comments

Comments
 (0)