diff --git a/jambo/parser/__init__.py b/jambo/parser/__init__.py index a953057..f3b8b25 100644 --- a/jambo/parser/__init__.py +++ b/jambo/parser/__init__.py @@ -7,6 +7,7 @@ from .const_type_parser import ConstTypeParser from .enum_type_parser import EnumTypeParser from .float_type_parser import FloatTypeParser from .int_type_parser import IntTypeParser +from .null_type_parser import NullTypeParser from .object_type_parser import ObjectTypeParser from .ref_type_parser import RefTypeParser from .string_type_parser import StringTypeParser @@ -22,6 +23,7 @@ __all__ = [ "BooleanTypeParser", "FloatTypeParser", "IntTypeParser", + "NullTypeParser", "ObjectTypeParser", "StringTypeParser", "RefTypeParser", diff --git a/jambo/parser/null_type_parser.py b/jambo/parser/null_type_parser.py new file mode 100644 index 0000000..4c384f4 --- /dev/null +++ b/jambo/parser/null_type_parser.py @@ -0,0 +1,18 @@ +from jambo.parser._type_parser import GenericTypeParser +from jambo.types.type_parser_options import TypeParserOptions + +from typing_extensions import Unpack + + +class NullTypeParser(GenericTypeParser): + mapped_type = type(None) + + json_schema_type = "type:null" + + def from_properties_impl( + self, name, properties, **kwargs: Unpack[TypeParserOptions] + ): + mapped_properties = self.mappings_properties_builder(properties, **kwargs) + mapped_properties["default"] = None + + return self.mapped_type, mapped_properties diff --git a/tests/parser/test_null_type_parser.py b/tests/parser/test_null_type_parser.py new file mode 100644 index 0000000..e2732c0 --- /dev/null +++ b/tests/parser/test_null_type_parser.py @@ -0,0 +1,29 @@ +from jambo.parser import NullTypeParser + +from unittest import TestCase + + +class TestNullTypeParser(TestCase): + def test_null_parser_no_options(self): + parser = NullTypeParser() + + properties = {"type": "null"} + + type_parsing, type_validator = parser.from_properties_impl( + "placeholder", properties + ) + + self.assertEqual(type_parsing, type(None)) + self.assertEqual(type_validator, {"default": None}) + + def test_null_parser_with_invalid_default(self): + parser = NullTypeParser() + + properties = {"type": "null", "default": "invalid"} + + type_parsing, type_validator = parser.from_properties_impl( + "placeholder", properties + ) + + self.assertEqual(type_parsing, type(None)) + self.assertEqual(type_validator, {"default": None}) diff --git a/tests/test_schema_converter.py b/tests/test_schema_converter.py index 472ea8d..c5a7c3a 100644 --- a/tests/test_schema_converter.py +++ b/tests/test_schema_converter.py @@ -700,3 +700,23 @@ class TestSchemaConverter(TestCase): with self.assertRaises(ValueError): Model(name="Canada") + + def test_null_type_parser(self): + schema = { + "title": "Test", + "type": "object", + "properties": { + "a_thing": {"type": "null"}, + }, + } + + Model = SchemaConverter.build(schema) + + obj = Model() + self.assertIsNone(obj.a_thing) + + obj = Model(a_thing=None) + self.assertIsNone(obj.a_thing) + + with self.assertRaises(ValueError): + Model(a_thing="not none")