|
"""Base classes and other customizations for generated pydantic types.""" |
|
|
|
from __future__ import annotations |
|
|
|
from typing import TYPE_CHECKING, Any, Callable, Literal, TypeVar |
|
|
|
from pydantic import BaseModel, ConfigDict, Field, Json, StrictStr |
|
from typing_extensions import Annotated, TypedDict, Unpack, override |
|
|
|
from .utils import IS_PYDANTIC_V2, to_json |
|
from .v1_compat import PydanticCompatMixin |
|
|
|
if TYPE_CHECKING: |
|
from pydantic.main import IncEx |
|
|
|
|
|
class ModelDumpKwargs(TypedDict, total=False): |
|
"""Shared keyword arguments for `BaseModel.model_{dump,dump_json}`.""" |
|
|
|
include: IncEx | None |
|
exclude: IncEx | None |
|
context: dict[str, Any] | None |
|
by_alias: bool | None |
|
exclude_unset: bool |
|
exclude_defaults: bool |
|
exclude_none: bool |
|
round_trip: bool |
|
warnings: bool | Literal["none", "warn", "error"] |
|
fallback: Callable[[Any], Any] | None |
|
serialize_as_any: bool |
|
|
|
|
|
|
|
MODEL_DUMP_DEFAULTS = ModelDumpKwargs( |
|
by_alias=True, |
|
round_trip=True, |
|
) |
|
|
|
|
|
|
|
class CompatBaseModel(PydanticCompatMixin, BaseModel): |
|
__doc__ = None |
|
|
|
|
|
|
|
|
|
class GQLBase(CompatBaseModel): |
|
model_config = ConfigDict( |
|
populate_by_name=True, |
|
validate_by_name=True, |
|
validate_by_alias=True, |
|
serialize_by_alias=True, |
|
validate_assignment=True, |
|
validate_default=True, |
|
use_attribute_docstrings=True, |
|
from_attributes=True, |
|
revalidate_instances="always", |
|
protected_namespaces=(), |
|
) |
|
|
|
@override |
|
def model_dump( |
|
self, |
|
*, |
|
mode: Literal["json", "python"] | str = "json", |
|
**kwargs: Unpack[ModelDumpKwargs], |
|
) -> dict[str, Any]: |
|
kwargs = {**MODEL_DUMP_DEFAULTS, **kwargs} |
|
return super().model_dump(mode=mode, **kwargs) |
|
|
|
@override |
|
def model_dump_json( |
|
self, |
|
*, |
|
indent: int | None = None, |
|
**kwargs: Unpack[ModelDumpKwargs], |
|
) -> str: |
|
kwargs = {**MODEL_DUMP_DEFAULTS, **kwargs} |
|
return super().model_dump_json(indent=indent, **kwargs) |
|
|
|
|
|
|
|
|
|
T = TypeVar("T") |
|
|
|
if IS_PYDANTIC_V2 or TYPE_CHECKING: |
|
GQLId = Annotated[ |
|
StrictStr, |
|
Field(repr=False, frozen=True), |
|
] |
|
else: |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
GQLId = StrictStr |
|
|
|
Typename = Annotated[ |
|
T, |
|
Field(repr=False, frozen=True, alias="__typename"), |
|
] |
|
|
|
|
|
def ensure_json(v: Any) -> Any: |
|
"""In case the incoming value isn't serialized JSON, reserialize it. |
|
|
|
This lets us use `Json[...]` fields with values that are already deserialized. |
|
""" |
|
|
|
|
|
return v if isinstance(v, (str, bytes)) else to_json(v) |
|
|
|
|
|
if IS_PYDANTIC_V2 or TYPE_CHECKING: |
|
from pydantic import BeforeValidator, PlainSerializer |
|
|
|
SerializedToJson = Annotated[ |
|
Json[T], |
|
|
|
BeforeValidator(ensure_json), |
|
PlainSerializer(to_json), |
|
] |
|
else: |
|
|
|
SerializedToJson = Json[T] |
|
|