Skip to content

Commit 9de0e57

Browse files
committed
fix - pydantic model_validator("after")/classmethod deprecation
pydantic.warnings.PydanticDeprecatedSince212: Using `@model_validator` with mode='after' on a classmethod is deprecated. Instead, use an instance method. See the documentation at https://docs.pydantic.dev/2.12/concepts/validators/#model-after-validator. Deprecated in Pydantic V2.12 to be removed in V3.0.
1 parent b5b9280 commit 9de0e57

File tree

9 files changed

+37
-40
lines changed

9 files changed

+37
-40
lines changed

src/aiopenapi3/v30/parameter.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -316,9 +316,11 @@ class Parameter(ParameterBase, _ParameterCodec):
316316
in_: _In = Field(alias="in") # TODO must be one of ["query","header","path","cookie"]
317317

318318
@model_validator(mode="after")
319-
def validate_Parameter(cls, p: "ParameterBase"):
320-
assert p.in_ != "path" or p.required is True, "Parameter '%s' must be required since it is in the path" % p.name
321-
return p
319+
def validate_Parameter(self):
320+
assert self.in_ != "path" or self.required is True, (
321+
"Parameter '%s' must be required since it is in the path" % self.name
322+
)
323+
return self
322324

323325

324326
def encode_parameter(

src/aiopenapi3/v30/paths.py

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,15 +38,14 @@ class Link(ObjectExtended):
3838
server: Server | None = Field(default=None)
3939

4040
@model_validator(mode="after")
41-
@classmethod
42-
def validate_Link_operation(cls, l: '__types["Link"]'): # type: ignore[name-defined]
41+
def validate_Link_operation(self): # type: ignore[name-defined]
4342
assert not (
44-
l.operationId != None and l.operationRef != None
43+
self.operationId != None and self.operationRef != None
4544
), "operationId and operationRef are mutually exclusive, only one of them is allowed"
4645
assert not (
47-
l.operationId == l.operationRef == None
46+
self.operationId == self.operationRef == None
4847
), "operationId and operationRef are mutually exclusive, one of them must be specified"
49-
return l
48+
return self
5049

5150

5251
class Response(ObjectExtended):

src/aiopenapi3/v30/schemas.py

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -74,13 +74,12 @@ def is_boolean_schema(cls, data: Any) -> Any:
7474
return {"not": {}}
7575

7676
@model_validator(mode="after")
77-
@classmethod
78-
def validate_Schema_number_type(cls, s: "Schema"):
79-
if s.type == "integer":
77+
def validate_Schema_number_type(self):
78+
if self.type == "integer":
8079
for i in ["minimum", "maximum"]:
81-
if (v := getattr(s, i, None)) is not None and not isinstance(v, int):
82-
setattr(s, i, int(v))
83-
return s
80+
if (v := getattr(self, i, None)) is not None and not isinstance(v, int):
81+
setattr(self, i, int(v))
82+
return self
8483

8584
def __getstate__(self):
8685
return SchemaBase.__getstate__(self)

src/aiopenapi3/v30/servers.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,11 @@ class ServerVariable(ObjectExtended):
1717
description: str | None = Field(default=None)
1818

1919
@model_validator(mode="after")
20-
def validate_ServerVariable(cls, s: "ServerVariable"):
21-
assert isinstance(s.enum, (list, None.__class__))
20+
def validate_ServerVariable(self):
21+
assert isinstance(self.enum, (list, None.__class__))
2222
# default value must be in enum
23-
assert s.default is None or s.default in (s.enum or [s.default])
24-
return s
23+
assert self.default is None or self.default in (self.enum or [self.default])
24+
return self
2525

2626

2727
class Server(ObjectExtended):

src/aiopenapi3/v31/info.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,12 @@ class License(ObjectExtended):
2727
url: str | None = Field(default=None)
2828

2929
@model_validator(mode="after")
30-
@classmethod
31-
def validate_License(cls, l: "License"):
30+
def validate_License(self):
3231
"""
3332
A URL to the license used for the API. This MUST be in the form of a URL. The url field is mutually exclusive of the identifier field.
3433
"""
35-
assert not all([getattr(l, i, None) is not None for i in ["identifier", "url"]])
36-
return l
34+
assert not all([getattr(self, i, None) is not None for i in ["identifier", "url"]])
35+
return self
3736

3837

3938
class Info(ObjectExtended):

src/aiopenapi3/v31/paths.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,14 +38,14 @@ class Link(ObjectExtended):
3838
server: Server | None = Field(default=None)
3939

4040
@model_validator(mode="after")
41-
def validate_Link_operation(cls, l: '__types["Link"]'): # type: ignore[name-defined]
41+
def validate_Link_operation(self): # type: ignore[name-defined]
4242
assert not (
43-
l.operationId != None and l.operationRef != None
43+
self.operationId != None and self.operationRef != None
4444
), "operationId and operationRef are mutually exclusive, only one of them is allowed"
4545
assert not (
46-
l.operationId == l.operationRef == None
46+
self.operationId == self.operationRef == None
4747
), "operationId and operationRef are mutually exclusive, one of them must be specified"
48-
return l
48+
return self
4949

5050

5151
class Response(ObjectExtended):

src/aiopenapi3/v31/root.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,9 @@ class Root(ObjectExtended, RootBase):
3535
externalDocs: dict[Any, Any] = Field(default_factory=dict)
3636

3737
@model_validator(mode="after")
38-
@classmethod
39-
def validate_Root(cls, r: "Root") -> "Self":
40-
assert r.paths or r.components or r.webhooks
41-
return r
38+
def validate_Root(self) -> "Self":
39+
assert self.paths or self.components or self.webhooks
40+
return self
4241

4342
def _resolve_references(self, api):
4443
RootBase.resolve(api, self, self, PathItem, Reference)

src/aiopenapi3/v31/schemas.py

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -173,13 +173,12 @@ def is_boolean_schema(cls, data: Any) -> Any:
173173
return {"not": {}}
174174

175175
@model_validator(mode="after")
176-
@classmethod
177-
def validate_Schema_number_type(cls, s: "Schema"):
178-
if s.type == "integer":
176+
def validate_Schema_number_type(self):
177+
if self.type == "integer":
179178
for i in ["minimum", "maximum"]:
180-
if (v := getattr(s, i, None)) is not None and not isinstance(v, int):
181-
setattr(s, i, int(v))
182-
return s
179+
if (v := getattr(self, i, None)) is not None and not isinstance(v, int):
180+
setattr(self, i, int(v))
181+
return self
183182

184183
def __getstate__(self):
185184
return SchemaBase.__getstate__(self)

src/aiopenapi3/v31/servers.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,11 @@ class ServerVariable(ObjectExtended):
1717
description: str | None = Field(default=None)
1818

1919
@model_validator(mode="after")
20-
def validate_ServerVariable(cls, s: "ServerVariable"):
21-
assert isinstance(s.enum, (list, None.__class__))
20+
def validate_ServerVariable(self):
21+
assert isinstance(self.enum, (list, None.__class__))
2222
# default value must be in enum
23-
assert s.default is None or s.default in (s.enum or [s.default])
24-
return s
23+
assert self.default is None or self.default in (self.enum or [self.default])
24+
return self
2525

2626

2727
class Server(ObjectExtended):

0 commit comments

Comments
 (0)