updates
This commit is contained in:
@@ -2,36 +2,31 @@
|
||||
|
||||
from __future__ import annotations as _annotations
|
||||
|
||||
import typing
|
||||
from copy import copy, deepcopy
|
||||
from typing import TYPE_CHECKING, Any, Generic, Literal, TypeVar
|
||||
|
||||
from pydantic_core import PydanticUndefined
|
||||
from typing_extensions import Self, dataclass_transform
|
||||
|
||||
from . import PydanticUserError
|
||||
from ._internal import _model_construction, _repr
|
||||
from ._internal import _repr
|
||||
from .main import BaseModel, _object_setattr
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from .fields import Field as PydanticModelField
|
||||
from .fields import PrivateAttr as PydanticModelPrivateAttr
|
||||
if typing.TYPE_CHECKING:
|
||||
from typing import Any
|
||||
|
||||
from typing_extensions import Literal
|
||||
|
||||
Model = typing.TypeVar('Model', bound='BaseModel')
|
||||
|
||||
# dataclass_transform could be applied to RootModel directly, but `ModelMetaclass`'s dataclass_transform
|
||||
# takes priority (at least with pyright). We trick type checkers into thinking we apply dataclass_transform
|
||||
# on a new metaclass.
|
||||
@dataclass_transform(kw_only_default=False, field_specifiers=(PydanticModelField, PydanticModelPrivateAttr))
|
||||
class _RootModelMetaclass(_model_construction.ModelMetaclass): ...
|
||||
else:
|
||||
_RootModelMetaclass = _model_construction.ModelMetaclass
|
||||
|
||||
__all__ = ('RootModel',)
|
||||
|
||||
RootModelRootType = TypeVar('RootModelRootType')
|
||||
|
||||
RootModelRootType = typing.TypeVar('RootModelRootType')
|
||||
|
||||
|
||||
class RootModel(BaseModel, Generic[RootModelRootType], metaclass=_RootModelMetaclass):
|
||||
"""!!! abstract "Usage Documentation"
|
||||
[`RootModel` and Custom Root Types](../concepts/models.md#rootmodel-and-custom-root-types)
|
||||
class RootModel(BaseModel, typing.Generic[RootModelRootType]):
|
||||
"""Usage docs: https://docs.pydantic.dev/2.5/concepts/models/#rootmodel-and-custom-root-types
|
||||
|
||||
A Pydantic `BaseModel` for the root object of the model.
|
||||
|
||||
@@ -57,7 +52,7 @@ class RootModel(BaseModel, Generic[RootModelRootType], metaclass=_RootModelMetac
|
||||
)
|
||||
super().__init_subclass__(**kwargs)
|
||||
|
||||
def __init__(self, /, root: RootModelRootType = PydanticUndefined, **data) -> None: # type: ignore
|
||||
def __init__(__pydantic_self__, root: RootModelRootType = PydanticUndefined, **data) -> None: # type: ignore
|
||||
__tracebackhide__ = True
|
||||
if data:
|
||||
if root is not PydanticUndefined:
|
||||
@@ -65,12 +60,12 @@ class RootModel(BaseModel, Generic[RootModelRootType], metaclass=_RootModelMetac
|
||||
'"RootModel.__init__" accepts either a single positional argument or arbitrary keyword arguments'
|
||||
)
|
||||
root = data # type: ignore
|
||||
self.__pydantic_validator__.validate_python(root, self_instance=self)
|
||||
__pydantic_self__.__pydantic_validator__.validate_python(root, self_instance=__pydantic_self__)
|
||||
|
||||
__init__.__pydantic_base_init__ = True # pyright: ignore[reportFunctionMemberAccess]
|
||||
__init__.__pydantic_base_init__ = True
|
||||
|
||||
@classmethod
|
||||
def model_construct(cls, root: RootModelRootType, _fields_set: set[str] | None = None) -> Self: # type: ignore
|
||||
def model_construct(cls: type[Model], root: RootModelRootType, _fields_set: set[str] | None = None) -> Model:
|
||||
"""Create a new model using the provided root object and update fields set.
|
||||
|
||||
Args:
|
||||
@@ -95,7 +90,7 @@ class RootModel(BaseModel, Generic[RootModelRootType], metaclass=_RootModelMetac
|
||||
_object_setattr(self, '__pydantic_fields_set__', state['__pydantic_fields_set__'])
|
||||
_object_setattr(self, '__dict__', state['__dict__'])
|
||||
|
||||
def __copy__(self) -> Self:
|
||||
def __copy__(self: Model) -> Model:
|
||||
"""Returns a shallow copy of the model."""
|
||||
cls = type(self)
|
||||
m = cls.__new__(cls)
|
||||
@@ -103,7 +98,7 @@ class RootModel(BaseModel, Generic[RootModelRootType], metaclass=_RootModelMetac
|
||||
_object_setattr(m, '__pydantic_fields_set__', copy(self.__pydantic_fields_set__))
|
||||
return m
|
||||
|
||||
def __deepcopy__(self, memo: dict[int, Any] | None = None) -> Self:
|
||||
def __deepcopy__(self: Model, memo: dict[int, Any] | None = None) -> Model:
|
||||
"""Returns a deep copy of the model."""
|
||||
cls = type(self)
|
||||
m = cls.__new__(cls)
|
||||
@@ -113,43 +108,32 @@ class RootModel(BaseModel, Generic[RootModelRootType], metaclass=_RootModelMetac
|
||||
_object_setattr(m, '__pydantic_fields_set__', copy(self.__pydantic_fields_set__))
|
||||
return m
|
||||
|
||||
if TYPE_CHECKING:
|
||||
if typing.TYPE_CHECKING:
|
||||
|
||||
def model_dump( # type: ignore
|
||||
def model_dump(
|
||||
self,
|
||||
*,
|
||||
mode: Literal['json', 'python'] | str = 'python',
|
||||
include: Any = None,
|
||||
exclude: Any = None,
|
||||
context: dict[str, Any] | None = None,
|
||||
by_alias: bool | None = None,
|
||||
by_alias: bool = False,
|
||||
exclude_unset: bool = False,
|
||||
exclude_defaults: bool = False,
|
||||
exclude_none: bool = False,
|
||||
exclude_computed_fields: bool = False,
|
||||
round_trip: bool = False,
|
||||
warnings: bool | Literal['none', 'warn', 'error'] = True,
|
||||
serialize_as_any: bool = False,
|
||||
) -> Any:
|
||||
warnings: bool = True,
|
||||
) -> RootModelRootType:
|
||||
"""This method is included just to get a more accurate return type for type checkers.
|
||||
It is included in this `if TYPE_CHECKING:` block since no override is actually necessary.
|
||||
|
||||
See the documentation of `BaseModel.model_dump` for more details about the arguments.
|
||||
|
||||
Generally, this method will have a return type of `RootModelRootType`, assuming that `RootModelRootType` is
|
||||
not a `BaseModel` subclass. If `RootModelRootType` is a `BaseModel` subclass, then the return
|
||||
type will likely be `dict[str, Any]`, as `model_dump` calls are recursive. The return type could
|
||||
even be something different, in the case of a custom serializer.
|
||||
Thus, `Any` is used here to catch all of these cases.
|
||||
"""
|
||||
...
|
||||
|
||||
def __eq__(self, other: Any) -> bool:
|
||||
if not isinstance(other, RootModel):
|
||||
return NotImplemented
|
||||
return self.__pydantic_fields__['root'].annotation == other.__pydantic_fields__[
|
||||
'root'
|
||||
].annotation and super().__eq__(other)
|
||||
return self.model_fields['root'].annotation == other.model_fields['root'].annotation and super().__eq__(other)
|
||||
|
||||
def __repr_args__(self) -> _repr.ReprArgs:
|
||||
yield 'root', self.root
|
||||
|
||||
Reference in New Issue
Block a user