Team Ai
Datasetpublic

codekingpro/portable-devtools

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes14kdownloads
main.py1839 linesDownload Raw Back to pydantic
1"""Logic for creating models."""2 3# Because `dict` is in the local namespace of the `BaseModel` class, we use `Dict` for annotations.4# TODO v3 fallback to `dict` when the deprecated `dict` method gets removed.5# ruff: noqa: UP0356 7from __future__ import annotations as _annotations8 9import operator10import sys11import types12import warnings13from collections.abc import Generator, Mapping14from copy import copy, deepcopy15from functools import cached_property16from typing import (17    TYPE_CHECKING,18    Any,19    Callable,20    ClassVar,21    Dict,22    Generic,23    Literal,24    TypeVar,25    Union,26    cast,27    overload,28)29 30import pydantic_core31import typing_extensions32from pydantic_core import PydanticUndefined, ValidationError33from typing_extensions import Self, TypeAlias, Unpack34 35from . import PydanticDeprecatedSince20, PydanticDeprecatedSince21136from ._internal import (37    _config,38    _decorators,39    _fields,40    _forward_ref,41    _generics,42    _mock_val_ser,43    _model_construction,44    _namespace_utils,45    _repr,46    _typing_extra,47    _utils,48)49from ._migration import getattr_migration50from .aliases import AliasChoices, AliasPath51from .annotated_handlers import GetCoreSchemaHandler, GetJsonSchemaHandler52from .config import ConfigDict, ExtraValues53from .errors import PydanticUndefinedAnnotation, PydanticUserError54from .json_schema import DEFAULT_REF_TEMPLATE, GenerateJsonSchema, JsonSchemaMode, JsonSchemaValue, model_json_schema55from .plugin._schema_validator import PluggableSchemaValidator56 57if TYPE_CHECKING:58    from inspect import Signature59    from pathlib import Path60 61    from pydantic_core import CoreSchema, SchemaSerializer, SchemaValidator62 63    from ._internal._fields import PydanticExtraInfo64    from ._internal._namespace_utils import MappingNamespace65    from ._internal._utils import AbstractSetIntStr, MappingIntStrAny66    from .deprecated.parse import Protocol as DeprecatedParseProtocol67    from .fields import ComputedFieldInfo, FieldInfo, ModelPrivateAttr68 69 70__all__ = 'BaseModel', 'create_model'71 72# Keep these type aliases available at runtime:73TupleGenerator: TypeAlias = Generator[tuple[str, Any], None, None]74# NOTE: In reality, `bool` should be replaced by `Literal[True]` but mypy fails to correctly apply bidirectional75# type inference (e.g. when using `{'a': {'b': True}}`):76# NOTE: Keep this type alias in sync with the stub definition in `pydantic-core`:77IncEx: TypeAlias = Union[set[int], set[str], Mapping[int, Union['IncEx', bool]], Mapping[str, Union['IncEx', bool]]]78 79_object_setattr = _model_construction.object_setattr80 81 82def _check_frozen(model_cls: type[BaseModel], name: str, value: Any) -> None:83    if model_cls.model_config.get('frozen'):84        error_type = 'frozen_instance'85    elif getattr(model_cls.__pydantic_fields__.get(name), 'frozen', False):86        error_type = 'frozen_field'87    else:88        return89 90    raise ValidationError.from_exception_data(91        model_cls.__name__, [{'type': error_type, 'loc': (name,), 'input': value}]92    )93 94 95def _model_field_setattr_handler(model: BaseModel, name: str, val: Any) -> None:96    model.__dict__[name] = val97    model.__pydantic_fields_set__.add(name)98 99 100def _private_setattr_handler(model: BaseModel, name: str, val: Any) -> None:101    if getattr(model, '__pydantic_private__', None) is None:102        # While the attribute should be present at this point, this may not be the case if103        # users do unusual stuff with `model_post_init()` (which is where the  `__pydantic_private__`104        # is initialized, by wrapping the user-defined `model_post_init()`), e.g. if they mock105        # the `model_post_init()` call. Ideally we should find a better way to init private attrs.106        object.__setattr__(model, '__pydantic_private__', {})107    model.__pydantic_private__[name] = val  # pyright: ignore[reportOptionalSubscript]108 109 110_SIMPLE_SETATTR_HANDLERS: Mapping[str, Callable[[BaseModel, str, Any], None]] = {111    'model_field': _model_field_setattr_handler,112    'validate_assignment': lambda model, name, val: model.__pydantic_validator__.validate_assignment(model, name, val),  # pyright: ignore[reportAssignmentType]113    'private': _private_setattr_handler,114    'cached_property': lambda model, name, val: model.__dict__.__setitem__(name, val),115    'extra_known': lambda model, name, val: _object_setattr(model, name, val),116}117 118 119class BaseModel(metaclass=_model_construction.ModelMetaclass):120    """!!! abstract "Usage Documentation"121        [Models](../concepts/models.md)122 123    A base class for creating Pydantic models.124 125    Attributes:126        __class_vars__: The names of the class variables defined on the model.127        __private_attributes__: Metadata about the private attributes of the model.128        __signature__: The synthesized `__init__` [`Signature`][inspect.Signature] of the model.129 130        __pydantic_complete__: Whether model building is completed, or if there are still undefined fields.131        __pydantic_core_schema__: The core schema of the model.132        __pydantic_custom_init__: Whether the model has a custom `__init__` function.133        __pydantic_decorators__: Metadata containing the decorators defined on the model.134            This replaces `Model.__validators__` and `Model.__root_validators__` from Pydantic V1.135        __pydantic_generic_metadata__: A dictionary containing metadata about generic Pydantic models.136            The `origin` and `args` items map to the [`__origin__`][genericalias.__origin__]137            and [`__args__`][genericalias.__args__] attributes of [generic aliases][types-genericalias],138            and the `parameter` item maps to the `__parameter__` attribute of generic classes.139        __pydantic_parent_namespace__: Parent namespace of the model, used for automatic rebuilding of models.140        __pydantic_post_init__: The name of the post-init method for the model, if defined.141        __pydantic_root_model__: Whether the model is a [`RootModel`][pydantic.root_model.RootModel].142        __pydantic_serializer__: The `pydantic-core` `SchemaSerializer` used to dump instances of the model.143        __pydantic_validator__: The `pydantic-core` `SchemaValidator` used to validate instances of the model.144 145        __pydantic_fields__: A dictionary of field names and their corresponding [`FieldInfo`][pydantic.fields.FieldInfo] objects.146        __pydantic_computed_fields__: A dictionary of computed field names and their corresponding [`ComputedFieldInfo`][pydantic.fields.ComputedFieldInfo] objects.147 148        __pydantic_extra__: A dictionary containing extra values, if [`extra`][pydantic.config.ConfigDict.extra]149            is set to `'allow'`.150        __pydantic_fields_set__: The names of fields explicitly set during instantiation.151        __pydantic_private__: Values of private attributes set on the model instance.152    """153 154    # Note: Many of the below class vars are defined in the metaclass, but we define them here for type checking purposes.155 156    model_config: ClassVar[ConfigDict] = ConfigDict()157    """158    Configuration for the model, should be a dictionary conforming to [`ConfigDict`][pydantic.config.ConfigDict].159    """160 161    __class_vars__: ClassVar[set[str]]162    """The names of the class variables defined on the model."""163 164    __private_attributes__: ClassVar[Dict[str, ModelPrivateAttr]]  # noqa: UP006165    """Metadata about the private attributes of the model."""166 167    __signature__: ClassVar[Signature]168    """The synthesized `__init__` [`Signature`][inspect.Signature] of the model."""169 170    __pydantic_complete__: ClassVar[bool] = False171    """Whether model building is completed, or if there are still undefined fields."""172 173    __pydantic_core_schema__: ClassVar[CoreSchema]174    """The core schema of the model."""175 176    __pydantic_custom_init__: ClassVar[bool]177    """Whether the model has a custom `__init__` method."""178 179    # Must be set for `GenerateSchema.model_schema` to work for a plain `BaseModel` annotation.180    __pydantic_decorators__: ClassVar[_decorators.DecoratorInfos] = _decorators.DecoratorInfos()181    """Metadata containing the decorators defined on the model.182    This replaces `Model.__validators__` and `Model.__root_validators__` from Pydantic V1."""183 184    __pydantic_generic_metadata__: ClassVar[_generics.PydanticGenericMetadata]185    """A dictionary containing metadata about generic Pydantic models.186 187    The `origin` and `args` items map to the [`__origin__`][genericalias.__origin__]188    and [`__args__`][genericalias.__args__] attributes of [generic aliases][types-genericalias],189    and the `parameter` item maps to the `__parameter__` attribute of generic classes.190    """191 192    __pydantic_parent_namespace__: ClassVar[Dict[str, Any] | None] = None  # noqa: UP006193    """Parent namespace of the model, used for automatic rebuilding of models."""194 195    __pydantic_post_init__: ClassVar[None | Literal['model_post_init']]196    """The name of the post-init method for the model, if defined."""197 198    __pydantic_root_model__: ClassVar[bool] = False199    """Whether the model is a [`RootModel`][pydantic.root_model.RootModel]."""200 201    __pydantic_serializer__: ClassVar[SchemaSerializer]202    """The `pydantic-core` `SchemaSerializer` used to dump instances of the model."""203 204    __pydantic_validator__: ClassVar[SchemaValidator | PluggableSchemaValidator]205    """The `pydantic-core` `SchemaValidator` used to validate instances of the model."""206 207    __pydantic_fields__: ClassVar[Dict[str, FieldInfo]]  # noqa: UP006208    """A dictionary of field names and their corresponding [`FieldInfo`][pydantic.fields.FieldInfo] objects.209    This replaces `Model.__fields__` from Pydantic V1.210    """211 212    __pydantic_setattr_handlers__: ClassVar[Dict[str, Callable[[BaseModel, str, Any], None]]]  # noqa: UP006213    """`__setattr__` handlers. Memoizing the handlers leads to a dramatic performance improvement in `__setattr__`"""214 215    __pydantic_computed_fields__: ClassVar[Dict[str, ComputedFieldInfo]]  # noqa: UP006216    """A dictionary of computed field names and their corresponding [`ComputedFieldInfo`][pydantic.fields.ComputedFieldInfo] objects."""217 218    __pydantic_extra_info__: ClassVar[PydanticExtraInfo | None]219    """A wrapper around the `__pydantic_extra__` annotation, if explicitly annotated on a model.220 221    This is a private attribute, not meant to be used outside Pydantic.222    """223 224    __pydantic_extra__: Dict[str, Any] | None = _model_construction.NoInitField(init=False)  # noqa: UP006225    """A dictionary containing extra values, if [`extra`][pydantic.config.ConfigDict.extra] is set to `'allow'`."""226 227    __pydantic_fields_set__: set[str] = _model_construction.NoInitField(init=False)228    """The names of fields explicitly set during instantiation."""229 230    __pydantic_private__: Dict[str, Any] | None = _model_construction.NoInitField(init=False)  # noqa: UP006231    """Values of private attributes set on the model instance."""232 233    if not TYPE_CHECKING:234        # Prevent `BaseModel` from being instantiated directly235        # (defined in an `if not TYPE_CHECKING` block for clarity and to avoid type checking errors):236        __pydantic_core_schema__ = _mock_val_ser.MockCoreSchema(237            'Pydantic models should inherit from BaseModel, BaseModel cannot be instantiated directly',238            code='base-model-instantiated',239        )240        __pydantic_validator__ = _mock_val_ser.MockValSer(241            'Pydantic models should inherit from BaseModel, BaseModel cannot be instantiated directly',242            val_or_ser='validator',243            code='base-model-instantiated',244        )245        __pydantic_serializer__ = _mock_val_ser.MockValSer(246            'Pydantic models should inherit from BaseModel, BaseModel cannot be instantiated directly',247            val_or_ser='serializer',248            code='base-model-instantiated',249        )250 251    __slots__ = '__dict__', '__pydantic_fields_set__', '__pydantic_extra__', '__pydantic_private__'252 253    def __init__(self, /, **data: Any) -> None:254        """Create a new model by parsing and validating input data from keyword arguments.255 256        Raises [`ValidationError`][pydantic_core.ValidationError] if the input data cannot be257        validated to form a valid model.258 259        `self` is explicitly positional-only to allow `self` as a field name.260        """261        # `__tracebackhide__` tells pytest and some other tools to omit this function from tracebacks262        __tracebackhide__ = True263        validated_self = self.__pydantic_validator__.validate_python(data, self_instance=self)264        if self is not validated_self:265            warnings.warn(266                'A custom validator is returning a value other than `self`.\n'267                "Returning anything other than `self` from a top level model validator isn't supported when validating via `__init__`.\n"268                'See the `model_validator` docs (https://docs.pydantic.dev/latest/concepts/validators/#model-validators) for more details.',269                stacklevel=2,270            )271 272    # The following line sets a flag that we use to determine when `__init__` gets overridden by the user273    __init__.__pydantic_base_init__ = True  # pyright: ignore[reportFunctionMemberAccess]274 275    @_utils.deprecated_instance_property276    @classmethod277    def model_fields(cls) -> dict[str, FieldInfo]:278        """A mapping of field names to their respective [`FieldInfo`][pydantic.fields.FieldInfo] instances.279 280        !!! warning281            Accessing this attribute from a model instance is deprecated, and will not work in Pydantic V3.282            Instead, you should access this attribute from the model class.283        """284        return getattr(cls, '__pydantic_fields__', {})285 286    @_utils.deprecated_instance_property287    @classmethod288    def model_computed_fields(cls) -> dict[str, ComputedFieldInfo]:289        """A mapping of computed field names to their respective [`ComputedFieldInfo`][pydantic.fields.ComputedFieldInfo] instances.290 291        !!! warning292            Accessing this attribute from a model instance is deprecated, and will not work in Pydantic V3.293            Instead, you should access this attribute from the model class.294        """295        return getattr(cls, '__pydantic_computed_fields__', {})296 297    @property298    def model_extra(self) -> dict[str, Any] | None:299        """Get extra fields set during validation.300 301        Returns:302            A dictionary of extra fields, or `None` if `config.extra` is not set to `"allow"`.303        """304        return self.__pydantic_extra__305 306    @property307    def model_fields_set(self) -> set[str]:308        """Returns the set of fields that have been explicitly set on this model instance.309 310        Returns:311            A set of strings representing the fields that have been set,312                i.e. that were not filled from defaults.313        """314        return self.__pydantic_fields_set__315 316    @classmethod317    def model_construct(cls, _fields_set: set[str] | None = None, **values: Any) -> Self:  # noqa: C901318        """Creates a new instance of the `Model` class with validated data.319 320        Creates a new model setting `__dict__` and `__pydantic_fields_set__` from trusted or pre-validated data.321        Default values are respected, but no other validation is performed.322 323        !!! note324            `model_construct()` generally respects the `model_config.extra` setting on the provided model.325            That is, if `model_config.extra == 'allow'`, then all extra passed values are added to the model instance's `__dict__`326            and `__pydantic_extra__` fields. If `model_config.extra == 'ignore'` (the default), then all extra passed values are ignored.327            Because no validation is performed with a call to `model_construct()`, having `model_config.extra == 'forbid'` does not result in328            an error if extra values are passed, but they will be ignored.329 330        Args:331            _fields_set: A set of field names that were originally explicitly set during instantiation. If provided,332                this is directly used for the [`model_fields_set`][pydantic.BaseModel.model_fields_set] attribute.333                Otherwise, the field names from the `values` argument will be used.334            values: Trusted or pre-validated data dictionary.335 336        Returns:337            A new instance of the `Model` class with validated data.338        """339        m = cls.__new__(cls)340        fields_values: dict[str, Any] = {}341        fields_set = set()342 343        for name, field in cls.__pydantic_fields__.items():344            if field.alias is not None and field.alias in values:345                fields_values[name] = values.pop(field.alias)346                fields_set.add(name)347 348            if (name not in fields_set) and (field.validation_alias is not None):349                validation_aliases: list[str | AliasPath] = (350                    field.validation_alias.choices351                    if isinstance(field.validation_alias, AliasChoices)352                    else [field.validation_alias]353                )354 355                for alias in validation_aliases:356                    if isinstance(alias, str) and alias in values:357                        fields_values[name] = values.pop(alias)358                        fields_set.add(name)359                        break360                    elif isinstance(alias, AliasPath):361                        value = alias.search_dict_for_path(values)362                        if value is not PydanticUndefined:363                            fields_values[name] = value364                            fields_set.add(name)365                            break366 367            if name not in fields_set:368                if name in values:369                    fields_values[name] = values.pop(name)370                    fields_set.add(name)371                elif not field.is_required():372                    fields_values[name] = field.get_default(call_default_factory=True, validated_data=fields_values)373        if _fields_set is None:374            _fields_set = fields_set375 376        _extra: dict[str, Any] | None = values if cls.model_config.get('extra') == 'allow' else None377        _object_setattr(m, '__dict__', fields_values)378        _object_setattr(m, '__pydantic_fields_set__', _fields_set)379        if not cls.__pydantic_root_model__:380            _object_setattr(m, '__pydantic_extra__', _extra)381            _object_setattr(m, '__pydantic_private__', None)382 383        if cls.__pydantic_post_init__:384            m.model_post_init(None)385            # update private attributes with values set386            if hasattr(m, '__pydantic_private__') and m.__pydantic_private__ is not None:387                for k, v in values.items():388                    if k in m.__private_attributes__:389                        m.__pydantic_private__[k] = v390 391        return m392 393    def model_copy(self, *, update: Mapping[str, Any] | None = None, deep: bool = False) -> Self:394        """!!! abstract "Usage Documentation"395            [`model_copy`](../concepts/models.md#model-copy)396 397        Returns a copy of the model.398 399        !!! note400            The underlying instance's [`__dict__`][object.__dict__] attribute is copied. This401            might have unexpected side effects if you store anything in it, on top of the model402            fields (e.g. the value of [cached properties][functools.cached_property]).403 404        Args:405            update: Values to change/add in the new model. Note: the data is not validated406                before creating the new model. You should trust this data.407            deep: Set to `True` to make a deep copy of the model.408 409        Returns:410            New model instance.411        """412        copied = self.__deepcopy__() if deep else self.__copy__()413        if update:414            if self.model_config.get('extra') == 'allow':415                for k, v in update.items():416                    if k in self.__pydantic_fields__:417                        copied.__dict__[k] = v418                    else:419                        if copied.__pydantic_extra__ is None:420                            copied.__pydantic_extra__ = {}421                        copied.__pydantic_extra__[k] = v422            else:423                copied.__dict__.update(update)424            copied.__pydantic_fields_set__.update(update.keys())425        return copied426 427    def model_dump(428        self,429        *,430        mode: Literal['json', 'python'] | str = 'python',431        include: IncEx | None = None,432        exclude: IncEx | None = None,433        context: Any | None = None,434        by_alias: bool | None = None,435        exclude_unset: bool = False,436        exclude_defaults: bool = False,437        exclude_none: bool = False,438        exclude_computed_fields: bool = False,439        round_trip: bool = False,440        warnings: bool | Literal['none', 'warn', 'error'] = True,441        fallback: Callable[[Any], Any] | None = None,442        serialize_as_any: bool = False,443        polymorphic_serialization: bool | None = None,444    ) -> dict[str, Any]:445        """!!! abstract "Usage Documentation"446            [`model_dump`](../concepts/serialization.md#python-mode)447 448        Generate a dictionary representation of the model, optionally specifying which fields to include or exclude.449 450        Args:451            mode: The mode in which `to_python` should run.452                If mode is 'json', the output will only contain JSON serializable types.453                If mode is 'python', the output may contain non-JSON-serializable Python objects.454            include: A set of fields to include in the output.455            exclude: A set of fields to exclude from the output.456            context: Additional context to pass to the serializer.457            by_alias: Whether to use the field's alias in the dictionary key if defined.458            exclude_unset: Whether to exclude fields that have not been explicitly set.459            exclude_defaults: Whether to exclude fields that are set to their default value.460            exclude_none: Whether to exclude fields that have a value of `None`.461            exclude_computed_fields: Whether to exclude computed fields.462                While this can be useful for round-tripping, it is usually recommended to use the dedicated463                `round_trip` parameter instead.464            round_trip: If True, dumped values should be valid as input for non-idempotent types such as Json[T].465            warnings: How to handle serialization errors. False/"none" ignores them, True/"warn" logs errors,466                "error" raises a [`PydanticSerializationError`][pydantic_core.PydanticSerializationError].467            fallback: A function to call when an unknown value is encountered. If not provided,468                a [`PydanticSerializationError`][pydantic_core.PydanticSerializationError] error is raised.469            serialize_as_any: Whether to serialize fields with duck-typing serialization behavior.470            polymorphic_serialization: Whether to use model and dataclass polymorphic serialization for this call.471 472        Returns:473            A dictionary representation of the model.474        """475        return self.__pydantic_serializer__.to_python(476            self,477            mode=mode,478            by_alias=by_alias,479            include=include,480            exclude=exclude,481            context=context,482            exclude_unset=exclude_unset,483            exclude_defaults=exclude_defaults,484            exclude_none=exclude_none,485            exclude_computed_fields=exclude_computed_fields,486            round_trip=round_trip,487            warnings=warnings,488            fallback=fallback,489            serialize_as_any=serialize_as_any,490            polymorphic_serialization=polymorphic_serialization,491        )492 493    def model_dump_json(494        self,495        *,496        indent: int | None = None,497        ensure_ascii: bool = False,498        include: IncEx | None = None,499        exclude: IncEx | None = None,500        context: Any | None = None,501        by_alias: bool | None = None,502        exclude_unset: bool = False,503        exclude_defaults: bool = False,504        exclude_none: bool = False,505        exclude_computed_fields: bool = False,506        round_trip: bool = False,507        warnings: bool | Literal['none', 'warn', 'error'] = True,508        fallback: Callable[[Any], Any] | None = None,509        serialize_as_any: bool = False,510        polymorphic_serialization: bool | None = None,511    ) -> str:512        """!!! abstract "Usage Documentation"513            [`model_dump_json`](../concepts/serialization.md#json-mode)514 515        Generates a JSON representation of the model using Pydantic's `to_json` method.516 517        Args:518            indent: Indentation to use in the JSON output. If None is passed, the output will be compact.519            ensure_ascii: If `True`, the output is guaranteed to have all incoming non-ASCII characters escaped.520                If `False` (the default), these characters will be output as-is.521            include: Field(s) to include in the JSON output.522            exclude: Field(s) to exclude from the JSON output.523            context: Additional context to pass to the serializer.524            by_alias: Whether to serialize using field aliases.525            exclude_unset: Whether to exclude fields that have not been explicitly set.526            exclude_defaults: Whether to exclude fields that are set to their default value.527            exclude_none: Whether to exclude fields that have a value of `None`.528            exclude_computed_fields: Whether to exclude computed fields.529                While this can be useful for round-tripping, it is usually recommended to use the dedicated530                `round_trip` parameter instead.531            round_trip: If True, dumped values should be valid as input for non-idempotent types such as Json[T].532            warnings: How to handle serialization errors. False/"none" ignores them, True/"warn" logs errors,533                "error" raises a [`PydanticSerializationError`][pydantic_core.PydanticSerializationError].534            fallback: A function to call when an unknown value is encountered. If not provided,535                a [`PydanticSerializationError`][pydantic_core.PydanticSerializationError] error is raised.536            serialize_as_any: Whether to serialize fields with duck-typing serialization behavior.537            polymorphic_serialization: Whether to use model and dataclass polymorphic serialization for this call.538 539        Returns:540            A JSON string representation of the model.541        """542        return self.__pydantic_serializer__.to_json(543            self,544            indent=indent,545            ensure_ascii=ensure_ascii,546            include=include,547            exclude=exclude,548            context=context,549            by_alias=by_alias,550            exclude_unset=exclude_unset,551            exclude_defaults=exclude_defaults,552            exclude_none=exclude_none,553            exclude_computed_fields=exclude_computed_fields,554            round_trip=round_trip,555            warnings=warnings,556            fallback=fallback,557            serialize_as_any=serialize_as_any,558            polymorphic_serialization=polymorphic_serialization,559        ).decode()560 561    @classmethod562    def model_json_schema(563        cls,564        by_alias: bool = True,565        ref_template: str = DEFAULT_REF_TEMPLATE,566        schema_generator: type[GenerateJsonSchema] = GenerateJsonSchema,567        mode: JsonSchemaMode = 'validation',568        *,569        union_format: Literal['any_of', 'primitive_type_array'] = 'any_of',570    ) -> dict[str, Any]:571        """Generates a JSON schema for a model class.572 573        Args:574            by_alias: Whether to use attribute aliases or not.575            ref_template: The reference template.576            union_format: The format to use when combining schemas from unions together. Can be one of:577 578                - `'any_of'`: Use the [`anyOf`](https://json-schema.org/understanding-json-schema/reference/combining#anyOf)579                keyword to combine schemas (the default).580                - `'primitive_type_array'`: Use the [`type`](https://json-schema.org/understanding-json-schema/reference/type)581                keyword as an array of strings, containing each type of the combination. If any of the schemas is not a primitive582                type (`string`, `boolean`, `null`, `integer` or `number`) or contains constraints/metadata, falls back to583                `any_of`.584            schema_generator: To override the logic used to generate the JSON schema, as a subclass of585                `GenerateJsonSchema` with your desired modifications586            mode: The mode in which to generate the schema.587 588        Returns:589            The JSON schema for the given model class.590        """591        return model_json_schema(592            cls,593            by_alias=by_alias,594            ref_template=ref_template,595            union_format=union_format,596            schema_generator=schema_generator,597            mode=mode,598        )599 600    @classmethod601    def model_parametrized_name(cls, params: tuple[type[Any], ...]) -> str:602        """Compute the class name for parametrizations of generic classes.603 604        This method can be overridden to achieve a custom naming scheme for generic BaseModels.605 606        Args:607            params: Tuple of types of the class. Given a generic class608                `Model` with 2 type variables and a concrete model `Model[str, int]`,609                the value `(str, int)` would be passed to `params`.610 611        Returns:612            String representing the new class where `params` are passed to `cls` as type variables.613 614        Raises:615            TypeError: Raised when trying to generate concrete names for non-generic models.616        """617        if not issubclass(cls, Generic):618            raise TypeError('Concrete names should only be generated for generic models.')619 620        # Any strings received should represent forward references, so we handle them specially below.621        # If we eventually move toward wrapping them in a ForwardRef in __class_getitem__ in the future,622        # we may be able to remove this special case.623        param_names = [param if isinstance(param, str) else _repr.display_as_type(param) for param in params]624        params_component = ', '.join(param_names)625        return f'{cls.__name__}[{params_component}]'626 627    def model_post_init(self, context: Any, /) -> None:628        """Override this method to perform additional initialization after `__init__` and `model_construct`.629        This is useful if you want to do some validation that requires the entire model to be initialized.630        """631 632    @classmethod633    def model_rebuild(634        cls,635        *,636        force: bool = False,637        raise_errors: bool = True,638        _parent_namespace_depth: int = 2,639        _types_namespace: MappingNamespace | None = None,640    ) -> bool | None:641        """Try to rebuild the pydantic-core schema for the model.642 643        This may be necessary when one of the annotations is a ForwardRef which could not be resolved during644        the initial attempt to build the schema, and automatic rebuilding fails.645 646        Args:647            force: Whether to force the rebuilding of the model schema, defaults to `False`.648            raise_errors: Whether to raise errors, defaults to `True`.649            _parent_namespace_depth: The depth level of the parent namespace, defaults to 2.650            _types_namespace: The types namespace, defaults to `None`.651 652        Returns:653            Returns `None` if the schema is already "complete" and rebuilding was not required.654            If rebuilding _was_ required, returns `True` if rebuilding was successful, otherwise `False`.655        """656        already_complete = cls.__pydantic_complete__657        if already_complete and not force:658            return None659 660        cls.__pydantic_complete__ = False661 662        for attr in ('__pydantic_core_schema__', '__pydantic_validator__', '__pydantic_serializer__'):663            if attr in cls.__dict__ and not isinstance(getattr(cls, attr), _mock_val_ser.MockValSer):664                # Deleting the validator/serializer is necessary as otherwise they can get reused in665                # pydantic-core. We do so only if they aren't mock instances, otherwise — as `model_rebuild()`666                # isn't thread-safe — concurrent model instantiations can lead to the parent validator being used.667                # Same applies for the core schema that can be reused in schema generation.668                delattr(cls, attr)669 670        if _types_namespace is not None:671            rebuild_ns = _types_namespace672        elif _parent_namespace_depth > 0:673            rebuild_ns = _typing_extra.parent_frame_namespace(parent_depth=_parent_namespace_depth, force=True) or {}674        else:675            rebuild_ns = {}676 677        parent_ns = _model_construction.unpack_lenient_weakvaluedict(cls.__pydantic_parent_namespace__) or {}678 679        ns_resolver = _namespace_utils.NsResolver(680            parent_namespace={**rebuild_ns, **parent_ns},681        )682 683        return _model_construction.complete_model_class(684            cls,685            _config.ConfigWrapper(cls.model_config, check=False),686            ns_resolver,687            raise_errors=raise_errors,688            # If the model was already complete, we don't need to call the hook again.689            call_on_complete_hook=not already_complete,690            is_force_rebuild=force,691        )692 693    @classmethod694    def model_validate(695        cls,696        obj: Any,697        *,698        strict: bool | None = None,699        extra: ExtraValues | None = None,700        from_attributes: bool | None = None,701        context: Any | None = None,702        by_alias: bool | None = None,703        by_name: bool | None = None,704    ) -> Self:705        """Validate a pydantic model instance.706 707        Args:708            obj: The object to validate.709            strict: Whether to enforce types strictly.710            extra: Whether to ignore, allow, or forbid extra data during model validation.711                See the [`extra` configuration value][pydantic.ConfigDict.extra] for details.712            from_attributes: Whether to extract data from object attributes.713            context: Additional context to pass to the validator.714            by_alias: Whether to use the field's alias when validating against the provided input data.715            by_name: Whether to use the field's name when validating against the provided input data.716 717        Raises:718            ValidationError: If the object could not be validated.719 720        Returns:721            The validated model instance.722        """723        # `__tracebackhide__` tells pytest and some other tools to omit this function from tracebacks724        __tracebackhide__ = True725 726        if by_alias is False and by_name is not True:727            raise PydanticUserError(728                'At least one of `by_alias` or `by_name` must be set to True.',729                code='validate-by-alias-and-name-false',730            )731 732        return cls.__pydantic_validator__.validate_python(733            obj,734            strict=strict,735            extra=extra,736            from_attributes=from_attributes,737            context=context,738            by_alias=by_alias,739            by_name=by_name,740        )741 742    @classmethod743    def model_validate_json(744        cls,745        json_data: str | bytes | bytearray,746        *,747        strict: bool | None = None,748        extra: ExtraValues | None = None,749        context: Any | None = None,750        by_alias: bool | None = None,751        by_name: bool | None = None,752    ) -> Self:753        """!!! abstract "Usage Documentation"754            [JSON Parsing](../concepts/json.md#json-parsing)755 756        Validate the given JSON data against the Pydantic model.757 758        Args:759            json_data: The JSON data to validate.760            strict: Whether to enforce types strictly.761            extra: Whether to ignore, allow, or forbid extra data during model validation.762                See the [`extra` configuration value][pydantic.ConfigDict.extra] for details.763            context: Extra variables to pass to the validator.764            by_alias: Whether to use the field's alias when validating against the provided input data.765            by_name: Whether to use the field's name when validating against the provided input data.766 767        Returns:768            The validated Pydantic model.769 770        Raises:771            ValidationError: If `json_data` is not a JSON string or the object could not be validated.772        """773        # `__tracebackhide__` tells pytest and some other tools to omit this function from tracebacks774        __tracebackhide__ = True775 776        if by_alias is False and by_name is not True:777            raise PydanticUserError(778                'At least one of `by_alias` or `by_name` must be set to True.',779                code='validate-by-alias-and-name-false',780            )781 782        return cls.__pydantic_validator__.validate_json(783            json_data, strict=strict, extra=extra, context=context, by_alias=by_alias, by_name=by_name784        )785 786    @classmethod787    def model_validate_strings(788        cls,789        obj: Any,790        *,791        strict: bool | None = None,792        extra: ExtraValues | None = None,793        context: Any | None = None,794        by_alias: bool | None = None,795        by_name: bool | None = None,796    ) -> Self:797        """Validate the given object with string data against the Pydantic model.798 799        Args:800            obj: The object containing string data to validate.801            strict: Whether to enforce types strictly.802            extra: Whether to ignore, allow, or forbid extra data during model validation.803                See the [`extra` configuration value][pydantic.ConfigDict.extra] for details.804            context: Extra variables to pass to the validator.805            by_alias: Whether to use the field's alias when validating against the provided input data.806            by_name: Whether to use the field's name when validating against the provided input data.807 808        Returns:809            The validated Pydantic model.810        """811        # `__tracebackhide__` tells pytest and some other tools to omit this function from tracebacks812        __tracebackhide__ = True813 814        if by_alias is False and by_name is not True:815            raise PydanticUserError(816                'At least one of `by_alias` or `by_name` must be set to True.',817                code='validate-by-alias-and-name-false',818            )819 820        return cls.__pydantic_validator__.validate_strings(821            obj, strict=strict, extra=extra, context=context, by_alias=by_alias, by_name=by_name822        )823 824    @classmethod825    def __get_pydantic_core_schema__(cls, source: type[BaseModel], handler: GetCoreSchemaHandler, /) -> CoreSchema:826        # This warning is only emitted when calling `super().__get_pydantic_core_schema__` from a model subclass.827        # In the generate schema logic, this method (`BaseModel.__get_pydantic_core_schema__`) is special cased to828        # *not* be called if not overridden.829        warnings.warn(830            'The `__get_pydantic_core_schema__` method of the `BaseModel` class is deprecated. If you are calling '831            '`super().__get_pydantic_core_schema__` when overriding the method on a Pydantic model, consider using '832            '`handler(source)` instead. However, note that overriding this method on models can lead to unexpected '833            'side effects.',834            PydanticDeprecatedSince211,835            stacklevel=2,836        )837        # Logic copied over from `GenerateSchema._model_schema`:838        schema = cls.__dict__.get('__pydantic_core_schema__')839        if schema is not None and not isinstance(schema, _mock_val_ser.MockCoreSchema):840            return cls.__pydantic_core_schema__841 842        return handler(source)843 844    @classmethod845    def __get_pydantic_json_schema__(846        cls,847        core_schema: CoreSchema,848        handler: GetJsonSchemaHandler,849        /,850    ) -> JsonSchemaValue:851        """Hook into generating the model's JSON schema.852 853        Args:854            core_schema: A `pydantic-core` CoreSchema.855                You can ignore this argument and call the handler with a new CoreSchema,856                wrap this CoreSchema (`{'type': 'nullable', 'schema': current_schema}`),857                or just call the handler with the original schema.858            handler: Call into Pydantic's internal JSON schema generation.859                This will raise a `pydantic.errors.PydanticInvalidForJsonSchema` if JSON schema860                generation fails.861                Since this gets called by `BaseModel.model_json_schema` you can override the862                `schema_generator` argument to that function to change JSON schema generation globally863                for a type.864 865        Returns:866            A JSON schema, as a Python object.867        """868        return handler(core_schema)869 870    @classmethod871    def __pydantic_init_subclass__(cls, **kwargs: Any) -> None:872        """This is intended to behave just like `__init_subclass__`, but is called by `ModelMetaclass`873        only after basic class initialization is complete. In particular, attributes like `model_fields` will874        be present when this is called, but forward annotations are not guaranteed to be resolved yet,875        meaning that creating an instance of the class may fail.876 877        This is necessary because `__init_subclass__` will always be called by `type.__new__`,878        and it would require a prohibitively large refactor to the `ModelMetaclass` to ensure that879        `type.__new__` was called in such a manner that the class would already be sufficiently initialized.880 881        This will receive the same `kwargs` that would be passed to the standard `__init_subclass__`, namely,882        any kwargs passed to the class definition that aren't used internally by Pydantic.883 884        Args:885            **kwargs: Any keyword arguments passed to the class definition that aren't used internally886                by Pydantic.887 888        Note:889            You may want to override [`__pydantic_on_complete__()`][pydantic.main.BaseModel.__pydantic_on_complete__]890            instead, which is called once the class and its fields are fully initialized and ready for validation.891        """892 893    @classmethod894    def __pydantic_on_complete__(cls) -> None:895        """This is called once the class and its fields are fully initialized and ready to be used.896 897        This typically happens when the class is created (just before898        [`__pydantic_init_subclass__()`][pydantic.main.BaseModel.__pydantic_init_subclass__] is called on the superclass),899        except when forward annotations are used that could not immediately be resolved.900        In that case, it will be called later, when the model is rebuilt automatically or explicitly using901        [`model_rebuild()`][pydantic.main.BaseModel.model_rebuild].902        """903 904    def __class_getitem__(905        cls, typevar_values: type[Any] | tuple[type[Any], ...]906    ) -> type[BaseModel] | _forward_ref.PydanticRecursiveRef:907        cached = _generics.get_cached_generic_type_early(cls, typevar_values)908        if cached is not None:909            return cached910 911        if cls is BaseModel:912            raise TypeError('Type parameters should be placed on typing.Generic, not BaseModel')913        if not hasattr(cls, '__parameters__'):914            raise TypeError(f'{cls} cannot be parametrized because it does not inherit from typing.Generic')915        if not cls.__pydantic_generic_metadata__['parameters'] and Generic not in cls.__bases__:916            raise TypeError(f'{cls} is not a generic class')917 918        if not isinstance(typevar_values, tuple):919            typevar_values = (typevar_values,)920 921        # For a model `class Model[T, U, V = int](BaseModel): ...` parametrized with `(str, bool)`,922        # this gives us `{T: str, U: bool, V: int}`:923        typevars_map = _generics.map_generic_model_arguments(cls, typevar_values)924        # We also update the provided args to use defaults values (`(str, bool)` becomes `(str, bool, int)`):925        typevar_values = tuple(v for v in typevars_map.values())926 927        if _utils.all_identical(typevars_map.keys(), typevars_map.values()) and typevars_map:928            submodel = cls  # if arguments are equal to parameters it's the same object929            _generics.set_cached_generic_type(cls, typevar_values, submodel)930        else:931            parent_args = cls.__pydantic_generic_metadata__['args']932            if not parent_args:933                args = typevar_values934            else:935                args = tuple(_generics.replace_types(arg, typevars_map) for arg in parent_args)936 937            origin = cls.__pydantic_generic_metadata__['origin'] or cls938            model_name = origin.model_parametrized_name(args)939            params = tuple(940                dict.fromkeys(_generics.iter_contained_typevars(typevars_map.values()))941            )  # use dict as ordered set942 943            with _generics.generic_recursion_self_type(origin, args) as maybe_self_type:944                cached = _generics.get_cached_generic_type_late(cls, typevar_values, origin, args)945                if cached is not None:946                    return cached947 948                if maybe_self_type is not None:949                    return maybe_self_type950 951                # Attempt to rebuild the origin in case new types have been defined952                try:953                    # depth 2 gets you above this __class_getitem__ call.954                    # Note that we explicitly provide the parent ns, otherwise955                    # `model_rebuild` will use the parent ns no matter if it is the ns of a module.956                    # We don't want this here, as this has unexpected effects when a model957                    # is being parametrized during a forward annotation evaluation.958                    parent_ns = _typing_extra.parent_frame_namespace(parent_depth=2) or {}959                    origin.model_rebuild(_types_namespace=parent_ns)960                except PydanticUndefinedAnnotation:961                    # It's okay if it fails, it just means there are still undefined types962                    # that could be evaluated later.963                    pass964 965                submodel = _generics.create_generic_submodel(model_name, origin, args, params)966 967                _generics.set_cached_generic_type(cls, typevar_values, submodel, origin, args)968 969        return submodel970 971    def __copy__(self) -> Self:972        """Returns a shallow copy of the model."""973        cls = type(self)974        m = cls.__new__(cls)975        _object_setattr(m, '__dict__', copy(self.__dict__))976        _object_setattr(m, '__pydantic_extra__', copy(self.__pydantic_extra__))977        _object_setattr(m, '__pydantic_fields_set__', copy(self.__pydantic_fields_set__))978 979        if not hasattr(self, '__pydantic_private__') or self.__pydantic_private__ is None:980            _object_setattr(m, '__pydantic_private__', None)981        else:982            _object_setattr(983                m,984                '__pydantic_private__',985                {k: v for k, v in self.__pydantic_private__.items() if v is not PydanticUndefined},986            )987 988        return m989 990    def __deepcopy__(self, memo: dict[int, Any] | None = None) -> Self:991        """Returns a deep copy of the model."""992        cls = type(self)993        m = cls.__new__(cls)994        _object_setattr(m, '__dict__', deepcopy(self.__dict__, memo=memo))995        _object_setattr(m, '__pydantic_extra__', deepcopy(self.__pydantic_extra__, memo=memo))996        # This next line doesn't need a deepcopy because __pydantic_fields_set__ is a set[str],997        # and attempting a deepcopy would be marginally slower.998        _object_setattr(m, '__pydantic_fields_set__', copy(self.__pydantic_fields_set__))999 1000        if not hasattr(self, '__pydantic_private__') or self.__pydantic_private__ is None:1001            _object_setattr(m, '__pydantic_private__', None)1002        else:1003            _object_setattr(1004                m,1005                '__pydantic_private__',1006                deepcopy({k: v for k, v in self.__pydantic_private__.items() if v is not PydanticUndefined}, memo=memo),1007            )1008 1009        return m1010 1011    if not TYPE_CHECKING:1012        # We put `__getattr__` in a non-TYPE_CHECKING block because otherwise, mypy allows arbitrary attribute access1013        # The same goes for __setattr__ and __delattr__, see: https://github.com/pydantic/pydantic/issues/86431014 1015        def __getattr__(self, item: str) -> Any:1016            private_attributes = object.__getattribute__(self, '__private_attributes__')1017            if item in private_attributes:1018                attribute = private_attributes[item]1019                if hasattr(attribute, '__get__'):1020                    return attribute.__get__(self, type(self))  # type: ignore1021 1022                try:1023                    # Note: self.__pydantic_private__ cannot be None if self.__private_attributes__ has items1024                    return self.__pydantic_private__[item]  # type: ignore1025                except KeyError as exc:1026                    raise AttributeError(f'{type(self).__name__!r} object has no attribute {item!r}') from exc1027            else:1028                # `__pydantic_extra__` can fail to be set if the model is not yet fully initialized.1029                # See `BaseModel.__repr_args__` for more details1030                try:1031                    pydantic_extra = object.__getattribute__(self, '__pydantic_extra__')1032                except AttributeError:1033                    pydantic_extra = None1034 1035                if pydantic_extra and item in pydantic_extra:1036                    return pydantic_extra[item]1037                else:1038                    if hasattr(self.__class__, item):1039                        return super().__getattribute__(item)  # Raises AttributeError if appropriate1040                    else:1041                        # this is the current error1042                        raise AttributeError(f'{type(self).__name__!r} object has no attribute {item!r}')1043 1044        def __setattr__(self, name: str, value: Any) -> None:1045            if (setattr_handler := self.__pydantic_setattr_handlers__.get(name)) is not None:1046                setattr_handler(self, name, value)1047            # if None is returned from _setattr_handler, the attribute was set directly1048            elif (setattr_handler := self._setattr_handler(name, value)) is not None:1049                setattr_handler(self, name, value)  # call here to not memo on possibly unknown fields1050                self.__pydantic_setattr_handlers__[name] = setattr_handler  # memoize the handler for faster access1051 1052        def _setattr_handler(self, name: str, value: Any) -> Callable[[BaseModel, str, Any], None] | None:1053            """Get a handler for setting an attribute on the model instance.1054 1055            Returns:1056                A handler for setting an attribute on the model instance. Used for memoization of the handler.1057                Memoizing the handlers leads to a dramatic performance improvement in `__setattr__`1058                Returns `None` when memoization is not safe, then the attribute is set directly.1059            """1060            cls = self.__class__1061            if name in cls.__class_vars__:1062                raise AttributeError(1063                    f'{name!r} is a ClassVar of `{cls.__name__}` and cannot be set on an instance. '1064                    f'If you want to set a value on the class, use `{cls.__name__}.{name} = value`.'1065                )1066            elif not _fields.is_valid_field_name(name):1067                if (attribute := cls.__private_attributes__.get(name)) is not None:1068                    if hasattr(attribute, '__set__'):1069                        return lambda model, _name, val: attribute.__set__(model, val)1070                    else:1071                        return _SIMPLE_SETATTR_HANDLERS['private']1072                else:1073                    _object_setattr(self, name, value)1074                    return None  # Can not return memoized handler with possibly freeform attr names1075 1076            attr = getattr(cls, name, None)1077            # NOTE: We currently special case properties and `cached_property`, but we might need1078            # to generalize this to all data/non-data descriptors at some point. For non-data descriptors1079            # (such as `cached_property`), it isn't obvious though. `cached_property` caches the value1080            # to the instance's `__dict__`, but other non-data descriptors might do things differently.1081            if isinstance(attr, cached_property):1082                return _SIMPLE_SETATTR_HANDLERS['cached_property']1083 1084            _check_frozen(cls, name, value)1085 1086            # We allow properties to be set only on non frozen models for now (to match dataclasses).1087            # This can be changed if it ever gets requested.1088            if isinstance(attr, property):1089                return lambda model, _name, val: attr.__set__(model, val)1090            elif cls.model_config.get('validate_assignment'):1091                return _SIMPLE_SETATTR_HANDLERS['validate_assignment']1092            elif name not in cls.__pydantic_fields__:1093                if cls.model_config.get('extra') != 'allow':1094                    # TODO - matching error1095                    raise ValueError(f'"{cls.__name__}" object has no field "{name}"')1096                elif attr is None:1097                    # attribute does not exist, so put it in extra1098                    self.__pydantic_extra__[name] = value1099                    self.__pydantic_fields_set__.add(name)1100                    return None  # Can not return memoized handler with possibly freeform attr names1101                else:1102                    # attribute _does_ exist, and was not in extra, so update it1103                    return _SIMPLE_SETATTR_HANDLERS['extra_known']1104            else:1105                return _SIMPLE_SETATTR_HANDLERS['model_field']1106 1107        def __delattr__(self, item: str) -> Any:1108            cls = self.__class__1109 1110            if item in self.__private_attributes__:1111                attribute = self.__private_attributes__[item]1112                if hasattr(attribute, '__delete__'):1113                    attribute.__delete__(self)  # type: ignore1114                    return1115 1116                try:1117                    # Note: self.__pydantic_private__ cannot be None if self.__private_attributes__ has items1118                    del self.__pydantic_private__[item]  # type: ignore1119                    return1120                except KeyError as exc:1121                    raise AttributeError(f'{cls.__name__!r} object has no attribute {item!r}') from exc1122 1123            # Allow cached properties to be deleted (even if the class is frozen):1124            attr = getattr(cls, item, None)1125            if isinstance(attr, cached_property):1126                return object.__delattr__(self, item)1127 1128            _check_frozen(cls, name=item, value=None)1129 1130            if item in self.__pydantic_fields__:1131                object.__delattr__(self, item)1132            elif self.__pydantic_extra__ is not None and item in self.__pydantic_extra__:1133                del self.__pydantic_extra__[item]1134            else:1135                try:1136                    object.__delattr__(self, item)1137                except AttributeError:1138                    raise AttributeError(f'{type(self).__name__!r} object has no attribute {item!r}')1139 1140        # Because we make use of `@dataclass_transform()`, `__replace__` is already synthesized by1141        # type checkers, so we define the implementation in this `if not TYPE_CHECKING:` block:1142        def __replace__(self, **changes: Any) -> Self:1143            return self.model_copy(update=changes)1144 1145    def __getstate__(self) -> dict[Any, Any]:1146        private = self.__pydantic_private__1147        if private:1148            private = {k: v for k, v in private.items() if v is not PydanticUndefined}1149        return {1150            '__dict__': self.__dict__,1151            '__pydantic_extra__': self.__pydantic_extra__,1152            '__pydantic_fields_set__': self.__pydantic_fields_set__,1153            '__pydantic_private__': private,1154        }1155 1156    def __setstate__(self, state: dict[Any, Any]) -> None:1157        _object_setattr(self, '__pydantic_fields_set__', state.get('__pydantic_fields_set__', {}))1158        _object_setattr(self, '__pydantic_extra__', state.get('__pydantic_extra__', {}))1159        _object_setattr(self, '__pydantic_private__', state.get('__pydantic_private__', {}))1160        _object_setattr(self, '__dict__', state.get('__dict__', {}))1161 1162    if not TYPE_CHECKING:1163 1164        def __eq__(self, other: Any) -> bool:1165            if isinstance(other, BaseModel):1166                # When comparing instances of generic types for equality, as long as all field values are equal,1167                # only require their generic origin types to be equal, rather than exact type equality.1168                # This prevents headaches like MyGeneric(x=1) != MyGeneric[Any](x=1).1169                self_type = self.__pydantic_generic_metadata__['origin'] or self.__class__1170                other_type = other.__pydantic_generic_metadata__['origin'] or other.__class__1171 1172                # Perform common checks first1173                if not (1174                    self_type is other_type1175                    and getattr(self, '__pydantic_private__', None) == getattr(other, '__pydantic_private__', None)1176                    # We need to assume `None` and `{}` are equivalent, because extra behavior1177                    # can be controlled at validation time:1178                    and (self.__pydantic_extra__ or {}) == (other.__pydantic_extra__ or {})1179                ):1180                    return False1181 1182                # We only want to compare pydantic fields but ignoring fields is costly.1183                # We'll perform a fast check first, and fallback only when needed1184                # See GH-7444 and GH-7825 for rationale and a performance benchmark1185 1186                # First, do the fast (and sometimes faulty) __dict__ comparison1187                if self.__dict__ == other.__dict__:1188                    # If the check above passes, then pydantic fields are equal, we can return early1189                    return True1190 1191                # We don't want to trigger unnecessary costly filtering of __dict__ on all unequal objects, so we return1192                # early if there are no keys to ignore (we would just return False later on anyway)1193                model_fields = type(self).__pydantic_fields__.keys()1194                if self.__dict__.keys() <= model_fields and other.__dict__.keys() <= model_fields:1195                    return False1196 1197                # If we reach here, there are non-pydantic-fields keys, mapped to unequal values, that we need to ignore1198                # Resort to costly filtering of the __dict__ objects1199                # We use operator.itemgetter because it is much faster than dict comprehensions1200                # NOTE: Contrary to standard python class and instances, when the Model class has a default value for an

Showing the first 1,200 of 1839 lines. Download the file for the rest.

codekingpro/portable-devtools · Team Ai