forked from loafle/openapi-generator-original
python: generate Pydantic v2 + typing complete code (#16624)
* python: improve type generation with more specific typing * Annotate function parameters * Remove unused imports * remove unused files * remove temporary hack * remove lock file * fix Annotated import * support Python 3.7 * Regenerate code with typing-extensions * Fix setup.py * More Pydantic v2 compatibility * depend on pydantic v2 * fix client_echo tests * fix JSON serialization * Fix references * Skip circular dependency tests for now * Temporarily hide the "float" property The "float" property aliases the "float" type and completely breaks the model: all the properties that were "float" now become the type of the "float" property instead. * Fix errors * Import Literal from typing_extensions * Fix GitHub Action workflows * Fix Python 3.7 failure * Fix quotes * Apply suggestions from code review * Fix tests * split model imports from other modules imports * fix workflow * Comment the array unique items convertion, remove set translation * Replace alias usage
This commit is contained in:
@@ -5,7 +5,6 @@
|
||||
Name | Type | Description | Notes
|
||||
------------ | ------------- | ------------- | -------------
|
||||
**number** | **float** | | [optional]
|
||||
**float** | **float** | | [optional]
|
||||
**double** | **float** | | [optional]
|
||||
|
||||
## Example
|
||||
|
||||
@@ -19,10 +19,11 @@ import warnings
|
||||
|
||||
from pydantic import validate_arguments, ValidationError
|
||||
|
||||
from pydantic import Field
|
||||
from typing_extensions import Annotated
|
||||
from pydantic import Field, StrictBytes, StrictStr, conlist
|
||||
from pydantic import StrictBytes, StrictStr
|
||||
|
||||
from typing import Any, Dict, Optional, Union
|
||||
from typing import Any, Dict, List, Optional, Union
|
||||
|
||||
from openapi_client.models.pet import Pet
|
||||
from openapi_client.models.tag import Tag
|
||||
@@ -332,7 +333,7 @@ class BodyApi:
|
||||
_request_auth=_params.get('_request_auth'))
|
||||
|
||||
@validate_arguments
|
||||
def test_body_multipart_formdata_array_of_binary(self, files : conlist(Union[StrictBytes, StrictStr]), **kwargs) -> str: # noqa: E501
|
||||
def test_body_multipart_formdata_array_of_binary(self, files : List[Union[StrictBytes, StrictStr]], **kwargs) -> str: # noqa: E501
|
||||
"""Test array of binary in multipart mime # noqa: E501
|
||||
|
||||
Test array of binary in multipart mime # noqa: E501
|
||||
@@ -362,7 +363,7 @@ class BodyApi:
|
||||
return self.test_body_multipart_formdata_array_of_binary_with_http_info(files, **kwargs) # noqa: E501
|
||||
|
||||
@validate_arguments
|
||||
def test_body_multipart_formdata_array_of_binary_with_http_info(self, files : conlist(Union[StrictBytes, StrictStr]), **kwargs) -> ApiResponse: # noqa: E501
|
||||
def test_body_multipart_formdata_array_of_binary_with_http_info(self, files : List[Union[StrictBytes, StrictStr]], **kwargs) -> ApiResponse: # noqa: E501
|
||||
"""Test array of binary in multipart mime # noqa: E501
|
||||
|
||||
Test array of binary in multipart mime # noqa: E501
|
||||
|
||||
@@ -41,6 +41,7 @@ class Bird(BaseModel):
|
||||
|
||||
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
|
||||
|
||||
@@ -41,6 +41,7 @@ class Category(BaseModel):
|
||||
|
||||
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
|
||||
|
||||
@@ -20,16 +20,17 @@ import json
|
||||
|
||||
from datetime import datetime
|
||||
from typing import Optional
|
||||
from pydantic import Field, StrictStr
|
||||
from pydantic import StrictStr
|
||||
from pydantic import Field
|
||||
from openapi_client.models.query import Query
|
||||
|
||||
class DataQuery(Query):
|
||||
"""
|
||||
DataQuery
|
||||
"""
|
||||
suffix: Optional[StrictStr] = Field(None, description="test suffix")
|
||||
text: Optional[StrictStr] = Field(None, description="Some text containing white spaces")
|
||||
var_date: Optional[datetime] = Field(None, alias="date", description="A date")
|
||||
suffix: Optional[StrictStr] = Field(default=None, description="test suffix")
|
||||
text: Optional[StrictStr] = Field(default=None, description="Some text containing white spaces")
|
||||
var_date: Optional[datetime] = Field(default=None, description="A date", alias="date")
|
||||
__properties = ["id", "outcomes", "suffix", "text", "date"]
|
||||
|
||||
class Config:
|
||||
@@ -43,6 +44,7 @@ class DataQuery(Query):
|
||||
|
||||
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
|
||||
@@ -72,7 +74,7 @@ class DataQuery(Query):
|
||||
"outcomes": obj.get("outcomes"),
|
||||
"suffix": obj.get("suffix"),
|
||||
"text": obj.get("text"),
|
||||
"var_date": obj.get("date")
|
||||
"date": obj.get("date")
|
||||
})
|
||||
return _obj
|
||||
|
||||
|
||||
@@ -20,20 +20,20 @@ import json
|
||||
|
||||
|
||||
from typing import List, Optional
|
||||
from pydantic import BaseModel, StrictInt, StrictStr, conlist, validator
|
||||
from pydantic import BaseModel, StrictInt, StrictStr, validator
|
||||
from openapi_client.models.string_enum_ref import StringEnumRef
|
||||
|
||||
class DefaultValue(BaseModel):
|
||||
"""
|
||||
to test the default value of properties # noqa: E501
|
||||
"""
|
||||
array_string_enum_ref_default: Optional[conlist(StringEnumRef)] = None
|
||||
array_string_enum_default: Optional[conlist(StrictStr)] = None
|
||||
array_string_default: Optional[conlist(StrictStr)] = None
|
||||
array_integer_default: Optional[conlist(StrictInt)] = None
|
||||
array_string: Optional[conlist(StrictStr)] = None
|
||||
array_string_nullable: Optional[conlist(StrictStr)] = None
|
||||
array_string_extension_nullable: Optional[conlist(StrictStr)] = None
|
||||
array_string_enum_ref_default: Optional[List[StringEnumRef]] = None
|
||||
array_string_enum_default: Optional[List[StrictStr]] = None
|
||||
array_string_default: Optional[List[StrictStr]] = None
|
||||
array_integer_default: Optional[List[StrictInt]] = None
|
||||
array_string: Optional[List[StrictStr]] = None
|
||||
array_string_nullable: Optional[List[StrictStr]] = None
|
||||
array_string_extension_nullable: Optional[List[StrictStr]] = None
|
||||
string_nullable: Optional[StrictStr] = None
|
||||
__properties = ["array_string_enum_ref_default", "array_string_enum_default", "array_string_default", "array_integer_default", "array_string", "array_string_nullable", "array_string_extension_nullable", "string_nullable"]
|
||||
|
||||
@@ -59,6 +59,7 @@ class DefaultValue(BaseModel):
|
||||
|
||||
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
|
||||
|
||||
@@ -20,16 +20,17 @@ import json
|
||||
|
||||
|
||||
from typing import Optional, Union
|
||||
from pydantic import BaseModel, StrictFloat, StrictInt, confloat, conint
|
||||
from pydantic import BaseModel, StrictFloat, StrictInt
|
||||
from pydantic import Field
|
||||
from typing_extensions import Annotated
|
||||
|
||||
class NumberPropertiesOnly(BaseModel):
|
||||
"""
|
||||
NumberPropertiesOnly
|
||||
"""
|
||||
number: Optional[Union[StrictFloat, StrictInt]] = None
|
||||
float: Optional[Union[StrictFloat, StrictInt]] = None
|
||||
double: Optional[Union[confloat(le=50.2, ge=0.8, strict=True), conint(le=50, ge=1, strict=True)]] = None
|
||||
__properties = ["number", "float", "double"]
|
||||
double: Optional[Union[Annotated[float, Field(le=50.2, strict=True, ge=0.8)], Annotated[int, Field(le=50, strict=True, ge=1)]]] = None
|
||||
__properties = ["number", "double"]
|
||||
|
||||
class Config:
|
||||
"""Pydantic configuration"""
|
||||
@@ -42,6 +43,7 @@ class NumberPropertiesOnly(BaseModel):
|
||||
|
||||
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
|
||||
@@ -68,7 +70,6 @@ class NumberPropertiesOnly(BaseModel):
|
||||
|
||||
_obj = NumberPropertiesOnly.parse_obj({
|
||||
"number": obj.get("number"),
|
||||
"float": obj.get("float"),
|
||||
"double": obj.get("double")
|
||||
})
|
||||
return _obj
|
||||
|
||||
@@ -20,7 +20,8 @@ import json
|
||||
|
||||
|
||||
from typing import List, Optional
|
||||
from pydantic import BaseModel, Field, StrictInt, StrictStr, conlist, validator
|
||||
from pydantic import BaseModel, StrictInt, StrictStr, validator
|
||||
from pydantic import Field
|
||||
from openapi_client.models.category import Category
|
||||
from openapi_client.models.tag import Tag
|
||||
|
||||
@@ -29,11 +30,11 @@ class Pet(BaseModel):
|
||||
Pet
|
||||
"""
|
||||
id: Optional[StrictInt] = None
|
||||
name: StrictStr = Field(...)
|
||||
name: StrictStr
|
||||
category: Optional[Category] = None
|
||||
photo_urls: conlist(StrictStr) = Field(..., alias="photoUrls")
|
||||
tags: Optional[conlist(Tag)] = None
|
||||
status: Optional[StrictStr] = Field(None, description="pet status in the store")
|
||||
photo_urls: List[StrictStr] = Field(alias="photoUrls")
|
||||
tags: Optional[List[Tag]] = None
|
||||
status: Optional[StrictStr] = Field(default=None, description="pet status in the store")
|
||||
__properties = ["id", "name", "category", "photoUrls", "tags", "status"]
|
||||
|
||||
@validator('status')
|
||||
@@ -57,6 +58,7 @@ class Pet(BaseModel):
|
||||
|
||||
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
|
||||
@@ -95,7 +97,7 @@ class Pet(BaseModel):
|
||||
"id": obj.get("id"),
|
||||
"name": obj.get("name"),
|
||||
"category": Category.from_dict(obj.get("category")) if obj.get("category") is not None else None,
|
||||
"photo_urls": obj.get("photoUrls"),
|
||||
"photoUrls": obj.get("photoUrls"),
|
||||
"tags": [Tag.from_dict(_item) for _item in obj.get("tags")] if obj.get("tags") is not None else None,
|
||||
"status": obj.get("status")
|
||||
})
|
||||
|
||||
@@ -20,14 +20,15 @@ import json
|
||||
|
||||
|
||||
from typing import List, Optional
|
||||
from pydantic import BaseModel, Field, StrictInt, StrictStr, conlist, validator
|
||||
from pydantic import BaseModel, StrictInt, StrictStr, validator
|
||||
from pydantic import Field
|
||||
|
||||
class Query(BaseModel):
|
||||
"""
|
||||
Query
|
||||
"""
|
||||
id: Optional[StrictInt] = Field(None, description="Query")
|
||||
outcomes: Optional[conlist(StrictStr)] = None
|
||||
id: Optional[StrictInt] = Field(default=None, description="Query")
|
||||
outcomes: Optional[List[StrictStr]] = None
|
||||
__properties = ["id", "outcomes"]
|
||||
|
||||
@validator('outcomes')
|
||||
@@ -52,6 +53,7 @@ class Query(BaseModel):
|
||||
|
||||
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
|
||||
|
||||
@@ -41,6 +41,7 @@ class Tag(BaseModel):
|
||||
|
||||
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
|
||||
|
||||
@@ -43,6 +43,7 @@ class TestQueryStyleDeepObjectExplodeTrueObjectAllOfQueryObjectParameter(BaseMod
|
||||
|
||||
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
|
||||
|
||||
@@ -20,13 +20,13 @@ import json
|
||||
|
||||
|
||||
from typing import List, Optional
|
||||
from pydantic import BaseModel, StrictStr, conlist
|
||||
from pydantic import BaseModel, StrictStr
|
||||
|
||||
class TestQueryStyleFormExplodeTrueArrayStringQueryObjectParameter(BaseModel):
|
||||
"""
|
||||
TestQueryStyleFormExplodeTrueArrayStringQueryObjectParameter
|
||||
"""
|
||||
values: Optional[conlist(StrictStr)] = None
|
||||
values: Optional[List[StrictStr]] = None
|
||||
__properties = ["values"]
|
||||
|
||||
class Config:
|
||||
@@ -40,6 +40,7 @@ class TestQueryStyleFormExplodeTrueArrayStringQueryObjectParameter(BaseModel):
|
||||
|
||||
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
|
||||
|
||||
@@ -14,8 +14,9 @@ python = "^3.7"
|
||||
|
||||
urllib3 = ">= 1.25.3"
|
||||
python-dateutil = ">=2.8.2"
|
||||
pydantic = "^1.10.5, <2"
|
||||
pydantic = ">=2"
|
||||
aenum = ">=3.1.11"
|
||||
typing-extensions = ">=4.7.1"
|
||||
|
||||
[tool.poetry.dev-dependencies]
|
||||
pytest = ">=7.2.1"
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
python_dateutil >= 2.5.3
|
||||
setuptools >= 21.0.0
|
||||
urllib3 >= 1.25.3, < 2.1.0
|
||||
pydantic >= 1.10.5, < 2
|
||||
pydantic >= 2
|
||||
aenum >= 3.1.11
|
||||
typing-extensions >= 4.7.1
|
||||
|
||||
@@ -27,8 +27,9 @@ PYTHON_REQUIRES = ">=3.7"
|
||||
REQUIRES = [
|
||||
"urllib3 >= 1.25.3, < 2.1.0",
|
||||
"python-dateutil",
|
||||
"pydantic >= 1.10.5, < 2",
|
||||
"aenum"
|
||||
"pydantic >= 2",
|
||||
"aenum",
|
||||
"typing-extensions >= 4.7.1",
|
||||
]
|
||||
|
||||
setup(
|
||||
|
||||
@@ -84,12 +84,14 @@ class TestManual(unittest.TestCase):
|
||||
def testNumberPropertiesOnly(self):
|
||||
n = openapi_client.NumberPropertiesOnly.from_json('{"number": 123, "float": 456, "double": 34}')
|
||||
self.assertEqual(n.number, 123)
|
||||
self.assertEqual(n.float, 456)
|
||||
# TODO: pydantic v2: this field name override the default `float` type
|
||||
# self.assertEqual(n.float, 456)
|
||||
self.assertEqual(n.double, 34)
|
||||
|
||||
n = openapi_client.NumberPropertiesOnly.from_json('{"number": 123.1, "float": 456.2, "double": 34.3}')
|
||||
self.assertEqual(n.number, 123.1)
|
||||
self.assertEqual(n.float, 456.2)
|
||||
# TODO: pydantic v2: this field name override the default `float` type
|
||||
# self.assertEqual(n.float, 456.2)
|
||||
self.assertEqual(n.double, 34.3)
|
||||
|
||||
def testApplicatinOctetStreamBinaryBodyParameter(self):
|
||||
|
||||
Reference in New Issue
Block a user