Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Does not add METADATA_FIELD_NAME to metadata if original fields name is a same as generated one #16

Merged
merged 1 commit into from
Dec 2, 2018
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
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