Skip to content

Commit a6d7d7b

Browse files
feat: Upgrade internal Pydantic use to v2. Thanks @KristinnVikar! (#779)
* initial changes for update to pydantic v2 * remove debug print * Update pydantic to v2.1.0 * Fix OpenAPI model rebuilding * Parameters.classes_by_name use str as key Looking at tests shows me that str as key instead of ClassName is more expected? * Update tests to reflect new error messages * update poetry lock * Misc fixes for pydantic validation * Schema union ordering try Schema before Reference * Support for boolean values in Schema.enum * Missing default=None in SecurityScheme.security_scheme_in which is enforced by Pydantic V2 * Update Pydantic to V2.1.1 * Add missing type to union in build_enum_property * chore: Clean up a couple of warnings * chore: Allow future semver-compatible versions of Pydantic * fix: Undo incomplete support for bool enums * chore: Reformat --------- Co-authored-by: Dylan Anthony <[email protected]> Co-authored-by: Dylan Anthony <[email protected]>
1 parent be5b306 commit a6d7d7b

40 files changed

+726
-618
lines changed

openapi_python_client/config.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,9 @@ class Config(BaseModel):
2424
"""
2525

2626
class_overrides: Dict[str, ClassOverride] = {}
27-
project_name_override: Optional[str]
28-
package_name_override: Optional[str]
29-
package_version_override: Optional[str]
27+
project_name_override: Optional[str] = None
28+
package_name_override: Optional[str] = None
29+
package_version_override: Optional[str] = None
3030
use_path_prefixes_for_title_model_names: bool = True
3131
post_hooks: List[str] = [
3232
"autoflake -i -r --remove-all-unused-imports --remove-unused-variables --ignore-init-module-imports .",

openapi_python_client/parser/openapi.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -559,7 +559,7 @@ class GeneratorData:
559559
def from_dict(data: Dict[str, Any], *, config: Config) -> Union["GeneratorData", GeneratorError]:
560560
"""Create an OpenAPI from dict"""
561561
try:
562-
openapi = oai.OpenAPI.parse_obj(data)
562+
openapi = oai.OpenAPI.model_validate(data)
563563
except ValidationError as err:
564564
detail = str(err)
565565
if "swagger" in data:

openapi_python_client/parser/properties/model_property.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -289,7 +289,7 @@ def _get_additional_properties(
289289
if isinstance(schema_additional, bool):
290290
return schema_additional, schemas
291291

292-
if isinstance(schema_additional, oai.Schema) and not any(schema_additional.dict().values()):
292+
if isinstance(schema_additional, oai.Schema) and not any(schema_additional.model_dump().values()):
293293
# An empty schema
294294
return True, schemas
295295

openapi_python_client/schema/openapi_schema_pydantic/components.py

+7-7
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from typing import Dict, Optional, Union
22

3-
from pydantic import BaseModel, Extra
3+
from pydantic import BaseModel, ConfigDict
44

55
from .callback import Callback
66
from .example import Example
@@ -25,7 +25,7 @@ class Components(BaseModel):
2525
- https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#componentsObject
2626
"""
2727

28-
schemas: Optional[Dict[str, Union[Reference, Schema]]] = None
28+
schemas: Optional[Dict[str, Union[Schema, Reference]]] = None
2929
responses: Optional[Dict[str, Union[Response, Reference]]] = None
3030
parameters: Optional[Dict[str, Union[Parameter, Reference]]] = None
3131
examples: Optional[Dict[str, Union[Example, Reference]]] = None
@@ -34,10 +34,9 @@ class Components(BaseModel):
3434
securitySchemes: Optional[Dict[str, Union[SecurityScheme, Reference]]] = None
3535
links: Optional[Dict[str, Union[Link, Reference]]] = None
3636
callbacks: Optional[Dict[str, Union[Callback, Reference]]] = None
37-
38-
class Config: # pylint: disable=missing-class-docstring
39-
extra = Extra.allow
40-
schema_extra = {
37+
model_config = ConfigDict(
38+
extra="allow",
39+
json_schema_extra={
4140
"examples": [
4241
{
4342
"schemas": {
@@ -98,4 +97,5 @@ class Config: # pylint: disable=missing-class-docstring
9897
},
9998
}
10099
]
101-
}
100+
},
101+
)
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from typing import Optional
22

3-
from pydantic import BaseModel, Extra
3+
from pydantic import BaseModel, ConfigDict
44

55

66
class Contact(BaseModel):
@@ -14,11 +14,11 @@ class Contact(BaseModel):
1414
name: Optional[str] = None
1515
url: Optional[str] = None
1616
email: Optional[str] = None
17-
18-
class Config: # pylint: disable=missing-class-docstring
19-
extra = Extra.allow
20-
schema_extra = {
17+
model_config = ConfigDict(
18+
extra="allow",
19+
json_schema_extra={
2120
"examples": [
2221
{"name": "API Support", "url": "http://www.example.com/support", "email": "[email protected]"}
2322
]
24-
}
23+
},
24+
)

openapi_python_client/schema/openapi_schema_pydantic/discriminator.py

+6-6
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from typing import Dict, Optional
22

3-
from pydantic import BaseModel, Extra
3+
from pydantic import BaseModel, ConfigDict
44

55

66
class Discriminator(BaseModel):
@@ -20,10 +20,9 @@ class Discriminator(BaseModel):
2020

2121
propertyName: str
2222
mapping: Optional[Dict[str, str]] = None
23-
24-
class Config: # pylint: disable=missing-class-docstring
25-
extra = Extra.allow
26-
schema_extra = {
23+
model_config = ConfigDict(
24+
extra="allow",
25+
json_schema_extra={
2726
"examples": [
2827
{
2928
"propertyName": "petType",
@@ -33,4 +32,5 @@ class Config: # pylint: disable=missing-class-docstring
3332
},
3433
}
3534
]
36-
}
35+
},
36+
)

openapi_python_client/schema/openapi_schema_pydantic/encoding.py

+6-6
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from typing import TYPE_CHECKING, Dict, Optional, Union
22

3-
from pydantic import BaseModel, Extra
3+
from pydantic import BaseModel, ConfigDict
44

55
from .reference import Reference
66

@@ -23,10 +23,9 @@ class Encoding(BaseModel):
2323
style: Optional[str] = None
2424
explode: bool = False
2525
allowReserved: bool = False
26-
27-
class Config: # pylint: disable=missing-class-docstring
28-
extra = Extra.allow
29-
schema_extra = {
26+
model_config = ConfigDict(
27+
extra="allow",
28+
json_schema_extra={
3029
"examples": [
3130
{
3231
"contentType": "image/png, image/jpeg",
@@ -38,4 +37,5 @@ class Config: # pylint: disable=missing-class-docstring
3837
},
3938
}
4039
]
41-
}
40+
},
41+
)

openapi_python_client/schema/openapi_schema_pydantic/example.py

+6-6
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from typing import Any, Optional
22

3-
from pydantic import BaseModel, Extra
3+
from pydantic import BaseModel, ConfigDict
44

55

66
class Example(BaseModel):
@@ -15,10 +15,9 @@ class Example(BaseModel):
1515
description: Optional[str] = None
1616
value: Optional[Any] = None
1717
externalValue: Optional[str] = None
18-
19-
class Config: # pylint: disable=missing-class-docstring
20-
extra = Extra.allow
21-
schema_extra = {
18+
model_config = ConfigDict(
19+
extra="allow",
20+
json_schema_extra={
2221
"examples": [
2322
{"summary": "A foo example", "value": {"foo": "bar"}},
2423
{
@@ -27,4 +26,5 @@ class Config: # pylint: disable=missing-class-docstring
2726
},
2827
{"summary": "This is a text example", "externalValue": "http://foo.bar/examples/address-example.txt"},
2928
]
30-
}
29+
},
30+
)
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from typing import Optional
22

3-
from pydantic import BaseModel, Extra
3+
from pydantic import BaseModel, ConfigDict
44

55

66
class ExternalDocumentation(BaseModel):
@@ -12,7 +12,7 @@ class ExternalDocumentation(BaseModel):
1212

1313
description: Optional[str] = None
1414
url: str
15-
16-
class Config: # pylint: disable=missing-class-docstring
17-
extra = Extra.allow
18-
schema_extra = {"examples": [{"description": "Find more info here", "url": "https://example.com"}]}
15+
model_config = ConfigDict(
16+
extra="allow",
17+
json_schema_extra={"examples": [{"description": "Find more info here", "url": "https://example.com"}]},
18+
)

openapi_python_client/schema/openapi_schema_pydantic/header.py

+9-9
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from pydantic import Extra, Field
1+
from pydantic import ConfigDict, Field
22

33
from ..parameter_location import ParameterLocation
44
from .parameter import Parameter
@@ -18,14 +18,14 @@ class Header(Parameter):
1818
- https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#headerObject
1919
"""
2020

21-
name = Field(default="", const=True)
22-
param_in = Field(default=ParameterLocation.HEADER, const=True, alias="in")
23-
24-
class Config: # pylint: disable=missing-class-docstring
25-
extra = Extra.allow
26-
allow_population_by_field_name = True
27-
schema_extra = {
21+
name: str = Field(default="")
22+
param_in: ParameterLocation = Field(default=ParameterLocation.HEADER, alias="in")
23+
model_config = ConfigDict(
24+
extra="allow",
25+
populate_by_name=True,
26+
json_schema_extra={
2827
"examples": [
2928
{"description": "The number of allowed requests in the current period", "schema": {"type": "integer"}}
3029
]
31-
}
30+
},
31+
)

openapi_python_client/schema/openapi_schema_pydantic/info.py

+6-6
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from typing import Optional
22

3-
from pydantic import BaseModel, Extra
3+
from pydantic import BaseModel, ConfigDict
44

55
from .contact import Contact
66
from .license import License
@@ -23,10 +23,9 @@ class Info(BaseModel):
2323
contact: Optional[Contact] = None
2424
license: Optional[License] = None
2525
version: str
26-
27-
class Config: # pylint: disable=missing-class-docstring
28-
extra = Extra.allow
29-
schema_extra = {
26+
model_config = ConfigDict(
27+
extra="allow",
28+
json_schema_extra={
3029
"examples": [
3130
{
3231
"title": "Sample Pet Store App",
@@ -41,4 +40,5 @@ class Config: # pylint: disable=missing-class-docstring
4140
"version": "1.0.1",
4241
}
4342
]
44-
}
43+
},
44+
)
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from typing import Optional
22

3-
from pydantic import BaseModel, Extra
3+
from pydantic import BaseModel, ConfigDict
44

55

66
class License(BaseModel):
@@ -13,7 +13,9 @@ class License(BaseModel):
1313

1414
name: str
1515
url: Optional[str] = None
16-
17-
class Config: # pylint: disable=missing-class-docstring
18-
extra = Extra.allow
19-
schema_extra = {"examples": [{"name": "Apache 2.0", "url": "https://www.apache.org/licenses/LICENSE-2.0.html"}]}
16+
model_config = ConfigDict(
17+
extra="allow",
18+
json_schema_extra={
19+
"examples": [{"name": "Apache 2.0", "url": "https://www.apache.org/licenses/LICENSE-2.0.html"}]
20+
},
21+
)

openapi_python_client/schema/openapi_schema_pydantic/link.py

+6-6
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from typing import Any, Dict, Optional
22

3-
from pydantic import BaseModel, Extra
3+
from pydantic import BaseModel, ConfigDict
44

55
from .server import Server
66

@@ -29,15 +29,15 @@ class Link(BaseModel):
2929
requestBody: Optional[Any] = None
3030
description: Optional[str] = None
3131
server: Optional[Server] = None
32-
33-
class Config: # pylint: disable=missing-class-docstring
34-
extra = Extra.allow
35-
schema_extra = {
32+
model_config = ConfigDict(
33+
extra="allow",
34+
json_schema_extra={
3635
"examples": [
3736
{"operationId": "getUserAddressByUUID", "parameters": {"userUuid": "$response.body#/uuid"}},
3837
{
3938
"operationRef": "#/paths/~12.0~1repositories~1{username}/get",
4039
"parameters": {"username": "$response.body#/username"},
4140
},
4241
]
43-
}
42+
},
43+
)

openapi_python_client/schema/openapi_schema_pydantic/media_type.py

+7-7
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from typing import Any, Dict, Optional, Union
22

3-
from pydantic import BaseModel, Extra, Field
3+
from pydantic import BaseModel, ConfigDict, Field
44

55
from .encoding import Encoding
66
from .example import Example
@@ -20,11 +20,10 @@ class MediaType(BaseModel):
2020
example: Optional[Any] = None
2121
examples: Optional[Dict[str, Union[Example, Reference]]] = None
2222
encoding: Optional[Dict[str, Encoding]] = None
23-
24-
class Config: # pylint: disable=missing-class-docstring
25-
extra = Extra.allow
26-
allow_population_by_field_name = True
27-
schema_extra = {
23+
model_config = ConfigDict(
24+
extra="allow",
25+
populate_by_name=True,
26+
json_schema_extra={
2827
"examples": [
2928
{
3029
"schema": {"$ref": "#/components/schemas/Pet"},
@@ -52,4 +51,5 @@ class Config: # pylint: disable=missing-class-docstring
5251
},
5352
}
5453
]
55-
}
54+
},
55+
)

openapi_python_client/schema/openapi_schema_pydantic/oauth_flow.py

+6-6
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from typing import Dict, Optional
22

3-
from pydantic import BaseModel, Extra
3+
from pydantic import BaseModel, ConfigDict
44

55

66
class OAuthFlow(BaseModel):
@@ -16,10 +16,9 @@ class OAuthFlow(BaseModel):
1616
tokenUrl: Optional[str] = None
1717
refreshUrl: Optional[str] = None
1818
scopes: Dict[str, str]
19-
20-
class Config: # pylint: disable=missing-class-docstring
21-
extra = Extra.allow
22-
schema_extra = {
19+
model_config = ConfigDict(
20+
extra="allow",
21+
json_schema_extra={
2322
"examples": [
2423
{
2524
"authorizationUrl": "https://example.com/api/oauth/dialog",
@@ -31,4 +30,5 @@ class Config: # pylint: disable=missing-class-docstring
3130
"scopes": {"write:pets": "modify pets in your account", "read:pets": "read your pets"},
3231
},
3332
]
34-
}
33+
},
34+
)

openapi_python_client/schema/openapi_schema_pydantic/oauth_flows.py

+2-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from typing import Optional
22

3-
from pydantic import BaseModel, Extra
3+
from pydantic import BaseModel, ConfigDict
44

55
from .oauth_flow import OAuthFlow
66

@@ -18,6 +18,4 @@ class OAuthFlows(BaseModel):
1818
password: Optional[OAuthFlow] = None
1919
clientCredentials: Optional[OAuthFlow] = None
2020
authorizationCode: Optional[OAuthFlow] = None
21-
22-
class Config: # pylint: disable=missing-class-docstring
23-
extra = Extra.allow
21+
model_config = ConfigDict(extra="allow")

0 commit comments

Comments
 (0)