From ca2a18be6822831d16e5c33873536ee77248f373 Mon Sep 17 00:00:00 2001 From: Packy Gallagher Date: Tue, 15 Dec 2020 10:23:03 -0800 Subject: [PATCH 1/9] Fix indentation of union-ed addtionalProperties --- openapi_python_client/templates/model.pyi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openapi_python_client/templates/model.pyi b/openapi_python_client/templates/model.pyi index c66ba46a3..0c81a32f9 100644 --- a/openapi_python_client/templates/model.pyi +++ b/openapi_python_client/templates/model.pyi @@ -51,7 +51,7 @@ class {{ model.reference.class_name }}: {% if model.additional_properties.template %} {% from "property_templates/" + model.additional_properties.template import transform %} for prop_name, prop in self.additional_properties.items(): - {{ transform(model.additional_properties, "prop", "field_dict[prop_name]") | indent(4) }} + {{ transform(model.additional_properties, "prop", "field_dict[prop_name]") | indent(12) }} {% else %} field_dict.update(self.additional_properties) {% endif %} From ab6622d48c7e9c469cbfbe8d74aec82c17cae2cf Mon Sep 17 00:00:00 2001 From: Packy Gallagher Date: Tue, 15 Dec 2020 13:33:16 -0800 Subject: [PATCH 2/9] Typing fixes check for list not List in isinstance cast primitives returned by union property's _parse_* --- openapi_python_client/parser/properties/__init__.py | 4 ++++ openapi_python_client/parser/properties/property.py | 4 ++++ .../templates/property_templates/union_property.pyi | 6 +++--- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/openapi_python_client/parser/properties/__init__.py b/openapi_python_client/parser/properties/__init__.py index 98fc4fc14..746de4bdd 100644 --- a/openapi_python_client/parser/properties/__init__.py +++ b/openapi_python_client/parser/properties/__init__.py @@ -135,6 +135,10 @@ def get_type_string(self, no_optional: bool = False) -> str: type_string = f"Union[Unset, {type_string}]" return type_string + def get_instance_type_string(self): + """Get a string representation of runtime type that should be used for `isinstance` checks""" + return "list" + def get_imports(self, *, prefix: str) -> Set[str]: """ Get a set of import strings that should be included when this property is used somewhere diff --git a/openapi_python_client/parser/properties/property.py b/openapi_python_client/parser/properties/property.py index c7649200f..e820c72ce 100644 --- a/openapi_python_client/parser/properties/property.py +++ b/openapi_python_client/parser/properties/property.py @@ -48,6 +48,10 @@ def get_type_string(self, no_optional: bool = False) -> str: type_string = f"Union[Unset, {type_string}]" return type_string + def get_instance_type_string(self): + """Get a string representation of runtime type that should be used for `isinstance` checks""" + return self.get_type_string(no_optional=True) + # noinspection PyUnusedLocal def get_imports(self, *, prefix: str) -> Set[str]: """ diff --git a/openapi_python_client/templates/property_templates/union_property.pyi b/openapi_python_client/templates/property_templates/union_property.pyi index 114838b1c..ee5aa1f3b 100644 --- a/openapi_python_client/templates/property_templates/union_property.pyi +++ b/openapi_python_client/templates/property_templates/union_property.pyi @@ -15,7 +15,7 @@ def _parse_{{ property.python_name }}(data: Any) -> {{ property.get_type_string( {{ construct(inner_property, "data", initial_value="UNSET") | indent(4) }} return {{ property.python_name }} {% else %} - return {{ source }} + return cast({{ inner_property.get_type_string() }}, {{ source }}) {% endif %} {% endfor %} @@ -39,9 +39,9 @@ elif {{ source }} is None: {% endif %} {% for inner_property in property.inner_properties %} {% if loop.first and property.required and not property.nullable %}{# No if UNSET or if None statement before this #} -if isinstance({{ source }}, {{ inner_property.get_type_string(no_optional=True) }}): +if isinstance({{ source }}, {{ inner_property.get_instance_type_string() }}): {% elif not loop.last %} -elif isinstance({{ source }}, {{ inner_property.get_type_string(no_optional=True) }}): +elif isinstance({{ source }}, {{ inner_property.get_instance_type_string() }}): {% else %} else: {% endif %} From 45d18013045bc3496524f657e518821b88cc2e88 Mon Sep 17 00:00:00 2001 From: Packy Gallagher Date: Tue, 15 Dec 2020 13:33:41 -0800 Subject: [PATCH 3/9] Add ModelWithAnyJsonProperties to e2e tests --- end_to_end_tests/openapi.json | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/end_to_end_tests/openapi.json b/end_to_end_tests/openapi.json index 1cbfd9597..2a0c1a644 100644 --- a/end_to_end_tests/openapi.json +++ b/end_to_end_tests/openapi.json @@ -806,6 +806,38 @@ "additionalProperties": { "$ref": "#/components/schemas/AnEnum" } + }, + "ModelWithAnyJsonProperties": { + "title": "ModelWithAnyJsonProperties", + "type": "object", + "additionalProperties": { + "anyOf": [ + { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + { + "type": "array", + "items": { + "type": "string" + } + }, + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "integer" + }, + { + "type": "boolean" + } + ] + } } } } From 85fc68591683606047dd9443b1b542fdce0d8fe1 Mon Sep 17 00:00:00 2001 From: Packy Gallagher Date: Tue, 15 Dec 2020 13:33:51 -0800 Subject: [PATCH 4/9] Regen golden record --- .../custom_e2e/models/__init__.py | 2 + .../models/model_with_any_json_properties.py | 97 +++++++++++++++++++ ...any_json_properties_additional_property.py | 42 ++++++++ .../my_test_api_client/models/__init__.py | 2 + .../models/model_with_any_json_properties.py | 97 +++++++++++++++++++ ...any_json_properties_additional_property.py | 42 ++++++++ 6 files changed, 282 insertions(+) create mode 100644 end_to_end_tests/golden-record-custom/custom_e2e/models/model_with_any_json_properties.py create mode 100644 end_to_end_tests/golden-record-custom/custom_e2e/models/model_with_any_json_properties_additional_property.py create mode 100644 end_to_end_tests/golden-record/my_test_api_client/models/model_with_any_json_properties.py create mode 100644 end_to_end_tests/golden-record/my_test_api_client/models/model_with_any_json_properties_additional_property.py diff --git a/end_to_end_tests/golden-record-custom/custom_e2e/models/__init__.py b/end_to_end_tests/golden-record-custom/custom_e2e/models/__init__.py index 475172136..d3ca924b3 100644 --- a/end_to_end_tests/golden-record-custom/custom_e2e/models/__init__.py +++ b/end_to_end_tests/golden-record-custom/custom_e2e/models/__init__.py @@ -12,6 +12,8 @@ ModelWithAdditionalPropertiesInlinedAdditionalProperty, ) from .model_with_additional_properties_refed import ModelWithAdditionalPropertiesRefed +from .model_with_any_json_properties import ModelWithAnyJsonProperties +from .model_with_any_json_properties_additional_property import ModelWithAnyJsonPropertiesAdditionalProperty from .model_with_primitive_additional_properties import ModelWithPrimitiveAdditionalProperties from .model_with_primitive_additional_properties_a_date_holder import ModelWithPrimitiveAdditionalPropertiesADateHolder from .model_with_union_property import ModelWithUnionProperty diff --git a/end_to_end_tests/golden-record-custom/custom_e2e/models/model_with_any_json_properties.py b/end_to_end_tests/golden-record-custom/custom_e2e/models/model_with_any_json_properties.py new file mode 100644 index 000000000..aac19fe73 --- /dev/null +++ b/end_to_end_tests/golden-record-custom/custom_e2e/models/model_with_any_json_properties.py @@ -0,0 +1,97 @@ +from typing import Any, Dict, List, Union, cast + +import attr + +from ..models.model_with_any_json_properties_additional_property import ModelWithAnyJsonPropertiesAdditionalProperty +from ..types import Unset + + +@attr.s(auto_attribs=True) +class ModelWithAnyJsonProperties: + """ """ + + additional_properties: Dict[ + str, Union[ModelWithAnyJsonPropertiesAdditionalProperty, List[str], str, float, int, bool] + ] = attr.ib(init=False, factory=dict) + + def to_dict(self) -> Dict[str, Any]: + + field_dict: Dict[str, Any] = {} + for prop_name, prop in self.additional_properties.items(): + if isinstance(prop, ModelWithAnyJsonPropertiesAdditionalProperty): + field_dict[prop_name] = prop.to_dict() + + elif isinstance(prop, list): + field_dict[prop_name] = prop + + elif isinstance(prop, str): + field_dict[prop_name] = prop + elif isinstance(prop, float): + field_dict[prop_name] = prop + elif isinstance(prop, int): + field_dict[prop_name] = prop + else: + field_dict[prop_name] = prop + + field_dict.update({}) + + return field_dict + + @staticmethod + def from_dict(src_dict: Dict[str, Any]) -> "ModelWithAnyJsonProperties": + d = src_dict.copy() + model_with_any_json_properties = ModelWithAnyJsonProperties() + + additional_properties = {} + for prop_name, prop_dict in d.items(): + + def _parse_additional_property( + data: Any, + ) -> Union[ModelWithAnyJsonPropertiesAdditionalProperty, List[str], str, float, int, bool]: + data = None if isinstance(data, Unset) else data + additional_property: Union[ + ModelWithAnyJsonPropertiesAdditionalProperty, List[str], str, float, int, bool + ] + try: + additional_property = ModelWithAnyJsonPropertiesAdditionalProperty.from_dict(data) + + return additional_property + except: # noqa: E722 + pass + try: + additional_property = cast(List[str], data) + + return additional_property + except: # noqa: E722 + pass + return cast(str, prop_dict) + return cast(float, prop_dict) + return cast(int, prop_dict) + return cast(bool, prop_dict) + + additional_property = _parse_additional_property(prop_dict) + + additional_properties[prop_name] = additional_property + + model_with_any_json_properties.additional_properties = additional_properties + return model_with_any_json_properties + + @property + def additional_keys(self) -> List[str]: + return list(self.additional_properties.keys()) + + def __getitem__( + self, key: str + ) -> Union[ModelWithAnyJsonPropertiesAdditionalProperty, List[str], str, float, int, bool]: + return self.additional_properties[key] + + def __setitem__( + self, key: str, value: Union[ModelWithAnyJsonPropertiesAdditionalProperty, List[str], str, float, int, bool] + ) -> None: + self.additional_properties[key] = value + + def __delitem__(self, key: str) -> None: + del self.additional_properties[key] + + def __contains__(self, key: str) -> bool: + return key in self.additional_properties diff --git a/end_to_end_tests/golden-record-custom/custom_e2e/models/model_with_any_json_properties_additional_property.py b/end_to_end_tests/golden-record-custom/custom_e2e/models/model_with_any_json_properties_additional_property.py new file mode 100644 index 000000000..c823a73ed --- /dev/null +++ b/end_to_end_tests/golden-record-custom/custom_e2e/models/model_with_any_json_properties_additional_property.py @@ -0,0 +1,42 @@ +from typing import Any, Dict, List + +import attr + + +@attr.s(auto_attribs=True) +class ModelWithAnyJsonPropertiesAdditionalProperty: + """ """ + + additional_properties: Dict[str, str] = attr.ib(init=False, factory=dict) + + def to_dict(self) -> Dict[str, Any]: + + field_dict: Dict[str, Any] = {} + field_dict.update(self.additional_properties) + field_dict.update({}) + + return field_dict + + @staticmethod + def from_dict(src_dict: Dict[str, Any]) -> "ModelWithAnyJsonPropertiesAdditionalProperty": + d = src_dict.copy() + model_with_any_json_properties_additional_property = ModelWithAnyJsonPropertiesAdditionalProperty() + + model_with_any_json_properties_additional_property.additional_properties = d + return model_with_any_json_properties_additional_property + + @property + def additional_keys(self) -> List[str]: + return list(self.additional_properties.keys()) + + def __getitem__(self, key: str) -> str: + return self.additional_properties[key] + + def __setitem__(self, key: str, value: str) -> None: + self.additional_properties[key] = value + + def __delitem__(self, key: str) -> None: + del self.additional_properties[key] + + def __contains__(self, key: str) -> bool: + return key in self.additional_properties diff --git a/end_to_end_tests/golden-record/my_test_api_client/models/__init__.py b/end_to_end_tests/golden-record/my_test_api_client/models/__init__.py index 475172136..d3ca924b3 100644 --- a/end_to_end_tests/golden-record/my_test_api_client/models/__init__.py +++ b/end_to_end_tests/golden-record/my_test_api_client/models/__init__.py @@ -12,6 +12,8 @@ ModelWithAdditionalPropertiesInlinedAdditionalProperty, ) from .model_with_additional_properties_refed import ModelWithAdditionalPropertiesRefed +from .model_with_any_json_properties import ModelWithAnyJsonProperties +from .model_with_any_json_properties_additional_property import ModelWithAnyJsonPropertiesAdditionalProperty from .model_with_primitive_additional_properties import ModelWithPrimitiveAdditionalProperties from .model_with_primitive_additional_properties_a_date_holder import ModelWithPrimitiveAdditionalPropertiesADateHolder from .model_with_union_property import ModelWithUnionProperty diff --git a/end_to_end_tests/golden-record/my_test_api_client/models/model_with_any_json_properties.py b/end_to_end_tests/golden-record/my_test_api_client/models/model_with_any_json_properties.py new file mode 100644 index 000000000..aac19fe73 --- /dev/null +++ b/end_to_end_tests/golden-record/my_test_api_client/models/model_with_any_json_properties.py @@ -0,0 +1,97 @@ +from typing import Any, Dict, List, Union, cast + +import attr + +from ..models.model_with_any_json_properties_additional_property import ModelWithAnyJsonPropertiesAdditionalProperty +from ..types import Unset + + +@attr.s(auto_attribs=True) +class ModelWithAnyJsonProperties: + """ """ + + additional_properties: Dict[ + str, Union[ModelWithAnyJsonPropertiesAdditionalProperty, List[str], str, float, int, bool] + ] = attr.ib(init=False, factory=dict) + + def to_dict(self) -> Dict[str, Any]: + + field_dict: Dict[str, Any] = {} + for prop_name, prop in self.additional_properties.items(): + if isinstance(prop, ModelWithAnyJsonPropertiesAdditionalProperty): + field_dict[prop_name] = prop.to_dict() + + elif isinstance(prop, list): + field_dict[prop_name] = prop + + elif isinstance(prop, str): + field_dict[prop_name] = prop + elif isinstance(prop, float): + field_dict[prop_name] = prop + elif isinstance(prop, int): + field_dict[prop_name] = prop + else: + field_dict[prop_name] = prop + + field_dict.update({}) + + return field_dict + + @staticmethod + def from_dict(src_dict: Dict[str, Any]) -> "ModelWithAnyJsonProperties": + d = src_dict.copy() + model_with_any_json_properties = ModelWithAnyJsonProperties() + + additional_properties = {} + for prop_name, prop_dict in d.items(): + + def _parse_additional_property( + data: Any, + ) -> Union[ModelWithAnyJsonPropertiesAdditionalProperty, List[str], str, float, int, bool]: + data = None if isinstance(data, Unset) else data + additional_property: Union[ + ModelWithAnyJsonPropertiesAdditionalProperty, List[str], str, float, int, bool + ] + try: + additional_property = ModelWithAnyJsonPropertiesAdditionalProperty.from_dict(data) + + return additional_property + except: # noqa: E722 + pass + try: + additional_property = cast(List[str], data) + + return additional_property + except: # noqa: E722 + pass + return cast(str, prop_dict) + return cast(float, prop_dict) + return cast(int, prop_dict) + return cast(bool, prop_dict) + + additional_property = _parse_additional_property(prop_dict) + + additional_properties[prop_name] = additional_property + + model_with_any_json_properties.additional_properties = additional_properties + return model_with_any_json_properties + + @property + def additional_keys(self) -> List[str]: + return list(self.additional_properties.keys()) + + def __getitem__( + self, key: str + ) -> Union[ModelWithAnyJsonPropertiesAdditionalProperty, List[str], str, float, int, bool]: + return self.additional_properties[key] + + def __setitem__( + self, key: str, value: Union[ModelWithAnyJsonPropertiesAdditionalProperty, List[str], str, float, int, bool] + ) -> None: + self.additional_properties[key] = value + + def __delitem__(self, key: str) -> None: + del self.additional_properties[key] + + def __contains__(self, key: str) -> bool: + return key in self.additional_properties diff --git a/end_to_end_tests/golden-record/my_test_api_client/models/model_with_any_json_properties_additional_property.py b/end_to_end_tests/golden-record/my_test_api_client/models/model_with_any_json_properties_additional_property.py new file mode 100644 index 000000000..c823a73ed --- /dev/null +++ b/end_to_end_tests/golden-record/my_test_api_client/models/model_with_any_json_properties_additional_property.py @@ -0,0 +1,42 @@ +from typing import Any, Dict, List + +import attr + + +@attr.s(auto_attribs=True) +class ModelWithAnyJsonPropertiesAdditionalProperty: + """ """ + + additional_properties: Dict[str, str] = attr.ib(init=False, factory=dict) + + def to_dict(self) -> Dict[str, Any]: + + field_dict: Dict[str, Any] = {} + field_dict.update(self.additional_properties) + field_dict.update({}) + + return field_dict + + @staticmethod + def from_dict(src_dict: Dict[str, Any]) -> "ModelWithAnyJsonPropertiesAdditionalProperty": + d = src_dict.copy() + model_with_any_json_properties_additional_property = ModelWithAnyJsonPropertiesAdditionalProperty() + + model_with_any_json_properties_additional_property.additional_properties = d + return model_with_any_json_properties_additional_property + + @property + def additional_keys(self) -> List[str]: + return list(self.additional_properties.keys()) + + def __getitem__(self, key: str) -> str: + return self.additional_properties[key] + + def __setitem__(self, key: str, value: str) -> None: + self.additional_properties[key] = value + + def __delitem__(self, key: str) -> None: + del self.additional_properties[key] + + def __contains__(self, key: str) -> bool: + return key in self.additional_properties From bd59aa65094472fe777600a94a9f9e3600301a14 Mon Sep 17 00:00:00 2001 From: Packy Gallagher Date: Tue, 15 Dec 2020 14:36:45 -0800 Subject: [PATCH 5/9] Add return type for get_instance_type_string --- openapi_python_client/parser/properties/__init__.py | 2 +- openapi_python_client/parser/properties/property.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/openapi_python_client/parser/properties/__init__.py b/openapi_python_client/parser/properties/__init__.py index 746de4bdd..4708bdc14 100644 --- a/openapi_python_client/parser/properties/__init__.py +++ b/openapi_python_client/parser/properties/__init__.py @@ -135,7 +135,7 @@ def get_type_string(self, no_optional: bool = False) -> str: type_string = f"Union[Unset, {type_string}]" return type_string - def get_instance_type_string(self): + def get_instance_type_string(self) -> str: """Get a string representation of runtime type that should be used for `isinstance` checks""" return "list" diff --git a/openapi_python_client/parser/properties/property.py b/openapi_python_client/parser/properties/property.py index e820c72ce..0b7047551 100644 --- a/openapi_python_client/parser/properties/property.py +++ b/openapi_python_client/parser/properties/property.py @@ -48,7 +48,7 @@ def get_type_string(self, no_optional: bool = False) -> str: type_string = f"Union[Unset, {type_string}]" return type_string - def get_instance_type_string(self): + def get_instance_type_string(self) -> str: """Get a string representation of runtime type that should be used for `isinstance` checks""" return self.get_type_string(no_optional=True) From c5f21b58f72cb06774ce602c5d4235f650a2467c Mon Sep 17 00:00:00 2001 From: Packy Gallagher Date: Wed, 16 Dec 2020 11:09:03 -0800 Subject: [PATCH 6/9] Union Property - use `data` from inner function when returning primitive values --- .../templates/property_templates/union_property.pyi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openapi_python_client/templates/property_templates/union_property.pyi b/openapi_python_client/templates/property_templates/union_property.pyi index ee5aa1f3b..f2a0359fa 100644 --- a/openapi_python_client/templates/property_templates/union_property.pyi +++ b/openapi_python_client/templates/property_templates/union_property.pyi @@ -15,7 +15,7 @@ def _parse_{{ property.python_name }}(data: Any) -> {{ property.get_type_string( {{ construct(inner_property, "data", initial_value="UNSET") | indent(4) }} return {{ property.python_name }} {% else %} - return cast({{ inner_property.get_type_string() }}, {{ source }}) + return cast({{ inner_property.get_type_string() }}, data) {% endif %} {% endfor %} From 0521e366e5aefd757fa4becf978240a6077284a1 Mon Sep 17 00:00:00 2001 From: Packy Gallagher Date: Wed, 16 Dec 2020 11:09:13 -0800 Subject: [PATCH 7/9] Update golden record --- .../custom_e2e/models/model_with_any_json_properties.py | 8 ++++---- .../models/model_with_any_json_properties.py | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/end_to_end_tests/golden-record-custom/custom_e2e/models/model_with_any_json_properties.py b/end_to_end_tests/golden-record-custom/custom_e2e/models/model_with_any_json_properties.py index aac19fe73..4aafeb91a 100644 --- a/end_to_end_tests/golden-record-custom/custom_e2e/models/model_with_any_json_properties.py +++ b/end_to_end_tests/golden-record-custom/custom_e2e/models/model_with_any_json_properties.py @@ -64,10 +64,10 @@ def _parse_additional_property( return additional_property except: # noqa: E722 pass - return cast(str, prop_dict) - return cast(float, prop_dict) - return cast(int, prop_dict) - return cast(bool, prop_dict) + return cast(str, data) + return cast(float, data) + return cast(int, data) + return cast(bool, data) additional_property = _parse_additional_property(prop_dict) diff --git a/end_to_end_tests/golden-record/my_test_api_client/models/model_with_any_json_properties.py b/end_to_end_tests/golden-record/my_test_api_client/models/model_with_any_json_properties.py index aac19fe73..4aafeb91a 100644 --- a/end_to_end_tests/golden-record/my_test_api_client/models/model_with_any_json_properties.py +++ b/end_to_end_tests/golden-record/my_test_api_client/models/model_with_any_json_properties.py @@ -64,10 +64,10 @@ def _parse_additional_property( return additional_property except: # noqa: E722 pass - return cast(str, prop_dict) - return cast(float, prop_dict) - return cast(int, prop_dict) - return cast(bool, prop_dict) + return cast(str, data) + return cast(float, data) + return cast(int, data) + return cast(bool, data) additional_property = _parse_additional_property(prop_dict) From 9a679afcb4e21aded441e265239f38e31d75aca9 Mon Sep 17 00:00:00 2001 From: Packy Gallagher Date: Fri, 18 Dec 2020 17:43:14 -0800 Subject: [PATCH 8/9] Update union properties handling of props with and without template --- .../parser/properties/__init__.py | 9 +++++++ .../property_templates/union_property.pyi | 25 +++++++++++-------- 2 files changed, 24 insertions(+), 10 deletions(-) diff --git a/openapi_python_client/parser/properties/__init__.py b/openapi_python_client/parser/properties/__init__.py index 4708bdc14..b5c47c0ea 100644 --- a/openapi_python_client/parser/properties/__init__.py +++ b/openapi_python_client/parser/properties/__init__.py @@ -1,3 +1,4 @@ +import builtins from itertools import chain from typing import Any, ClassVar, Dict, Generic, Iterable, List, Optional, Set, Tuple, TypeVar, Union @@ -187,6 +188,14 @@ def get_imports(self, *, prefix: str) -> Set[str]: imports.add("from typing import Union") return imports + @builtins.property + def inner_properties_with_template(self) -> List[Property]: + return [prop for prop in self.inner_properties if prop.template] + + @builtins.property + def inner_properties_without_template(self) -> List[Property]: + return [prop for prop in self.inner_properties if not prop.template] + def _string_based_property( name: str, required: bool, data: oai.Schema diff --git a/openapi_python_client/templates/property_templates/union_property.pyi b/openapi_python_client/templates/property_templates/union_property.pyi index f2a0359fa..c3cfee05e 100644 --- a/openapi_python_client/templates/property_templates/union_property.pyi +++ b/openapi_python_client/templates/property_templates/union_property.pyi @@ -2,22 +2,24 @@ def _parse_{{ property.python_name }}(data: Any) -> {{ property.get_type_string() }}: data = None if isinstance(data, Unset) else data {{ property.python_name }}: {{ property.get_type_string() }} - {% for inner_property in property.inner_properties %} - {% if inner_property.template and not loop.last %} + {% for inner_property in property.inner_properties_with_template %} + {% if not loop.last or property.inner_properties_without_template %} try: {% from "property_templates/" + inner_property.template import construct %} {{ construct(inner_property, "data", initial_value="UNSET") | indent(8) }} return {{ property.python_name }} except: # noqa: E722 pass - {% elif inner_property.template and loop.last %}{# Don't do try/except for the last one #} + {% else %}{# Don't do try/except for the last one #} {% from "property_templates/" + inner_property.template import construct %} {{ construct(inner_property, "data", initial_value="UNSET") | indent(4) }} return {{ property.python_name }} - {% else %} - return cast({{ inner_property.get_type_string() }}, data) {% endif %} {% endfor %} + {% if property.inner_properties_without_template %} + {# Doesn't really matter what we cast it to as this type will be erased, so cast to one of the options #} + return cast({{ property.inner_properties_without_template[0].get_type_string() }}, data) + {% endif %} {{ property.python_name }} = _parse_{{ property.python_name }}({{ source }}) {% endmacro %} @@ -37,19 +39,22 @@ elif {{ source }} is None: {% endif %} {{ destination }}{% if declare_type %}: {{ property.get_type_string() }}{% endif %} = None {% endif %} -{% for inner_property in property.inner_properties %} +{% for inner_property in property.inner_properties_with_template %} {% if loop.first and property.required and not property.nullable %}{# No if UNSET or if None statement before this #} if isinstance({{ source }}, {{ inner_property.get_instance_type_string() }}): - {% elif not loop.last %} + {% elif not loop.last or property.inner_properties_without_template %} elif isinstance({{ source }}, {{ inner_property.get_instance_type_string() }}): {% else %} else: {% endif %} -{% if inner_property.template %} {% from "property_templates/" + inner_property.template import transform %} {{ transform(inner_property, source, destination, declare_type=False) | indent(4) }} -{% else %} +{% endfor %} +{% if property.inner_properties_without_template and (property.inner_properties_with_template or not property.required)%} +else: {{ destination }} = {{ source }} +{% elif property.inner_properties_without_template %} +{{ destination }} = {{ source }} {% endif %} -{% endfor %} + {% endmacro %} From bfab9d4312a4717324eb9fc5f6214c62ec2b904b Mon Sep 17 00:00:00 2001 From: Packy Gallagher Date: Fri, 18 Dec 2020 17:43:24 -0800 Subject: [PATCH 9/9] Update golden record --- .../custom_e2e/api/tests/defaults_tests_defaults_post.py | 9 ++++----- .../custom_e2e/models/model_with_any_json_properties.py | 9 --------- .../api/tests/defaults_tests_defaults_post.py | 9 ++++----- .../models/model_with_any_json_properties.py | 9 --------- 4 files changed, 8 insertions(+), 28 deletions(-) diff --git a/end_to_end_tests/golden-record-custom/custom_e2e/api/tests/defaults_tests_defaults_post.py b/end_to_end_tests/golden-record-custom/custom_e2e/api/tests/defaults_tests_defaults_post.py index fa6e9e47c..574d5018b 100644 --- a/end_to_end_tests/golden-record-custom/custom_e2e/api/tests/defaults_tests_defaults_post.py +++ b/end_to_end_tests/golden-record-custom/custom_e2e/api/tests/defaults_tests_defaults_post.py @@ -71,21 +71,20 @@ def httpx_request( json_union_prop: Union[Unset, float, str] if isinstance(union_prop, Unset): json_union_prop = UNSET - elif isinstance(union_prop, float): - json_union_prop = union_prop else: json_union_prop = union_prop json_union_prop_with_ref: Union[Unset, float, AnEnum] if isinstance(union_prop_with_ref, Unset): json_union_prop_with_ref = UNSET - elif isinstance(union_prop_with_ref, float): - json_union_prop_with_ref = union_prop_with_ref - else: + 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 + else: + json_union_prop_with_ref = union_prop_with_ref + json_enum_prop: Union[Unset, AnEnum] = UNSET if not isinstance(enum_prop, Unset): json_enum_prop = enum_prop diff --git a/end_to_end_tests/golden-record-custom/custom_e2e/models/model_with_any_json_properties.py b/end_to_end_tests/golden-record-custom/custom_e2e/models/model_with_any_json_properties.py index 4aafeb91a..2e488ea69 100644 --- a/end_to_end_tests/golden-record-custom/custom_e2e/models/model_with_any_json_properties.py +++ b/end_to_end_tests/golden-record-custom/custom_e2e/models/model_with_any_json_properties.py @@ -24,12 +24,6 @@ def to_dict(self) -> Dict[str, Any]: elif isinstance(prop, list): field_dict[prop_name] = prop - elif isinstance(prop, str): - field_dict[prop_name] = prop - elif isinstance(prop, float): - field_dict[prop_name] = prop - elif isinstance(prop, int): - field_dict[prop_name] = prop else: field_dict[prop_name] = prop @@ -65,9 +59,6 @@ def _parse_additional_property( except: # noqa: E722 pass return cast(str, data) - return cast(float, data) - return cast(int, data) - return cast(bool, data) additional_property = _parse_additional_property(prop_dict) diff --git a/end_to_end_tests/golden-record/my_test_api_client/api/tests/defaults_tests_defaults_post.py b/end_to_end_tests/golden-record/my_test_api_client/api/tests/defaults_tests_defaults_post.py index e4e7a7c73..9242cddaa 100644 --- a/end_to_end_tests/golden-record/my_test_api_client/api/tests/defaults_tests_defaults_post.py +++ b/end_to_end_tests/golden-record/my_test_api_client/api/tests/defaults_tests_defaults_post.py @@ -47,21 +47,20 @@ def _get_kwargs( json_union_prop: Union[Unset, float, str] if isinstance(union_prop, Unset): json_union_prop = UNSET - elif isinstance(union_prop, float): - json_union_prop = union_prop else: json_union_prop = union_prop json_union_prop_with_ref: Union[Unset, float, AnEnum] if isinstance(union_prop_with_ref, Unset): json_union_prop_with_ref = UNSET - elif isinstance(union_prop_with_ref, float): - json_union_prop_with_ref = union_prop_with_ref - else: + 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 + else: + json_union_prop_with_ref = union_prop_with_ref + json_enum_prop: Union[Unset, AnEnum] = UNSET if not isinstance(enum_prop, Unset): json_enum_prop = enum_prop diff --git a/end_to_end_tests/golden-record/my_test_api_client/models/model_with_any_json_properties.py b/end_to_end_tests/golden-record/my_test_api_client/models/model_with_any_json_properties.py index 4aafeb91a..2e488ea69 100644 --- a/end_to_end_tests/golden-record/my_test_api_client/models/model_with_any_json_properties.py +++ b/end_to_end_tests/golden-record/my_test_api_client/models/model_with_any_json_properties.py @@ -24,12 +24,6 @@ def to_dict(self) -> Dict[str, Any]: elif isinstance(prop, list): field_dict[prop_name] = prop - elif isinstance(prop, str): - field_dict[prop_name] = prop - elif isinstance(prop, float): - field_dict[prop_name] = prop - elif isinstance(prop, int): - field_dict[prop_name] = prop else: field_dict[prop_name] = prop @@ -65,9 +59,6 @@ def _parse_additional_property( except: # noqa: E722 pass return cast(str, data) - return cast(float, data) - return cast(int, data) - return cast(bool, data) additional_property = _parse_additional_property(prop_dict)