[python] Fix Circular imports on inherited discriminators. (#17886)

* [python] add inheritance discriminators test #16808

* [python] update samples

* [python] fix assert in test

* [python] fix inheritance discriminators circular import

* [python] update samples

* [python] undo type changes related to discriminator

* [python] remove extraneous processing

* [python-pydantic-v1] fix inheritance discriminators circular import

* [python] remove type ignore comment

* [python] update samples

* [python] fix avoid the empty line break

* [python] update samples
This commit is contained in:
ふぁ
2024-02-20 13:17:32 +09:00
committed by GitHub
parent bf8ee80001
commit ad08581f16
50 changed files with 1541 additions and 70 deletions

View File

@@ -30,6 +30,8 @@ docs/CreatureInfo.md
docs/DanishPig.md
docs/DefaultApi.md
docs/DeprecatedObject.md
docs/DiscriminatorAllOfSub.md
docs/DiscriminatorAllOfSuper.md
docs/Dog.md
docs/DummyModel.md
docs/EnumArrays.md
@@ -140,6 +142,8 @@ petstore_api/models/creature.py
petstore_api/models/creature_info.py
petstore_api/models/danish_pig.py
petstore_api/models/deprecated_object.py
petstore_api/models/discriminator_all_of_sub.py
petstore_api/models/discriminator_all_of_super.py
petstore_api/models/dog.py
petstore_api/models/dummy_model.py
petstore_api/models/enum_arrays.py

View File

@@ -164,6 +164,8 @@ Class | Method | HTTP request | Description
- [CreatureInfo](docs/CreatureInfo.md)
- [DanishPig](docs/DanishPig.md)
- [DeprecatedObject](docs/DeprecatedObject.md)
- [DiscriminatorAllOfSub](docs/DiscriminatorAllOfSub.md)
- [DiscriminatorAllOfSuper](docs/DiscriminatorAllOfSuper.md)
- [Dog](docs/Dog.md)
- [DummyModel](docs/DummyModel.md)
- [EnumArrays](docs/EnumArrays.md)

View File

@@ -0,0 +1,28 @@
# DiscriminatorAllOfSub
## Properties
Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
## Example
```python
from petstore_api.models.discriminator_all_of_sub import DiscriminatorAllOfSub
# TODO update the JSON string below
json = "{}"
# create an instance of DiscriminatorAllOfSub from a JSON string
discriminator_all_of_sub_instance = DiscriminatorAllOfSub.from_json(json)
# print the JSON string representation of the object
print DiscriminatorAllOfSub.to_json()
# convert the object into a dict
discriminator_all_of_sub_dict = discriminator_all_of_sub_instance.to_dict()
# create an instance of DiscriminatorAllOfSub from a dict
discriminator_all_of_sub_form_dict = discriminator_all_of_sub.from_dict(discriminator_all_of_sub_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)

View File

@@ -0,0 +1,29 @@
# DiscriminatorAllOfSuper
## Properties
Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
**element_type** | **str** | |
## Example
```python
from petstore_api.models.discriminator_all_of_super import DiscriminatorAllOfSuper
# TODO update the JSON string below
json = "{}"
# create an instance of DiscriminatorAllOfSuper from a JSON string
discriminator_all_of_super_instance = DiscriminatorAllOfSuper.from_json(json)
# print the JSON string representation of the object
print DiscriminatorAllOfSuper.to_json()
# convert the object into a dict
discriminator_all_of_super_dict = discriminator_all_of_super_instance.to_dict()
# create an instance of DiscriminatorAllOfSuper from a dict
discriminator_all_of_super_form_dict = discriminator_all_of_super.from_dict(discriminator_all_of_super_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)

View File

@@ -63,6 +63,8 @@ from petstore_api.models.creature import Creature
from petstore_api.models.creature_info import CreatureInfo
from petstore_api.models.danish_pig import DanishPig
from petstore_api.models.deprecated_object import DeprecatedObject
from petstore_api.models.discriminator_all_of_sub import DiscriminatorAllOfSub
from petstore_api.models.discriminator_all_of_super import DiscriminatorAllOfSuper
from petstore_api.models.dog import Dog
from petstore_api.models.dummy_model import DummyModel
from petstore_api.models.enum_arrays import EnumArrays

View File

@@ -39,6 +39,8 @@ from petstore_api.models.creature import Creature
from petstore_api.models.creature_info import CreatureInfo
from petstore_api.models.danish_pig import DanishPig
from petstore_api.models.deprecated_object import DeprecatedObject
from petstore_api.models.discriminator_all_of_sub import DiscriminatorAllOfSub
from petstore_api.models.discriminator_all_of_super import DiscriminatorAllOfSuper
from petstore_api.models.dog import Dog
from petstore_api.models.dummy_model import DummyModel
from petstore_api.models.enum_arrays import EnumArrays

View File

@@ -17,11 +17,17 @@ import pprint
import re # noqa: F401
import json
from importlib import import_module
from pydantic import BaseModel, Field, StrictStr
from typing import Any, ClassVar, Dict, List, Optional, Union
from typing import Optional, Set
from typing_extensions import Self
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from petstore_api.models.cat import Cat
from petstore_api.models.dog import Dog
class Animal(BaseModel):
"""
Animal
@@ -65,7 +71,7 @@ class Animal(BaseModel):
return json.dumps(self.to_dict())
@classmethod
def from_json(cls, json_str: str) -> Optional[Union[Self, Self]]:
def from_json(cls, json_str: str) -> Optional[Union[Cat, Dog]]:
"""Create an instance of Animal from a JSON string"""
return cls.from_dict(json.loads(json_str))
@@ -97,20 +103,17 @@ class Animal(BaseModel):
return _dict
@classmethod
def from_dict(cls, obj: Dict[str, Any]) -> Optional[Union[Self, Self]]:
def from_dict(cls, obj: Dict[str, Any]) -> Optional[Union[Cat, Dog]]:
"""Create an instance of Animal from a dict"""
# look up the object type based on discriminator mapping
object_type = cls.get_discriminator_value(obj)
if object_type:
klass = globals()[object_type]
return klass.from_dict(obj)
else:
raise ValueError("Animal failed to lookup discriminator value from " +
json.dumps(obj) + ". Discriminator property name: " + cls.__discriminator_property_name +
", mapping: " + json.dumps(cls.__discriminator_value_class_map))
if object_type == 'Cat':
return import_module("petstore_api.models.cat").Cat.from_dict(obj)
if object_type == 'Dog':
return import_module("petstore_api.models.dog").Dog.from_dict(obj)
raise ValueError("Animal failed to lookup discriminator value from " +
json.dumps(obj) + ". Discriminator property name: " + cls.__discriminator_property_name +
", mapping: " + json.dumps(cls.__discriminator_value_class_map))
from petstore_api.models.cat import Cat
from petstore_api.models.dog import Dog
# TODO: Rewrite to not use raise_errors
Animal.model_rebuild(raise_errors=False)

View File

@@ -0,0 +1,99 @@
# coding: utf-8
"""
OpenAPI Petstore
This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\
The version of the OpenAPI document: 1.0.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
""" # noqa: E501
from __future__ import annotations
import pprint
import re # noqa: F401
import json
from typing import Any, ClassVar, Dict, List
from petstore_api.models.discriminator_all_of_super import DiscriminatorAllOfSuper
from typing import Optional, Set
from typing_extensions import Self
class DiscriminatorAllOfSub(DiscriminatorAllOfSuper):
"""
DiscriminatorAllOfSub
""" # noqa: E501
additional_properties: Dict[str, Any] = {}
__properties: ClassVar[List[str]] = ["elementType"]
model_config = {
"populate_by_name": True,
"validate_assignment": True,
"protected_namespaces": (),
}
def to_str(self) -> str:
"""Returns the string representation of the model using alias"""
return pprint.pformat(self.model_dump(by_alias=True))
def to_json(self) -> str:
"""Returns the JSON representation of the model using alias"""
# TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead
return json.dumps(self.to_dict())
@classmethod
def from_json(cls, json_str: str) -> Optional[Self]:
"""Create an instance of DiscriminatorAllOfSub from a JSON string"""
return cls.from_dict(json.loads(json_str))
def to_dict(self) -> Dict[str, Any]:
"""Return the dictionary representation of the model using alias.
This has the following differences from calling pydantic's
`self.model_dump(by_alias=True)`:
* `None` is only added to the output dict for nullable fields that
were set at model initialization. Other fields with value `None`
are ignored.
* Fields in `self.additional_properties` are added to the output dict.
"""
excluded_fields: Set[str] = set([
"additional_properties",
])
_dict = self.model_dump(
by_alias=True,
exclude=excluded_fields,
exclude_none=True,
)
# puts key-value pairs in additional_properties in the top level
if self.additional_properties is not None:
for _key, _value in self.additional_properties.items():
_dict[_key] = _value
return _dict
@classmethod
def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:
"""Create an instance of DiscriminatorAllOfSub from a dict"""
if obj is None:
return None
if not isinstance(obj, dict):
return cls.model_validate(obj)
_obj = cls.model_validate({
"elementType": obj.get("elementType")
})
# store additional fields in additional_properties
for _key in obj.keys():
if _key not in cls.__properties:
_obj.additional_properties[_key] = obj.get(_key)
return _obj

View File

@@ -0,0 +1,115 @@
# coding: utf-8
"""
OpenAPI Petstore
This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\
The version of the OpenAPI document: 1.0.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
""" # noqa: E501
from __future__ import annotations
import pprint
import re # noqa: F401
import json
from importlib import import_module
from pydantic import BaseModel, Field, StrictStr
from typing import Any, ClassVar, Dict, List, Union
from typing import Optional, Set
from typing_extensions import Self
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from petstore_api.models.discriminator_all_of_sub import DiscriminatorAllOfSub
class DiscriminatorAllOfSuper(BaseModel):
"""
DiscriminatorAllOfSuper
""" # noqa: E501
element_type: StrictStr = Field(alias="elementType")
additional_properties: Dict[str, Any] = {}
__properties: ClassVar[List[str]] = ["elementType"]
model_config = {
"populate_by_name": True,
"validate_assignment": True,
"protected_namespaces": (),
}
# JSON field name that stores the object type
__discriminator_property_name: ClassVar[str] = 'elementType'
# discriminator mappings
__discriminator_value_class_map: ClassVar[Dict[str, str]] = {
'DiscriminatorAllOfSub': 'DiscriminatorAllOfSub'
}
@classmethod
def get_discriminator_value(cls, obj: Dict[str, Any]) -> Optional[str]:
"""Returns the discriminator value (object type) of the data"""
discriminator_value = obj[cls.__discriminator_property_name]
if discriminator_value:
return cls.__discriminator_value_class_map.get(discriminator_value)
else:
return None
def to_str(self) -> str:
"""Returns the string representation of the model using alias"""
return pprint.pformat(self.model_dump(by_alias=True))
def to_json(self) -> str:
"""Returns the JSON representation of the model using alias"""
# TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead
return json.dumps(self.to_dict())
@classmethod
def from_json(cls, json_str: str) -> Optional[Union[DiscriminatorAllOfSub]]:
"""Create an instance of DiscriminatorAllOfSuper from a JSON string"""
return cls.from_dict(json.loads(json_str))
def to_dict(self) -> Dict[str, Any]:
"""Return the dictionary representation of the model using alias.
This has the following differences from calling pydantic's
`self.model_dump(by_alias=True)`:
* `None` is only added to the output dict for nullable fields that
were set at model initialization. Other fields with value `None`
are ignored.
* Fields in `self.additional_properties` are added to the output dict.
"""
excluded_fields: Set[str] = set([
"additional_properties",
])
_dict = self.model_dump(
by_alias=True,
exclude=excluded_fields,
exclude_none=True,
)
# puts key-value pairs in additional_properties in the top level
if self.additional_properties is not None:
for _key, _value in self.additional_properties.items():
_dict[_key] = _value
return _dict
@classmethod
def from_dict(cls, obj: Dict[str, Any]) -> Optional[Union[DiscriminatorAllOfSub]]:
"""Create an instance of DiscriminatorAllOfSuper from a dict"""
# look up the object type based on discriminator mapping
object_type = cls.get_discriminator_value(obj)
if object_type == 'DiscriminatorAllOfSub':
return import_module("petstore_api.models.discriminator_all_of_sub").DiscriminatorAllOfSub.from_dict(obj)
raise ValueError("DiscriminatorAllOfSuper failed to lookup discriminator value from " +
json.dumps(obj) + ". Discriminator property name: " + cls.__discriminator_property_name +
", mapping: " + json.dumps(cls.__discriminator_value_class_map))

View File

@@ -0,0 +1,50 @@
# coding: utf-8
"""
OpenAPI Petstore
This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\
The version of the OpenAPI document: 1.0.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
""" # noqa: E501
import unittest
from petstore_api.models.discriminator_all_of_sub import DiscriminatorAllOfSub
class TestDiscriminatorAllOfSub(unittest.TestCase):
"""DiscriminatorAllOfSub unit test stubs"""
def setUp(self):
pass
def tearDown(self):
pass
def make_instance(self, include_optional) -> DiscriminatorAllOfSub:
"""Test DiscriminatorAllOfSub
include_option is a boolean, when False only required
params are included, when True both required and
optional params are included """
# uncomment below to create an instance of `DiscriminatorAllOfSub`
"""
model = DiscriminatorAllOfSub()
if include_optional:
return DiscriminatorAllOfSub(
)
else:
return DiscriminatorAllOfSub(
)
"""
def testDiscriminatorAllOfSub(self):
"""Test DiscriminatorAllOfSub"""
# inst_req_only = self.make_instance(include_optional=False)
# inst_req_and_optional = self.make_instance(include_optional=True)
if __name__ == '__main__':
unittest.main()

View File

@@ -0,0 +1,52 @@
# coding: utf-8
"""
OpenAPI Petstore
This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\
The version of the OpenAPI document: 1.0.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
""" # noqa: E501
import unittest
from petstore_api.models.discriminator_all_of_super import DiscriminatorAllOfSuper
class TestDiscriminatorAllOfSuper(unittest.TestCase):
"""DiscriminatorAllOfSuper unit test stubs"""
def setUp(self):
pass
def tearDown(self):
pass
def make_instance(self, include_optional) -> DiscriminatorAllOfSuper:
"""Test DiscriminatorAllOfSuper
include_option is a boolean, when False only required
params are included, when True both required and
optional params are included """
# uncomment below to create an instance of `DiscriminatorAllOfSuper`
"""
model = DiscriminatorAllOfSuper()
if include_optional:
return DiscriminatorAllOfSuper(
element_type = ''
)
else:
return DiscriminatorAllOfSuper(
element_type = '',
)
"""
def testDiscriminatorAllOfSuper(self):
"""Test DiscriminatorAllOfSuper"""
# inst_req_only = self.make_instance(include_optional=False)
# inst_req_and_optional = self.make_instance(include_optional=True)
if __name__ == '__main__':
unittest.main()

View File

@@ -342,6 +342,10 @@ class ModelTests(unittest.TestCase):
self.assertEqual(dog2.breed, 'bulldog')
self.assertEqual(dog2.class_name, "dog")
self.assertEqual(dog2.color, 'white')
def test_inheritance_discriminators(self):
model = petstore_api.DiscriminatorAllOfSuper.from_dict({"elementType": "DiscriminatorAllOfSub"})
self.assertIsInstance(model, petstore_api.DiscriminatorAllOfSub)
def test_list(self):
# should throw exception as var_123_list should be string