Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion TODO.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
- Features
- Models layer
- [X] Data variant converting
- [ ] Change empty dict to actual dict type, not empty models
- [X] Change empty dict to actual dict type, not empty models
- [X] Data variant merging
- [X] Create and register models
- [X] Merge meta-models and extract common ones
Expand Down
6 changes: 3 additions & 3 deletions json_to_models/generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@ def _detect_type(self, value, convert_dict=True) -> MetaData:

# Dict should be processed as another model if convert_dict is enabled
elif isinstance(value, dict):
if not value:
return DDict(Unknown)
for reg in self.dict_keys_regex:
if all(map(reg.match, value.keys())):
convert_dict = False
Expand All @@ -91,10 +93,8 @@ def _detect_type(self, value, convert_dict=True) -> MetaData:
if len(union.types) == 1:
return DDict(*union.types)
return DDict(union)
elif types:
return DDict(*types)
else:
return DDict(Unknown)
return DDict(*types)

# null interpreted as is and will be processed later on Union merge stage
elif value is None:
Expand Down
4 changes: 2 additions & 2 deletions json_to_models/registry.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from collections import OrderedDict, defaultdict
from itertools import chain, combinations
from typing import Dict, List, Set, Tuple
from typing import Dict, Iterable, List, Set, Tuple

from ordered_set import OrderedSet

Expand Down Expand Up @@ -147,7 +147,7 @@ def merge_models(self, generator, strict=False) -> List[Tuple[ModelMeta, Set[Mod
models2merge[model_b].add(model_a)

# Groups of models to merge
groups: List[Set[ModelMeta]] = [{model, *models} for model, models in models2merge.items()]
groups: Iterable[Set[ModelMeta]] = [{model, *models} for model, models in models2merge.items()]
# Make groups non-overlapping.
# This is not optimal algorithm but it works and we probably will not have thousands of models here.
flag = True
Expand Down
17 changes: 12 additions & 5 deletions test/test_code_generation/test_models_code_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

import pytest

from json_to_models.dynamic_typing import (AbsoluteModelRef, DList, DOptional, IntString, ModelMeta, ModelPtr,
compile_imports)
from json_to_models.dynamic_typing import (AbsoluteModelRef, DDict, DList, DOptional, IntString, ModelMeta, ModelPtr,
Unknown, compile_imports)
from json_to_models.models import indent, sort_fields
from json_to_models.models.base import GenericModelCodeGenerator, generate_code

Expand Down Expand Up @@ -101,7 +101,8 @@ class Test:
"model": ("Test", {
"foo": int,
"baz": DOptional(DList(DList(str))),
"bar": IntString
"bar": IntString,
"d": DDict(Unknown)
}),
"fields_data": {
"foo": {
Expand All @@ -115,25 +116,31 @@ class Test:
"bar": {
"name": "bar",
"type": "IntString"
},
"d": {
"name": "d",
"type": "Dict[str, Any]"
}
},
"fields": {
"imports": "from json_to_models.dynamic_typing import IntString\n"
"from typing import List, Optional",
"from typing import Any, Dict, List, Optional",
"fields": [
"foo: int",
"bar: IntString",
"d: Dict[str, Any]",
"baz: Optional[List[List[str]]]",
]
},
"generated": trim("""
from json_to_models.dynamic_typing import IntString
from typing import List, Optional
from typing import Any, Dict, List, Optional


class Test:
foo: int
bar: IntString
d: Dict[str, Any]
baz: Optional[List[List[str]]]
""")
}
Expand Down
3 changes: 2 additions & 1 deletion test/test_generator/test_detect_type.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@
pytest.param("1", IntString, id="int_str"),
pytest.param("1.0", FloatString, id="float_str"),
pytest.param("true", BooleanString, id="bool_str"),
pytest.param({"test_dict_field_a": 1, "test_dict_field_b": "a"}, DDict(DUnion(int, str)), id="dict")
pytest.param({"test_dict_field_a": 1, "test_dict_field_b": "a"}, DDict(DUnion(int, str)), id="dict"),
pytest.param({}, DDict(Unknown))
]

test_dict = {param.id: param.values[0] for param in test_data}
Expand Down