Skip to content

Commit 1a8adde

Browse files
authored
Merge pull request #16 from bogdandm/feature-RCG_ORIGINAL_FIELD-optimization
Does not add METADATA_FIELD_NAME to metadata if original fields name is a same as generated one
2 parents a5c8155 + cfa5bd5 commit 1a8adde

File tree

7 files changed

+60
-65
lines changed

7 files changed

+60
-65
lines changed

TODO.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
- [X] Data variant merging
88
- [X] Create and register models
99
- [X] Merge meta-models and extract common ones
10-
- [ ] Save meta-models as python code
10+
- [X] Save meta-models as python code
1111
- [X] typing code generation
1212
- [ ] (Maybe in future) Extract to another module (by serializers for each dynamic typing class)
1313
- [X] attrs
@@ -25,19 +25,19 @@
2525
- [ ] Decode unicode in keys
2626
- [ ] Nesting models generation
2727
- [X] Cascade (default)
28-
- [ ] Flat
28+
- [X] Flat
2929
- [ ] OptionalFieldsPolicy
3030
- [X] Merge (default)
31-
- [ ] Field sets
3231
- [X] Key as data (does not process json dict as a model but process it as a python dict)
32+
- [ ] Field sets
3333
- [ ] Complex python types annotations
3434
- [ ] Decorator to specify field metatype
3535
- [ ] Specify metatype in attr/dataclass argument (if dataclasses has such)
3636
- [X] String based types (Warning: 6 times slow down)
3737
- [X] ISO date
3838
- [X] ISO time
3939
- [X] ISO datetime
40-
- [ ] Don't create metadata (RCG_ORIGINAL_FIELD) if original_field == generated_field
40+
- [X] Don't create metadata (J2M_ORIGINAL_FIELD) if original_field == generated_field
4141
- [X] Cli tool
4242

4343
- Testing

json_to_models/models/attr.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ def field_data(self, name: str, meta: MetaData, optional: bool) -> Tuple[ImportP
4949
"""
5050
Form field data for template
5151
52-
:param name: Field name
52+
:param name: Original field name
5353
:param meta: Field metadata
5454
:param optional: Is field optional
5555
:return: imports, field data
@@ -70,7 +70,7 @@ def field_data(self, name: str, meta: MetaData, optional: bool) -> Tuple[ImportP
7070
elif isclass(meta) and issubclass(meta, StringSerializable):
7171
body_kwargs["converter"] = meta.__name__
7272

73-
if not self.no_meta:
73+
if not self.no_meta and name != data["name"]:
7474
body_kwargs["metadata"] = {METADATA_FIELD_NAME: name}
7575
data["body"] = self.ATTRIB.render(kwargs=sort_kwargs(body_kwargs, DEFAULT_ORDER))
7676
return imports, data

json_to_models/models/base.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
from . import INDENT, ModelsStructureType, OBJECTS_DELIMITER, indent, sort_fields
77
from ..dynamic_typing import AbsoluteModelRef, ImportPathList, MetaData, ModelMeta, compile_imports, metadata_to_typing
88

9-
METADATA_FIELD_NAME = "RCG_ORIGINAL_FIELD"
9+
METADATA_FIELD_NAME = "J2M_ORIGINAL_FIELD"
1010
KWAGRS_TEMPLATE = "{% for key, value in kwargs.items() %}" \
1111
"{{ key }}={{ value }}" \
1212
"{% if not loop.last %}, {% endif %}" \
@@ -84,7 +84,7 @@ def field_data(self, name: str, meta: MetaData, optional: bool) -> Tuple[ImportP
8484
"""
8585
Form field data for template
8686
87-
:param name: Field name
87+
:param name: Original field name
8888
:param meta: Field metadata
8989
:param optional: Is field optional
9090
:return: imports, field data

json_to_models/models/dataclasses.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ def field_data(self, name: str, meta: MetaData, optional: bool) -> Tuple[ImportP
5252
"""
5353
Form field data for template
5454
55-
:param name: Field name
55+
:param name: Original field name
5656
:param meta: Field metadata
5757
:param optional: Is field optional
5858
:return: imports, field data
@@ -72,7 +72,7 @@ def field_data(self, name: str, meta: MetaData, optional: bool) -> Tuple[ImportP
7272
elif isclass(meta) and issubclass(meta, StringSerializable):
7373
pass
7474

75-
if not self.no_meta:
75+
if not self.no_meta and name != data["name"]:
7676
body_kwargs["metadata"] = {METADATA_FIELD_NAME: name}
7777
if len(body_kwargs) == 1 and next(iter(body_kwargs.keys())) == "default":
7878
data["body"] = body_kwargs["default"]

test/test_code_generation/test_attrs_generation.py

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -42,32 +42,32 @@ def field_meta(original_name):
4242
"base": {
4343
"model": ("Test", {
4444
"foo": int,
45-
"bar": int,
45+
"Bar": int,
4646
"baz": float
4747
}),
4848
"fields_data": {
4949
"foo": {
5050
"name": "foo",
5151
"type": "int",
52-
"body": f"attr.ib({field_meta('foo')})"
52+
"body": f"attr.ib()"
5353
},
54-
"bar": {
54+
"Bar": {
5555
"name": "bar",
5656
"type": "int",
57-
"body": f"attr.ib({field_meta('bar')})"
57+
"body": f"attr.ib({field_meta('Bar')})"
5858
},
5959
"baz": {
6060
"name": "baz",
6161
"type": "float",
62-
"body": f"attr.ib({field_meta('baz')})"
62+
"body": f"attr.ib()"
6363
}
6464
},
6565
"fields": {
6666
"imports": "",
6767
"fields": [
68-
f"foo: int = attr.ib({field_meta('foo')})",
69-
f"bar: int = attr.ib({field_meta('bar')})",
70-
f"baz: float = attr.ib({field_meta('baz')})",
68+
f"foo: int = attr.ib()",
69+
f"bar: int = attr.ib({field_meta('Bar')})",
70+
f"baz: float = attr.ib()",
7171
]
7272
},
7373
"generated": trim(f"""
@@ -76,9 +76,9 @@ def field_meta(original_name):
7676
7777
@attr.s
7878
class Test:
79-
foo: int = attr.ib({field_meta('foo')})
80-
bar: int = attr.ib({field_meta('bar')})
81-
baz: float = attr.ib({field_meta('baz')})
79+
foo: int = attr.ib()
80+
bar: int = attr.ib({field_meta('Bar')})
81+
baz: float = attr.ib()
8282
""")
8383
},
8484
"complex": {
@@ -94,32 +94,32 @@ class Test:
9494
"foo": {
9595
"name": "foo",
9696
"type": "int",
97-
"body": f"attr.ib({field_meta('foo')})"
97+
"body": f"attr.ib()"
9898
},
9999
"baz": {
100100
"name": "baz",
101101
"type": "Optional[List[List[str]]]",
102-
"body": f"attr.ib(factory=list, {field_meta('baz')})"
102+
"body": f"attr.ib(factory=list)"
103103
},
104104
"bar": {
105105
"name": "bar",
106106
"type": "Optional[IntString]",
107-
"body": f"attr.ib(default=None, converter=optional(IntString), {field_meta('bar')})"
107+
"body": f"attr.ib(default=None, converter=optional(IntString))"
108108
},
109109
"qwerty": {
110110
"name": "qwerty",
111111
"type": "FloatString",
112-
"body": f"attr.ib(converter=FloatString, {field_meta('qwerty')})"
112+
"body": f"attr.ib(converter=FloatString)"
113113
},
114114
"asdfg": {
115115
"name": "asdfg",
116116
"type": "Optional[int]",
117-
"body": f"attr.ib(default=None, {field_meta('asdfg')})"
117+
"body": f"attr.ib(default=None)"
118118
},
119119
"dict": {
120120
"name": "dict",
121121
"type": "Dict[str, int]",
122-
"body": f"attr.ib({field_meta('dict')})"
122+
"body": f"attr.ib()"
123123
}
124124
},
125125
"generated": trim(f"""
@@ -131,12 +131,12 @@ class Test:
131131
132132
@attr.s
133133
class Test:
134-
foo: int = attr.ib({field_meta('foo')})
135-
qwerty: FloatString = attr.ib(converter=FloatString, {field_meta('qwerty')})
136-
dict: Dict[str, int] = attr.ib({field_meta('dict')})
137-
baz: Optional[List[List[str]]] = attr.ib(factory=list, {field_meta('baz')})
138-
bar: Optional[IntString] = attr.ib(default=None, converter=optional(IntString), {field_meta('bar')})
139-
asdfg: Optional[int] = attr.ib(default=None, {field_meta('asdfg')})
134+
foo: int = attr.ib()
135+
qwerty: FloatString = attr.ib(converter=FloatString)
136+
dict: Dict[str, int] = attr.ib()
137+
baz: Optional[List[List[str]]] = attr.ib(factory=list)
138+
bar: Optional[IntString] = attr.ib(default=None, converter=optional(IntString))
139+
asdfg: Optional[int] = attr.ib(default=None)
140140
""")
141141
}
142142
}

test/test_code_generation/test_dataclasses_generation.py

Lines changed: 26 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -22,32 +22,30 @@ def field_meta(original_name):
2222
"base": {
2323
"model": ("Test", {
2424
"foo": int,
25-
"bar": int,
25+
"Bar": int,
2626
"baz": float
2727
}),
2828
"fields_data": {
2929
"foo": {
3030
"name": "foo",
31-
"type": "int",
32-
"body": f"field({field_meta('foo')})"
31+
"type": "int"
3332
},
34-
"bar": {
33+
"Bar": {
3534
"name": "bar",
3635
"type": "int",
37-
"body": f"field({field_meta('bar')})"
36+
"body": f"field({field_meta('Bar')})"
3837
},
3938
"baz": {
4039
"name": "baz",
41-
"type": "float",
42-
"body": f"field({field_meta('baz')})"
40+
"type": "float"
4341
}
4442
},
4543
"fields": {
4644
"imports": "",
4745
"fields": [
48-
f"foo: int = field({field_meta('foo')})",
49-
f"bar: int = field({field_meta('bar')})",
50-
f"baz: float = field({field_meta('baz')})",
46+
f"foo: int",
47+
f"bar: int = field({field_meta('Bar')})",
48+
f"baz: float",
5149
]
5250
},
5351
"generated": trim(f"""
@@ -56,9 +54,9 @@ def field_meta(original_name):
5654
5755
@dataclass
5856
class Test:
59-
foo: int = field({field_meta('foo')})
60-
bar: int = field({field_meta('bar')})
61-
baz: float = field({field_meta('baz')})
57+
foo: int
58+
bar: int = field({field_meta('Bar')})
59+
baz: float
6260
""")
6361
},
6462
"complex": {
@@ -73,33 +71,30 @@ class Test:
7371
"fields_data": {
7472
"foo": {
7573
"name": "foo",
76-
"type": "int",
77-
"body": f"field({field_meta('foo')})"
74+
"type": "int"
7875
},
7976
"baz": {
8077
"name": "baz",
8178
"type": "Optional[List[List[str]]]",
82-
"body": f"field(default_factory=list, {field_meta('baz')})"
79+
"body": f"field(default_factory=list)"
8380
},
8481
"bar": {
8582
"name": "bar",
8683
"type": "Optional[IntString]",
87-
"body": f"field(default=None, {field_meta('bar')})"
84+
"body": "None"
8885
},
8986
"qwerty": {
9087
"name": "qwerty",
91-
"type": "FloatString",
92-
"body": f"field({field_meta('qwerty')})"
88+
"type": "FloatString"
9389
},
9490
"asdfg": {
9591
"name": "asdfg",
9692
"type": "Optional[int]",
97-
"body": f"field(default=None, {field_meta('asdfg')})"
93+
"body": "None"
9894
},
9995
"dict": {
10096
"name": "dict",
101-
"type": "Dict[str, int]",
102-
"body": f"field({field_meta('dict')})"
97+
"type": "Dict[str, int]"
10398
}
10499
},
105100
"generated": trim(f"""
@@ -110,12 +105,12 @@ class Test:
110105
111106
@dataclass
112107
class Test:
113-
foo: int = field({field_meta('foo')})
114-
qwerty: FloatString = field({field_meta('qwerty')})
115-
dict: Dict[str, int] = field({field_meta('dict')})
116-
baz: Optional[List[List[str]]] = field(default_factory=list, {field_meta('baz')})
117-
bar: Optional[IntString] = field(default=None, {field_meta('bar')})
118-
asdfg: Optional[int] = field(default=None, {field_meta('asdfg')})
108+
foo: int
109+
qwerty: FloatString
110+
dict: Dict[str, int]
111+
baz: Optional[List[List[str]]] = field(default_factory=list)
112+
bar: Optional[IntString] = None
113+
asdfg: Optional[int] = None
119114
""")
120115
}
121116
}
@@ -135,7 +130,7 @@ class Test:
135130

136131

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

146141

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

157152

158153
@pytest.mark.parametrize("value,expected", test_data_unzip["generated"])
159-
def test_generated_attr(value: ModelMeta, expected: str):
154+
def test_generated_dc(value: ModelMeta, expected: str):
160155
generated = generate_code(([{"model": value, "nested": []}], {}), DataclassModelCodeGenerator,
161156
class_generator_kwargs={'meta': True})
162157
assert generated.rstrip() == expected, generated

testing_tools/real_apis/large_data_set.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ def main():
3838
"\nPress enter to continue...\n")
3939
input()
4040
structure_flat = compose_models_flat(reg.models_map)
41-
code = generate_code(structure_flat, DataclassModelCodeGenerator)
41+
code = generate_code(structure_flat, DataclassModelCodeGenerator, class_generator_kwargs={"meta": True})
4242
print(code)
4343

4444

0 commit comments

Comments
 (0)