Fix Python codegen in specific additionalProperties case. (#17659)

* Fix Python codegen is specific additionalProperties case.

* Add generated test files.

* Apply fix to AbstractPythonPydanticV1Codegen.java.
This commit is contained in:
Jonathan Klaassen
2024-02-05 06:17:14 -08:00
committed by GitHub
parent 334ddca021
commit 6bcf8cd332
43 changed files with 1514 additions and 6 deletions

View File

@@ -49,6 +49,7 @@ docs/FormatTest.md
docs/HasOnlyReadOnly.md
docs/HealthCheckResult.md
docs/InnerDictWithProperty.md
docs/InputAllOf.md
docs/IntOrString.md
docs/ListClass.md
docs/MapOfArrayOfModel.md
@@ -77,6 +78,7 @@ docs/Pet.md
docs/PetApi.md
docs/Pig.md
docs/PoopCleaning.md
docs/PropertyMap.md
docs/PropertyNameCollision.md
docs/ReadOnlyFirst.md
docs/SecondRef.md
@@ -155,6 +157,7 @@ petstore_api/models/format_test.py
petstore_api/models/has_only_read_only.py
petstore_api/models/health_check_result.py
petstore_api/models/inner_dict_with_property.py
petstore_api/models/input_all_of.py
petstore_api/models/int_or_string.py
petstore_api/models/list_class.py
petstore_api/models/map_of_array_of_model.py
@@ -182,6 +185,7 @@ petstore_api/models/parent_with_optional_dict.py
petstore_api/models/pet.py
petstore_api/models/pig.py
petstore_api/models/poop_cleaning.py
petstore_api/models/property_map.py
petstore_api/models/property_name_collision.py
petstore_api/models/read_only_first.py
petstore_api/models/second_ref.py

View File

@@ -181,6 +181,7 @@ Class | Method | HTTP request | Description
- [HasOnlyReadOnly](docs/HasOnlyReadOnly.md)
- [HealthCheckResult](docs/HealthCheckResult.md)
- [InnerDictWithProperty](docs/InnerDictWithProperty.md)
- [InputAllOf](docs/InputAllOf.md)
- [IntOrString](docs/IntOrString.md)
- [ListClass](docs/ListClass.md)
- [MapOfArrayOfModel](docs/MapOfArrayOfModel.md)
@@ -208,6 +209,7 @@ Class | Method | HTTP request | Description
- [Pet](docs/Pet.md)
- [Pig](docs/Pig.md)
- [PoopCleaning](docs/PoopCleaning.md)
- [PropertyMap](docs/PropertyMap.md)
- [PropertyNameCollision](docs/PropertyNameCollision.md)
- [ReadOnlyFirst](docs/ReadOnlyFirst.md)
- [SecondRef](docs/SecondRef.md)

View File

@@ -0,0 +1,29 @@
# InputAllOf
## Properties
Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
**some_data** | [**Dict[str, Tag]**](Tag.md) | | [optional]
## Example
```python
from petstore_api.models.input_all_of import InputAllOf
# TODO update the JSON string below
json = "{}"
# create an instance of InputAllOf from a JSON string
input_all_of_instance = InputAllOf.from_json(json)
# print the JSON string representation of the object
print InputAllOf.to_json()
# convert the object into a dict
input_all_of_dict = input_all_of_instance.to_dict()
# create an instance of InputAllOf from a dict
input_all_of_form_dict = input_all_of.from_dict(input_all_of_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 @@
# PropertyMap
## Properties
Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
**some_data** | [**Dict[str, Tag]**](Tag.md) | | [optional]
## Example
```python
from petstore_api.models.property_map import PropertyMap
# TODO update the JSON string below
json = "{}"
# create an instance of PropertyMap from a JSON string
property_map_instance = PropertyMap.from_json(json)
# print the JSON string representation of the object
print PropertyMap.to_json()
# convert the object into a dict
property_map_dict = property_map_instance.to_dict()
# create an instance of PropertyMap from a dict
property_map_form_dict = property_map.from_dict(property_map_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

@@ -80,6 +80,7 @@ from petstore_api.models.format_test import FormatTest
from petstore_api.models.has_only_read_only import HasOnlyReadOnly
from petstore_api.models.health_check_result import HealthCheckResult
from petstore_api.models.inner_dict_with_property import InnerDictWithProperty
from petstore_api.models.input_all_of import InputAllOf
from petstore_api.models.int_or_string import IntOrString
from petstore_api.models.list_class import ListClass
from petstore_api.models.map_of_array_of_model import MapOfArrayOfModel
@@ -107,6 +108,7 @@ from petstore_api.models.parent_with_optional_dict import ParentWithOptionalDict
from petstore_api.models.pet import Pet
from petstore_api.models.pig import Pig
from petstore_api.models.poop_cleaning import PoopCleaning
from petstore_api.models.property_map import PropertyMap
from petstore_api.models.property_name_collision import PropertyNameCollision
from petstore_api.models.read_only_first import ReadOnlyFirst
from petstore_api.models.second_ref import SecondRef

View File

@@ -56,6 +56,7 @@ from petstore_api.models.format_test import FormatTest
from petstore_api.models.has_only_read_only import HasOnlyReadOnly
from petstore_api.models.health_check_result import HealthCheckResult
from petstore_api.models.inner_dict_with_property import InnerDictWithProperty
from petstore_api.models.input_all_of import InputAllOf
from petstore_api.models.int_or_string import IntOrString
from petstore_api.models.list_class import ListClass
from petstore_api.models.map_of_array_of_model import MapOfArrayOfModel
@@ -83,6 +84,7 @@ from petstore_api.models.parent_with_optional_dict import ParentWithOptionalDict
from petstore_api.models.pet import Pet
from petstore_api.models.pig import Pig
from petstore_api.models.poop_cleaning import PoopCleaning
from petstore_api.models.property_map import PropertyMap
from petstore_api.models.property_name_collision import PropertyNameCollision
from petstore_api.models.read_only_first import ReadOnlyFirst
from petstore_api.models.second_ref import SecondRef

View File

@@ -0,0 +1,113 @@
# 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 pydantic import BaseModel
from typing import Any, ClassVar, Dict, List, Optional
from petstore_api.models.tag import Tag
from typing import Optional, Set
from typing_extensions import Self
class InputAllOf(BaseModel):
"""
InputAllOf
""" # noqa: E501
some_data: Optional[Dict[str, Tag]] = None
additional_properties: Dict[str, Any] = {}
__properties: ClassVar[List[str]] = ["some_data"]
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 InputAllOf 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,
)
# override the default output from pydantic by calling `to_dict()` of each value in some_data (dict)
_field_dict = {}
if self.some_data:
for _key in self.some_data:
if self.some_data[_key]:
_field_dict[_key] = self.some_data[_key].to_dict()
_dict['some_data'] = _field_dict
# 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 InputAllOf from a dict"""
if obj is None:
return None
if not isinstance(obj, dict):
return cls.model_validate(obj)
_obj = cls.model_validate({
"some_data": dict(
(_k, Tag.from_dict(_v))
for _k, _v in obj["some_data"].items()
)
if obj.get("some_data") is not None
else None
})
# 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,113 @@
# 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 pydantic import BaseModel
from typing import Any, ClassVar, Dict, List, Optional
from petstore_api.models.tag import Tag
from typing import Optional, Set
from typing_extensions import Self
class PropertyMap(BaseModel):
"""
PropertyMap
""" # noqa: E501
some_data: Optional[Dict[str, Tag]] = None
additional_properties: Dict[str, Any] = {}
__properties: ClassVar[List[str]] = ["some_data"]
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 PropertyMap 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,
)
# override the default output from pydantic by calling `to_dict()` of each value in some_data (dict)
_field_dict = {}
if self.some_data:
for _key in self.some_data:
if self.some_data[_key]:
_field_dict[_key] = self.some_data[_key].to_dict()
_dict['some_data'] = _field_dict
# 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 PropertyMap from a dict"""
if obj is None:
return None
if not isinstance(obj, dict):
return cls.model_validate(obj)
_obj = cls.model_validate({
"some_data": dict(
(_k, Tag.from_dict(_v))
for _k, _v in obj["some_data"].items()
)
if obj.get("some_data") is not None
else None
})
# 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,55 @@
# 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.input_all_of import InputAllOf
class TestInputAllOf(unittest.TestCase):
"""InputAllOf unit test stubs"""
def setUp(self):
pass
def tearDown(self):
pass
def make_instance(self, include_optional) -> InputAllOf:
"""Test InputAllOf
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 `InputAllOf`
"""
model = InputAllOf()
if include_optional:
return InputAllOf(
some_data = {
'key' : petstore_api.models.tag.Tag(
id = 56,
name = '', )
}
)
else:
return InputAllOf(
)
"""
def testInputAllOf(self):
"""Test InputAllOf"""
# 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,55 @@
# 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.property_map import PropertyMap
class TestPropertyMap(unittest.TestCase):
"""PropertyMap unit test stubs"""
def setUp(self):
pass
def tearDown(self):
pass
def make_instance(self, include_optional) -> PropertyMap:
"""Test PropertyMap
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 `PropertyMap`
"""
model = PropertyMap()
if include_optional:
return PropertyMap(
some_data = {
'key' : petstore_api.models.tag.Tag(
id = 56,
name = '', )
}
)
else:
return PropertyMap(
)
"""
def testPropertyMap(self):
"""Test PropertyMap"""
# inst_req_only = self.make_instance(include_optional=False)
# inst_req_and_optional = self.make_instance(include_optional=True)
if __name__ == '__main__':
unittest.main()