diff --git a/json_to_models/cli.py b/json_to_models/cli.py index 04b78ce..ee5d74a 100644 --- a/json_to_models/cli.py +++ b/json_to_models/cli.py @@ -300,7 +300,7 @@ def main(version_string=None): cli.parse_args() if not version_string: version_string = ( - '"""\n' + 'r"""\n' f'generated by json2python-models v{json_to_models.__version__} at {datetime.now().ctime()}\n' f'command: {" ".join(sys.argv)}\n' '"""\n' diff --git a/json_to_models/dynamic_typing/__init__.py b/json_to_models/dynamic_typing/__init__.py index 247e7bc..a6a7ebf 100644 --- a/json_to_models/dynamic_typing/__init__.py +++ b/json_to_models/dynamic_typing/__init__.py @@ -1,5 +1,5 @@ from .base import ( - BaseType, ImportPathList, MetaData, NoneType, Unknown, UnknownType, get_hash_string + BaseType, ImportPathList, MetaData, Null, Unknown, get_hash_string ) from .complex import ComplexType, DDict, DList, DOptional, DTuple, DUnion, SingleType from .models_meta import AbsoluteModelRef, ModelMeta, ModelPtr diff --git a/json_to_models/dynamic_typing/base.py b/json_to_models/dynamic_typing/base.py index 7aa4849..5e80b6d 100644 --- a/json_to_models/dynamic_typing/base.py +++ b/json_to_models/dynamic_typing/base.py @@ -70,8 +70,27 @@ def to_hash_string(self) -> str: return "Unknown" +class NoneType(BaseType): + __slots__ = [] + + def __str__(self): + return "NoneType" + + def __iter__(self) -> Iterable['MetaData']: + return iter(tuple()) + + def replace(self, t: 'MetaData', **kwargs) -> 'NoneType': + return self + + def to_typing_code(self) -> Tuple[ImportPathList, str]: + return ([], 'None') + + def to_hash_string(self) -> str: + return "NoneType" + + Unknown = UnknownType() -NoneType = type(None) +Null = NoneType() MetaData = Union[type, dict, BaseType] diff --git a/json_to_models/generator.py b/json_to_models/generator.py index ccbcfe6..b0a0acb 100644 --- a/json_to_models/generator.py +++ b/json_to_models/generator.py @@ -5,7 +5,7 @@ from unidecode import unidecode -from .dynamic_typing import (ComplexType, DDict, DList, DOptional, DUnion, MetaData, ModelPtr, NoneType, SingleType, +from .dynamic_typing import (ComplexType, DDict, DList, DOptional, DUnion, MetaData, ModelPtr, Null, SingleType, StringSerializable, StringSerializableRegistry, Unknown, registry) keywords_set = set(keyword.kwlist) @@ -105,7 +105,7 @@ def _detect_type(self, value, convert_dict=True) -> MetaData: # null interpreted as is and will be processed later on Union merge stage elif value is None: - return NoneType + return Null # string types trying to convert to other string-serializable types else: @@ -211,7 +211,7 @@ def _optimize_union(self, t: DUnion): for item in t.types: if isinstance(item, DOptional): item = item.type - other_types.append(NoneType) + other_types.append(Null) if isinstance(item, dict): types_to_merge.append(item) elif item in self.str_types_registry or item is str: @@ -248,10 +248,10 @@ def _optimize_union(self, t: DUnion): types.remove(Unknown) optional = False - if NoneType in types: + if Null in types: optional = True - while NoneType in types: - types.remove(NoneType) + while Null in types: + types.remove(Null) if len(types) > 1: meta_type = DUnion(*types) diff --git a/test/test_code_generation/test_typing.py b/test/test_code_generation/test_typing.py index 495293b..2923b3f 100644 --- a/test/test_code_generation/test_typing.py +++ b/test/test_code_generation/test_typing.py @@ -63,7 +63,7 @@ class TestModel: # MetaData | Tuple[import_stmnt, type] test_data = [ pytest.param( - UnknownType(), + Unknown, ('from typing import Any', Any), id="UnknownType" ), @@ -78,7 +78,7 @@ class TestModel: id="DOptional" ), pytest.param( - DOptional(UnknownType()), + DOptional(Unknown), ('from typing import Any, Optional', Optional[Any]), id="DOptional_UnknownType" ), diff --git a/test/test_generator/test_detect_type.py b/test/test_generator/test_detect_type.py index f847e20..1e9fb4d 100644 --- a/test/test_generator/test_detect_type.py +++ b/test/test_generator/test_detect_type.py @@ -1,6 +1,6 @@ import pytest -from json_to_models.dynamic_typing import BooleanString, DDict, DList, DUnion, FloatString, IntString, NoneType, Unknown +from json_to_models.dynamic_typing import BooleanString, DDict, DList, DUnion, FloatString, IntString, Null, Unknown from json_to_models.generator import MetadataGenerator # JSON data | MetaData @@ -9,7 +9,7 @@ pytest.param(1, int, id="int"), pytest.param(True, bool, id="bool"), pytest.param("abc", str, id="str"), - pytest.param(None, NoneType, id="null"), + pytest.param(None, Null, id="null"), pytest.param([], DList(Unknown), id="list_empty"), pytest.param([1], DList(int), id="list_single"), pytest.param([*range(100)], DList(int), id="list_single_type"), diff --git a/test/test_generator/test_optimize_type.py b/test/test_generator/test_optimize_type.py index 6f68fb0..3dcd612 100644 --- a/test/test_generator/test_optimize_type.py +++ b/test/test_generator/test_optimize_type.py @@ -1,7 +1,7 @@ import pytest from json_to_models.dynamic_typing import (BooleanString, DDict, DList, DOptional, DTuple, DUnion, FloatString, - IntString, NoneType, Unknown) + IntString, Null, Unknown) from json_to_models.generator import MetadataGenerator # MetaData | Optimized MetaData @@ -16,7 +16,7 @@ {'1': DUnion( {'a': DUnion({'b': int}, {'b': float})}, {'a': DUnion({'b': float}, {'b': int})}, - {'a': NoneType}, + {'a': Null}, )}, {'1': {'a': DOptional({'b': float})}}, id="merge_nested_dicts" @@ -72,32 +72,32 @@ id="list_unknown_vs_multi" ), pytest.param( - DUnion(NoneType, str), + DUnion(Null, str), DOptional(str), id="optional_str" ), pytest.param( - DUnion(NoneType, DList(str)), + DUnion(Null, DList(str)), DOptional(DList(str)), id="optional_list" ), pytest.param( - DList(DUnion(NoneType, str)), + DList(DUnion(Null, str)), DList(DOptional(str)), id="list_of_optional_strings" ), pytest.param( - DUnion(NoneType, DList(str), int), + DUnion(Null, DList(str), int), DOptional(DUnion(DList(str), int)), id="optional_list_or_int" ), pytest.param( - DUnion(NoneType, DList(DUnion(str, int))), + DUnion(Null, DList(DUnion(str, int))), DOptional(DList(DUnion(str, int))), id="optional_list_of_str_or_int" ), pytest.param( - DList(DUnion(NoneType, str, int)), + DList(DUnion(Null, str, int)), DList(DOptional(DUnion(str, int))), id="list_of_optional_strings_ot_int" ), @@ -112,7 +112,7 @@ id="optional_union_nested" ), pytest.param( - DUnion(NoneType, str, NoneType), + DUnion(Null, str, Null), DOptional(str), id="optional_str" ),