mirror of
https://github.com/OpenAPITools/openapi-generator.git
synced 2025-12-20 19:57:11 +00:00
Support normalizing anyof/oneof enum constraints to a single enum (#21917)
* Support normalizing anyof/oneof enum constraints to a single enum * Add SIMPLIFY_ONEOF_ANYOF_ENUM to the documentation * Process referenced schemas with oneof/enum as well * Implement referenced enum merging from oneof/anyof * Implement retaining the enum description as x-enum-desriptions for oneof enum * Update samples and docs with oneOf enum normalization * update samples to fix python tests * fix test file name * fix incorrect filename --------- Co-authored-by: Pieter Bos <pieter.bos@nedap.com>
This commit is contained in:
@@ -2,27 +2,16 @@
|
||||
|
||||
oneOf enum strings
|
||||
|
||||
## Properties
|
||||
Name | Type | Description | Notes
|
||||
------------ | ------------- | ------------- | -------------
|
||||
## Enum
|
||||
|
||||
## Example
|
||||
* `A` (value: `'a'`)
|
||||
|
||||
```python
|
||||
from petstore_api.models.one_of_enum_string import OneOfEnumString
|
||||
* `B` (value: `'b'`)
|
||||
|
||||
# TODO update the JSON string below
|
||||
json = "{}"
|
||||
# create an instance of OneOfEnumString from a JSON string
|
||||
one_of_enum_string_instance = OneOfEnumString.from_json(json)
|
||||
# print the JSON string representation of the object
|
||||
print OneOfEnumString.to_json()
|
||||
* `C` (value: `'c'`)
|
||||
|
||||
* `D` (value: `'d'`)
|
||||
|
||||
# convert the object into a dict
|
||||
one_of_enum_string_dict = one_of_enum_string_instance.to_dict()
|
||||
# create an instance of OneOfEnumString from a dict
|
||||
one_of_enum_string_from_dict = OneOfEnumString.from_dict(one_of_enum_string_dict)
|
||||
```
|
||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
||||
|
||||
|
||||
|
||||
@@ -12,130 +12,31 @@
|
||||
""" # noqa: E501
|
||||
|
||||
|
||||
from __future__ import annotations
|
||||
from inspect import getfullargspec
|
||||
import json
|
||||
import pprint
|
||||
import re # noqa: F401
|
||||
from aenum import Enum, no_arg
|
||||
|
||||
from typing import Any, List, Optional
|
||||
from pydantic import BaseModel, Field, StrictStr, ValidationError, validator
|
||||
from petstore_api.models.enum_string1 import EnumString1
|
||||
from petstore_api.models.enum_string2 import EnumString2
|
||||
from typing import Union, Any, List, TYPE_CHECKING
|
||||
from pydantic import StrictStr, Field
|
||||
|
||||
ONEOFENUMSTRING_ONE_OF_SCHEMAS = ["EnumString1", "EnumString2"]
|
||||
|
||||
class OneOfEnumString(BaseModel):
|
||||
|
||||
|
||||
class OneOfEnumString(str, Enum):
|
||||
"""
|
||||
oneOf enum strings
|
||||
"""
|
||||
# data type: EnumString1
|
||||
oneof_schema_1_validator: Optional[EnumString1] = None
|
||||
# data type: EnumString2
|
||||
oneof_schema_2_validator: Optional[EnumString2] = None
|
||||
if TYPE_CHECKING:
|
||||
actual_instance: Union[EnumString1, EnumString2]
|
||||
else:
|
||||
actual_instance: Any
|
||||
one_of_schemas: List[str] = Field(ONEOFENUMSTRING_ONE_OF_SCHEMAS, const=True)
|
||||
|
||||
class Config:
|
||||
validate_assignment = True
|
||||
|
||||
def __init__(self, *args, **kwargs) -> None:
|
||||
if args:
|
||||
if len(args) > 1:
|
||||
raise ValueError("If a position argument is used, only 1 is allowed to set `actual_instance`")
|
||||
if kwargs:
|
||||
raise ValueError("If a position argument is used, keyword arguments cannot be used.")
|
||||
super().__init__(actual_instance=args[0])
|
||||
else:
|
||||
super().__init__(**kwargs)
|
||||
|
||||
@validator('actual_instance')
|
||||
def actual_instance_must_validate_oneof(cls, v):
|
||||
instance = OneOfEnumString.construct()
|
||||
error_messages = []
|
||||
match = 0
|
||||
# validate data type: EnumString1
|
||||
if not isinstance(v, EnumString1):
|
||||
error_messages.append(f"Error! Input type `{type(v)}` is not `EnumString1`")
|
||||
else:
|
||||
match += 1
|
||||
# validate data type: EnumString2
|
||||
if not isinstance(v, EnumString2):
|
||||
error_messages.append(f"Error! Input type `{type(v)}` is not `EnumString2`")
|
||||
else:
|
||||
match += 1
|
||||
if match > 1:
|
||||
# more than 1 match
|
||||
raise ValueError("Multiple matches found when setting `actual_instance` in OneOfEnumString with oneOf schemas: EnumString1, EnumString2. Details: " + ", ".join(error_messages))
|
||||
elif match == 0:
|
||||
# no match
|
||||
raise ValueError("No match found when setting `actual_instance` in OneOfEnumString with oneOf schemas: EnumString1, EnumString2. Details: " + ", ".join(error_messages))
|
||||
else:
|
||||
return v
|
||||
|
||||
@classmethod
|
||||
def from_dict(cls, obj: dict) -> OneOfEnumString:
|
||||
return cls.from_json(json.dumps(obj))
|
||||
"""
|
||||
allowed enum values
|
||||
"""
|
||||
A = 'a'
|
||||
B = 'b'
|
||||
C = 'c'
|
||||
D = 'd'
|
||||
|
||||
@classmethod
|
||||
def from_json(cls, json_str: str) -> OneOfEnumString:
|
||||
"""Returns the object represented by the json string"""
|
||||
instance = OneOfEnumString.construct()
|
||||
error_messages = []
|
||||
match = 0
|
||||
|
||||
# deserialize data into EnumString1
|
||||
try:
|
||||
instance.actual_instance = EnumString1.from_json(json_str)
|
||||
match += 1
|
||||
except (ValidationError, ValueError) as e:
|
||||
error_messages.append(str(e))
|
||||
# deserialize data into EnumString2
|
||||
try:
|
||||
instance.actual_instance = EnumString2.from_json(json_str)
|
||||
match += 1
|
||||
except (ValidationError, ValueError) as e:
|
||||
error_messages.append(str(e))
|
||||
|
||||
if match > 1:
|
||||
# more than 1 match
|
||||
raise ValueError("Multiple matches found when deserializing the JSON string into OneOfEnumString with oneOf schemas: EnumString1, EnumString2. Details: " + ", ".join(error_messages))
|
||||
elif match == 0:
|
||||
# no match
|
||||
raise ValueError("No match found when deserializing the JSON string into OneOfEnumString with oneOf schemas: EnumString1, EnumString2. Details: " + ", ".join(error_messages))
|
||||
else:
|
||||
return instance
|
||||
|
||||
def to_json(self) -> str:
|
||||
"""Returns the JSON representation of the actual instance"""
|
||||
if self.actual_instance is None:
|
||||
return "null"
|
||||
|
||||
to_json = getattr(self.actual_instance, "to_json", None)
|
||||
if callable(to_json):
|
||||
return self.actual_instance.to_json()
|
||||
else:
|
||||
return json.dumps(self.actual_instance)
|
||||
|
||||
def to_dict(self) -> dict:
|
||||
"""Returns the dict representation of the actual instance"""
|
||||
if self.actual_instance is None:
|
||||
return None
|
||||
|
||||
to_dict = getattr(self.actual_instance, "to_dict", None)
|
||||
if callable(to_dict):
|
||||
return self.actual_instance.to_dict()
|
||||
else:
|
||||
# primitive type
|
||||
return self.actual_instance
|
||||
|
||||
def to_str(self) -> str:
|
||||
"""Returns the string representation of the actual instance"""
|
||||
return pprint.pformat(self.dict())
|
||||
"""Create an instance of OneOfEnumString from a JSON string"""
|
||||
return OneOfEnumString(json.loads(json_str))
|
||||
|
||||
|
||||
|
||||
@@ -59,9 +59,6 @@ class WithNestedOneOf(BaseModel):
|
||||
# override the default output from pydantic by calling `to_dict()` of nested_pig
|
||||
if self.nested_pig:
|
||||
_dict['nested_pig'] = self.nested_pig.to_dict()
|
||||
# override the default output from pydantic by calling `to_dict()` of nested_oneof_enum_string
|
||||
if self.nested_oneof_enum_string:
|
||||
_dict['nested_oneof_enum_string'] = self.nested_oneof_enum_string.to_dict()
|
||||
return _dict
|
||||
|
||||
@classmethod
|
||||
@@ -76,7 +73,7 @@ class WithNestedOneOf(BaseModel):
|
||||
_obj = WithNestedOneOf.parse_obj({
|
||||
"size": obj.get("size"),
|
||||
"nested_pig": Pig.from_dict(obj.get("nested_pig")) if obj.get("nested_pig") is not None else None,
|
||||
"nested_oneof_enum_string": OneOfEnumString.from_dict(obj.get("nested_oneof_enum_string")) if obj.get("nested_oneof_enum_string") is not None else None
|
||||
"nested_oneof_enum_string": obj.get("nested_oneof_enum_string")
|
||||
})
|
||||
return _obj
|
||||
|
||||
|
||||
Reference in New Issue
Block a user