Skip to content

Commit da1d970

Browse files
Merge upstream/main
2 parents c251560 + 661de57 commit da1d970

29 files changed

+235
-111
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
2121
- Attempt to detect and alert users if they are using an unsupported version of OpenAPI (#281).
2222
- Fixes `Enum` deserialization when the value is `UNSET`.
2323
- Add handling of application/vnd.api+json media type.
24+
- Support passing models into query parameters (#316). Thanks @forest-benchling!
2425

2526
### Changes
2627

@@ -32,6 +33,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
3233

3334
- Parser will softly ignore value error during schema responses' status code convertion from string to integer (not a number). Errors will be reported to the end user and parsing will continue to proceed (#327).
3435
- The generated `from_dict` and `to_dict` methods of models will now properly handle `nullable` and `not required` properties that are themselves generated models (#315). Thanks @forest-benchling!
36+
- Fix deserialization of `None` and `Unset` properties for all types by unifying the checks (#334). Thanks @forest-benchling!
37+
- If duplicate model names are detected during generation, you'll now get an error message instead of broken code (#336). Thanks @forest-benchling!
3538

3639
## 0.7.3 - 2020-12-21
3740

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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
from ...models.an_enum import AnEnum
1515
from ...models.http_validation_error import HTTPValidationError
16+
from ...models.model_with_union_property import ModelWithUnionProperty
1617
from ...types import UNSET, Unset
1718

1819

@@ -50,6 +51,8 @@ def httpx_request(
5051
union_prop: Union[Unset, float, str] = "not a float",
5152
union_prop_with_ref: Union[Unset, float, AnEnum] = 0.6,
5253
enum_prop: Union[Unset, AnEnum] = UNSET,
54+
model_prop: Union[ModelWithUnionProperty, Unset] = UNSET,
55+
required_model_prop: ModelWithUnionProperty,
5356
) -> Response[Union[None, HTTPValidationError]]:
5457

5558
json_datetime_prop: Union[Unset, str] = UNSET
@@ -89,6 +92,12 @@ def httpx_request(
8992
if not isinstance(enum_prop, Unset):
9093
json_enum_prop = enum_prop
9194

95+
json_model_prop: Union[Unset, Dict[str, Any]] = UNSET
96+
if not isinstance(model_prop, Unset):
97+
json_model_prop = model_prop.to_dict()
98+
99+
json_required_model_prop = required_model_prop.to_dict()
100+
92101
params: Dict[str, Any] = {
93102
"string_prop": string_prop,
94103
"datetime_prop": json_datetime_prop,
@@ -101,6 +110,9 @@ def httpx_request(
101110
"union_prop_with_ref": json_union_prop_with_ref,
102111
"enum_prop": json_enum_prop,
103112
}
113+
if not isinstance(json_model_prop, Unset):
114+
params.update(json_model_prop)
115+
params.update(json_required_model_prop)
104116
params = {k: v for k, v in params.items() if v is not UNSET and v is not None}
105117

106118
response = client.request(

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ def _parse_response(*, response: httpx.Response) -> Optional[Union[
2424
if response.status_code == 422:
2525
response_422 = HTTPValidationError.from_dict(response.json())
2626

27+
28+
2729
return response_422
2830
return None
2931

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

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import datetime
2-
from typing import Any, Dict, List, Optional, Type, TypeVar, Union, cast
2+
from typing import Any, Dict, List, Optional, Type, TypeVar, Union
33

44
import attr
55
from dateutil.parser import isoparse
@@ -28,6 +28,7 @@ class AModel:
2828
required_nullable: Optional[str]
2929
nullable_model: Optional[AModelNullableModel]
3030
nested_list_of_enums: Union[Unset, List[List[DifferentEnum]]] = UNSET
31+
a_not_required_date: Union[Unset, datetime.date] = UNSET
3132
attr_1_leading_digit: Union[Unset, str] = UNSET
3233
not_required_nullable: Union[Unset, Optional[str]] = UNSET
3334
not_required_not_nullable: Union[Unset, str] = UNSET
@@ -60,6 +61,10 @@ def to_dict(self) -> Dict[str, Any]:
6061
nested_list_of_enums.append(nested_list_of_enums_item)
6162

6263
a_nullable_date = self.a_nullable_date.isoformat() if self.a_nullable_date else None
64+
a_not_required_date: Union[Unset, str] = UNSET
65+
if not isinstance(self.a_not_required_date, Unset):
66+
a_not_required_date = self.a_not_required_date.isoformat()
67+
6368
attr_1_leading_digit = self.attr_1_leading_digit
6469
required_nullable = self.required_nullable
6570
not_required_nullable = self.not_required_nullable
@@ -91,6 +96,8 @@ def to_dict(self) -> Dict[str, Any]:
9196
)
9297
if nested_list_of_enums is not UNSET:
9398
field_dict["nested_list_of_enums"] = nested_list_of_enums
99+
if a_not_required_date is not UNSET:
100+
field_dict["a_not_required_date"] = a_not_required_date
94101
if attr_1_leading_digit is not UNSET:
95102
field_dict["1_leading_digit"] = attr_1_leading_digit
96103
if not_required_nullable is not UNSET:
@@ -146,7 +153,12 @@ def _parse_a_camel_date_time(data: Any) -> Union[datetime.datetime, datetime.dat
146153
a_nullable_date = None
147154
_a_nullable_date = d.pop("a_nullable_date")
148155
if _a_nullable_date is not None:
149-
a_nullable_date = isoparse(cast(str, _a_nullable_date)).date()
156+
a_nullable_date = isoparse(_a_nullable_date).date()
157+
158+
a_not_required_date: Union[Unset, datetime.date] = UNSET
159+
_a_not_required_date = d.pop("a_not_required_date", UNSET)
160+
if not isinstance(_a_not_required_date, Unset):
161+
a_not_required_date = isoparse(_a_not_required_date).date()
150162

151163
attr_1_leading_digit = d.pop("1_leading_digit", UNSET)
152164

@@ -159,19 +171,17 @@ def _parse_a_camel_date_time(data: Any) -> Union[datetime.datetime, datetime.dat
159171
nullable_model = None
160172
_nullable_model = d.pop("nullable_model")
161173
if _nullable_model is not None:
162-
nullable_model = AModelNullableModel.from_dict(cast(Dict[str, Any], _nullable_model))
174+
nullable_model = AModelNullableModel.from_dict(_nullable_model)
163175

164176
not_required_model: Union[AModelNotRequiredModel, Unset] = UNSET
165177
_not_required_model = d.pop("not_required_model", UNSET)
166178
if not isinstance(_not_required_model, Unset):
167-
not_required_model = AModelNotRequiredModel.from_dict(cast(Dict[str, Any], _not_required_model))
179+
not_required_model = AModelNotRequiredModel.from_dict(_not_required_model)
168180

169181
not_required_nullable_model = None
170182
_not_required_nullable_model = d.pop("not_required_nullable_model", UNSET)
171183
if _not_required_nullable_model is not None and not isinstance(_not_required_nullable_model, Unset):
172-
not_required_nullable_model = AModelNotRequiredNullableModel.from_dict(
173-
cast(Dict[str, Any], _not_required_nullable_model)
174-
)
184+
not_required_nullable_model = AModelNotRequiredNullableModel.from_dict(_not_required_nullable_model)
175185

176186
a_model = cls(
177187
an_enum_value=an_enum_value,
@@ -181,6 +191,7 @@ def _parse_a_camel_date_time(data: Any) -> Union[datetime.datetime, datetime.dat
181191
model=model,
182192
nested_list_of_enums=nested_list_of_enums,
183193
a_nullable_date=a_nullable_date,
194+
a_not_required_date=a_not_required_date,
184195
attr_1_leading_digit=attr_1_leading_digit,
185196
required_nullable=required_nullable,
186197
not_required_nullable=not_required_nullable,

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

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from typing import Any, Dict, List, Type, TypeVar, Union, cast
1+
from typing import Any, Dict, List, Type, TypeVar, Union
22

33
import attr
44

@@ -36,9 +36,7 @@ def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T:
3636
a_date_holder: Union[ModelWithPrimitiveAdditionalPropertiesADateHolder, Unset] = UNSET
3737
_a_date_holder = d.pop("a_date_holder", UNSET)
3838
if not isinstance(_a_date_holder, Unset):
39-
a_date_holder = ModelWithPrimitiveAdditionalPropertiesADateHolder.from_dict(
40-
cast(Dict[str, Any], _a_date_holder)
41-
)
39+
a_date_holder = ModelWithPrimitiveAdditionalPropertiesADateHolder.from_dict(_a_date_holder)
4240

4341
model_with_primitive_additional_properties = cls(
4442
a_date_holder=a_date_holder,

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ def _parse_a_property(data: Any) -> Union[Unset, AnEnum, AnIntEnum]:
4646
a_property_item0: Union[Unset, AnEnum]
4747
a_property_item0 = UNSET
4848
_a_property_item0 = data
49-
if _a_property_item0 is not None and _a_property_item0 is not UNSET:
49+
if not isinstance(_a_property_item0, Unset):
5050
a_property_item0 = AnEnum(_a_property_item0)
5151

5252
return a_property_item0
@@ -55,7 +55,7 @@ def _parse_a_property(data: Any) -> Union[Unset, AnEnum, AnIntEnum]:
5555
a_property_item1: Union[Unset, AnIntEnum]
5656
a_property_item1 = UNSET
5757
_a_property_item1 = data
58-
if _a_property_item1 is not None and _a_property_item1 is not UNSET:
58+
if not isinstance(_a_property_item1, Unset):
5959
a_property_item1 = AnIntEnum(_a_property_item1)
6060

6161
return a_property_item1

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from typing import Any, Dict, Type, TypeVar, Union, cast
1+
from typing import Any, Dict, Type, TypeVar, Union
22

33
import attr
44

@@ -49,7 +49,7 @@ def _parse_fruit(
4949
fruit_item0 = UNSET
5050
_fruit_item0 = data
5151
if not isinstance(_fruit_item0, Unset):
52-
fruit_item0 = ModelWithUnionPropertyInlinedFruitItem0.from_dict(cast(Dict[str, Any], _fruit_item0))
52+
fruit_item0 = ModelWithUnionPropertyInlinedFruitItem0.from_dict(_fruit_item0)
5353

5454
return fruit_item0
5555
except: # noqa: E722
@@ -58,7 +58,7 @@ def _parse_fruit(
5858
fruit_item1 = UNSET
5959
_fruit_item1 = data
6060
if not isinstance(_fruit_item1, Unset):
61-
fruit_item1 = ModelWithUnionPropertyInlinedFruitItem1.from_dict(cast(Dict[str, Any], _fruit_item1))
61+
fruit_item1 = ModelWithUnionPropertyInlinedFruitItem1.from_dict(_fruit_item1)
6262

6363
return fruit_item1
6464

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

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
from ...client import Client
88
from ...models.an_enum import AnEnum
99
from ...models.http_validation_error import HTTPValidationError
10+
from ...models.model_with_union_property import ModelWithUnionProperty
1011
from ...types import UNSET, Response, Unset
1112

1213

@@ -23,6 +24,8 @@ def _get_kwargs(
2324
union_prop: Union[Unset, float, str] = "not a float",
2425
union_prop_with_ref: Union[Unset, float, AnEnum] = 0.6,
2526
enum_prop: Union[Unset, AnEnum] = UNSET,
27+
model_prop: Union[ModelWithUnionProperty, Unset] = UNSET,
28+
required_model_prop: ModelWithUnionProperty,
2629
) -> Dict[str, Any]:
2730
url = "{}/tests/defaults".format(client.base_url)
2831

@@ -65,6 +68,12 @@ def _get_kwargs(
6568
if not isinstance(enum_prop, Unset):
6669
json_enum_prop = enum_prop
6770

71+
json_model_prop: Union[Unset, Dict[str, Any]] = UNSET
72+
if not isinstance(model_prop, Unset):
73+
json_model_prop = model_prop.to_dict()
74+
75+
json_required_model_prop = required_model_prop.to_dict()
76+
6877
params: Dict[str, Any] = {
6978
"string_prop": string_prop,
7079
"datetime_prop": json_datetime_prop,
@@ -77,6 +86,9 @@ def _get_kwargs(
7786
"union_prop_with_ref": json_union_prop_with_ref,
7887
"enum_prop": json_enum_prop,
7988
}
89+
if not isinstance(json_model_prop, Unset):
90+
params.update(json_model_prop)
91+
params.update(json_required_model_prop)
8092
params = {k: v for k, v in params.items() if v is not UNSET and v is not None}
8193

8294
return {
@@ -122,6 +134,8 @@ def sync_detailed(
122134
union_prop: Union[Unset, float, str] = "not a float",
123135
union_prop_with_ref: Union[Unset, float, AnEnum] = 0.6,
124136
enum_prop: Union[Unset, AnEnum] = UNSET,
137+
model_prop: Union[ModelWithUnionProperty, Unset] = UNSET,
138+
required_model_prop: ModelWithUnionProperty,
125139
) -> Response[Union[None, HTTPValidationError]]:
126140
kwargs = _get_kwargs(
127141
client=client,
@@ -135,6 +149,8 @@ def sync_detailed(
135149
union_prop=union_prop,
136150
union_prop_with_ref=union_prop_with_ref,
137151
enum_prop=enum_prop,
152+
model_prop=model_prop,
153+
required_model_prop=required_model_prop,
138154
)
139155

140156
response = httpx.post(
@@ -157,6 +173,8 @@ def sync(
157173
union_prop: Union[Unset, float, str] = "not a float",
158174
union_prop_with_ref: Union[Unset, float, AnEnum] = 0.6,
159175
enum_prop: Union[Unset, AnEnum] = UNSET,
176+
model_prop: Union[ModelWithUnionProperty, Unset] = UNSET,
177+
required_model_prop: ModelWithUnionProperty,
160178
) -> Optional[Union[None, HTTPValidationError]]:
161179
""" """
162180

@@ -172,6 +190,8 @@ def sync(
172190
union_prop=union_prop,
173191
union_prop_with_ref=union_prop_with_ref,
174192
enum_prop=enum_prop,
193+
model_prop=model_prop,
194+
required_model_prop=required_model_prop,
175195
).parsed
176196

177197

@@ -188,6 +208,8 @@ async def asyncio_detailed(
188208
union_prop: Union[Unset, float, str] = "not a float",
189209
union_prop_with_ref: Union[Unset, float, AnEnum] = 0.6,
190210
enum_prop: Union[Unset, AnEnum] = UNSET,
211+
model_prop: Union[ModelWithUnionProperty, Unset] = UNSET,
212+
required_model_prop: ModelWithUnionProperty,
191213
) -> Response[Union[None, HTTPValidationError]]:
192214
kwargs = _get_kwargs(
193215
client=client,
@@ -201,6 +223,8 @@ async def asyncio_detailed(
201223
union_prop=union_prop,
202224
union_prop_with_ref=union_prop_with_ref,
203225
enum_prop=enum_prop,
226+
model_prop=model_prop,
227+
required_model_prop=required_model_prop,
204228
)
205229

206230
async with httpx.AsyncClient() as _client:
@@ -222,6 +246,8 @@ async def asyncio(
222246
union_prop: Union[Unset, float, str] = "not a float",
223247
union_prop_with_ref: Union[Unset, float, AnEnum] = 0.6,
224248
enum_prop: Union[Unset, AnEnum] = UNSET,
249+
model_prop: Union[ModelWithUnionProperty, Unset] = UNSET,
250+
required_model_prop: ModelWithUnionProperty,
225251
) -> Optional[Union[None, HTTPValidationError]]:
226252
""" """
227253

@@ -238,5 +264,7 @@ async def asyncio(
238264
union_prop=union_prop,
239265
union_prop_with_ref=union_prop_with_ref,
240266
enum_prop=enum_prop,
267+
model_prop=model_prop,
268+
required_model_prop=required_model_prop,
241269
)
242270
).parsed

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

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import datetime
2-
from typing import Any, Dict, List, Optional, Type, TypeVar, Union, cast
2+
from typing import Any, Dict, List, Optional, Type, TypeVar, Union
33

44
import attr
55
from dateutil.parser import isoparse
@@ -28,6 +28,7 @@ class AModel:
2828
required_nullable: Optional[str]
2929
nullable_model: Optional[AModelNullableModel]
3030
nested_list_of_enums: Union[Unset, List[List[DifferentEnum]]] = UNSET
31+
a_not_required_date: Union[Unset, datetime.date] = UNSET
3132
attr_1_leading_digit: Union[Unset, str] = UNSET
3233
not_required_nullable: Union[Unset, Optional[str]] = UNSET
3334
not_required_not_nullable: Union[Unset, str] = UNSET
@@ -60,6 +61,10 @@ def to_dict(self) -> Dict[str, Any]:
6061
nested_list_of_enums.append(nested_list_of_enums_item)
6162

6263
a_nullable_date = self.a_nullable_date.isoformat() if self.a_nullable_date else None
64+
a_not_required_date: Union[Unset, str] = UNSET
65+
if not isinstance(self.a_not_required_date, Unset):
66+
a_not_required_date = self.a_not_required_date.isoformat()
67+
6368
attr_1_leading_digit = self.attr_1_leading_digit
6469
required_nullable = self.required_nullable
6570
not_required_nullable = self.not_required_nullable
@@ -91,6 +96,8 @@ def to_dict(self) -> Dict[str, Any]:
9196
)
9297
if nested_list_of_enums is not UNSET:
9398
field_dict["nested_list_of_enums"] = nested_list_of_enums
99+
if a_not_required_date is not UNSET:
100+
field_dict["a_not_required_date"] = a_not_required_date
94101
if attr_1_leading_digit is not UNSET:
95102
field_dict["1_leading_digit"] = attr_1_leading_digit
96103
if not_required_nullable is not UNSET:
@@ -146,7 +153,12 @@ def _parse_a_camel_date_time(data: Any) -> Union[datetime.datetime, datetime.dat
146153
a_nullable_date = None
147154
_a_nullable_date = d.pop("a_nullable_date")
148155
if _a_nullable_date is not None:
149-
a_nullable_date = isoparse(cast(str, _a_nullable_date)).date()
156+
a_nullable_date = isoparse(_a_nullable_date).date()
157+
158+
a_not_required_date: Union[Unset, datetime.date] = UNSET
159+
_a_not_required_date = d.pop("a_not_required_date", UNSET)
160+
if not isinstance(_a_not_required_date, Unset):
161+
a_not_required_date = isoparse(_a_not_required_date).date()
150162

151163
attr_1_leading_digit = d.pop("1_leading_digit", UNSET)
152164

@@ -159,19 +171,17 @@ def _parse_a_camel_date_time(data: Any) -> Union[datetime.datetime, datetime.dat
159171
nullable_model = None
160172
_nullable_model = d.pop("nullable_model")
161173
if _nullable_model is not None:
162-
nullable_model = AModelNullableModel.from_dict(cast(Dict[str, Any], _nullable_model))
174+
nullable_model = AModelNullableModel.from_dict(_nullable_model)
163175

164176
not_required_model: Union[AModelNotRequiredModel, Unset] = UNSET
165177
_not_required_model = d.pop("not_required_model", UNSET)
166178
if not isinstance(_not_required_model, Unset):
167-
not_required_model = AModelNotRequiredModel.from_dict(cast(Dict[str, Any], _not_required_model))
179+
not_required_model = AModelNotRequiredModel.from_dict(_not_required_model)
168180

169181
not_required_nullable_model = None
170182
_not_required_nullable_model = d.pop("not_required_nullable_model", UNSET)
171183
if _not_required_nullable_model is not None and not isinstance(_not_required_nullable_model, Unset):
172-
not_required_nullable_model = AModelNotRequiredNullableModel.from_dict(
173-
cast(Dict[str, Any], _not_required_nullable_model)
174-
)
184+
not_required_nullable_model = AModelNotRequiredNullableModel.from_dict(_not_required_nullable_model)
175185

176186
a_model = cls(
177187
an_enum_value=an_enum_value,
@@ -181,6 +191,7 @@ def _parse_a_camel_date_time(data: Any) -> Union[datetime.datetime, datetime.dat
181191
model=model,
182192
nested_list_of_enums=nested_list_of_enums,
183193
a_nullable_date=a_nullable_date,
194+
a_not_required_date=a_not_required_date,
184195
attr_1_leading_digit=attr_1_leading_digit,
185196
required_nullable=required_nullable,
186197
not_required_nullable=not_required_nullable,

0 commit comments

Comments
 (0)