Skip to content

Use default value for ref property #1202

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

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all 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/use_default_value_for_ref_property.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
default: patch
---

# Use default value for ref property

#1202 by @github-abcde

Use defined default value for referenced properties of a model instead of always defaulting to `UNSET` in the generated code.
9 changes: 9 additions & 0 deletions end_to_end_tests/baseline_openapi_3.0.json
Original file line number Diff line number Diff line change
Expand Up @@ -2563,6 +2563,15 @@
}
}
},
"AModelWithOptionalPropertyRefAndDefaultValue": {
"type": "object",
"properties": {
"enum_property_ref": {
"$ref": "#/components/schemas/AnEnum",
"default": "FIRST_VALUE"
}
}
},
"ModelWithDateTimeProperty": {
"type": "object",
"properties": {
Expand Down
9 changes: 9 additions & 0 deletions end_to_end_tests/baseline_openapi_3.1.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2555,6 +2555,15 @@ info:
}
}
},
"AModelWithOptionalPropertyRefAndDefaultValue": {
"type": "object",
"properties": {
"enum_property_ref": {
"$ref": "#/components/schemas/AnEnum",
"default": "FIRST_VALUE"
}
}
},
"ModelWithDateTimeProperty": {
"type": "object",
"properties": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from .a_discriminated_union_type_2 import ADiscriminatedUnionType2
from .a_form_data import AFormData
from .a_model import AModel
from .a_model_with_optional_property_ref_and_default_value import AModelWithOptionalPropertyRefAndDefaultValue
from .a_model_with_properties_reference_that_are_not_object import AModelWithPropertiesReferenceThatAreNotObject
from .all_of_has_properties_but_no_type import AllOfHasPropertiesButNoType
from .all_of_has_properties_but_no_type_type_enum import AllOfHasPropertiesButNoTypeTypeEnum
Expand Down Expand Up @@ -98,6 +99,7 @@
"AllOfSubModel",
"AllOfSubModelTypeEnum",
"AModel",
"AModelWithOptionalPropertyRefAndDefaultValue",
"AModelWithPropertiesReferenceThatAreNotObject",
"AnAllOfEnum",
"AnArrayWithACircularRefInItemsObjectAdditionalPropertiesAItem",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
from typing import Any, TypeVar, Union

from attrs import define as _attrs_define
from attrs import field as _attrs_field

from ..models.an_enum import AnEnum
from ..types import UNSET, Unset

T = TypeVar("T", bound="AModelWithOptionalPropertyRefAndDefaultValue")


@_attrs_define
class AModelWithOptionalPropertyRefAndDefaultValue:
"""
Attributes:
enum_property_ref (Union[Unset, AnEnum]): For testing Enums in all the ways they can be used Default:
AnEnum.FIRST_VALUE.
"""

enum_property_ref: Union[Unset, AnEnum] = AnEnum.FIRST_VALUE
additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)

def to_dict(self) -> dict[str, Any]:
enum_property_ref: Union[Unset, str] = UNSET
if not isinstance(self.enum_property_ref, Unset):
enum_property_ref = self.enum_property_ref.value

field_dict: dict[str, Any] = {}
field_dict.update(self.additional_properties)
field_dict.update({})
if enum_property_ref is not UNSET:
field_dict["enum_property_ref"] = enum_property_ref

return field_dict

@classmethod
def from_dict(cls: type[T], src_dict: dict[str, Any]) -> T:
d = src_dict.copy()
_enum_property_ref = d.pop("enum_property_ref", UNSET)
enum_property_ref: Union[Unset, AnEnum]
if isinstance(_enum_property_ref, Unset):
enum_property_ref = UNSET
else:
enum_property_ref = AnEnum(_enum_property_ref)

a_model_with_optional_property_ref_and_default_value = cls(
enum_property_ref=enum_property_ref,
)

a_model_with_optional_property_ref_and_default_value.additional_properties = d
return a_model_with_optional_property_ref_and_default_value

@property
def additional_keys(self) -> list[str]:
return list(self.additional_properties.keys())

def __getitem__(self, key: str) -> Any:
return self.additional_properties[key]

def __setitem__(self, key: str, value: Any) -> 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
16 changes: 12 additions & 4 deletions openapi_python_client/parser/properties/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,10 +120,18 @@ def _property_from_ref(
schemas,
)

default = existing.convert_value(parent.default) if parent is not None else None
if isinstance(default, PropertyError):
default.data = parent or data
return default, schemas
if hasattr(data, 'default'):
default = existing.convert_value(data.default)
if isinstance(default, PropertyError):
default.data = data
return default, schemas
elif parent is not None:
default = existing.convert_value(parent.default)
if isinstance(default, PropertyError):
default.data = parent
return default, schemas
else:
default = None

prop = evolve(
existing,
Expand Down