forked from loafle/openapi-generator-original
fix: Annotate free-form object as dict in Python (#17082)
This commit is contained in:
@@ -2024,16 +2024,6 @@ public abstract class AbstractPythonCodegen extends DefaultCodegen implements Co
|
|||||||
return new PythonType(cp.getDataType());
|
return new PythonType(cp.getDataType());
|
||||||
}
|
}
|
||||||
|
|
||||||
private PythonType freeFormType(IJsonSchemaValidationProperties cp) {
|
|
||||||
typingImports.add("Dict");
|
|
||||||
typingImports.add("Any");
|
|
||||||
typingImports.add("Union");
|
|
||||||
PythonType pt = new PythonType("Union");
|
|
||||||
pt.addTypeParam(new PythonType("str"));
|
|
||||||
pt.addTypeParam(new PythonType("Any"));
|
|
||||||
return pt;
|
|
||||||
}
|
|
||||||
|
|
||||||
private PythonType modelType(IJsonSchemaValidationProperties cp) {
|
private PythonType modelType(IJsonSchemaValidationProperties cp) {
|
||||||
// add model prefix
|
// add model prefix
|
||||||
hasModelsToImport = true;
|
hasModelsToImport = true;
|
||||||
@@ -2056,7 +2046,7 @@ public abstract class AbstractPythonCodegen extends DefaultCodegen implements Co
|
|||||||
|
|
||||||
if (cp.getIsArray()) {
|
if (cp.getIsArray()) {
|
||||||
return arrayType(cp);
|
return arrayType(cp);
|
||||||
} else if (cp.getIsMap()) {
|
} else if (cp.getIsMap() || cp.getIsFreeFormObject()) {
|
||||||
return mapType(cp);
|
return mapType(cp);
|
||||||
} else if (cp.getIsString()) {
|
} else if (cp.getIsString()) {
|
||||||
return stringType(cp);
|
return stringType(cp);
|
||||||
@@ -2076,8 +2066,6 @@ public abstract class AbstractPythonCodegen extends DefaultCodegen implements Co
|
|||||||
return dateType(cp);
|
return dateType(cp);
|
||||||
} else if (cp.getIsUuid()) {
|
} else if (cp.getIsUuid()) {
|
||||||
return uuidType(cp);
|
return uuidType(cp);
|
||||||
} else if (cp.getIsFreeFormObject()) { // type: object
|
|
||||||
return freeFormType(cp);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ import re # noqa: F401
|
|||||||
import json
|
import json
|
||||||
|
|
||||||
|
|
||||||
from typing import Any, ClassVar, Dict, List, Optional, Union
|
from typing import Any, ClassVar, Dict, List, Optional
|
||||||
from pydantic import BaseModel
|
from pydantic import BaseModel
|
||||||
from pydantic import Field
|
from pydantic import Field
|
||||||
try:
|
try:
|
||||||
@@ -30,7 +30,7 @@ class InnerDictWithProperty(BaseModel):
|
|||||||
"""
|
"""
|
||||||
InnerDictWithProperty
|
InnerDictWithProperty
|
||||||
""" # noqa: E501
|
""" # noqa: E501
|
||||||
a_property: Optional[Union[str, Any]] = Field(default=None, alias="aProperty")
|
a_property: Optional[Dict[str, Any]] = Field(default=None, alias="aProperty")
|
||||||
__properties: ClassVar[List[str]] = ["aProperty"]
|
__properties: ClassVar[List[str]] = ["aProperty"]
|
||||||
|
|
||||||
model_config = {
|
model_config = {
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ import re # noqa: F401
|
|||||||
import json
|
import json
|
||||||
|
|
||||||
from datetime import date, datetime
|
from datetime import date, datetime
|
||||||
from typing import Any, ClassVar, Dict, List, Optional, Union
|
from typing import Any, ClassVar, Dict, List, Optional
|
||||||
from pydantic import BaseModel, StrictBool, StrictInt, StrictStr
|
from pydantic import BaseModel, StrictBool, StrictInt, StrictStr
|
||||||
try:
|
try:
|
||||||
from typing import Self
|
from typing import Self
|
||||||
@@ -36,12 +36,12 @@ class NullableClass(BaseModel):
|
|||||||
string_prop: Optional[StrictStr] = None
|
string_prop: Optional[StrictStr] = None
|
||||||
date_prop: Optional[date] = None
|
date_prop: Optional[date] = None
|
||||||
datetime_prop: Optional[datetime] = None
|
datetime_prop: Optional[datetime] = None
|
||||||
array_nullable_prop: Optional[List[Union[str, Any]]] = None
|
array_nullable_prop: Optional[List[Dict[str, Any]]] = None
|
||||||
array_and_items_nullable_prop: Optional[List[Union[str, Any]]] = None
|
array_and_items_nullable_prop: Optional[List[Dict[str, Any]]] = None
|
||||||
array_items_nullable: Optional[List[Union[str, Any]]] = None
|
array_items_nullable: Optional[List[Dict[str, Any]]] = None
|
||||||
object_nullable_prop: Optional[Dict[str, Union[str, Any]]] = None
|
object_nullable_prop: Optional[Dict[str, Dict[str, Any]]] = None
|
||||||
object_and_items_nullable_prop: Optional[Dict[str, Union[str, Any]]] = None
|
object_and_items_nullable_prop: Optional[Dict[str, Dict[str, Any]]] = None
|
||||||
object_items_nullable: Optional[Dict[str, Union[str, Any]]] = None
|
object_items_nullable: Optional[Dict[str, Dict[str, Any]]] = None
|
||||||
additional_properties: Dict[str, Any] = {}
|
additional_properties: Dict[str, Any] = {}
|
||||||
__properties: ClassVar[List[str]] = ["required_integer_prop", "integer_prop", "number_prop", "boolean_prop", "string_prop", "date_prop", "datetime_prop", "array_nullable_prop", "array_and_items_nullable_prop", "array_items_nullable", "object_nullable_prop", "object_and_items_nullable_prop", "object_items_nullable"]
|
__properties: ClassVar[List[str]] = ["required_integer_prop", "integer_prop", "number_prop", "boolean_prop", "string_prop", "date_prop", "datetime_prop", "array_nullable_prop", "array_and_items_nullable_prop", "array_items_nullable", "object_nullable_prop", "object_and_items_nullable_prop", "object_items_nullable"]
|
||||||
|
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ import re # noqa: F401
|
|||||||
import json
|
import json
|
||||||
|
|
||||||
|
|
||||||
from typing import Any, ClassVar, Dict, List, Optional, Union
|
from typing import Any, ClassVar, Dict, List, Optional
|
||||||
from pydantic import BaseModel
|
from pydantic import BaseModel
|
||||||
from pydantic import Field
|
from pydantic import Field
|
||||||
try:
|
try:
|
||||||
@@ -30,7 +30,7 @@ class InnerDictWithProperty(BaseModel):
|
|||||||
"""
|
"""
|
||||||
InnerDictWithProperty
|
InnerDictWithProperty
|
||||||
""" # noqa: E501
|
""" # noqa: E501
|
||||||
a_property: Optional[Union[str, Any]] = Field(default=None, alias="aProperty")
|
a_property: Optional[Dict[str, Any]] = Field(default=None, alias="aProperty")
|
||||||
additional_properties: Dict[str, Any] = {}
|
additional_properties: Dict[str, Any] = {}
|
||||||
__properties: ClassVar[List[str]] = ["aProperty"]
|
__properties: ClassVar[List[str]] = ["aProperty"]
|
||||||
|
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ import re # noqa: F401
|
|||||||
import json
|
import json
|
||||||
|
|
||||||
from datetime import date, datetime
|
from datetime import date, datetime
|
||||||
from typing import Any, ClassVar, Dict, List, Optional, Union
|
from typing import Any, ClassVar, Dict, List, Optional
|
||||||
from pydantic import BaseModel, StrictBool, StrictFloat, StrictInt, StrictStr
|
from pydantic import BaseModel, StrictBool, StrictFloat, StrictInt, StrictStr
|
||||||
try:
|
try:
|
||||||
from typing import Self
|
from typing import Self
|
||||||
@@ -36,12 +36,12 @@ class NullableClass(BaseModel):
|
|||||||
string_prop: Optional[StrictStr] = None
|
string_prop: Optional[StrictStr] = None
|
||||||
date_prop: Optional[date] = None
|
date_prop: Optional[date] = None
|
||||||
datetime_prop: Optional[datetime] = None
|
datetime_prop: Optional[datetime] = None
|
||||||
array_nullable_prop: Optional[List[Union[str, Any]]] = None
|
array_nullable_prop: Optional[List[Dict[str, Any]]] = None
|
||||||
array_and_items_nullable_prop: Optional[List[Union[str, Any]]] = None
|
array_and_items_nullable_prop: Optional[List[Dict[str, Any]]] = None
|
||||||
array_items_nullable: Optional[List[Union[str, Any]]] = None
|
array_items_nullable: Optional[List[Dict[str, Any]]] = None
|
||||||
object_nullable_prop: Optional[Dict[str, Union[str, Any]]] = None
|
object_nullable_prop: Optional[Dict[str, Dict[str, Any]]] = None
|
||||||
object_and_items_nullable_prop: Optional[Dict[str, Union[str, Any]]] = None
|
object_and_items_nullable_prop: Optional[Dict[str, Dict[str, Any]]] = None
|
||||||
object_items_nullable: Optional[Dict[str, Union[str, Any]]] = None
|
object_items_nullable: Optional[Dict[str, Dict[str, Any]]] = None
|
||||||
additional_properties: Dict[str, Any] = {}
|
additional_properties: Dict[str, Any] = {}
|
||||||
__properties: ClassVar[List[str]] = ["required_integer_prop", "integer_prop", "number_prop", "boolean_prop", "string_prop", "date_prop", "datetime_prop", "array_nullable_prop", "array_and_items_nullable_prop", "array_items_nullable", "object_nullable_prop", "object_and_items_nullable_prop", "object_items_nullable"]
|
__properties: ClassVar[List[str]] = ["required_integer_prop", "integer_prop", "number_prop", "boolean_prop", "string_prop", "date_prop", "datetime_prop", "array_nullable_prop", "array_and_items_nullable_prop", "array_items_nullable", "object_nullable_prop", "object_and_items_nullable_prop", "object_items_nullable"]
|
||||||
|
|
||||||
|
|||||||
@@ -8,8 +8,10 @@ import time
|
|||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
from pydantic import ValidationError
|
from pydantic import ValidationError
|
||||||
|
import pytest
|
||||||
|
|
||||||
import petstore_api
|
import petstore_api
|
||||||
|
from petstore_api import InnerDictWithProperty
|
||||||
|
|
||||||
|
|
||||||
class ModelTests(unittest.TestCase):
|
class ModelTests(unittest.TestCase):
|
||||||
@@ -508,6 +510,19 @@ class ModelTests(unittest.TestCase):
|
|||||||
self.assertFalse(b is None)
|
self.assertFalse(b is None)
|
||||||
self.assertEqual(b.optional_dict["key"].a_property["a"], "b")
|
self.assertEqual(b.optional_dict["key"].a_property["a"], "b")
|
||||||
|
|
||||||
|
def test_freeform_object(self):
|
||||||
|
# Allows dict[str, Any] and is nullable
|
||||||
|
a = InnerDictWithProperty.from_dict({"aProperty": {"a": 12}})
|
||||||
|
a = InnerDictWithProperty.from_dict({"aProperty": None})
|
||||||
|
|
||||||
|
# Allows no other values
|
||||||
|
with pytest.raises(ValidationError):
|
||||||
|
a = InnerDictWithProperty.from_dict({"aProperty": {123: 45}})
|
||||||
|
with pytest.raises(ValidationError):
|
||||||
|
a = InnerDictWithProperty.from_dict({"aProperty": "abc"})
|
||||||
|
with pytest.raises(ValidationError):
|
||||||
|
a = InnerDictWithProperty.from_dict({"aProperty": 12})
|
||||||
|
|
||||||
def test_object_with_dict_of_dict_of_object(self):
|
def test_object_with_dict_of_dict_of_object(self):
|
||||||
# for https://github.com/OpenAPITools/openapi-generator/issues/15135
|
# for https://github.com/OpenAPITools/openapi-generator/issues/15135
|
||||||
d = {"optionalDict": {"a": {"b": {"aProperty": "value"}}}}
|
d = {"optionalDict": {"a": {"b": {"aProperty": "value"}}}}
|
||||||
|
|||||||
Reference in New Issue
Block a user