Skip to content

Commit 1512225

Browse files
Refactor out logic for JSON types and fix enum value bug
1 parent fa92f9a commit 1512225

File tree

18 files changed

+65
-37
lines changed

18 files changed

+65
-37
lines changed

end_to_end_tests/golden-record-custom/custom_e2e/api/tests/defaults_tests_defaults_post.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -96,22 +96,22 @@ def httpx_request(
9696
else:
9797
json_union_prop = union_prop
9898

99-
json_union_prop_with_ref: Union[Unset, None, float, AnEnum]
99+
json_union_prop_with_ref: Union[Unset, None, float, int]
100100
if isinstance(union_prop_with_ref, Unset):
101101
json_union_prop_with_ref = UNSET
102102
elif union_prop_with_ref is None:
103103
json_union_prop_with_ref = None
104104
elif isinstance(union_prop_with_ref, AnEnum):
105105
json_union_prop_with_ref = UNSET
106106
if not isinstance(union_prop_with_ref, Unset):
107-
json_union_prop_with_ref = union_prop_with_ref
107+
json_union_prop_with_ref = union_prop_with_ref.value
108108

109109
else:
110110
json_union_prop_with_ref = union_prop_with_ref
111111

112-
json_enum_prop: Union[Unset, None, AnEnum] = UNSET
112+
json_enum_prop: Union[Unset, None, int] = UNSET
113113
if not isinstance(enum_prop, Unset):
114-
json_enum_prop = enum_prop if enum_prop else None
114+
json_enum_prop = enum_prop.value if enum_prop else None
115115

116116
params: Dict[str, Any] = {
117117
"required_not_nullable_datetime_prop": json_required_not_nullable_datetime_prop,

end_to_end_tests/golden-record-custom/custom_e2e/models/model_with_union_property.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,18 +16,18 @@ class ModelWithUnionProperty:
1616
a_property: Union[Unset, AnEnum, AnIntEnum] = UNSET
1717

1818
def to_dict(self) -> Dict[str, Any]:
19-
a_property: Union[Unset, AnEnum, AnIntEnum]
19+
a_property: Union[Unset, int]
2020
if isinstance(self.a_property, Unset):
2121
a_property = UNSET
2222
elif isinstance(self.a_property, AnEnum):
2323
a_property = UNSET
2424
if not isinstance(self.a_property, Unset):
25-
a_property = self.a_property
25+
a_property = self.a_property.value
2626

2727
else:
2828
a_property = UNSET
2929
if not isinstance(self.a_property, Unset):
30-
a_property = self.a_property
30+
a_property = self.a_property.value
3131

3232
field_dict: Dict[str, Any] = {}
3333
field_dict.update({})

end_to_end_tests/golden-record-custom/custom_e2e/types.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ def __bool__(self) -> bool:
1111

1212
UNSET: Unset = Unset()
1313

14+
# Used as `FileProperty._json_type_string`
15+
FileJsonType = Tuple[Optional[str], Union[BinaryIO, TextIO], Optional[str]]
16+
1417

1518
@attr.s(auto_attribs=True)
1619
class File:
@@ -20,7 +23,7 @@ class File:
2023
file_name: Optional[str] = None
2124
mime_type: Optional[str] = None
2225

23-
def to_tuple(self) -> Tuple[Optional[str], Union[BinaryIO, TextIO], Optional[str]]:
26+
def to_tuple(self) -> FileJsonType:
2427
""" Return a tuple representation that httpx will accept for multipart/form-data """
2528
return self.file_name, self.payload, self.mime_type
2629

end_to_end_tests/golden-record/my_test_api_client/api/tests/defaults_tests_defaults_post.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -72,22 +72,22 @@ def _get_kwargs(
7272
else:
7373
json_union_prop = union_prop
7474

75-
json_union_prop_with_ref: Union[Unset, None, float, AnEnum]
75+
json_union_prop_with_ref: Union[Unset, None, float, int]
7676
if isinstance(union_prop_with_ref, Unset):
7777
json_union_prop_with_ref = UNSET
7878
elif union_prop_with_ref is None:
7979
json_union_prop_with_ref = None
8080
elif isinstance(union_prop_with_ref, AnEnum):
8181
json_union_prop_with_ref = UNSET
8282
if not isinstance(union_prop_with_ref, Unset):
83-
json_union_prop_with_ref = union_prop_with_ref
83+
json_union_prop_with_ref = union_prop_with_ref.value
8484

8585
else:
8686
json_union_prop_with_ref = union_prop_with_ref
8787

88-
json_enum_prop: Union[Unset, None, AnEnum] = UNSET
88+
json_enum_prop: Union[Unset, None, int] = UNSET
8989
if not isinstance(enum_prop, Unset):
90-
json_enum_prop = enum_prop if enum_prop else None
90+
json_enum_prop = enum_prop.value if enum_prop else None
9191

9292
params: Dict[str, Any] = {
9393
"required_not_nullable_datetime_prop": json_required_not_nullable_datetime_prop,

end_to_end_tests/golden-record/my_test_api_client/models/model_with_union_property.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,18 +16,18 @@ class ModelWithUnionProperty:
1616
a_property: Union[Unset, AnEnum, AnIntEnum] = UNSET
1717

1818
def to_dict(self) -> Dict[str, Any]:
19-
a_property: Union[Unset, AnEnum, AnIntEnum]
19+
a_property: Union[Unset, int]
2020
if isinstance(self.a_property, Unset):
2121
a_property = UNSET
2222
elif isinstance(self.a_property, AnEnum):
2323
a_property = UNSET
2424
if not isinstance(self.a_property, Unset):
25-
a_property = self.a_property
25+
a_property = self.a_property.value
2626

2727
else:
2828
a_property = UNSET
2929
if not isinstance(self.a_property, Unset):
30-
a_property = self.a_property
30+
a_property = self.a_property.value
3131

3232
field_dict: Dict[str, Any] = {}
3333
field_dict.update({})

end_to_end_tests/golden-record/my_test_api_client/types.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ def __bool__(self) -> bool:
1111

1212
UNSET: Unset = Unset()
1313

14+
# Used as `FileProperty._json_type_string`
15+
FileJsonType = Tuple[Optional[str], Union[BinaryIO, TextIO], Optional[str]]
16+
1417

1518
@attr.s(auto_attribs=True)
1619
class File:
@@ -20,7 +23,7 @@ class File:
2023
file_name: Optional[str] = None
2124
mime_type: Optional[str] = None
2225

23-
def to_tuple(self) -> Tuple[Optional[str], Union[BinaryIO, TextIO], Optional[str]]:
26+
def to_tuple(self) -> FileJsonType:
2427
""" Return a tuple representation that httpx will accept for multipart/form-data """
2528
return self.file_name, self.payload, self.mime_type
2629

openapi_python_client/parser/properties/__init__.py

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ class NoneProperty(Property):
1919
""" A property that is always None (used for empty schemas) """
2020

2121
_type_string: ClassVar[str] = "None"
22+
_json_type_string: ClassVar[str] = "None"
2223
template: ClassVar[Optional[str]] = "none_property.pyi"
2324

2425

@@ -29,6 +30,7 @@ class StringProperty(Property):
2930
max_length: Optional[int] = None
3031
pattern: Optional[str] = None
3132
_type_string: ClassVar[str] = "str"
33+
_json_type_string: ClassVar[str] = "str"
3234

3335

3436
@attr.s(auto_attribs=True, frozen=True)
@@ -38,6 +40,7 @@ class DateTimeProperty(Property):
3840
"""
3941

4042
_type_string: ClassVar[str] = "datetime.datetime"
43+
_json_type_string: ClassVar[str] = "str"
4144
template: ClassVar[str] = "datetime_property.pyi"
4245

4346
def get_imports(self, *, prefix: str) -> Set[str]:
@@ -58,6 +61,7 @@ class DateProperty(Property):
5861
""" A property of type datetime.date """
5962

6063
_type_string: ClassVar[str] = "datetime.date"
64+
_json_type_string: ClassVar[str] = "str"
6165
template: ClassVar[str] = "date_property.pyi"
6266

6367
def get_imports(self, *, prefix: str) -> Set[str]:
@@ -78,6 +82,8 @@ class FileProperty(Property):
7882
""" A property used for uploading files """
7983

8084
_type_string: ClassVar[str] = "File"
85+
# Return type of File.to_tuple()
86+
_json_type_string: ClassVar[str] = "Tuple[Optional[str], Union[BinaryIO, TextIO], Optional[str]]"
8187
template: ClassVar[str] = "file_property.pyi"
8288

8389
def get_imports(self, *, prefix: str) -> Set[str]:
@@ -98,20 +104,23 @@ class FloatProperty(Property):
98104
""" A property of type float """
99105

100106
_type_string: ClassVar[str] = "float"
107+
_json_type_string: ClassVar[str] = "float"
101108

102109

103110
@attr.s(auto_attribs=True, frozen=True)
104111
class IntProperty(Property):
105112
""" A property of type int """
106113

107114
_type_string: ClassVar[str] = "int"
115+
_json_type_string: ClassVar[str] = "int"
108116

109117

110118
@attr.s(auto_attribs=True, frozen=True)
111119
class BooleanProperty(Property):
112120
""" Property for bool """
113121

114122
_type_string: ClassVar[str] = "bool"
123+
_json_type_string: ClassVar[str] = "bool"
115124

116125

117126
InnerProp = TypeVar("InnerProp", bound=Property)
@@ -122,6 +131,7 @@ class ListProperty(Property, Generic[InnerProp]):
122131
""" A property representing a list (array) of other properties """
123132

124133
inner_property: InnerProp
134+
_json_type_string: ClassVar[str] = "List[Any]"
125135
template: ClassVar[str] = "list_property.pyi"
126136

127137
def get_base_type_string(self) -> str:
@@ -159,37 +169,38 @@ def __attrs_post_init__(self) -> None:
159169
self, "has_properties_without_templates", any(prop.template is None for prop in self.inner_properties)
160170
)
161171

162-
def _get_inner_prop_string(self) -> str:
163-
inner_types = [p.get_type_string(no_optional=True) for p in self.inner_properties]
164-
return ", ".join(inner_types)
172+
def _get_inner_prop_string(self, json: bool = False) -> str:
173+
inner_types = [p.get_type_string(no_optional=True, json=json) for p in self.inner_properties]
174+
unique_inner_types = list(dict.fromkeys(inner_types))
175+
return ", ".join(unique_inner_types)
165176

166177
def get_base_type_string(self) -> str:
167178
return f"Union[{self._get_inner_prop_string()}]"
168179

169-
def get_type_string(self, no_optional: bool = False, query_parameter: bool = False) -> str:
180+
def get_type_string(self, no_optional: bool = False, query_parameter: bool = False, json: bool = False) -> str:
170181
"""
171182
Get a string representation of type that should be used when declaring this property.
172183
173184
This implementation differs slightly from `Property.get_type_string` in order to collapse
174185
nested union types.
175186
"""
176-
type_string = self.get_base_type_string()
187+
type_string = f"Union[{self._get_inner_prop_string(json=json)}]"
177188
if no_optional:
178189
return type_string
179190
if self.required:
180191
if self.nullable:
181-
return f"Union[None, {self._get_inner_prop_string()}]"
192+
return f"Union[None, {self._get_inner_prop_string(json=json)}]"
182193
else:
183194
return type_string
184195
else:
185196
if self.nullable:
186-
return f"Union[Unset, None, {self._get_inner_prop_string()}]"
197+
return f"Union[Unset, None, {self._get_inner_prop_string(json=json)}]"
187198
else:
188199
if query_parameter:
189200
# For query parameters, None has the same meaning as Unset
190-
return f"Union[Unset, None, {self._get_inner_prop_string()}]"
201+
return f"Union[Unset, None, {self._get_inner_prop_string(json=json)}]"
191202
else:
192-
return f"Union[Unset, {self._get_inner_prop_string()}]"
203+
return f"Union[Unset, {self._get_inner_prop_string(json=json)}]"
193204

194205
def get_imports(self, *, prefix: str) -> Set[str]:
195206
"""

openapi_python_client/parser/properties/enum_property.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ class EnumProperty(Property):
1818
values: Dict[str, ValueType]
1919
reference: Reference
2020
value_type: Type[ValueType]
21+
_json_type_string: ClassVar[str] = "int"
2122
default: Optional[Any] = attr.ib()
2223

2324
template: ClassVar[str] = "enum_property.pyi"

openapi_python_client/parser/properties/model_property.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ class ModelProperty(Property):
1717
description: str
1818
relative_imports: Set[str]
1919
additional_properties: Union[bool, Property]
20+
_json_type_string: ClassVar[str] = "Dict[str, Any]"
2021

2122
template: ClassVar[str] = "model_property.pyi"
2223

openapi_python_client/parser/properties/property.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ class Property:
2424
required: bool
2525
nullable: bool
2626
_type_string: ClassVar[str] = ""
27+
_json_type_string: ClassVar[str] = "" # Type of the property after JSON serialization
2728
default: Optional[str] = attr.ib()
2829
python_name: str = attr.ib(init=False)
2930

@@ -35,15 +36,20 @@ def __attrs_post_init__(self) -> None:
3536
def get_base_type_string(self) -> str:
3637
return self._type_string
3738

38-
def get_type_string(self, no_optional: bool = False, query_parameter: bool = False) -> str:
39+
def get_type_string(self, no_optional: bool = False, query_parameter: bool = False, json: bool = False) -> str:
3940
"""
4041
Get a string representation of type that should be used when declaring this property
4142
4243
Args:
4344
no_optional: Do not include Optional or Unset even if the value is optional (needed for isinstance checks)
4445
query_parameter: True if the property's type is being used for a query parameter
46+
json: True if the type refers to the property after JSON serialization
4547
"""
46-
type_string = self.get_base_type_string()
48+
if json:
49+
type_string = self._json_type_string
50+
else:
51+
type_string = self.get_base_type_string()
52+
4753
if no_optional:
4854
return type_string
4955
if self.required:

0 commit comments

Comments
 (0)