Skip to content

Commit

Permalink
Merge cfa5bd5 into a5c8155
Browse files Browse the repository at this point in the history
  • Loading branch information
bogdandm committed Dec 2, 2018
2 parents a5c8155 + cfa5bd5 commit 7c353fa
Show file tree
Hide file tree
Showing 7 changed files with 60 additions and 65 deletions.
8 changes: 4 additions & 4 deletions TODO.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
- [X] Data variant merging
- [X] Create and register models
- [X] Merge meta-models and extract common ones
- [ ] Save meta-models as python code
- [X] Save meta-models as python code
- [X] typing code generation
- [ ] (Maybe in future) Extract to another module (by serializers for each dynamic typing class)
- [X] attrs
Expand All @@ -25,19 +25,19 @@
- [ ] Decode unicode in keys
- [ ] Nesting models generation
- [X] Cascade (default)
- [ ] Flat
- [X] Flat
- [ ] OptionalFieldsPolicy
- [X] Merge (default)
- [ ] Field sets
- [X] Key as data (does not process json dict as a model but process it as a python dict)
- [ ] Field sets
- [ ] Complex python types annotations
- [ ] Decorator to specify field metatype
- [ ] Specify metatype in attr/dataclass argument (if dataclasses has such)
- [X] String based types (Warning: 6 times slow down)
- [X] ISO date
- [X] ISO time
- [X] ISO datetime
- [ ] Don't create metadata (RCG_ORIGINAL_FIELD) if original_field == generated_field
- [X] Don't create metadata (J2M_ORIGINAL_FIELD) if original_field == generated_field
- [X] Cli tool

- Testing
Expand Down
4 changes: 2 additions & 2 deletions json_to_models/models/attr.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ def field_data(self, name: str, meta: MetaData, optional: bool) -> Tuple[ImportP
"""
Form field data for template
:param name: Field name
:param name: Original field name
:param meta: Field metadata
:param optional: Is field optional
:return: imports, field data
Expand All @@ -70,7 +70,7 @@ def field_data(self, name: str, meta: MetaData, optional: bool) -> Tuple[ImportP
elif isclass(meta) and issubclass(meta, StringSerializable):
body_kwargs["converter"] = meta.__name__

if not self.no_meta:
if not self.no_meta and name != data["name"]:
body_kwargs["metadata"] = {METADATA_FIELD_NAME: name}
data["body"] = self.ATTRIB.render(kwargs=sort_kwargs(body_kwargs, DEFAULT_ORDER))
return imports, data
4 changes: 2 additions & 2 deletions json_to_models/models/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from . import INDENT, ModelsStructureType, OBJECTS_DELIMITER, indent, sort_fields
from ..dynamic_typing import AbsoluteModelRef, ImportPathList, MetaData, ModelMeta, compile_imports, metadata_to_typing

METADATA_FIELD_NAME = "RCG_ORIGINAL_FIELD"
METADATA_FIELD_NAME = "J2M_ORIGINAL_FIELD"
KWAGRS_TEMPLATE = "{% for key, value in kwargs.items() %}" \
"{{ key }}={{ value }}" \
"{% if not loop.last %}, {% endif %}" \
Expand Down Expand Up @@ -84,7 +84,7 @@ def field_data(self, name: str, meta: MetaData, optional: bool) -> Tuple[ImportP
"""
Form field data for template
:param name: Field name
:param name: Original field name
:param meta: Field metadata
:param optional: Is field optional
:return: imports, field data
Expand Down
4 changes: 2 additions & 2 deletions json_to_models/models/dataclasses.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ def field_data(self, name: str, meta: MetaData, optional: bool) -> Tuple[ImportP
"""
Form field data for template
:param name: Field name
:param name: Original field name
:param meta: Field metadata
:param optional: Is field optional
:return: imports, field data
Expand All @@ -72,7 +72,7 @@ def field_data(self, name: str, meta: MetaData, optional: bool) -> Tuple[ImportP
elif isclass(meta) and issubclass(meta, StringSerializable):
pass

if not self.no_meta:
if not self.no_meta and name != data["name"]:
body_kwargs["metadata"] = {METADATA_FIELD_NAME: name}
if len(body_kwargs) == 1 and next(iter(body_kwargs.keys())) == "default":
data["body"] = body_kwargs["default"]
Expand Down
46 changes: 23 additions & 23 deletions test/test_code_generation/test_attrs_generation.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,32 +42,32 @@ def field_meta(original_name):
"base": {
"model": ("Test", {
"foo": int,
"bar": int,
"Bar": int,
"baz": float
}),
"fields_data": {
"foo": {
"name": "foo",
"type": "int",
"body": f"attr.ib({field_meta('foo')})"
"body": f"attr.ib()"
},
"bar": {
"Bar": {
"name": "bar",
"type": "int",
"body": f"attr.ib({field_meta('bar')})"
"body": f"attr.ib({field_meta('Bar')})"
},
"baz": {
"name": "baz",
"type": "float",
"body": f"attr.ib({field_meta('baz')})"
"body": f"attr.ib()"
}
},
"fields": {
"imports": "",
"fields": [
f"foo: int = attr.ib({field_meta('foo')})",
f"bar: int = attr.ib({field_meta('bar')})",
f"baz: float = attr.ib({field_meta('baz')})",
f"foo: int = attr.ib()",
f"bar: int = attr.ib({field_meta('Bar')})",
f"baz: float = attr.ib()",
]
},
"generated": trim(f"""
Expand All @@ -76,9 +76,9 @@ def field_meta(original_name):
@attr.s
class Test:
foo: int = attr.ib({field_meta('foo')})
bar: int = attr.ib({field_meta('bar')})
baz: float = attr.ib({field_meta('baz')})
foo: int = attr.ib()
bar: int = attr.ib({field_meta('Bar')})
baz: float = attr.ib()
""")
},
"complex": {
Expand All @@ -94,32 +94,32 @@ class Test:
"foo": {
"name": "foo",
"type": "int",
"body": f"attr.ib({field_meta('foo')})"
"body": f"attr.ib()"
},
"baz": {
"name": "baz",
"type": "Optional[List[List[str]]]",
"body": f"attr.ib(factory=list, {field_meta('baz')})"
"body": f"attr.ib(factory=list)"
},
"bar": {
"name": "bar",
"type": "Optional[IntString]",
"body": f"attr.ib(default=None, converter=optional(IntString), {field_meta('bar')})"
"body": f"attr.ib(default=None, converter=optional(IntString))"
},
"qwerty": {
"name": "qwerty",
"type": "FloatString",
"body": f"attr.ib(converter=FloatString, {field_meta('qwerty')})"
"body": f"attr.ib(converter=FloatString)"
},
"asdfg": {
"name": "asdfg",
"type": "Optional[int]",
"body": f"attr.ib(default=None, {field_meta('asdfg')})"
"body": f"attr.ib(default=None)"
},
"dict": {
"name": "dict",
"type": "Dict[str, int]",
"body": f"attr.ib({field_meta('dict')})"
"body": f"attr.ib()"
}
},
"generated": trim(f"""
Expand All @@ -131,12 +131,12 @@ class Test:
@attr.s
class Test:
foo: int = attr.ib({field_meta('foo')})
qwerty: FloatString = attr.ib(converter=FloatString, {field_meta('qwerty')})
dict: Dict[str, int] = attr.ib({field_meta('dict')})
baz: Optional[List[List[str]]] = attr.ib(factory=list, {field_meta('baz')})
bar: Optional[IntString] = attr.ib(default=None, converter=optional(IntString), {field_meta('bar')})
asdfg: Optional[int] = attr.ib(default=None, {field_meta('asdfg')})
foo: int = attr.ib()
qwerty: FloatString = attr.ib(converter=FloatString)
dict: Dict[str, int] = attr.ib()
baz: Optional[List[List[str]]] = attr.ib(factory=list)
bar: Optional[IntString] = attr.ib(default=None, converter=optional(IntString))
asdfg: Optional[int] = attr.ib(default=None)
""")
}
}
Expand Down
57 changes: 26 additions & 31 deletions test/test_code_generation/test_dataclasses_generation.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,32 +22,30 @@ def field_meta(original_name):
"base": {
"model": ("Test", {
"foo": int,
"bar": int,
"Bar": int,
"baz": float
}),
"fields_data": {
"foo": {
"name": "foo",
"type": "int",
"body": f"field({field_meta('foo')})"
"type": "int"
},
"bar": {
"Bar": {
"name": "bar",
"type": "int",
"body": f"field({field_meta('bar')})"
"body": f"field({field_meta('Bar')})"
},
"baz": {
"name": "baz",
"type": "float",
"body": f"field({field_meta('baz')})"
"type": "float"
}
},
"fields": {
"imports": "",
"fields": [
f"foo: int = field({field_meta('foo')})",
f"bar: int = field({field_meta('bar')})",
f"baz: float = field({field_meta('baz')})",
f"foo: int",
f"bar: int = field({field_meta('Bar')})",
f"baz: float",
]
},
"generated": trim(f"""
Expand All @@ -56,9 +54,9 @@ def field_meta(original_name):
@dataclass
class Test:
foo: int = field({field_meta('foo')})
bar: int = field({field_meta('bar')})
baz: float = field({field_meta('baz')})
foo: int
bar: int = field({field_meta('Bar')})
baz: float
""")
},
"complex": {
Expand All @@ -73,33 +71,30 @@ class Test:
"fields_data": {
"foo": {
"name": "foo",
"type": "int",
"body": f"field({field_meta('foo')})"
"type": "int"
},
"baz": {
"name": "baz",
"type": "Optional[List[List[str]]]",
"body": f"field(default_factory=list, {field_meta('baz')})"
"body": f"field(default_factory=list)"
},
"bar": {
"name": "bar",
"type": "Optional[IntString]",
"body": f"field(default=None, {field_meta('bar')})"
"body": "None"
},
"qwerty": {
"name": "qwerty",
"type": "FloatString",
"body": f"field({field_meta('qwerty')})"
"type": "FloatString"
},
"asdfg": {
"name": "asdfg",
"type": "Optional[int]",
"body": f"field(default=None, {field_meta('asdfg')})"
"body": "None"
},
"dict": {
"name": "dict",
"type": "Dict[str, int]",
"body": f"field({field_meta('dict')})"
"type": "Dict[str, int]"
}
},
"generated": trim(f"""
Expand All @@ -110,12 +105,12 @@ class Test:
@dataclass
class Test:
foo: int = field({field_meta('foo')})
qwerty: FloatString = field({field_meta('qwerty')})
dict: Dict[str, int] = field({field_meta('dict')})
baz: Optional[List[List[str]]] = field(default_factory=list, {field_meta('baz')})
bar: Optional[IntString] = field(default=None, {field_meta('bar')})
asdfg: Optional[int] = field(default=None, {field_meta('asdfg')})
foo: int
qwerty: FloatString
dict: Dict[str, int]
baz: Optional[List[List[str]]] = field(default_factory=list)
bar: Optional[IntString] = None
asdfg: Optional[int] = None
""")
}
}
Expand All @@ -135,7 +130,7 @@ class Test:


@pytest.mark.parametrize("value,expected", test_data_unzip["fields_data"])
def test_fields_data_attr(value: ModelMeta, expected: Dict[str, dict]):
def test_fields_data_dc(value: ModelMeta, expected: Dict[str, dict]):
gen = DataclassModelCodeGenerator(value, meta=True)
required, optional = sort_fields(value)
for is_optional, fields in enumerate((required, optional)):
Expand All @@ -145,7 +140,7 @@ def test_fields_data_attr(value: ModelMeta, expected: Dict[str, dict]):


@pytest.mark.parametrize("value,expected", test_data_unzip["fields"])
def test_fields_attr(value: ModelMeta, expected: dict):
def test_fields_dc(value: ModelMeta, expected: dict):
expected_imports: str = expected["imports"]
expected_fields: List[str] = expected["fields"]
gen = DataclassModelCodeGenerator(value, meta=True)
Expand All @@ -156,7 +151,7 @@ def test_fields_attr(value: ModelMeta, expected: dict):


@pytest.mark.parametrize("value,expected", test_data_unzip["generated"])
def test_generated_attr(value: ModelMeta, expected: str):
def test_generated_dc(value: ModelMeta, expected: str):
generated = generate_code(([{"model": value, "nested": []}], {}), DataclassModelCodeGenerator,
class_generator_kwargs={'meta': True})
assert generated.rstrip() == expected, generated
2 changes: 1 addition & 1 deletion testing_tools/real_apis/large_data_set.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ def main():
"\nPress enter to continue...\n")
input()
structure_flat = compose_models_flat(reg.models_map)
code = generate_code(structure_flat, DataclassModelCodeGenerator)
code = generate_code(structure_flat, DataclassModelCodeGenerator, class_generator_kwargs={"meta": True})
print(code)


Expand Down

0 comments on commit 7c353fa

Please sign in to comment.