Skip to content

Nullable array support fixes #929

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Jan 4, 2024
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions .changeset/fix_lists_within_unions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
default: patch
---

# Fix lists within unions

Fixes #756 and #928. Arrays within unions (which, as of 0.17 includes nullable arrays) would generate invalid code.

Thanks @kgutwin and @diesieben07!
5 changes: 5 additions & 0 deletions .changeset/simplify_type_checks_for_non_required_unions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
default: patch
---

# Simplify type checks for non-required unions
3 changes: 2 additions & 1 deletion end_to_end_tests/baseline_openapi_3.0.json
Original file line number Diff line number Diff line change
Expand Up @@ -1778,9 +1778,10 @@
},
"some_array": {
"title": "Some Array",
"nullable": true,
"type": "array",
"items": {
"type": "number"
"$ref": "#/components/schemas/AFormData"
}
},
"some_object": {
Expand Down
4 changes: 2 additions & 2 deletions end_to_end_tests/baseline_openapi_3.1.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1794,9 +1794,9 @@ info:
},
"some_array": {
"title": "Some Array",
"type": "array",
"type": [ "array", "null" ],
"items": {
"type": "number"
"$ref": "#/components/schemas/AFormData"
}
},
"some_object": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,7 @@ def _get_kwargs(
if isinstance(union_prop_with_ref, Unset):
json_union_prop_with_ref = UNSET
elif isinstance(union_prop_with_ref, AnEnum):
json_union_prop_with_ref = UNSET
if not isinstance(union_prop_with_ref, Unset):
json_union_prop_with_ref = union_prop_with_ref.value

json_union_prop_with_ref = union_prop_with_ref.value
else:
json_union_prop_with_ref = union_prop_with_ref
params["union_prop_with_ref"] = json_union_prop_with_ref
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,7 @@ def _get_kwargs(
if isinstance(null_not_required, Unset):
json_null_not_required = UNSET
elif isinstance(null_not_required, datetime.datetime):
json_null_not_required = UNSET
if not isinstance(null_not_required, Unset):
json_null_not_required = null_not_required.isoformat()
json_null_not_required = null_not_required.isoformat()
else:
json_null_not_required = null_not_required
params["null_not_required"] = json_null_not_required
Expand Down
61 changes: 10 additions & 51 deletions end_to_end_tests/golden-record/my_test_api_client/models/a_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -159,25 +159,17 @@ def to_dict(self) -> Dict[str, Any]:
if isinstance(self.not_required_one_of_models, Unset):
not_required_one_of_models = UNSET
elif isinstance(self.not_required_one_of_models, FreeFormModel):
not_required_one_of_models = UNSET
if not isinstance(self.not_required_one_of_models, Unset):
not_required_one_of_models = self.not_required_one_of_models.to_dict()
not_required_one_of_models = self.not_required_one_of_models.to_dict()
else:
not_required_one_of_models = UNSET
if not isinstance(self.not_required_one_of_models, Unset):
not_required_one_of_models = self.not_required_one_of_models.to_dict()
not_required_one_of_models = self.not_required_one_of_models.to_dict()

not_required_nullable_one_of_models: Union[Dict[str, Any], None, Unset, str]
if isinstance(self.not_required_nullable_one_of_models, Unset):
not_required_nullable_one_of_models = UNSET
elif isinstance(self.not_required_nullable_one_of_models, FreeFormModel):
not_required_nullable_one_of_models = UNSET
if not isinstance(self.not_required_nullable_one_of_models, Unset):
not_required_nullable_one_of_models = self.not_required_nullable_one_of_models.to_dict()
not_required_nullable_one_of_models = self.not_required_nullable_one_of_models.to_dict()
elif isinstance(self.not_required_nullable_one_of_models, ModelWithUnionProperty):
not_required_nullable_one_of_models = UNSET
if not isinstance(self.not_required_nullable_one_of_models, Unset):
not_required_nullable_one_of_models = self.not_required_nullable_one_of_models.to_dict()
not_required_nullable_one_of_models = self.not_required_nullable_one_of_models.to_dict()
else:
not_required_nullable_one_of_models = self.not_required_nullable_one_of_models

Expand All @@ -189,9 +181,7 @@ def to_dict(self) -> Dict[str, Any]:
if isinstance(self.not_required_nullable_model, Unset):
not_required_nullable_model = UNSET
elif isinstance(self.not_required_nullable_model, ModelWithUnionProperty):
not_required_nullable_model = UNSET
if not isinstance(self.not_required_nullable_model, Unset):
not_required_nullable_model = self.not_required_nullable_model.to_dict()
not_required_nullable_model = self.not_required_nullable_model.to_dict()
else:
not_required_nullable_model = self.not_required_nullable_model

Expand Down Expand Up @@ -401,24 +391,14 @@ def _parse_not_required_one_of_models(data: object) -> Union["FreeFormModel", "M
try:
if not isinstance(data, dict):
raise TypeError()
_not_required_one_of_models_type_0 = data
not_required_one_of_models_type_0: Union[Unset, FreeFormModel]
if isinstance(_not_required_one_of_models_type_0, Unset):
not_required_one_of_models_type_0 = UNSET
else:
not_required_one_of_models_type_0 = FreeFormModel.from_dict(_not_required_one_of_models_type_0)
not_required_one_of_models_type_0 = FreeFormModel.from_dict(data)

return not_required_one_of_models_type_0
except: # noqa: E722
pass
if not isinstance(data, dict):
raise TypeError()
_not_required_one_of_models_type_1 = data
not_required_one_of_models_type_1: Union[Unset, ModelWithUnionProperty]
if isinstance(_not_required_one_of_models_type_1, Unset):
not_required_one_of_models_type_1 = UNSET
else:
not_required_one_of_models_type_1 = ModelWithUnionProperty.from_dict(_not_required_one_of_models_type_1)
not_required_one_of_models_type_1 = ModelWithUnionProperty.from_dict(data)

return not_required_one_of_models_type_1

Expand All @@ -434,29 +414,15 @@ def _parse_not_required_nullable_one_of_models(
try:
if not isinstance(data, dict):
raise TypeError()
_not_required_nullable_one_of_models_type_0 = data
not_required_nullable_one_of_models_type_0: Union[Unset, FreeFormModel]
if isinstance(_not_required_nullable_one_of_models_type_0, Unset):
not_required_nullable_one_of_models_type_0 = UNSET
else:
not_required_nullable_one_of_models_type_0 = FreeFormModel.from_dict(
_not_required_nullable_one_of_models_type_0
)
not_required_nullable_one_of_models_type_0 = FreeFormModel.from_dict(data)

return not_required_nullable_one_of_models_type_0
except: # noqa: E722
pass
try:
if not isinstance(data, dict):
raise TypeError()
_not_required_nullable_one_of_models_type_1 = data
not_required_nullable_one_of_models_type_1: Union[Unset, ModelWithUnionProperty]
if isinstance(_not_required_nullable_one_of_models_type_1, Unset):
not_required_nullable_one_of_models_type_1 = UNSET
else:
not_required_nullable_one_of_models_type_1 = ModelWithUnionProperty.from_dict(
_not_required_nullable_one_of_models_type_1
)
not_required_nullable_one_of_models_type_1 = ModelWithUnionProperty.from_dict(data)

return not_required_nullable_one_of_models_type_1
except: # noqa: E722
Expand All @@ -482,14 +448,7 @@ def _parse_not_required_nullable_model(data: object) -> Union["ModelWithUnionPro
try:
if not isinstance(data, dict):
raise TypeError()
_not_required_nullable_model_type_1 = data
not_required_nullable_model_type_1: Union[Unset, ModelWithUnionProperty]
if isinstance(_not_required_nullable_model_type_1, Unset):
not_required_nullable_model_type_1 = UNSET
else:
not_required_nullable_model_type_1 = ModelWithUnionProperty.from_dict(
_not_required_nullable_model_type_1
)
not_required_nullable_model_type_1 = ModelWithUnionProperty.from_dict(data)

return not_required_nullable_model_type_1
except: # noqa: E722
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
from ..types import UNSET, File, FileJsonType, Unset

if TYPE_CHECKING:
from ..models.a_form_data import AFormData
from ..models.body_upload_file_tests_upload_post_additional_property import (
BodyUploadFileTestsUploadPostAdditionalProperty,
)
Expand Down Expand Up @@ -38,7 +39,7 @@ class BodyUploadFileTestsUploadPost:
a_datetime (Union[Unset, datetime.datetime]):
a_date (Union[Unset, datetime.date]):
some_number (Union[Unset, float]):
some_array (Union[Unset, List[float]]):
some_array (Union[List['AFormData'], None, Unset]):
some_optional_object (Union[Unset, BodyUploadFileTestsUploadPostSomeOptionalObject]):
some_enum (Union[Unset, DifferentEnum]): An enumeration.
"""
Expand All @@ -51,7 +52,7 @@ class BodyUploadFileTestsUploadPost:
a_datetime: Union[Unset, datetime.datetime] = UNSET
a_date: Union[Unset, datetime.date] = UNSET
some_number: Union[Unset, float] = UNSET
some_array: Union[Unset, List[float]] = UNSET
some_array: Union[List["AFormData"], None, Unset] = UNSET
some_optional_object: Union[Unset, "BodyUploadFileTestsUploadPostSomeOptionalObject"] = UNSET
some_enum: Union[Unset, DifferentEnum] = UNSET
additional_properties: Dict[str, "BodyUploadFileTestsUploadPostAdditionalProperty"] = _attrs_field(
Expand Down Expand Up @@ -89,8 +90,16 @@ def to_dict(self) -> Dict[str, Any]:

some_number = self.some_number

some_array: Union[Unset, List[float]] = UNSET
if not isinstance(self.some_array, Unset):
some_array: Union[List[Dict[str, Any]], None, Unset]
if isinstance(self.some_array, Unset):
some_array = UNSET
elif isinstance(self.some_array, list):
some_array = []
for some_array_type_0_item_data in self.some_array:
some_array_type_0_item = some_array_type_0_item_data.to_dict()
some_array.append(some_array_type_0_item)

else:
some_array = self.some_array

some_optional_object: Union[Unset, Dict[str, Any]] = UNSET
Expand Down Expand Up @@ -165,11 +174,19 @@ def to_multipart(self) -> Dict[str, Any]:
else (None, str(self.some_number).encode(), "text/plain")
)

some_array: Union[Unset, Tuple[None, bytes, str]] = UNSET
if not isinstance(self.some_array, Unset):
_temp_some_array = self.some_array
some_array: Union[None, Tuple[None, bytes, str], Unset]
if isinstance(self.some_array, Unset):
some_array = UNSET
elif isinstance(self.some_array, list):
_temp_some_array = []
for some_array_type_0_item_data in self.some_array:
some_array_type_0_item = some_array_type_0_item_data.to_dict()
_temp_some_array.append(some_array_type_0_item)
some_array = (None, json.dumps(_temp_some_array).encode(), "application/json")

else:
some_array = self.some_array

some_optional_object: Union[Unset, Tuple[None, bytes, str]] = UNSET
if not isinstance(self.some_optional_object, Unset):
some_optional_object = (None, json.dumps(self.some_optional_object.to_dict()).encode(), "application/json")
Expand Down Expand Up @@ -209,6 +226,7 @@ def to_multipart(self) -> Dict[str, Any]:

@classmethod
def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T:
from ..models.a_form_data import AFormData
from ..models.body_upload_file_tests_upload_post_additional_property import (
BodyUploadFileTestsUploadPostAdditionalProperty,
)
Expand Down Expand Up @@ -265,7 +283,27 @@ def _parse_some_nullable_object(data: object) -> Union["BodyUploadFileTestsUploa

some_number = d.pop("some_number", UNSET)

some_array = cast(List[float], d.pop("some_array", UNSET))
def _parse_some_array(data: object) -> Union[List["AFormData"], None, Unset]:
if data is None:
return data
if isinstance(data, Unset):
return data
try:
if not isinstance(data, list):
raise TypeError()
some_array_type_0 = []
_some_array_type_0 = data
for some_array_type_0_item_data in _some_array_type_0:
some_array_type_0_item = AFormData.from_dict(some_array_type_0_item_data)

some_array_type_0.append(some_array_type_0_item)

return some_array_type_0
except: # noqa: E722
pass
return cast(Union[List["AFormData"], None, Unset], data)

some_array = _parse_some_array(d.pop("some_array", UNSET))

_some_optional_object = d.pop("some_optional_object", UNSET)
some_optional_object: Union[Unset, BodyUploadFileTestsUploadPostSomeOptionalObject]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,9 @@ def to_dict(self) -> Dict[str, Any]:
if isinstance(self.a_property, Unset):
a_property = UNSET
elif isinstance(self.a_property, AnEnum):
a_property = UNSET
if not isinstance(self.a_property, Unset):
a_property = self.a_property.value

a_property = self.a_property.value
else:
a_property = UNSET
if not isinstance(self.a_property, Unset):
a_property = self.a_property.value
a_property = self.a_property.value

field_dict: Dict[str, Any] = {}
field_dict.update({})
Expand All @@ -49,24 +44,14 @@ def _parse_a_property(data: object) -> Union[AnEnum, AnIntEnum, Unset]:
try:
if not isinstance(data, str):
raise TypeError()
_a_property_type_0 = data
a_property_type_0: Union[Unset, AnEnum]
if isinstance(_a_property_type_0, Unset):
a_property_type_0 = UNSET
else:
a_property_type_0 = AnEnum(_a_property_type_0)
a_property_type_0 = AnEnum(data)

return a_property_type_0
except: # noqa: E722
pass
if not isinstance(data, int):
raise TypeError()
_a_property_type_1 = data
a_property_type_1: Union[Unset, AnIntEnum]
if isinstance(_a_property_type_1, Unset):
a_property_type_1 = UNSET
else:
a_property_type_1 = AnIntEnum(_a_property_type_1)
a_property_type_1 = AnIntEnum(data)

return a_property_type_1

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,9 @@ def to_dict(self) -> Dict[str, Any]:
if isinstance(self.fruit, Unset):
fruit = UNSET
elif isinstance(self.fruit, ModelWithUnionPropertyInlinedFruitType0):
fruit = UNSET
if not isinstance(self.fruit, Unset):
fruit = self.fruit.to_dict()
fruit = self.fruit.to_dict()
else:
fruit = UNSET
if not isinstance(self.fruit, Unset):
fruit = self.fruit.to_dict()
fruit = self.fruit.to_dict()

field_dict: Dict[str, Any] = {}
field_dict.update({})
Expand All @@ -58,24 +54,14 @@ def _parse_fruit(
try:
if not isinstance(data, dict):
raise TypeError()
_fruit_type_0 = data
fruit_type_0: Union[Unset, ModelWithUnionPropertyInlinedFruitType0]
if isinstance(_fruit_type_0, Unset):
fruit_type_0 = UNSET
else:
fruit_type_0 = ModelWithUnionPropertyInlinedFruitType0.from_dict(_fruit_type_0)
fruit_type_0 = ModelWithUnionPropertyInlinedFruitType0.from_dict(data)

return fruit_type_0
except: # noqa: E722
pass
if not isinstance(data, dict):
raise TypeError()
_fruit_type_1 = data
fruit_type_1: Union[Unset, ModelWithUnionPropertyInlinedFruitType1]
if isinstance(_fruit_type_1, Unset):
fruit_type_1 = UNSET
else:
fruit_type_1 = ModelWithUnionPropertyInlinedFruitType1.from_dict(_fruit_type_1)
fruit_type_1 = ModelWithUnionPropertyInlinedFruitType1.from_dict(data)

return fruit_type_1

Expand Down
Loading