Skip to content

Commit 179153d

Browse files
authored
Cleanup generator type mapping functions (#1628)
* Cleanup generator type mapping functions This cleans up a bit the implementation of openapi types to python types which accumulated a lot of cruft over the years. * Remove DistributionPointData which was never used.
1 parent bdbdd1e commit 179153d

File tree

8 files changed

+49
-142
lines changed

8 files changed

+49
-142
lines changed

.generator/src/generator/cli.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,6 @@ def cli(specs, output):
7272
"rest.py": env.get_template("rest.j2"),
7373
}
7474

75-
7675
top_package = output / PACKAGE_NAME
7776
top_package.mkdir(parents=True, exist_ok=True)
7877

.generator/src/generator/formatter.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@
2727
"AzureAccountListResponse",
2828
"DashboardBulkActionDataList",
2929
"DistributionPoint",
30-
"DistributionPointData",
3130
"GCPAccountListResponse",
3231
"HTTPLog",
3332
"LogsPipelineList",
@@ -62,7 +61,6 @@
6261
"TimeseriesResponseTimes",
6362
"TimeseriesResponseValues",
6463
"TimeseriesResponseValuesList",
65-
6664
),
6765
}
6866

.generator/src/generator/openapi.py

Lines changed: 45 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ def load(filename):
2020
return JsonRef.replace_refs(yaml.load(fp, Loader=CSafeLoader))
2121

2222

23-
def type_to_python_helper(type_, schema, alternative_name=None, in_list=False, typing=False):
23+
def basic_type_to_python(type_, schema, typing=False):
2424
if type_ is None:
2525
if typing:
2626
return "Any"
@@ -39,11 +39,11 @@ def type_to_python_helper(type_, schema, alternative_name=None, in_list=False, t
3939
elif type_ == "boolean":
4040
return "bool"
4141
elif type_ == "array":
42-
subtype = type_to_python(schema["items"], alternative_name=alternative_name + "Item" if alternative_name else None, in_list=True, typing=typing)
43-
if schema["items"].get("nullable") and not typing:
44-
subtype += ", none_type"
42+
subtype = type_to_python(schema["items"], typing=typing)
4543
if typing:
4644
return "List[{}]".format(subtype)
45+
if schema["items"].get("nullable"):
46+
subtype += ", none_type"
4747
return "[{}]".format(subtype)
4848
elif type_ == "object":
4949
if "additionalProperties" in schema:
@@ -57,70 +57,49 @@ def type_to_python_helper(type_, schema, alternative_name=None, in_list=False, t
5757
if typing:
5858
return f"Dict[str, {nested_name}]"
5959
return "{{str: ({},)}}".format(nested_name)
60-
return (
61-
alternative_name
62-
if alternative_name
63-
and ("properties" in schema or "oneOf" in schema)
64-
else "dict"
65-
)
66-
elif type_ == "null":
67-
return "none_type"
60+
return "dict"
6861
else:
6962
raise ValueError(f"Unknown type {type_}")
7063

7164

72-
def type_to_python(schema, alternative_name=None, in_list=False, typing=False):
65+
def type_to_python(schema, typing=False):
7366
"""Return Python type name for the type."""
7467

7568
name = formatter.get_name(schema)
76-
# TODO: double check
77-
if name and "items" not in schema or formatter.is_list_model_whitelisted(name):
78-
if "enum" in schema:
79-
return name
80-
if schema.get("type", "object") == "object" or formatter.is_list_model_whitelisted(name):
81-
if typing and "oneOf" in schema:
82-
types = [name]
83-
types.extend(get_oneof_types(schema, typing=typing))
84-
return f"Union[{','.join(types)}]"
69+
70+
if "oneOf" in schema:
71+
types = list(get_oneof_types(schema, typing=typing))
72+
if name and typing:
73+
types.insert(0, name)
74+
type_ = ", ".join(types)
75+
if typing:
76+
return f"Union[{type_}]"
77+
elif name:
8578
return name
79+
return type_
8680

87-
if name:
88-
alternative_name = name
81+
if "enum" in schema:
82+
return name
8983

9084
type_ = schema.get("type")
91-
if type_ is None:
92-
if "oneOf" in schema and in_list:
93-
type_ = ""
94-
for child in schema["oneOf"]:
95-
# We do not generate model for nested primitive oneOfs
96-
if in_list and "items" in child and child["items"].get("type") in PRIMITIVE_TYPES:
97-
type_ += f"{type_to_python_helper(child.get('type'), child, in_list=in_list, typing=typing)},"
98-
else:
99-
type_ += f"{type_to_python(child, in_list=in_list, typing=typing)},"
100-
if typing:
101-
return f"Union[{type_}]"
102-
return type_
103-
if "items" in schema:
104-
type_ = "array"
10585

106-
return type_to_python_helper(type_, schema, alternative_name=alternative_name, in_list=in_list, typing=typing)
86+
if name and (type_ == "object" or formatter.is_list_model_whitelisted(name)):
87+
return name
88+
89+
return basic_type_to_python(type_, schema, typing=typing)
10790

10891

10992
def get_type_for_attribute(schema, attribute, current_name=None):
11093
"""Return Python type name for the attribute."""
11194
child_schema = schema.get("properties", {}).get(attribute)
112-
alternative_name = current_name + formatter.camel_case(attribute) if current_name else None
113-
return type_to_python(child_schema, alternative_name=alternative_name)
95+
return type_to_python(child_schema)
11496

11597

11698
def get_typing_for_attribute(schema, attribute, current_name=None, optional=False):
11799
child_schema = schema.get("properties", {}).get(attribute)
118-
alternative_name = current_name + formatter.camel_case(attribute) if current_name else None
119-
attr_type = type_to_python(child_schema, alternative_name=alternative_name, typing=True)
100+
attr_type = type_to_python(child_schema, typing=True)
120101
if child_schema.get("nullable"):
121-
if optional:
122-
return f"Union[{attr_type}, none_type, UnsetType]"
123-
return f"Union[{attr_type}, none_type]"
102+
attr_type = f"Union[{attr_type}, none_type]"
124103
if optional:
125104
if attr_type.startswith("Union"):
126105
return attr_type[:-1] + ", UnsetType]"
@@ -137,8 +116,7 @@ def get_types_for_attribute(schema, attribute, current_name=None):
137116

138117

139118
def get_type_for_items(schema):
140-
name = formatter.get_name(schema.get("items"))
141-
return name
119+
return formatter.get_name(schema.get("items"))
142120

143121

144122
def get_type_for_parameter(parameter, typing=False):
@@ -158,44 +136,38 @@ def get_enum_type(schema):
158136
elif type_ == "string":
159137
return "str"
160138

139+
raise ValueError(f"Unknown type {type_}")
140+
161141

162142
def get_enum_default(model):
163143
return model["enum"][0] if len(model["enum"]) == 1 else model.get("default")
164144

165145

166-
def child_models(schema, alternative_name=None, seen=None, in_list=False):
146+
def child_models(schema, alternative_name=None, seen=None):
167147
seen = seen or set()
168148
current_name = formatter.get_name(schema)
169149
name = current_name or alternative_name
170150

151+
if name in seen:
152+
return
153+
171154
has_sub_models = False
172155
if "oneOf" in schema:
173-
has_sub_models = not in_list and not formatter.is_list_model_whitelisted(name)
156+
has_sub_models = not formatter.is_list_model_whitelisted(name)
174157
for child in schema["oneOf"]:
175158
sub_models = list(child_models(child, seen=seen))
176159
if sub_models:
177160
has_sub_models = True
178161
yield from sub_models
179-
if in_list and not has_sub_models:
162+
if not has_sub_models:
180163
return
181164

182165
if "items" in schema:
183-
if formatter.is_list_model_whitelisted(name):
184-
alt_name = None
185-
else:
186-
alt_name = name + "Item" if name is not None else None
187-
188-
yield from child_models(schema["items"], alternative_name=alt_name, seen=seen, in_list=True)
166+
yield from child_models(schema["items"], seen=seen)
189167

190168
if schema.get("type") == "object" or "properties" in schema or has_sub_models:
191-
if not has_sub_models and name is None:
192-
# this is a basic map object so we don't need a type
193-
return
194-
195169
if name is None:
196-
return
197-
198-
if name in seen:
170+
# this is a basic map object so we don't need a type
199171
return
200172

201173
if "properties" in schema or has_sub_models:
@@ -210,9 +182,6 @@ def child_models(schema, alternative_name=None, seen=None, in_list=False):
210182
yield from child_models(child, alternative_name=name + formatter.camel_case(key), seen=seen)
211183

212184
if current_name and schema.get("type") == "array":
213-
if name in seen:
214-
return
215-
216185
if formatter.is_list_model_whitelisted(name):
217186
seen.add(name)
218187
yield name, schema
@@ -221,9 +190,6 @@ def child_models(schema, alternative_name=None, seen=None, in_list=False):
221190
if name is None:
222191
raise ValueError(f"Schema {schema} has no name")
223192

224-
if name in seen:
225-
return
226-
227193
seen.add(name)
228194
yield name, schema
229195

@@ -266,9 +232,7 @@ def find_non_primitive_type(schema):
266232
sub_type = schema.get("type")
267233
if sub_type == "array":
268234
return find_non_primitive_type(schema["items"])
269-
if sub_type not in PRIMITIVE_TYPES:
270-
return True
271-
return False
235+
return sub_type not in PRIMITIVE_TYPES
272236

273237

274238
def get_references_for_model(model, model_name):
@@ -290,13 +254,13 @@ def get_references_for_model(model, model_name):
290254
if name and formatter.is_list_model_whitelisted(name):
291255
result[name] = None
292256
else:
293-
name = formatter.get_name(definition.get("items"))
294-
if name and find_non_primitive_type(definition["items"]):
295-
result[name] = None
296-
elif name and formatter.is_list_model_whitelisted(name):
297-
result[name] = None
298-
elif formatter.get_name(definition) and definition["items"].get("type") not in PRIMITIVE_TYPES:
299-
result[formatter.get_name(definition) + "Item"] = None
257+
items_name = formatter.get_name(definition.get("items"))
258+
if items_name and (
259+
find_non_primitive_type(definition["items"]) or formatter.is_list_model_whitelisted(items_name)
260+
):
261+
result[items_name] = None
262+
elif name and definition["items"].get("type") not in PRIMITIVE_TYPES:
263+
result[f"{name}Item"] = None
300264

301265
elif definition.get("properties") and top_name:
302266
result[top_name + formatter.camel_case(key)] = None
@@ -362,23 +326,8 @@ def get_oneof_types(model, typing=False):
362326
name = formatter.get_name(schema)
363327
if type_ == "object" or formatter.is_list_model_whitelisted(name):
364328
yield name
365-
elif type_ == "array":
366-
name = formatter.get_name(schema["items"])
367-
if name:
368-
if typing:
369-
yield f"List[{name}]"
370-
else:
371-
yield f"[{name}]"
372-
elif type_ == "integer":
373-
yield "int"
374-
elif type_ == "string":
375-
yield "str"
376-
elif type_ == "number":
377-
yield "float"
378-
elif type_ == "boolean":
379-
yield "bool"
380329
else:
381-
raise NotImplementedError(f"Type {type_} not implemented")
330+
yield basic_type_to_python(type_, schema, typing=typing)
382331

383332

384333
def get_oneof_models(model):

.generator/src/generator/templates/model_simple.j2

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ class {{ name }}(ModelSimple):
1111
{%- if ref %}
1212
:type value: [{{ ref }}]
1313
{%- else %}
14-
:type value: [{{ type_to_python(model.get("items"), in_list=True) }}{%- if model["items"].get("nullable") %}, none_type{%- endif %}]
14+
:type value: [{{ type_to_python(model.get("items")) }}{%- if model["items"].get("nullable") %}, none_type{%- endif %}]
1515
{%- endif %}
1616
"""
1717

@@ -65,6 +65,6 @@ class {{ name }}(ModelSimple):
6565
}
6666
{%- else %}
6767
return {
68-
"value": ([{{ type_to_python(model.get("items"), in_list=True) }}{%- if model["items"].get("nullable") %}, none_type{%- endif %}],),
68+
"value": ([{{ type_to_python(model.get("items")) }}{%- if model["items"].get("nullable") %}, none_type{%- endif %}],),
6969
}
7070
{%- endif %}

docs/datadog_api_client.v1.model.rst

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -519,13 +519,6 @@ distribution\_point
519519
:members:
520520
:show-inheritance:
521521

522-
distribution\_point\_data
523-
-------------------------
524-
525-
.. automodule:: datadog_api_client.v1.model.distribution_point_data
526-
:members:
527-
:show-inheritance:
528-
529522
distribution\_points\_content\_encoding
530523
---------------------------------------
531524

src/datadog_api_client/v1/model/distribution_point.py

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ class DistributionPoint(ModelSimple):
1515
Array of distribution points.
1616
1717
18-
:type value: [float,[float],]
18+
:type value: [float, [float]]
1919
"""
2020

2121
validations = {
@@ -28,10 +28,5 @@ class DistributionPoint(ModelSimple):
2828
@cached_property
2929
def openapi_types(_):
3030
return {
31-
"value": (
32-
[
33-
float,
34-
[float],
35-
],
36-
),
31+
"value": ([float, [float]],),
3732
}

src/datadog_api_client/v1/model/distribution_point_data.py

Lines changed: 0 additions & 25 deletions
This file was deleted.

src/datadog_api_client/v1/models/__init__.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,6 @@
7272
from datadog_api_client.v1.model.delete_shared_dashboard_response import DeleteSharedDashboardResponse
7373
from datadog_api_client.v1.model.deleted_monitor import DeletedMonitor
7474
from datadog_api_client.v1.model.distribution_point import DistributionPoint
75-
from datadog_api_client.v1.model.distribution_point_data import DistributionPointData
7675
from datadog_api_client.v1.model.distribution_points_content_encoding import DistributionPointsContentEncoding
7776
from datadog_api_client.v1.model.distribution_points_payload import DistributionPointsPayload
7877
from datadog_api_client.v1.model.distribution_points_series import DistributionPointsSeries
@@ -993,7 +992,6 @@
993992
"DeleteSharedDashboardResponse",
994993
"DeletedMonitor",
995994
"DistributionPoint",
996-
"DistributionPointData",
997995
"DistributionPointsContentEncoding",
998996
"DistributionPointsPayload",
999997
"DistributionPointsSeries",

0 commit comments

Comments
 (0)