diff --git a/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model.py b/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model.py index 9599f7fd5..87175124c 100644 --- a/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model.py +++ b/end_to_end_tests/golden-record-custom/custom_e2e/models/a_model.py @@ -6,6 +6,7 @@ from ..models.an_enum import AnEnum from ..models.different_enum import DifferentEnum +from ..types import UNSET, Unset @attr.s(auto_attribs=True) @@ -16,11 +17,11 @@ class AModel: a_camel_date_time: Union[datetime.datetime, datetime.date] a_date: datetime.date required_not_nullable: str - nested_list_of_enums: List[List[DifferentEnum]] - attr_1_leading_digit: str required_nullable: Optional[str] - not_required_nullable: Optional[str] - not_required_not_nullable: str + nested_list_of_enums: Union[Unset, List[List[DifferentEnum]]] = UNSET + attr_1_leading_digit: Union[Unset, str] = UNSET + not_required_nullable: Union[Unset, Optional[str]] = UNSET + not_required_not_nullable: Union[Unset, str] = UNSET def to_dict(self) -> Dict[str, Any]: an_enum_value = self.an_enum_value.value @@ -34,15 +35,17 @@ def to_dict(self) -> Dict[str, Any]: a_date = self.a_date.isoformat() required_not_nullable = self.required_not_nullable - nested_list_of_enums = [] - for nested_list_of_enums_item_data in self.nested_list_of_enums: - nested_list_of_enums_item = [] - for nested_list_of_enums_item_item_data in nested_list_of_enums_item_data: - nested_list_of_enums_item_item = nested_list_of_enums_item_item_data.value + nested_list_of_enums: Union[Unset, List[Any]] = UNSET + if not isinstance(self.nested_list_of_enums, Unset): + nested_list_of_enums = [] + for nested_list_of_enums_item_data in self.nested_list_of_enums: + nested_list_of_enums_item = [] + for nested_list_of_enums_item_item_data in nested_list_of_enums_item_data: + nested_list_of_enums_item_item = nested_list_of_enums_item_item_data.value - nested_list_of_enums_item.append(nested_list_of_enums_item_item) + nested_list_of_enums_item.append(nested_list_of_enums_item_item) - nested_list_of_enums.append(nested_list_of_enums_item) + nested_list_of_enums.append(nested_list_of_enums_item) attr_1_leading_digit = self.attr_1_leading_digit required_nullable = self.required_nullable @@ -54,12 +57,16 @@ def to_dict(self) -> Dict[str, Any]: "aCamelDateTime": a_camel_date_time, "a_date": a_date, "required_not_nullable": required_not_nullable, - "nested_list_of_enums": nested_list_of_enums, - "1_leading_digit": attr_1_leading_digit, "required_nullable": required_nullable, - "not_required_nullable": not_required_nullable, - "not_required_not_nullable": not_required_not_nullable, } + if nested_list_of_enums is not UNSET: + field_dict["nested_list_of_enums"] = nested_list_of_enums + if attr_1_leading_digit is not UNSET: + field_dict["1_leading_digit"] = attr_1_leading_digit + if not_required_nullable is not UNSET: + field_dict["not_required_nullable"] = not_required_nullable + if not_required_not_nullable is not UNSET: + field_dict["not_required_not_nullable"] = not_required_not_nullable return field_dict @@ -86,7 +93,7 @@ def _parse_a_camel_date_time(data: Dict[str, Any]) -> Union[datetime.datetime, d required_not_nullable = d["required_not_nullable"] nested_list_of_enums = [] - for nested_list_of_enums_item_data in d["nested_list_of_enums"]: + for nested_list_of_enums_item_data in d.get("nested_list_of_enums", UNSET) or []: nested_list_of_enums_item = [] for nested_list_of_enums_item_item_data in nested_list_of_enums_item_data: nested_list_of_enums_item_item = DifferentEnum(nested_list_of_enums_item_item_data) @@ -95,13 +102,13 @@ def _parse_a_camel_date_time(data: Dict[str, Any]) -> Union[datetime.datetime, d nested_list_of_enums.append(nested_list_of_enums_item) - attr_1_leading_digit = d["1_leading_digit"] + attr_1_leading_digit = d.get("1_leading_digit", UNSET) required_nullable = d["required_nullable"] - not_required_nullable = d["not_required_nullable"] + not_required_nullable = d.get("not_required_nullable", UNSET) - not_required_not_nullable = d["not_required_not_nullable"] + not_required_not_nullable = d.get("not_required_not_nullable", UNSET) return AModel( an_enum_value=an_enum_value, diff --git a/end_to_end_tests/golden-record-custom/custom_e2e/models/http_validation_error.py b/end_to_end_tests/golden-record-custom/custom_e2e/models/http_validation_error.py index 2b83121ce..9d29faa4d 100644 --- a/end_to_end_tests/golden-record-custom/custom_e2e/models/http_validation_error.py +++ b/end_to_end_tests/golden-record-custom/custom_e2e/models/http_validation_error.py @@ -1,33 +1,36 @@ -from typing import Any, Dict, List +from typing import Any, Dict, List, Union import attr from ..models.validation_error import ValidationError +from ..types import UNSET, Unset @attr.s(auto_attribs=True) class HTTPValidationError: """ """ - detail: List[ValidationError] + detail: Union[Unset, List[ValidationError]] = UNSET def to_dict(self) -> Dict[str, Any]: - detail = [] - for detail_item_data in self.detail: - detail_item = detail_item_data.to_dict() + detail: Union[Unset, List[Any]] = UNSET + if not isinstance(self.detail, Unset): + detail = [] + for detail_item_data in self.detail: + detail_item = detail_item_data.to_dict() - detail.append(detail_item) + detail.append(detail_item) - field_dict = { - "detail": detail, - } + field_dict = {} + if detail is not UNSET: + field_dict["detail"] = detail return field_dict @staticmethod def from_dict(d: Dict[str, Any]) -> "HTTPValidationError": detail = [] - for detail_item_data in d["detail"]: + for detail_item_data in d.get("detail", UNSET) or []: detail_item = ValidationError.from_dict(detail_item_data) detail.append(detail_item) diff --git a/end_to_end_tests/golden-record-custom/custom_e2e/models/test_inline_objectsjson_body.py b/end_to_end_tests/golden-record-custom/custom_e2e/models/test_inline_objectsjson_body.py index 833d8f9a0..329218025 100644 --- a/end_to_end_tests/golden-record-custom/custom_e2e/models/test_inline_objectsjson_body.py +++ b/end_to_end_tests/golden-record-custom/custom_e2e/models/test_inline_objectsjson_body.py @@ -1,26 +1,28 @@ -from typing import Any, Dict +from typing import Any, Dict, Union import attr +from ..types import UNSET, Unset + @attr.s(auto_attribs=True) class TestInlineObjectsjsonBody: """ """ - a_property: str + a_property: Union[Unset, str] = UNSET def to_dict(self) -> Dict[str, Any]: a_property = self.a_property - field_dict = { - "a_property": a_property, - } + field_dict = {} + if a_property is not UNSET: + field_dict["a_property"] = a_property return field_dict @staticmethod def from_dict(d: Dict[str, Any]) -> "TestInlineObjectsjsonBody": - a_property = d["a_property"] + a_property = d.get("a_property", UNSET) return TestInlineObjectsjsonBody( a_property=a_property, diff --git a/end_to_end_tests/golden-record-custom/custom_e2e/models/test_inline_objectsresponse_200.py b/end_to_end_tests/golden-record-custom/custom_e2e/models/test_inline_objectsresponse_200.py index ebe0a4d72..73a6b082a 100644 --- a/end_to_end_tests/golden-record-custom/custom_e2e/models/test_inline_objectsresponse_200.py +++ b/end_to_end_tests/golden-record-custom/custom_e2e/models/test_inline_objectsresponse_200.py @@ -1,26 +1,28 @@ -from typing import Any, Dict +from typing import Any, Dict, Union import attr +from ..types import UNSET, Unset + @attr.s(auto_attribs=True) class TestInlineObjectsresponse_200: """ """ - a_property: str + a_property: Union[Unset, str] = UNSET def to_dict(self) -> Dict[str, Any]: a_property = self.a_property - field_dict = { - "a_property": a_property, - } + field_dict = {} + if a_property is not UNSET: + field_dict["a_property"] = a_property return field_dict @staticmethod def from_dict(d: Dict[str, Any]) -> "TestInlineObjectsresponse_200": - a_property = d["a_property"] + a_property = d.get("a_property", UNSET) return TestInlineObjectsresponse_200( a_property=a_property, diff --git a/end_to_end_tests/golden-record/my_test_api_client/models/a_model.py b/end_to_end_tests/golden-record/my_test_api_client/models/a_model.py index 9599f7fd5..87175124c 100644 --- a/end_to_end_tests/golden-record/my_test_api_client/models/a_model.py +++ b/end_to_end_tests/golden-record/my_test_api_client/models/a_model.py @@ -6,6 +6,7 @@ from ..models.an_enum import AnEnum from ..models.different_enum import DifferentEnum +from ..types import UNSET, Unset @attr.s(auto_attribs=True) @@ -16,11 +17,11 @@ class AModel: a_camel_date_time: Union[datetime.datetime, datetime.date] a_date: datetime.date required_not_nullable: str - nested_list_of_enums: List[List[DifferentEnum]] - attr_1_leading_digit: str required_nullable: Optional[str] - not_required_nullable: Optional[str] - not_required_not_nullable: str + nested_list_of_enums: Union[Unset, List[List[DifferentEnum]]] = UNSET + attr_1_leading_digit: Union[Unset, str] = UNSET + not_required_nullable: Union[Unset, Optional[str]] = UNSET + not_required_not_nullable: Union[Unset, str] = UNSET def to_dict(self) -> Dict[str, Any]: an_enum_value = self.an_enum_value.value @@ -34,15 +35,17 @@ def to_dict(self) -> Dict[str, Any]: a_date = self.a_date.isoformat() required_not_nullable = self.required_not_nullable - nested_list_of_enums = [] - for nested_list_of_enums_item_data in self.nested_list_of_enums: - nested_list_of_enums_item = [] - for nested_list_of_enums_item_item_data in nested_list_of_enums_item_data: - nested_list_of_enums_item_item = nested_list_of_enums_item_item_data.value + nested_list_of_enums: Union[Unset, List[Any]] = UNSET + if not isinstance(self.nested_list_of_enums, Unset): + nested_list_of_enums = [] + for nested_list_of_enums_item_data in self.nested_list_of_enums: + nested_list_of_enums_item = [] + for nested_list_of_enums_item_item_data in nested_list_of_enums_item_data: + nested_list_of_enums_item_item = nested_list_of_enums_item_item_data.value - nested_list_of_enums_item.append(nested_list_of_enums_item_item) + nested_list_of_enums_item.append(nested_list_of_enums_item_item) - nested_list_of_enums.append(nested_list_of_enums_item) + nested_list_of_enums.append(nested_list_of_enums_item) attr_1_leading_digit = self.attr_1_leading_digit required_nullable = self.required_nullable @@ -54,12 +57,16 @@ def to_dict(self) -> Dict[str, Any]: "aCamelDateTime": a_camel_date_time, "a_date": a_date, "required_not_nullable": required_not_nullable, - "nested_list_of_enums": nested_list_of_enums, - "1_leading_digit": attr_1_leading_digit, "required_nullable": required_nullable, - "not_required_nullable": not_required_nullable, - "not_required_not_nullable": not_required_not_nullable, } + if nested_list_of_enums is not UNSET: + field_dict["nested_list_of_enums"] = nested_list_of_enums + if attr_1_leading_digit is not UNSET: + field_dict["1_leading_digit"] = attr_1_leading_digit + if not_required_nullable is not UNSET: + field_dict["not_required_nullable"] = not_required_nullable + if not_required_not_nullable is not UNSET: + field_dict["not_required_not_nullable"] = not_required_not_nullable return field_dict @@ -86,7 +93,7 @@ def _parse_a_camel_date_time(data: Dict[str, Any]) -> Union[datetime.datetime, d required_not_nullable = d["required_not_nullable"] nested_list_of_enums = [] - for nested_list_of_enums_item_data in d["nested_list_of_enums"]: + for nested_list_of_enums_item_data in d.get("nested_list_of_enums", UNSET) or []: nested_list_of_enums_item = [] for nested_list_of_enums_item_item_data in nested_list_of_enums_item_data: nested_list_of_enums_item_item = DifferentEnum(nested_list_of_enums_item_item_data) @@ -95,13 +102,13 @@ def _parse_a_camel_date_time(data: Dict[str, Any]) -> Union[datetime.datetime, d nested_list_of_enums.append(nested_list_of_enums_item) - attr_1_leading_digit = d["1_leading_digit"] + attr_1_leading_digit = d.get("1_leading_digit", UNSET) required_nullable = d["required_nullable"] - not_required_nullable = d["not_required_nullable"] + not_required_nullable = d.get("not_required_nullable", UNSET) - not_required_not_nullable = d["not_required_not_nullable"] + not_required_not_nullable = d.get("not_required_not_nullable", UNSET) return AModel( an_enum_value=an_enum_value, diff --git a/end_to_end_tests/golden-record/my_test_api_client/models/http_validation_error.py b/end_to_end_tests/golden-record/my_test_api_client/models/http_validation_error.py index 2b83121ce..9d29faa4d 100644 --- a/end_to_end_tests/golden-record/my_test_api_client/models/http_validation_error.py +++ b/end_to_end_tests/golden-record/my_test_api_client/models/http_validation_error.py @@ -1,33 +1,36 @@ -from typing import Any, Dict, List +from typing import Any, Dict, List, Union import attr from ..models.validation_error import ValidationError +from ..types import UNSET, Unset @attr.s(auto_attribs=True) class HTTPValidationError: """ """ - detail: List[ValidationError] + detail: Union[Unset, List[ValidationError]] = UNSET def to_dict(self) -> Dict[str, Any]: - detail = [] - for detail_item_data in self.detail: - detail_item = detail_item_data.to_dict() + detail: Union[Unset, List[Any]] = UNSET + if not isinstance(self.detail, Unset): + detail = [] + for detail_item_data in self.detail: + detail_item = detail_item_data.to_dict() - detail.append(detail_item) + detail.append(detail_item) - field_dict = { - "detail": detail, - } + field_dict = {} + if detail is not UNSET: + field_dict["detail"] = detail return field_dict @staticmethod def from_dict(d: Dict[str, Any]) -> "HTTPValidationError": detail = [] - for detail_item_data in d["detail"]: + for detail_item_data in d.get("detail", UNSET) or []: detail_item = ValidationError.from_dict(detail_item_data) detail.append(detail_item) diff --git a/end_to_end_tests/golden-record/my_test_api_client/models/test_inline_objectsjson_body.py b/end_to_end_tests/golden-record/my_test_api_client/models/test_inline_objectsjson_body.py index 833d8f9a0..329218025 100644 --- a/end_to_end_tests/golden-record/my_test_api_client/models/test_inline_objectsjson_body.py +++ b/end_to_end_tests/golden-record/my_test_api_client/models/test_inline_objectsjson_body.py @@ -1,26 +1,28 @@ -from typing import Any, Dict +from typing import Any, Dict, Union import attr +from ..types import UNSET, Unset + @attr.s(auto_attribs=True) class TestInlineObjectsjsonBody: """ """ - a_property: str + a_property: Union[Unset, str] = UNSET def to_dict(self) -> Dict[str, Any]: a_property = self.a_property - field_dict = { - "a_property": a_property, - } + field_dict = {} + if a_property is not UNSET: + field_dict["a_property"] = a_property return field_dict @staticmethod def from_dict(d: Dict[str, Any]) -> "TestInlineObjectsjsonBody": - a_property = d["a_property"] + a_property = d.get("a_property", UNSET) return TestInlineObjectsjsonBody( a_property=a_property, diff --git a/end_to_end_tests/golden-record/my_test_api_client/models/test_inline_objectsresponse_200.py b/end_to_end_tests/golden-record/my_test_api_client/models/test_inline_objectsresponse_200.py index ebe0a4d72..73a6b082a 100644 --- a/end_to_end_tests/golden-record/my_test_api_client/models/test_inline_objectsresponse_200.py +++ b/end_to_end_tests/golden-record/my_test_api_client/models/test_inline_objectsresponse_200.py @@ -1,26 +1,28 @@ -from typing import Any, Dict +from typing import Any, Dict, Union import attr +from ..types import UNSET, Unset + @attr.s(auto_attribs=True) class TestInlineObjectsresponse_200: """ """ - a_property: str + a_property: Union[Unset, str] = UNSET def to_dict(self) -> Dict[str, Any]: a_property = self.a_property - field_dict = { - "a_property": a_property, - } + field_dict = {} + if a_property is not UNSET: + field_dict["a_property"] = a_property return field_dict @staticmethod def from_dict(d: Dict[str, Any]) -> "TestInlineObjectsresponse_200": - a_property = d["a_property"] + a_property = d.get("a_property", UNSET) return TestInlineObjectsresponse_200( a_property=a_property, diff --git a/openapi_python_client/parser/properties/__init__.py b/openapi_python_client/parser/properties/__init__.py index 1295854fd..e203fc99a 100644 --- a/openapi_python_client/parser/properties/__init__.py +++ b/openapi_python_client/parser/properties/__init__.py @@ -245,7 +245,7 @@ def build_model_property( for key, value in (data.properties or {}).items(): prop_required = key in required_set prop, schemas = property_from_data( - name=key, required=required, data=value, schemas=schemas, parent_name=class_name + name=key, required=prop_required, data=value, schemas=schemas, parent_name=class_name ) if isinstance(prop, PropertyError): return prop, schemas diff --git a/tests/test_parser/test_properties/test_init.py b/tests/test_parser/test_properties/test_init.py index 80bd74858..2bfbd5843 100644 --- a/tests/test_parser/test_properties/test_init.py +++ b/tests/test_parser/test_properties/test_init.py @@ -1074,9 +1074,15 @@ def test_build_model_property(): default=None, reference=Reference(class_name="ParentMyModel", module_name="parent_my_model"), required_properties=[StringProperty(name="req", required=True, nullable=False, default=None)], - optional_properties=[DateTimeProperty(name="opt", required=True, nullable=False, default=None)], + optional_properties=[DateTimeProperty(name="opt", required=False, nullable=False, default=None)], description=data.description, - relative_imports={"from dateutil.parser import isoparse", "from typing import cast", "import datetime"}, + relative_imports={ + "from dateutil.parser import isoparse", + "from typing import cast", + "import datetime", + "from ..types import UNSET, Unset", + "from typing import Union", + }, )