mirror of https://github.com/tiangolo/fastapi.git
👽️ Ensure compatibility with Pydantic 2.12.0 (#14036)
Co-authored-by: Sofie Van Landeghem <svlandeg@users.noreply.github.com> Co-authored-by: Victorien <65306057+Viicos@users.noreply.github.com> Co-authored-by: svlandeg <svlandeg@github.com> Co-authored-by: Motov Yurii <109919500+YuriiMotov@users.noreply.github.com> Co-authored-by: Patrick Arminio <patrick.arminio@gmail.com>
This commit is contained in:
parent
22b38099ce
commit
c970d8a735
|
|
@ -1,3 +1,4 @@
|
||||||
|
import warnings
|
||||||
from collections import deque
|
from collections import deque
|
||||||
from copy import copy
|
from copy import copy
|
||||||
from dataclasses import dataclass, is_dataclass
|
from dataclasses import dataclass, is_dataclass
|
||||||
|
|
@ -109,9 +110,20 @@ if PYDANTIC_V2:
|
||||||
return self.field_info.annotation
|
return self.field_info.annotation
|
||||||
|
|
||||||
def __post_init__(self) -> None:
|
def __post_init__(self) -> None:
|
||||||
self._type_adapter: TypeAdapter[Any] = TypeAdapter(
|
with warnings.catch_warnings():
|
||||||
Annotated[self.field_info.annotation, self.field_info]
|
# Pydantic >= 2.12.0 warns about field specific metadata that is unused
|
||||||
)
|
# (e.g. `TypeAdapter(Annotated[int, Field(alias='b')])`). In some cases, we
|
||||||
|
# end up building the type adapter from a model field annotation so we
|
||||||
|
# need to ignore the warning:
|
||||||
|
if PYDANTIC_VERSION_MINOR_TUPLE >= (2, 12):
|
||||||
|
from pydantic.warnings import UnsupportedFieldAttributeWarning
|
||||||
|
|
||||||
|
warnings.simplefilter(
|
||||||
|
"ignore", category=UnsupportedFieldAttributeWarning
|
||||||
|
)
|
||||||
|
self._type_adapter: TypeAdapter[Any] = TypeAdapter(
|
||||||
|
Annotated[self.field_info.annotation, self.field_info]
|
||||||
|
)
|
||||||
|
|
||||||
def get_default(self) -> Any:
|
def get_default(self) -> Any:
|
||||||
if self.field_info.is_required():
|
if self.field_info.is_required():
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ class ParamTypes(Enum):
|
||||||
cookie = "cookie"
|
cookie = "cookie"
|
||||||
|
|
||||||
|
|
||||||
class Param(FieldInfo):
|
class Param(FieldInfo): # type: ignore[misc]
|
||||||
in_: ParamTypes
|
in_: ParamTypes
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
|
|
@ -136,7 +136,7 @@ class Param(FieldInfo):
|
||||||
return f"{self.__class__.__name__}({self.default})"
|
return f"{self.__class__.__name__}({self.default})"
|
||||||
|
|
||||||
|
|
||||||
class Path(Param):
|
class Path(Param): # type: ignore[misc]
|
||||||
in_ = ParamTypes.path
|
in_ = ParamTypes.path
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
|
|
@ -222,7 +222,7 @@ class Path(Param):
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class Query(Param):
|
class Query(Param): # type: ignore[misc]
|
||||||
in_ = ParamTypes.query
|
in_ = ParamTypes.query
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
|
|
@ -306,7 +306,7 @@ class Query(Param):
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class Header(Param):
|
class Header(Param): # type: ignore[misc]
|
||||||
in_ = ParamTypes.header
|
in_ = ParamTypes.header
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
|
|
@ -392,7 +392,7 @@ class Header(Param):
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class Cookie(Param):
|
class Cookie(Param): # type: ignore[misc]
|
||||||
in_ = ParamTypes.cookie
|
in_ = ParamTypes.cookie
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
|
|
@ -476,7 +476,7 @@ class Cookie(Param):
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class Body(FieldInfo):
|
class Body(FieldInfo): # type: ignore[misc]
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
default: Any = Undefined,
|
default: Any = Undefined,
|
||||||
|
|
@ -593,7 +593,7 @@ class Body(FieldInfo):
|
||||||
return f"{self.__class__.__name__}({self.default})"
|
return f"{self.__class__.__name__}({self.default})"
|
||||||
|
|
||||||
|
|
||||||
class Form(Body):
|
class Form(Body): # type: ignore[misc]
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
default: Any = Undefined,
|
default: Any = Undefined,
|
||||||
|
|
@ -677,7 +677,7 @@ class Form(Body):
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class File(Form):
|
class File(Form): # type: ignore[misc]
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
default: Any = Undefined,
|
default: Any = Undefined,
|
||||||
|
|
|
||||||
|
|
@ -185,7 +185,15 @@ def test_openapi_schema():
|
||||||
"title": "Age",
|
"title": "Age",
|
||||||
"anyOf": [
|
"anyOf": [
|
||||||
{"exclusiveMinimum": 0.0, "type": "number"},
|
{"exclusiveMinimum": 0.0, "type": "number"},
|
||||||
{"type": "string"},
|
IsOneOf(
|
||||||
|
# pydantic < 2.12.0
|
||||||
|
{"type": "string"},
|
||||||
|
# pydantic >= 2.12.0
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"pattern": r"^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$",
|
||||||
|
},
|
||||||
|
),
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue