-
-
Notifications
You must be signed in to change notification settings - Fork 229
bugfix: correct indentation of additionalProperties that are union types #266 #268
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
Changes from 5 commits
ca2a18b
ab6622d
45d1801
85fc685
bd59aa6
c5f21b5
0521e36
9a679af
bfab9d4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Feels like maybe we need a way to indicate whether or not a given property actually needs to be transformed and if not, just have an |
||
|
||
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 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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 %} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So if we aren't running a construct macro because the inner prop doesn't have a template, then we really aren't doing anything with it. So instead of having this in a loop, we could just do this after the loop:
So basically, loop through all the things that require some construction, if none of those work, just return what we have and assume it's one of the values. Technically it's one of the values we didn't check yet, but that doesn't really matter to the return type since the calling function doesn't know which union member was selected. Also, it doesn't look like we actually need to use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We do still need |
||
|
||
|
@@ -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 %} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Similar story here I think, we just change the order of some checks. Something like
Editing in GH UI, so probably some mistakes made, but hopefully you get the idea. |
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, this is ugly. I'll see if I can find the cause and propose a solution further down.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would do this before, just without the
cast
s. It's because inunion_property.pyi
we loop through each property and if it doesn't have a template we just return it.What is here is ugly, yes, but it works. However, I do think there is an issue if we declare a templated type before a primitive type - then the primitive type would cause it to return early. Something , like
So I think we need to loop over templated properties first, then untemplated properties. Also we'll want to figure out lists, as casting it to a
List
will not error so that breaks the try/catch logic.While responding to this comment, I realized that these should be using
cast(<primitive type>, data)
notcast(<primitive type>, prop_dict)
- I added commits to this branch to change thatThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll try looking at this soon as I have time