Skip to content

Commit ff4a3a6

Browse files
authored
Client generation type and typing refactor (#1471)
* typing refactor * reduce ternary operator usage for readability
1 parent ddb31aa commit ff4a3a6

File tree

1 file changed

+27
-93
lines changed

1 file changed

+27
-93
lines changed

.generator/src/generator/openapi.py

Lines changed: 27 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,10 @@ def load(filename):
1919
return JsonRef.replace_refs(yaml.load(fp, Loader=CSafeLoader))
2020

2121

22-
def type_to_python_helper(type_, schema, alternative_name=None, in_list=False):
22+
def type_to_python_helper(type_, schema, alternative_name=None, in_list=False, typing=False):
2323
if type_ is None:
24+
if typing:
25+
return "Any"
2426
return "bool, date, datetime, dict, float, int, list, str, none_type"
2527

2628
if type_ == "integer":
@@ -37,16 +39,23 @@ def type_to_python_helper(type_, schema, alternative_name=None, in_list=False):
3739
elif type_ == "boolean":
3840
return "bool"
3941
elif type_ == "array":
40-
subtype = type_to_python(schema["items"], alternative_name=alternative_name + "Item" if alternative_name else None, in_list=True)
41-
if schema["items"].get("nullable"):
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:
4244
subtype += ", none_type"
45+
if typing:
46+
return "List[{}]".format(subtype)
4347
return "[{}]".format(subtype)
4448
elif type_ == "object":
4549
if "additionalProperties" in schema:
4650
nested_schema = schema["additionalProperties"]
47-
nested_name = type_to_python(nested_schema)
51+
nested_name = type_to_python(nested_schema, typing=typing)
4852
if nested_schema.get("nullable"):
49-
nested_name += ", none_type"
53+
if typing:
54+
nested_name = f"Union[{nested_name}, none_type]"
55+
else:
56+
nested_name += ", none_type"
57+
if typing:
58+
return f"Dict[str, {nested_name}]"
5059
return "{{str: ({},)}}".format(nested_name)
5160
return (
5261
alternative_name
@@ -60,13 +69,17 @@ def type_to_python_helper(type_, schema, alternative_name=None, in_list=False):
6069
raise ValueError(f"Unknown type {type_}")
6170

6271

63-
def type_to_python(schema, alternative_name=None, in_list=False):
72+
def type_to_python(schema, alternative_name=None, in_list=False, typing=False):
6473
"""Return Python type name for the type."""
6574
name = formatter.get_name(schema)
6675
if name and "items" not in schema:
6776
if "enum" in schema:
6877
return name
6978
if schema.get("type", "object") == "object":
79+
if typing and "oneOf" in schema:
80+
types = [name]
81+
types.extend(get_oneof_types(schema, typing=typing))
82+
return f"Union[{','.join(types)}]"
7083
return name
7184

7285
if name:
@@ -79,14 +92,16 @@ def type_to_python(schema, alternative_name=None, in_list=False):
7992
for child in schema["oneOf"]:
8093
# We do not generate model for nested primitive oneOfs
8194
if in_list and "items" in child and child["items"].get("type") in PRIMITIVE_TYPES:
82-
type_ += f"{type_to_python_helper(child.get('type'), child, in_list=in_list)},"
95+
type_ += f"{type_to_python_helper(child.get('type'), child, in_list=in_list, typing=typing)},"
8396
else:
84-
type_ += f"{type_to_python(child, in_list=in_list)},"
97+
type_ += f"{type_to_python(child, in_list=in_list, typing=typing)},"
98+
if typing:
99+
return f"Union[{type_}]"
85100
return type_
86101
if "items" in schema:
87102
type_ = "array"
88103

89-
return type_to_python_helper(type_, schema, alternative_name=alternative_name, in_list=in_list)
104+
return type_to_python_helper(type_, schema, alternative_name=alternative_name, in_list=in_list, typing=typing)
90105

91106

92107
def get_type_for_attribute(schema, attribute, current_name=None):
@@ -96,81 +111,10 @@ def get_type_for_attribute(schema, attribute, current_name=None):
96111
return type_to_python(child_schema, alternative_name=alternative_name)
97112

98113

99-
def typing_to_python_helper(type_, schema, alternative_name=None, in_list=False):
100-
if type_ is None:
101-
return "Any"
102-
103-
if type_ == "integer":
104-
return "int"
105-
elif type_ == "number":
106-
return "float"
107-
elif type_ == "string":
108-
format_ = schema.get("format")
109-
if format_ in {"date", "date-time"}:
110-
return "datetime"
111-
elif format_ == "binary":
112-
return "file_type"
113-
return "str"
114-
elif type_ == "boolean":
115-
return "bool"
116-
elif type_ == "array":
117-
return "List[{}]".format(typing_to_python(schema["items"], alternative_name=alternative_name + "Item" if alternative_name else None, in_list=True))
118-
elif type_ == "object":
119-
if "additionalProperties" in schema:
120-
nested_schema = schema["additionalProperties"]
121-
nested_name = typing_to_python(nested_schema)
122-
if nested_schema.get("nullable"):
123-
nested_name = f"Union[{nested_name}, none_type]"
124-
return f"Dict[str, {nested_name}]"
125-
return (
126-
alternative_name
127-
if alternative_name
128-
and ("properties" in schema or "oneOf" in schema)
129-
else "dict"
130-
)
131-
elif type_ == "null":
132-
return "none_type"
133-
else:
134-
raise ValueError(f"Unknown type {type_}")
135-
136-
137-
def typing_to_python(schema, alternative_name=None, in_list=False):
138-
"""Return Python type name for the type."""
139-
name = formatter.get_name(schema)
140-
if name:
141-
if "enum" in schema:
142-
return name
143-
if schema.get("type", "object") == "object":
144-
if "oneOf" in schema:
145-
types = [name]
146-
types.extend(get_oneof_types(schema, typing=True))
147-
return f"Union[{','.join(types)}]"
148-
return name
149-
150-
if name:
151-
alternative_name = name
152-
153-
type_ = schema.get("type")
154-
if type_ is None:
155-
if "oneOf" in schema and in_list:
156-
type_ = ""
157-
for child in schema["oneOf"]:
158-
# We do not generate model for nested primitive oneOfs
159-
if in_list and "items" in child and child["items"].get("type") in PRIMITIVE_TYPES:
160-
type_ += f"{typing_to_python_helper(child.get('type'), child, in_list=in_list)},"
161-
else:
162-
type_ += f"{typing_to_python(child, in_list=in_list)},"
163-
return f"Union[{type_}]"
164-
if "items" in schema:
165-
type_ = "array"
166-
167-
return typing_to_python_helper(type_, schema, alternative_name=alternative_name, in_list=in_list)
168-
169-
170114
def get_typing_for_attribute(schema, attribute, current_name=None, optional=False):
171115
child_schema = schema.get("properties", {}).get(attribute)
172116
alternative_name = current_name + formatter.camel_case(attribute) if current_name else None
173-
attr_type = typing_to_python(child_schema, alternative_name=alternative_name)
117+
attr_type = type_to_python(child_schema, alternative_name=alternative_name, typing=True)
174118
if child_schema.get("nullable"):
175119
if optional:
176120
return f"Union[{attr_type}, none_type, UnsetType]"
@@ -200,18 +144,8 @@ def get_type_for_parameter(parameter, typing=False):
200144
if "content" in parameter:
201145
assert "in" not in parameter
202146
for content in parameter["content"].values():
203-
data = type_to_python(content["schema"])
204-
if typing:
205-
if "oneOf" in content["schema"]:
206-
types = [data]
207-
types.extend(get_oneof_types(content["schema"]))
208-
return f"Union[{','.join(types)}]"
209-
data = data.replace("[", "List[")
210-
return data
211-
data = type_to_python(parameter.get("schema"))
212-
if typing:
213-
data = data.replace("[", "List[")
214-
return data
147+
return type_to_python(content["schema"], typing=typing)
148+
return type_to_python(parameter.get("schema"), typing=typing)
215149

216150

217151
def get_enum_type(schema):

0 commit comments

Comments
 (0)