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:
Jonathan Ballet
2023-09-28 13:13:14 +02:00
committed by GitHub
parent af352df10f
commit 04fa53b692
219 changed files with 3305 additions and 1566 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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")
})

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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