Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/pydantic/main.py: 40%
Shortcuts on this page
r m x toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
Shortcuts on this page
r m x toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1"""Logic for creating models."""
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: UP035
7from __future__ import annotations as _annotations
9import operator
10import sys
11import threading
12import types
13import warnings
14from collections.abc import Generator, Mapping
15from copy import copy, deepcopy
16from functools import cached_property
17from typing import (
18 TYPE_CHECKING,
19 Any,
20 Callable,
21 ClassVar,
22 Dict,
23 Generic,
24 Literal,
25 TypeVar,
26 Union,
27 cast,
28 overload,
29)
31import pydantic_core
32import typing_extensions
33from pydantic_core import PydanticUndefined, ValidationError
34from typing_extensions import Self, Sentinel, TypeAlias, TypeForm, Unpack
36from . import PydanticDeprecatedSince20, PydanticDeprecatedSince211
37from ._internal import (
38 _config,
39 _decorators,
40 _fields,
41 _forward_ref,
42 _generics,
43 _mock_val_ser,
44 _model_construction,
45 _namespace_utils,
46 _repr,
47 _typing_extra,
48 _utils,
49)
50from ._migration import getattr_migration
51from .aliases import AliasChoices, AliasPath
52from .annotated_handlers import GetCoreSchemaHandler, GetJsonSchemaHandler
53from .config import ConfigDict, ExtraValues
54from .errors import PydanticUndefinedAnnotation, PydanticUserError
55from .json_schema import DEFAULT_REF_TEMPLATE, GenerateJsonSchema, JsonSchemaMode, JsonSchemaValue, model_json_schema
56from .plugin._schema_validator import PluggableSchemaValidator
57from .version import version_short
59if TYPE_CHECKING:
60 from inspect import Signature
61 from pathlib import Path
63 from pydantic_core import CoreSchema, SchemaSerializer, SchemaValidator
65 from ._internal._fields import PydanticExtraInfo
66 from ._internal._namespace_utils import MappingNamespace
67 from ._internal._utils import AbstractSetIntStr, MappingIntStrAny
68 from .deprecated.parse import Protocol as DeprecatedParseProtocol
69 from .fields import ComputedFieldInfo, FieldInfo, ModelPrivateAttr
72__all__ = 'BaseModel', 'create_model'
74# Keep these type aliases available at runtime:
75TupleGenerator: TypeAlias = Generator[tuple[str, Any], None, None]
76# NOTE: In reality, `bool` should be replaced by `Literal[True]` but mypy fails to correctly apply bidirectional
77# type inference (e.g. when using `{'a': {'b': True}}`):
78# NOTE: Keep this type alias in sync with the stub definition in `pydantic-core`:
79IncEx: TypeAlias = set[int] | set[str] | Mapping[int, Union['IncEx', bool]] | Mapping[str, Union['IncEx', bool]]
81_object_setattr = _model_construction.object_setattr
83_rebuild_lock = threading.RLock()
84"""
85A lock used to make model rebuilds thread-safe when first instantiating an incomplete model.
87Rebuilding a model isn't thread-safe (the class attributes are mutated during the rebuild,
88while other threads may be reading them to perform validation/serialization), so `model_rebuild()`
89calls are serialized using this lock. The lock is reentrant, as rebuilding a model can trigger the
90rebuild of another one (e.g. when a generic origin is rebuilt during parametrization in
91`__class_getitem__()`). For the same reason, the lock is global and not per-class: two threads
92holding their own class's lock could otherwise request the other's and deadlock.
93"""
96def _check_frozen(model_cls: type[BaseModel], name: str, value: Any) -> None:
97 if model_cls.model_config.get('frozen'):
98 error_type = 'frozen_instance'
99 elif getattr(model_cls.__pydantic_fields__.get(name), 'frozen', False):
100 error_type = 'frozen_field'
101 else:
102 return
104 raise ValidationError.from_exception_data(
105 model_cls.__name__, [{'type': error_type, 'loc': (name,), 'input': value}]
106 )
109def _model_field_setattr_handler(model: BaseModel, name: str, val: Any) -> None:
110 model.__dict__[name] = val # pyright: ignore[reportIndexIssue] (https://github.com/microsoft/pyright/issues/11548)
111 model.__pydantic_fields_set__.add(name)
114def _private_setattr_handler(model: BaseModel, name: str, val: Any) -> None:
115 if getattr(model, '__pydantic_private__', None) is None:
116 # While the attribute should be present at this point, this may not be the case if
117 # users do unusual stuff with `model_post_init()` (which is where the `__pydantic_private__`
118 # is initialized, by wrapping the user-defined `model_post_init()`), e.g. if they mock
119 # the `model_post_init()` call. Ideally we should find a better way to init private attrs.
120 object.__setattr__(model, '__pydantic_private__', {})
121 model.__pydantic_private__[name] = val # pyright: ignore[reportOptionalSubscript]
124_ATTRIBUTE_MISSING = Sentinel('_ATTRIBUTE_MISSING')
127_SIMPLE_SETATTR_HANDLERS: Mapping[str, Callable[[BaseModel, str, Any], None]] = {
128 'model_field': _model_field_setattr_handler,
129 'validate_assignment': lambda model, name, val: model.__pydantic_validator__.validate_assignment(model, name, val), # pyright: ignore[reportAssignmentType]
130 'private': _private_setattr_handler,
131 'cached_property': lambda model, name, val: model.__dict__.__setitem__(name, val), # pyright: ignore[reportAttributeAccessIssue] (https://github.com/microsoft/pyright/issues/11548)
132 'extra_known': lambda model, name, val: _object_setattr(model, name, val),
133}
136class BaseModel(metaclass=_model_construction.ModelMetaclass):
137 """!!! abstract "Usage Documentation"
138 [Models](../concepts/models.md)
140 A base class for creating Pydantic models.
142 Attributes:
143 __class_vars__: The names of the class variables defined on the model.
144 __private_attributes__: Metadata about the private attributes of the model.
145 __signature__: The synthesized `__init__` [`Signature`][inspect.Signature] of the model.
147 __pydantic_complete__: Whether model building is completed, or if there are still undefined fields.
148 __pydantic_core_schema__: The core schema of the model.
149 __pydantic_custom_init__: Whether the model has a custom `__init__` function.
150 __pydantic_decorators__: Metadata containing the decorators defined on the model.
151 This replaces `Model.__validators__` and `Model.__root_validators__` from Pydantic V1.
152 __pydantic_generic_metadata__: A dictionary containing metadata about generic Pydantic models.
153 The `origin` and `args` items map to the [`__origin__`][genericalias.__origin__]
154 and [`__args__`][genericalias.__args__] attributes of [generic aliases][types-genericalias],
155 and the `parameter` item maps to the `__parameter__` attribute of generic classes.
156 __pydantic_parent_namespace__: Parent namespace of the model, used for automatic rebuilding of models.
157 __pydantic_post_init__: The name of the post-init method for the model, if defined.
158 __pydantic_root_model__: Whether the model is a [`RootModel`][pydantic.root_model.RootModel].
159 __pydantic_serializer__: The `pydantic-core` `SchemaSerializer` used to dump instances of the model.
160 __pydantic_validator__: The `pydantic-core` `SchemaValidator` used to validate instances of the model.
162 __pydantic_fields__: A dictionary of field names and their corresponding [`FieldInfo`][pydantic.fields.FieldInfo] objects.
163 __pydantic_computed_fields__: A dictionary of computed field names and their corresponding [`ComputedFieldInfo`][pydantic.fields.ComputedFieldInfo] objects.
165 __pydantic_extra__: A dictionary containing extra values, if [`extra`][pydantic.config.ConfigDict.extra]
166 is set to `'allow'`.
167 __pydantic_fields_set__: The names of fields explicitly set during instantiation.
168 __pydantic_private__: Values of private attributes set on the model instance.
169 """
171 # Note: Many of the below class vars are defined in the metaclass, but we define them here for type checking purposes.
173 model_config: ClassVar[ConfigDict] = ConfigDict()
174 """
175 Configuration for the model, should be a dictionary conforming to [`ConfigDict`][pydantic.config.ConfigDict].
176 """
178 __class_vars__: ClassVar[set[str]]
179 """The names of the class variables defined on the model."""
181 __private_attributes__: ClassVar[Dict[str, ModelPrivateAttr]] # noqa: UP006
182 """Metadata about the private attributes of the model."""
184 __signature__: ClassVar[Signature]
185 """The synthesized `__init__` [`Signature`][inspect.Signature] of the model."""
187 __pydantic_complete__: ClassVar[bool] = False
188 """Whether model building is completed, or if there are still undefined fields."""
190 __pydantic_core_schema__: ClassVar[CoreSchema]
191 """The core schema of the model."""
193 __pydantic_custom_init__: ClassVar[bool]
194 """Whether the model has a custom `__init__` method."""
196 # Must be set for `GenerateSchema.model_schema` to work for a plain `BaseModel` annotation.
197 __pydantic_decorators__: ClassVar[_decorators.DecoratorInfos] = _decorators.DecoratorInfos()
198 """Metadata containing the decorators defined on the model.
199 This replaces `Model.__validators__` and `Model.__root_validators__` from Pydantic V1."""
201 __pydantic_generic_metadata__: ClassVar[_generics.PydanticGenericMetadata]
202 """A dictionary containing metadata about generic Pydantic models.
204 The `origin` and `args` items map to the [`__origin__`][genericalias.__origin__]
205 and [`__args__`][genericalias.__args__] attributes of [generic aliases][types-genericalias],
206 and the `parameter` item maps to the `__parameter__` attribute of generic classes.
207 """
209 __pydantic_parent_namespace__: ClassVar[Dict[str, Any] | None] = None # noqa: UP006
210 """Parent namespace of the model, used for automatic rebuilding of models."""
212 __pydantic_post_init__: ClassVar[None | Literal['model_post_init']]
213 """The name of the post-init method for the model, if defined."""
215 __pydantic_root_model__: ClassVar[bool] = False
216 """Whether the model is a [`RootModel`][pydantic.root_model.RootModel]."""
218 __pydantic_serializer__: ClassVar[SchemaSerializer]
219 """The `pydantic-core` `SchemaSerializer` used to dump instances of the model."""
221 __pydantic_validator__: ClassVar[SchemaValidator | PluggableSchemaValidator]
222 """The `pydantic-core` `SchemaValidator` used to validate instances of the model."""
224 __pydantic_fields__: ClassVar[Dict[str, FieldInfo]] # noqa: UP006
225 """A dictionary of field names and their corresponding [`FieldInfo`][pydantic.fields.FieldInfo] objects.
226 This replaces `Model.__fields__` from Pydantic V1.
227 """
229 __pydantic_setattr_handlers__: ClassVar[Dict[str, Callable[[BaseModel, str, Any], None]]] # noqa: UP006
230 """`__setattr__` handlers. Memoizing the handlers leads to a dramatic performance improvement in `__setattr__`"""
232 __pydantic_computed_fields__: ClassVar[Dict[str, ComputedFieldInfo]] # noqa: UP006
233 """A dictionary of computed field names and their corresponding [`ComputedFieldInfo`][pydantic.fields.ComputedFieldInfo] objects."""
235 __pydantic_extra_info__: ClassVar[PydanticExtraInfo | None]
236 """A wrapper around the `__pydantic_extra__` annotation, if explicitly annotated on a model.
238 This is a private attribute, not meant to be used outside Pydantic.
239 """
241 __pydantic_extra__: Dict[str, Any] | None = _model_construction.NoInitField(init=False) # noqa: UP006
242 """A dictionary containing extra values, if [`extra`][pydantic.config.ConfigDict.extra] is set to `'allow'`."""
244 __pydantic_fields_set__: set[str] = _model_construction.NoInitField(init=False)
245 """The names of fields explicitly set during instantiation."""
247 __pydantic_private__: Dict[str, Any] | None = _model_construction.NoInitField(init=False) # noqa: UP006
248 """Values of private attributes set on the model instance."""
250 if not TYPE_CHECKING:
251 # Prevent `BaseModel` from being instantiated directly
252 # (defined in an `if not TYPE_CHECKING` block for clarity and to avoid type checking errors):
253 __pydantic_core_schema__ = _mock_val_ser.MockCoreSchema(
254 'Pydantic models should inherit from BaseModel, BaseModel cannot be instantiated directly',
255 code='base-model-instantiated',
256 )
257 __pydantic_validator__ = _mock_val_ser.MockValSer(
258 'Pydantic models should inherit from BaseModel, BaseModel cannot be instantiated directly',
259 val_or_ser='validator',
260 code='base-model-instantiated',
261 )
262 __pydantic_serializer__ = _mock_val_ser.MockValSer(
263 'Pydantic models should inherit from BaseModel, BaseModel cannot be instantiated directly',
264 val_or_ser='serializer',
265 code='base-model-instantiated',
266 )
268 __slots__ = '__dict__', '__pydantic_fields_set__', '__pydantic_extra__', '__pydantic_private__'
270 def __init__(self, /, **data: Any) -> None:
271 """Create a new model by parsing and validating input data from keyword arguments.
273 Raises [`ValidationError`][pydantic_core.ValidationError] if the input data cannot be
274 validated to form a valid model.
276 `self` is explicitly positional-only to allow `self` as a field name.
277 """
278 # `__tracebackhide__` tells pytest and some other tools to omit this function from tracebacks
279 __tracebackhide__ = True
280 validated_self = self.__pydantic_validator__.validate_python(data, self_instance=self)
281 if self is not validated_self:
282 warnings.warn(
283 'A custom validator is returning a value other than `self`.\n'
284 "Returning anything other than `self` from a top level model validator isn't supported when validating via `__init__`.\n"
285 f'See the `model_validator` docs (https://pydantic.dev/docs/validation/{version_short()}/concepts/validators/#model-validators) for more details.',
286 stacklevel=2,
287 )
289 # The following line sets a flag that we use to determine when `__init__` gets overridden by the user
290 __init__.__pydantic_base_init__ = True # pyright: ignore[reportFunctionMemberAccess]
292 @_utils.deprecated_instance_property
293 @classmethod
294 def model_fields(cls) -> Dict[str, FieldInfo]: # noqa: UP006
295 """A mapping of field names to their respective [`FieldInfo`][pydantic.fields.FieldInfo] instances.
297 !!! warning
298 Accessing this attribute from a model instance is deprecated, and will not work in Pydantic V3.
299 Instead, you should access this attribute from the model class.
300 """
301 return getattr(cls, '__pydantic_fields__', {})
303 @_utils.deprecated_instance_property
304 @classmethod
305 def model_computed_fields(cls) -> Dict[str, ComputedFieldInfo]: # noqa: UP006
306 """A mapping of computed field names to their respective [`ComputedFieldInfo`][pydantic.fields.ComputedFieldInfo] instances.
308 !!! warning
309 Accessing this attribute from a model instance is deprecated, and will not work in Pydantic V3.
310 Instead, you should access this attribute from the model class.
311 """
312 return getattr(cls, '__pydantic_computed_fields__', {})
314 @property
315 def model_extra(self) -> Dict[str, Any] | None: # noqa: UP006
316 """Get extra fields set during validation.
318 Returns:
319 A dictionary of extra fields, or `None` if `config.extra` is not set to `"allow"`.
320 """
321 return self.__pydantic_extra__
323 @property
324 def model_fields_set(self) -> set[str]:
325 """Returns the set of fields that have been explicitly set on this model instance.
327 Returns:
328 A set of strings representing the fields that have been set,
329 i.e. that were not filled from defaults.
330 """
331 return self.__pydantic_fields_set__
333 @classmethod
334 def model_construct(cls, _fields_set: set[str] | None = None, **values: Any) -> Self: # noqa: C901
335 """Creates a new instance of the `Model` class with validated data.
337 Creates a new model setting `__dict__` and `__pydantic_fields_set__` from trusted or pre-validated data.
338 Default values are respected, but no other validation is performed.
340 !!! note
341 `model_construct()` generally respects the `model_config.extra` setting on the provided model.
342 That is, if `model_config.extra == 'allow'`, then all extra passed values are added to the model instance's `__dict__`
343 and `__pydantic_extra__` fields. If `model_config.extra == 'ignore'` (the default), then all extra passed values are ignored.
344 Because no validation is performed with a call to `model_construct()`, having `model_config.extra == 'forbid'` does not result in
345 an error if extra values are passed, but they will be ignored.
347 Args:
348 _fields_set: A set of field names that were originally explicitly set during instantiation. If provided,
349 this is directly used for the [`model_fields_set`][pydantic.BaseModel.model_fields_set] attribute.
350 Otherwise, the field names from the `values` argument will be used.
351 values: Trusted or pre-validated data dictionary.
353 Returns:
354 A new instance of the `Model` class with validated data.
355 """
356 m = cls.__new__(cls)
357 fields_values: dict[str, Any] = {}
358 fields_set = set()
360 for name, field in cls.__pydantic_fields__.items():
361 if field.alias is not None and field.alias in values:
362 fields_values[name] = values.pop(field.alias)
363 fields_set.add(name)
365 if (name not in fields_set) and (field.validation_alias is not None):
366 validation_aliases: list[str | AliasPath] = (
367 field.validation_alias.choices
368 if isinstance(field.validation_alias, AliasChoices)
369 else [field.validation_alias]
370 )
372 for alias in validation_aliases:
373 if isinstance(alias, str) and alias in values:
374 fields_values[name] = values.pop(alias)
375 fields_set.add(name)
376 break
377 elif isinstance(alias, AliasPath):
378 value = alias.search_dict_for_path(values)
379 if value is not PydanticUndefined:
380 fields_values[name] = value
381 fields_set.add(name)
382 break
384 if name not in fields_set:
385 if name in values:
386 fields_values[name] = values.pop(name)
387 fields_set.add(name)
388 elif not field.is_required():
389 fields_values[name] = field.get_default(call_default_factory=True, validated_data=fields_values)
390 if _fields_set is None:
391 _fields_set = fields_set
393 _extra: dict[str, Any] | None = values if cls.model_config.get('extra') == 'allow' else None
394 _object_setattr(m, '__dict__', fields_values)
395 _object_setattr(m, '__pydantic_fields_set__', _fields_set)
396 if not cls.__pydantic_root_model__:
397 _object_setattr(m, '__pydantic_extra__', _extra)
398 _object_setattr(m, '__pydantic_private__', None)
400 if cls.__pydantic_post_init__:
401 m.model_post_init(None)
402 # update private attributes with values set
403 if hasattr(m, '__pydantic_private__') and m.__pydantic_private__ is not None:
404 for k, v in values.items():
405 if k in m.__private_attributes__:
406 m.__pydantic_private__[k] = v
408 return m
410 def model_copy(self, *, update: Mapping[str, Any] | None = None, deep: bool = False) -> Self:
411 """!!! abstract "Usage Documentation"
412 [`model_copy`](../concepts/models.md#model-copy)
414 Returns a copy of the model.
416 !!! note
417 The underlying instance's [`__dict__`][object.__dict__] attribute is copied. This
418 might have unexpected side effects if you store anything in it, on top of the model
419 fields (e.g. the value of [cached properties][functools.cached_property]).
421 Args:
422 update: A mapping of values to update the copied model. Updates are *not*
423 applied recursively, and no validation is performed on updated values.
424 Only the known fields are updated (if unknown keys are being passed and
425 the model has [`extra`][pydantic.ConfigDict.extra] set to `'allow'`, they
426 are added as extra data).
427 deep: Whether a [deep copy][copy.deepcopy] of the model should be performed.
429 Returns:
430 New model instance.
431 """
432 if deep and update:
433 # Only deep copy the fields that won't be updated:
434 copied = self.__copy__()
436 # As we make separate `deepcopy()` calls, use a shared memo:
437 memo: dict[int, Any] = {}
439 # Selectively deepcopy fields that are not being updated:
440 for k, v in copied.__dict__.items():
441 if k not in update:
442 copied.__dict__[k] = deepcopy(v, memo) # pyright: ignore[reportIndexIssue] (https://github.com/microsoft/pyright/issues/11548)
443 if copied.__pydantic_extra__ is not None:
444 for k, v in copied.__pydantic_extra__.items():
445 if k not in update:
446 copied.__pydantic_extra__[k] = deepcopy(v, memo)
447 if copied.__pydantic_private__ is not None:
448 # Same logic as `BaseModel.__deepcopy__()`:
449 copied.__pydantic_private__ = deepcopy(
450 {k: v for k, v in copied.__pydantic_private__.items() if v is not PydanticUndefined},
451 memo,
452 )
453 else:
454 copied = self.__deepcopy__() if deep else self.__copy__()
456 if update:
457 if self.model_config.get('extra') == 'allow':
458 for k, v in update.items():
459 if k in self.__pydantic_fields__:
460 copied.__dict__[k] = v # pyright: ignore[reportIndexIssue] (https://github.com/microsoft/pyright/issues/11548)
461 else:
462 if copied.__pydantic_extra__ is None:
463 copied.__pydantic_extra__ = {}
464 copied.__pydantic_extra__[k] = v
465 else:
466 copied.__dict__.update(update) # pyright: ignore[reportAttributeAccessIssue] (https://github.com/microsoft/pyright/issues/11548)
468 copied.__pydantic_fields_set__.update(update.keys())
470 return copied
472 def model_dump(
473 self,
474 *,
475 mode: Literal['json', 'python'] | str = 'python',
476 include: IncEx | None = None,
477 exclude: IncEx | None = None,
478 context: Any | None = None,
479 by_alias: bool | None = None,
480 exclude_unset: bool = False,
481 exclude_defaults: bool = False,
482 exclude_none: bool = False,
483 exclude_computed_fields: bool = False,
484 round_trip: bool = False,
485 warnings: bool | Literal['none', 'warn', 'error'] = True,
486 fallback: Callable[[Any], Any] | None = None,
487 serialize_as_any: bool = False,
488 polymorphic_serialization: bool | None = None,
489 ) -> Dict[str, Any]: # noqa: UP006
490 """!!! abstract "Usage Documentation"
491 [`model_dump`](../concepts/serialization.md#python-mode)
493 Generate a dictionary representation of the model, optionally specifying which fields to include or exclude.
495 Args:
496 mode: The mode in which `to_python` should run.
497 If mode is 'json', the output will only contain JSON serializable types.
498 If mode is 'python', the output may contain non-JSON-serializable Python objects.
499 include: A set of fields to include in the output.
500 exclude: A set of fields to exclude from the output.
501 context: Additional context to pass to the serializer.
502 by_alias: Whether to use the field's alias in the dictionary key if defined.
503 exclude_unset: Whether to exclude fields that have not been explicitly set.
504 exclude_defaults: Whether to exclude fields that are set to their default value.
505 exclude_none: Whether to exclude fields that have a value of `None`.
506 exclude_computed_fields: Whether to exclude computed fields.
507 While this can be useful for round-tripping, it is usually recommended to use the dedicated
508 `round_trip` parameter instead.
509 round_trip: If True, dumped values should be valid as input for non-idempotent types such as Json[T].
510 warnings: How to handle serialization errors. False/"none" ignores them, True/"warn" logs errors,
511 "error" raises a [`PydanticSerializationError`][pydantic_core.PydanticSerializationError].
512 fallback: A function to call when an unknown value is encountered. If not provided,
513 a [`PydanticSerializationError`][pydantic_core.PydanticSerializationError] error is raised.
514 serialize_as_any: Whether to serialize fields with duck-typing serialization behavior.
515 polymorphic_serialization: Whether to use model and dataclass polymorphic serialization for this call.
517 Returns:
518 A dictionary representation of the model.
519 """
520 return self.__pydantic_serializer__.to_python(
521 self,
522 mode=mode,
523 by_alias=by_alias,
524 include=include,
525 exclude=exclude,
526 context=context,
527 exclude_unset=exclude_unset,
528 exclude_defaults=exclude_defaults,
529 exclude_none=exclude_none,
530 exclude_computed_fields=exclude_computed_fields,
531 round_trip=round_trip,
532 warnings=warnings,
533 fallback=fallback,
534 serialize_as_any=serialize_as_any,
535 polymorphic_serialization=polymorphic_serialization,
536 )
538 def model_dump_json(
539 self,
540 *,
541 indent: int | None = None,
542 ensure_ascii: bool = False,
543 include: IncEx | None = None,
544 exclude: IncEx | None = None,
545 context: Any | None = None,
546 by_alias: bool | None = None,
547 exclude_unset: bool = False,
548 exclude_defaults: bool = False,
549 exclude_none: bool = False,
550 exclude_computed_fields: bool = False,
551 round_trip: bool = False,
552 warnings: bool | Literal['none', 'warn', 'error'] = True,
553 fallback: Callable[[Any], Any] | None = None,
554 serialize_as_any: bool = False,
555 polymorphic_serialization: bool | None = None,
556 ) -> str:
557 """!!! abstract "Usage Documentation"
558 [`model_dump_json`](../concepts/serialization.md#json-mode)
560 Generates a JSON representation of the model using Pydantic's `to_json` method.
562 Args:
563 indent: Indentation to use in the JSON output. If None is passed, the output will be compact.
564 ensure_ascii: If `True`, the output is guaranteed to have all incoming non-ASCII characters escaped.
565 If `False` (the default), these characters will be output as-is.
566 include: Field(s) to include in the JSON output.
567 exclude: Field(s) to exclude from the JSON output.
568 context: Additional context to pass to the serializer.
569 by_alias: Whether to serialize using field aliases.
570 exclude_unset: Whether to exclude fields that have not been explicitly set.
571 exclude_defaults: Whether to exclude fields that are set to their default value.
572 exclude_none: Whether to exclude fields that have a value of `None`.
573 exclude_computed_fields: Whether to exclude computed fields.
574 While this can be useful for round-tripping, it is usually recommended to use the dedicated
575 `round_trip` parameter instead.
576 round_trip: If True, dumped values should be valid as input for non-idempotent types such as Json[T].
577 warnings: How to handle serialization errors. False/"none" ignores them, True/"warn" logs errors,
578 "error" raises a [`PydanticSerializationError`][pydantic_core.PydanticSerializationError].
579 fallback: A function to call when an unknown value is encountered. If not provided,
580 a [`PydanticSerializationError`][pydantic_core.PydanticSerializationError] error is raised.
581 serialize_as_any: Whether to serialize fields with duck-typing serialization behavior.
582 polymorphic_serialization: Whether to use model and dataclass polymorphic serialization for this call.
584 Returns:
585 A JSON string representation of the model.
586 """
587 return self.__pydantic_serializer__.to_json(
588 self,
589 indent=indent,
590 ensure_ascii=ensure_ascii,
591 include=include,
592 exclude=exclude,
593 context=context,
594 by_alias=by_alias,
595 exclude_unset=exclude_unset,
596 exclude_defaults=exclude_defaults,
597 exclude_none=exclude_none,
598 exclude_computed_fields=exclude_computed_fields,
599 round_trip=round_trip,
600 warnings=warnings,
601 fallback=fallback,
602 serialize_as_any=serialize_as_any,
603 polymorphic_serialization=polymorphic_serialization,
604 ).decode()
606 @classmethod
607 def model_json_schema(
608 cls,
609 by_alias: bool = True,
610 ref_template: str = DEFAULT_REF_TEMPLATE,
611 schema_generator: type[GenerateJsonSchema] = GenerateJsonSchema,
612 mode: JsonSchemaMode = 'validation',
613 *,
614 union_format: Literal['any_of', 'primitive_type_array'] = 'any_of',
615 ) -> Dict[str, Any]: # noqa: UP006
616 """Generates a JSON schema for a model class.
618 Args:
619 by_alias: Whether to use attribute aliases or not.
620 ref_template: The reference template.
621 union_format: The format to use when combining schemas from unions together. Can be one of:
623 - `'any_of'`: Use the [`anyOf`](https://json-schema.org/understanding-json-schema/reference/combining#anyOf)
624 keyword to combine schemas (the default).
625 - `'primitive_type_array'`: Use the [`type`](https://json-schema.org/understanding-json-schema/reference/type)
626 keyword as an array of strings, containing each type of the combination. If any of the schemas is not a primitive
627 type (`string`, `boolean`, `null`, `integer` or `number`) or contains constraints/metadata, falls back to
628 `any_of`.
629 schema_generator: To override the logic used to generate the JSON schema, as a subclass of
630 `GenerateJsonSchema` with your desired modifications
631 mode: The mode in which to generate the schema.
633 Returns:
634 The JSON schema for the given model class.
635 """
636 return model_json_schema(
637 cls,
638 by_alias=by_alias,
639 ref_template=ref_template,
640 union_format=union_format,
641 schema_generator=schema_generator,
642 mode=mode,
643 )
645 @classmethod
646 def model_parametrized_name(cls, params: tuple[TypeForm[Any], ...]) -> str:
647 """Compute the class name for parametrizations of generic classes.
649 This method can be overridden to achieve a custom naming scheme for generic BaseModels.
651 Args:
652 params: Tuple of types of the class. Given a generic class
653 `Model` with 2 type variables and a concrete model `Model[str, int]`,
654 the value `(str, int)` would be passed to `params`.
656 Returns:
657 String representing the new class where `params` are passed to `cls` as type variables.
659 Raises:
660 TypeError: Raised when trying to generate concrete names for non-generic models.
661 """
662 if not issubclass(cls, Generic):
663 raise TypeError('Concrete names should only be generated for generic models.')
665 # Any strings received should represent forward references, so we handle them specially below.
666 # If we eventually move toward wrapping them in a ForwardRef in __class_getitem__ in the future,
667 # we may be able to remove this special case.
668 param_names = [param if isinstance(param, str) else _repr.display_as_type(param) for param in params]
669 params_component = ', '.join(param_names)
670 return f'{cls.__name__}[{params_component}]'
672 def model_post_init(self, context: Any, /) -> None:
673 """Override this method to perform additional initialization after `__init__` and `model_construct`.
674 This is useful if you want to do some validation that requires the entire model to be initialized.
675 """
677 @classmethod
678 def model_rebuild(
679 cls,
680 *,
681 force: bool = False,
682 raise_errors: bool = True,
683 _parent_namespace_depth: int = 2,
684 _types_namespace: MappingNamespace | None = None,
685 ) -> bool | None:
686 """Try to rebuild the pydantic-core schema for the model.
688 This may be necessary when one of the annotations is a ForwardRef which could not be resolved during
689 the initial attempt to build the schema, and automatic rebuilding fails.
691 Args:
692 force: Whether to force the rebuilding of the model schema, defaults to `False`.
693 raise_errors: Whether to raise errors, defaults to `True`.
694 _parent_namespace_depth: The depth level of the parent namespace, defaults to 2.
695 _types_namespace: The types namespace, defaults to `None`.
697 Returns:
698 Returns `None` if the schema is already "complete" and rebuilding was not required.
699 If rebuilding _was_ required, returns `True` if rebuilding was successful, otherwise `False`.
700 """
701 # As the rebuild lock is global (not per model class), avoid needlessly holding it if the model is
702 # already complete:
703 if cls.__pydantic_complete__ and not force:
704 return None
706 with _rebuild_lock:
707 # Re-check inside the lock, as another thread may have rebuilt the model while we were waiting:
708 already_complete = cls.__pydantic_complete__
709 if already_complete and not force:
710 return None
712 cls.__pydantic_complete__ = False
714 if already_complete:
715 # The existing validator/serializer must not be reused in pydantic-core, and the core schema
716 # must not be reused in schema generation. If the model is already complete (i.e. `force=True`),
717 # we set back mocks for the model (we could also delete the complete core schema/validator/serializer,
718 # but this isn't thread-safe).
719 _mock_val_ser.set_model_mocks(cls)
721 if _types_namespace is not None:
722 rebuild_ns = _types_namespace
723 elif _parent_namespace_depth > 0:
724 rebuild_ns = (
725 _typing_extra.parent_frame_namespace(parent_depth=_parent_namespace_depth, force=True) or {}
726 )
727 else:
728 rebuild_ns = {}
730 parent_ns = _model_construction.unpack_lenient_weakvaluedict(cls.__pydantic_parent_namespace__) or {}
732 ns_resolver = _namespace_utils.NsResolver(
733 parent_namespace={**rebuild_ns, **parent_ns},
734 )
736 return _model_construction.complete_model_class(
737 cls,
738 _config.ConfigWrapper(cls.model_config, check=False),
739 ns_resolver,
740 raise_errors=raise_errors,
741 # If the model was already complete, we don't need to call the hook again.
742 call_on_complete_hook=not already_complete,
743 is_force_rebuild=force,
744 )
746 @classmethod
747 def model_validate(
748 cls,
749 obj: Any,
750 *,
751 strict: bool | None = None,
752 extra: ExtraValues | None = None,
753 from_attributes: bool | None = None,
754 context: Any | None = None,
755 by_alias: bool | None = None,
756 by_name: bool | None = None,
757 ) -> Self:
758 """Validate a pydantic model instance.
760 If validation fails, the resulting [`ValidationError`][pydantic_core.ValidationError] reports the
761 rejected locations and values. [Logfire](../integrations/logfire.md) can retain the complete validation
762 input and surrounding trace context for production debugging (see
763 [Troubleshooting validation errors](../errors/troubleshooting.md)).
765 Args:
766 obj: The object to validate.
767 strict: Whether to enforce types strictly.
768 extra: Whether to ignore, allow, or forbid extra data during model validation.
769 See the [`extra` configuration value][pydantic.ConfigDict.extra] for details.
770 from_attributes: Whether to extract data from object attributes.
771 context: Additional context to pass to the validator.
772 by_alias: Whether to use the field's alias when validating against the provided input data.
773 by_name: Whether to use the field's name when validating against the provided input data.
775 Raises:
776 ValidationError: If the object could not be validated.
778 Returns:
779 The validated model instance.
780 """
781 # `__tracebackhide__` tells pytest and some other tools to omit this function from tracebacks
782 __tracebackhide__ = True
784 if by_alias is False and by_name is not True:
785 raise PydanticUserError(
786 'At least one of `by_alias` or `by_name` must be set to True.',
787 code='validate-by-alias-and-name-false',
788 )
790 return cls.__pydantic_validator__.validate_python(
791 obj,
792 strict=strict,
793 extra=extra,
794 from_attributes=from_attributes,
795 context=context,
796 by_alias=by_alias,
797 by_name=by_name,
798 )
800 @classmethod
801 def model_validate_json(
802 cls,
803 json_data: str | bytes | bytearray,
804 *,
805 strict: bool | None = None,
806 extra: ExtraValues | None = None,
807 context: Any | None = None,
808 by_alias: bool | None = None,
809 by_name: bool | None = None,
810 ) -> Self:
811 """!!! abstract "Usage Documentation"
812 [JSON Parsing](../concepts/json.md#json-parsing)
814 Validate the given JSON data against the Pydantic model.
816 A [`ValidationError`][pydantic_core.ValidationError] raised here reports the rejected locations and
817 values, but may not retain the complete source document. Recording validations with
818 [Logfire](../integrations/logfire.md) keeps the complete JSON input alongside the error — see
819 [Troubleshooting validation errors](../errors/troubleshooting.md).
821 Args:
822 json_data: The JSON data to validate.
823 strict: Whether to enforce types strictly.
824 extra: Whether to ignore, allow, or forbid extra data during model validation.
825 See the [`extra` configuration value][pydantic.ConfigDict.extra] for details.
826 context: Extra variables to pass to the validator.
827 by_alias: Whether to use the field's alias when validating against the provided input data.
828 by_name: Whether to use the field's name when validating against the provided input data.
830 Returns:
831 The validated Pydantic model.
833 Raises:
834 ValidationError: If `json_data` is not a JSON string or the object could not be validated.
835 """
836 # `__tracebackhide__` tells pytest and some other tools to omit this function from tracebacks
837 __tracebackhide__ = True
839 if by_alias is False and by_name is not True:
840 raise PydanticUserError(
841 'At least one of `by_alias` or `by_name` must be set to True.',
842 code='validate-by-alias-and-name-false',
843 )
845 return cls.__pydantic_validator__.validate_json(
846 json_data, strict=strict, extra=extra, context=context, by_alias=by_alias, by_name=by_name
847 )
849 @classmethod
850 def model_validate_strings(
851 cls,
852 obj: Any,
853 *,
854 strict: bool | None = None,
855 extra: ExtraValues | None = None,
856 context: Any | None = None,
857 by_alias: bool | None = None,
858 by_name: bool | None = None,
859 ) -> Self:
860 """Validate the given object with string data against the Pydantic model.
862 Args:
863 obj: The object containing string data to validate.
864 strict: Whether to enforce types strictly.
865 extra: Whether to ignore, allow, or forbid extra data during model validation.
866 See the [`extra` configuration value][pydantic.ConfigDict.extra] for details.
867 context: Extra variables to pass to the validator.
868 by_alias: Whether to use the field's alias when validating against the provided input data.
869 by_name: Whether to use the field's name when validating against the provided input data.
871 Returns:
872 The validated Pydantic model.
873 """
874 # `__tracebackhide__` tells pytest and some other tools to omit this function from tracebacks
875 __tracebackhide__ = True
877 if by_alias is False and by_name is not True:
878 raise PydanticUserError(
879 'At least one of `by_alias` or `by_name` must be set to True.',
880 code='validate-by-alias-and-name-false',
881 )
883 return cls.__pydantic_validator__.validate_strings(
884 obj, strict=strict, extra=extra, context=context, by_alias=by_alias, by_name=by_name
885 )
887 @classmethod
888 def __get_pydantic_core_schema__(cls, source: type[BaseModel], handler: GetCoreSchemaHandler, /) -> CoreSchema:
889 # This warning is only emitted when calling `super().__get_pydantic_core_schema__` from a model subclass.
890 # In the generate schema logic, this method (`BaseModel.__get_pydantic_core_schema__`) is special cased to
891 # *not* be called if not overridden.
892 warnings.warn(
893 'The `__get_pydantic_core_schema__` method of the `BaseModel` class is deprecated. If you are calling '
894 '`super().__get_pydantic_core_schema__` when overriding the method on a Pydantic model, consider using '
895 '`handler(source)` instead. However, note that overriding this method on models can lead to unexpected '
896 'side effects.',
897 PydanticDeprecatedSince211,
898 stacklevel=2,
899 )
900 # Logic copied over from `GenerateSchema._model_schema`:
901 schema = cls.__dict__.get('__pydantic_core_schema__')
902 if schema is not None and not isinstance(schema, _mock_val_ser.MockCoreSchema):
903 return cls.__pydantic_core_schema__
905 return handler(source)
907 @classmethod
908 def __get_pydantic_json_schema__(
909 cls,
910 core_schema: CoreSchema,
911 handler: GetJsonSchemaHandler,
912 /,
913 ) -> JsonSchemaValue:
914 """Hook into generating the model's JSON schema.
916 Args:
917 core_schema: A `pydantic-core` CoreSchema.
918 You can ignore this argument and call the handler with a new CoreSchema,
919 wrap this CoreSchema (`{'type': 'nullable', 'schema': current_schema}`),
920 or just call the handler with the original schema.
921 handler: Call into Pydantic's internal JSON schema generation.
922 This will raise a `pydantic.errors.PydanticInvalidForJsonSchema` if JSON schema
923 generation fails.
924 Since this gets called by `BaseModel.model_json_schema` you can override the
925 `schema_generator` argument to that function to change JSON schema generation globally
926 for a type.
928 Returns:
929 A JSON schema, as a Python object.
930 """
931 return handler(core_schema)
933 @classmethod
934 def __pydantic_init_subclass__(cls, **kwargs: Any) -> None:
935 """This is intended to behave just like `__init_subclass__`, but is called by `ModelMetaclass`
936 only after basic class initialization is complete. In particular, attributes like `model_fields` will
937 be present when this is called, but forward annotations are not guaranteed to be resolved yet,
938 meaning that creating an instance of the class may fail.
940 This is necessary because `__init_subclass__` will always be called by `type.__new__`,
941 and it would require a prohibitively large refactor to the `ModelMetaclass` to ensure that
942 `type.__new__` was called in such a manner that the class would already be sufficiently initialized.
944 This will receive the same `kwargs` that would be passed to the standard `__init_subclass__`, namely,
945 any kwargs passed to the class definition that aren't used internally by Pydantic.
947 Args:
948 **kwargs: Any keyword arguments passed to the class definition that aren't used internally
949 by Pydantic.
951 Note:
952 You may want to override [`__pydantic_on_complete__()`][pydantic.main.BaseModel.__pydantic_on_complete__]
953 instead, which is called once the class and its fields are fully initialized and ready for validation.
954 """
956 @classmethod
957 def __pydantic_on_complete__(cls) -> None:
958 """This is called once the class and its fields are fully initialized and ready to be used.
960 This typically happens when the class is created (just before
961 [`__pydantic_init_subclass__()`][pydantic.main.BaseModel.__pydantic_init_subclass__] is called on the superclass),
962 except when forward annotations are used that could not immediately be resolved.
963 In that case, it will be called later, when the model is rebuilt automatically or explicitly using
964 [`model_rebuild()`][pydantic.main.BaseModel.model_rebuild].
965 """
967 def __class_getitem__(
968 cls, typevar_values: TypeForm[Any] | tuple[TypeForm[Any], ...]
969 ) -> type[BaseModel] | _forward_ref.PydanticRecursiveRef:
970 cached = _generics.get_cached_generic_type_early(cls, typevar_values)
971 if cached is not None:
972 return cached
974 if cls is BaseModel:
975 raise TypeError('Type parameters should be placed on typing.Generic, not BaseModel')
976 if not hasattr(cls, '__parameters__'):
977 raise TypeError(f'{cls} cannot be parametrized because it does not inherit from typing.Generic')
978 if not cls.__pydantic_generic_metadata__['parameters'] and Generic not in cls.__bases__:
979 raise TypeError(f'{cls} is not a generic class')
981 if not isinstance(typevar_values, tuple):
982 typevar_values = (typevar_values,)
984 # For a model `class Model[T, U, V = int](BaseModel): ...` parametrized with `(str, bool)`,
985 # this gives us `{T: str, U: bool, V: int}`:
986 typevars_map = _generics.map_generic_model_arguments(cls, typevar_values)
987 # We also update the provided args to use defaults values (`(str, bool)` becomes `(str, bool, int)`):
988 typevar_values = tuple(v for v in typevars_map.values())
990 if _utils.all_identical(typevars_map.keys(), typevars_map.values()) and typevars_map:
991 submodel = cls # if arguments are equal to parameters it's the same object
992 _generics.set_cached_generic_type(cls, typevar_values, submodel)
993 else:
994 parent_args = cls.__pydantic_generic_metadata__['args']
995 if not parent_args:
996 args = typevar_values
997 else:
998 args = tuple(_generics.replace_types(arg, typevars_map) for arg in parent_args)
1000 origin = cls.__pydantic_generic_metadata__['origin'] or cls
1001 model_name = origin.model_parametrized_name(args)
1002 params = tuple(
1003 dict.fromkeys(_generics.iter_contained_typevars(typevars_map.values()))
1004 ) # use dict as ordered set
1006 with _generics.generic_recursion_self_type(origin, args) as maybe_self_type:
1007 cached = _generics.get_cached_generic_type_late(cls, typevar_values, origin, args)
1008 if cached is not None:
1009 return cached
1011 if maybe_self_type is not None:
1012 return maybe_self_type
1014 # Attempt to rebuild the origin in case new types have been defined
1015 try:
1016 # depth 2 gets you above this __class_getitem__ call.
1017 # Note that we explicitly provide the parent ns, otherwise
1018 # `model_rebuild` will use the parent ns no matter if it is the ns of a module.
1019 # We don't want this here, as this has unexpected effects when a model
1020 # is being parametrized during a forward annotation evaluation.
1021 parent_ns = _typing_extra.parent_frame_namespace(parent_depth=2) or {}
1022 origin.model_rebuild(_types_namespace=parent_ns)
1023 except PydanticUndefinedAnnotation:
1024 # It's okay if it fails, it just means there are still undefined types
1025 # that could be evaluated later.
1026 pass
1028 submodel = _generics.create_generic_submodel(model_name, origin, args, params)
1030 _generics.set_cached_generic_type(cls, typevar_values, submodel, origin, args)
1032 return submodel
1034 def __copy__(self) -> Self:
1035 """Returns a shallow copy of the model."""
1036 cls = type(self)
1037 m = cls.__new__(cls)
1038 _object_setattr(m, '__dict__', copy(self.__dict__))
1039 _object_setattr(m, '__pydantic_extra__', copy(self.__pydantic_extra__))
1040 _object_setattr(m, '__pydantic_fields_set__', copy(self.__pydantic_fields_set__))
1042 if not hasattr(self, '__pydantic_private__') or self.__pydantic_private__ is None:
1043 _object_setattr(m, '__pydantic_private__', None)
1044 else:
1045 _object_setattr(
1046 m,
1047 '__pydantic_private__',
1048 {k: v for k, v in self.__pydantic_private__.items() if v is not PydanticUndefined},
1049 )
1051 return m
1053 def __deepcopy__(self, memo: Dict[int, Any] | None = None) -> Self: # noqa: UP006
1054 """Returns a deep copy of the model."""
1055 cls = type(self)
1056 m = cls.__new__(cls)
1057 _object_setattr(m, '__dict__', deepcopy(self.__dict__, memo=memo))
1058 _object_setattr(m, '__pydantic_extra__', deepcopy(self.__pydantic_extra__, memo=memo))
1059 # This next line doesn't need a deepcopy because __pydantic_fields_set__ is a set[str],
1060 # and attempting a deepcopy would be marginally slower.
1061 _object_setattr(m, '__pydantic_fields_set__', copy(self.__pydantic_fields_set__))
1063 if not hasattr(self, '__pydantic_private__') or self.__pydantic_private__ is None:
1064 _object_setattr(m, '__pydantic_private__', None)
1065 else:
1066 _object_setattr(
1067 m,
1068 '__pydantic_private__',
1069 deepcopy({k: v for k, v in self.__pydantic_private__.items() if v is not PydanticUndefined}, memo=memo),
1070 )
1072 return m
1074 if not TYPE_CHECKING:
1075 # We put `__getattr__` in a non-TYPE_CHECKING block because otherwise, mypy allows arbitrary attribute access
1076 # The same goes for __setattr__ and __delattr__, see: https://github.com/pydantic/pydantic/issues/8643
1078 def __getattr__(self, item: str) -> Any:
1079 private_attributes = object.__getattribute__(self, '__private_attributes__')
1080 if item in private_attributes:
1081 attribute = private_attributes[item]
1082 if hasattr(attribute, '__get__'):
1083 return attribute.__get__(self, type(self)) # type: ignore
1085 try:
1086 # Note: self.__pydantic_private__ cannot be None if self.__private_attributes__ has items
1087 return self.__pydantic_private__[item] # type: ignore
1088 except KeyError as exc:
1089 raise AttributeError(f'{type(self).__name__!r} object has no attribute {item!r}') from exc
1090 else:
1091 # `__pydantic_extra__` can fail to be set if the model is not yet fully initialized.
1092 # See `BaseModel.__repr_args__` for more details
1093 try:
1094 pydantic_extra = object.__getattribute__(self, '__pydantic_extra__')
1095 except AttributeError:
1096 pydantic_extra = None
1098 if pydantic_extra and item in pydantic_extra:
1099 return pydantic_extra[item]
1100 else:
1101 if hasattr(self.__class__, item):
1102 return super().__getattribute__(item) # Raises AttributeError if appropriate
1103 else:
1104 # this is the current error
1105 raise AttributeError(f'{type(self).__name__!r} object has no attribute {item!r}')
1107 def __setattr__(self, name: str, value: Any) -> None:
1108 if (setattr_handler := self.__pydantic_setattr_handlers__.get(name)) is not None:
1109 setattr_handler(self, name, value)
1110 # if None is returned from _setattr_handler, the attribute was set directly
1111 elif (setattr_handler := self._setattr_handler(name, value)) is not None:
1112 setattr_handler(self, name, value) # call here to not memo on possibly unknown fields
1113 self.__pydantic_setattr_handlers__[name] = setattr_handler # memoize the handler for faster access
1115 def _setattr_handler(self, name: str, value: Any) -> Callable[[BaseModel, str, Any], None] | None:
1116 """Get a handler for setting an attribute on the model instance.
1118 Returns:
1119 A handler for setting an attribute on the model instance. Used for memoization of the handler.
1120 Memoizing the handlers leads to a dramatic performance improvement in `__setattr__`
1121 Returns `None` when memoization is not safe, then the attribute is set directly.
1122 """
1123 cls = self.__class__
1124 if name in cls.__class_vars__:
1125 raise AttributeError(
1126 f'{name!r} is a ClassVar of `{cls.__name__}` and cannot be set on an instance. '
1127 f'If you want to set a value on the class, use `{cls.__name__}.{name} = value`.'
1128 )
1129 elif not _fields.is_valid_field_name(name):
1130 if (attribute := cls.__private_attributes__.get(name)) is not None:
1131 if hasattr(attribute, '__set__'):
1132 return lambda model, _name, val: attribute.__set__(model, val)
1133 else:
1134 return _SIMPLE_SETATTR_HANDLERS['private']
1135 else:
1136 _object_setattr(self, name, value)
1137 return None # Can not return memoized handler with possibly freeform attr names
1139 attr = getattr(cls, name, _ATTRIBUTE_MISSING)
1140 # NOTE: We currently special case properties and `cached_property`, but we might need
1141 # to generalize this to all data/non-data descriptors at some point. For non-data descriptors
1142 # (such as `cached_property`), it isn't obvious though. `cached_property` caches the value
1143 # to the instance's `__dict__`, but other non-data descriptors might do things differently.
1144 if isinstance(attr, cached_property):
1145 return _SIMPLE_SETATTR_HANDLERS['cached_property']
1147 _check_frozen(cls, name, value)
1149 # We allow properties to be set only on non frozen models for now (to match dataclasses).
1150 # This can be changed if it ever gets requested.
1151 if isinstance(attr, property):
1152 return lambda model, _name, val: attr.__set__(model, val)
1153 elif cls.model_config.get('validate_assignment'):
1154 return _SIMPLE_SETATTR_HANDLERS['validate_assignment']
1155 elif name not in cls.__pydantic_fields__:
1156 if cls.model_config.get('extra') != 'allow':
1157 # TODO - matching error
1158 raise ValueError(f'"{cls.__name__}" object has no field "{name}"')
1159 elif attr is _ATTRIBUTE_MISSING:
1160 # attribute does not exist, so put it in extra
1161 self.__pydantic_extra__[name] = value
1162 self.__pydantic_fields_set__.add(name)
1163 return None # Can not return memoized handler with possibly freeform attr names
1164 else:
1165 # attribute _does_ exist, and was not in extra, so update it
1166 return _SIMPLE_SETATTR_HANDLERS['extra_known']
1167 else:
1168 return _SIMPLE_SETATTR_HANDLERS['model_field']
1170 def __delattr__(self, item: str) -> Any:
1171 cls = self.__class__
1173 if item in self.__private_attributes__:
1174 attribute = self.__private_attributes__[item]
1175 if hasattr(attribute, '__delete__'):
1176 attribute.__delete__(self) # type: ignore
1177 return
1179 try:
1180 # Note: self.__pydantic_private__ cannot be None if self.__private_attributes__ has items
1181 del self.__pydantic_private__[item] # type: ignore
1182 return
1183 except KeyError as exc:
1184 raise AttributeError(f'{cls.__name__!r} object has no attribute {item!r}') from exc
1186 # Allow cached properties to be deleted (even if the class is frozen):
1187 attr = getattr(cls, item, None)
1188 if isinstance(attr, cached_property):
1189 return object.__delattr__(self, item)
1191 _check_frozen(cls, name=item, value=None)
1193 if item in self.__pydantic_fields__:
1194 object.__delattr__(self, item)
1195 elif self.__pydantic_extra__ is not None and item in self.__pydantic_extra__:
1196 del self.__pydantic_extra__[item]
1197 else:
1198 try:
1199 object.__delattr__(self, item)
1200 except AttributeError:
1201 raise AttributeError(f'{type(self).__name__!r} object has no attribute {item!r}')
1203 # Because we make use of `@dataclass_transform()`, `__replace__` is already synthesized by
1204 # type checkers, so we define the implementation in this `if not TYPE_CHECKING:` block:
1205 def __replace__(self, **changes: Any) -> Self:
1206 return self.model_copy(update=changes)
1208 def __getstate__(self) -> Dict[Any, Any]: # noqa: UP006
1209 private = self.__pydantic_private__
1210 if private:
1211 private = {k: v for k, v in private.items() if v is not PydanticUndefined}
1212 return {
1213 '__dict__': self.__dict__,
1214 '__pydantic_extra__': self.__pydantic_extra__,
1215 '__pydantic_fields_set__': self.__pydantic_fields_set__,
1216 '__pydantic_private__': private,
1217 }
1219 def __setstate__(self, state: Dict[Any, Any]) -> None: # noqa: UP006
1220 _object_setattr(self, '__pydantic_fields_set__', state.get('__pydantic_fields_set__', {}))
1221 _object_setattr(self, '__pydantic_extra__', state.get('__pydantic_extra__', {}))
1222 _object_setattr(self, '__pydantic_private__', state.get('__pydantic_private__', {}))
1223 _object_setattr(self, '__dict__', state.get('__dict__', {}))
1225 if not TYPE_CHECKING:
1227 def __eq__(self, other: Any) -> bool:
1228 if isinstance(other, BaseModel):
1229 # When comparing instances of generic types for equality, as long as all field values are equal,
1230 # only require their generic origin types to be equal, rather than exact type equality.
1231 # This prevents headaches like MyGeneric(x=1) != MyGeneric[Any](x=1).
1232 self_type = self.__pydantic_generic_metadata__['origin'] or self.__class__
1233 other_type = other.__pydantic_generic_metadata__['origin'] or other.__class__
1235 # Perform common checks first
1236 if not (
1237 self_type is other_type
1238 and getattr(self, '__pydantic_private__', None) == getattr(other, '__pydantic_private__', None)
1239 # We need to assume `None` and `{}` are equivalent, because extra behavior
1240 # can be controlled at validation time:
1241 and (self.__pydantic_extra__ or {}) == (other.__pydantic_extra__ or {})
1242 ):
1243 return False
1245 # We only want to compare pydantic fields but ignoring fields is costly.
1246 # We'll perform a fast check first, and fallback only when needed
1247 # See GH-7444 and GH-7825 for rationale and a performance benchmark
1249 # First, do the fast (and sometimes faulty) __dict__ comparison
1250 if self.__dict__ == other.__dict__:
1251 # If the check above passes, then pydantic fields are equal, we can return early
1252 return True
1254 # We don't want to trigger unnecessary costly filtering of __dict__ on all unequal objects, so we return
1255 # early if there are no keys to ignore (we would just return False later on anyway)
1256 model_fields = type(self).__pydantic_fields__.keys()
1257 if self.__dict__.keys() <= model_fields and other.__dict__.keys() <= model_fields:
1258 return False
1260 # If we reach here, there are non-pydantic-fields keys, mapped to unequal values, that we need to ignore
1261 # Resort to costly filtering of the __dict__ objects
1262 # We use operator.itemgetter because it is much faster than dict comprehensions
1263 # NOTE: Contrary to standard python class and instances, when the Model class has a default value for an
1264 # attribute and the model instance doesn't have a corresponding attribute, accessing the missing attribute
1265 # raises an error in BaseModel.__getattr__ instead of returning the class attribute
1266 # So we can use operator.itemgetter() instead of operator.attrgetter()
1267 getter = operator.itemgetter(*model_fields) if model_fields else lambda _: _utils._SENTINEL
1268 try:
1269 return getter(self.__dict__) == getter(other.__dict__)
1270 except KeyError:
1271 # In rare cases (such as when using the deprecated BaseModel.copy() method),
1272 # the __dict__ may not contain all model fields, which is how we can get here.
1273 # getter(self.__dict__) is much faster than any 'safe' method that accounts
1274 # for missing keys, and wrapping it in a `try` doesn't slow things down much
1275 # in the common case.
1276 self_fields_proxy = _utils.SafeGetItemProxy(self.__dict__)
1277 other_fields_proxy = _utils.SafeGetItemProxy(other.__dict__)
1278 return getter(self_fields_proxy) == getter(other_fields_proxy)
1280 # other instance is not a BaseModel
1281 else:
1282 return NotImplemented # delegate to the other item in the comparison
1284 if TYPE_CHECKING:
1285 # We put `__init_subclass__` in a TYPE_CHECKING block because, even though we want the type-checking benefits
1286 # described in the signature of `__init_subclass__` below, we don't want to modify the default behavior of
1287 # subclass initialization.
1289 def __init_subclass__(cls, **kwargs: Unpack[ConfigDict]):
1290 """This signature is included purely to help type-checkers check arguments to class declaration, which
1291 provides a way to conveniently set model_config key/value pairs.
1293 ```python
1294 from pydantic import BaseModel
1296 class MyModel(BaseModel, extra='allow'): ...
1297 ```
1299 However, this may be deceiving, since the _actual_ calls to `__init_subclass__` will not receive any
1300 of the config arguments, and will only receive any keyword arguments passed during class initialization
1301 that are _not_ expected keys in ConfigDict. (This is due to the way `ModelMetaclass.__new__` works.)
1303 Args:
1304 **kwargs: Keyword arguments passed to the class definition, which set model_config
1306 Note:
1307 You may want to override `__pydantic_init_subclass__` instead, which behaves similarly but is called
1308 *after* the class is fully initialized.
1309 """
1311 def __iter__(self) -> TupleGenerator:
1312 """So `dict(model)` works."""
1313 yield from [(k, v) for (k, v) in self.__dict__.items() if not k.startswith('_')]
1314 extra = self.__pydantic_extra__
1315 if extra:
1316 yield from extra.items()
1318 def __repr__(self) -> str:
1319 return f'{self.__repr_name__()}({self.__repr_str__(", ")})'
1321 def __repr_args__(self) -> _repr.ReprArgs:
1322 # Eagerly create the repr of computed fields, as this may trigger access of cached properties and as such
1323 # modify the instance's `__dict__`. If we don't do it now, it could happen when iterating over the `__dict__`
1324 # below if the instance happens to be referenced in a field, and would modify the `__dict__` size *during* iteration.
1325 computed_fields_repr_args = [
1326 (k, getattr(self, k)) for k, v in self.__pydantic_computed_fields__.items() if v.repr
1327 ]
1329 for k, v in self.__dict__.items():
1330 field = self.__pydantic_fields__.get(k)
1331 if field and field.repr:
1332 if v is not self:
1333 yield k, v
1334 else:
1335 yield k, self.__repr_recursion__(v)
1336 # `__pydantic_extra__` can fail to be set if the model is not yet fully initialized.
1337 # This can happen if a `ValidationError` is raised during initialization and the instance's
1338 # repr is generated as part of the exception handling. Therefore, we use `getattr` here
1339 # with a fallback, even though the type hints indicate the attribute will always be present.
1340 try:
1341 pydantic_extra = object.__getattribute__(self, '__pydantic_extra__')
1342 except AttributeError:
1343 pydantic_extra = None
1345 if pydantic_extra is not None:
1346 yield from ((k, v) for k, v in pydantic_extra.items())
1347 yield from computed_fields_repr_args
1349 # take logic from `_repr.Representation` without the side effects of inheritance, see #5740
1350 __repr_name__ = _repr.Representation.__repr_name__
1351 __repr_recursion__ = _repr.Representation.__repr_recursion__
1352 __repr_str__ = _repr.Representation.__repr_str__
1353 __pretty__ = _repr.Representation.__pretty__
1354 __rich_repr__ = _repr.Representation.__rich_repr__
1356 def __str__(self) -> str:
1357 return self.__repr_str__(' ')
1359 # ##### Deprecated methods from v1 #####
1360 @property
1361 @typing_extensions.deprecated(
1362 'The `__fields__` attribute is deprecated, use the `model_fields` class property instead.', category=None
1363 )
1364 def __fields__(self) -> Dict[str, FieldInfo]: # noqa: UP006
1365 warnings.warn(
1366 'The `__fields__` attribute is deprecated, use the `model_fields` class property instead.',
1367 category=PydanticDeprecatedSince20,
1368 stacklevel=2,
1369 )
1370 return getattr(type(self), '__pydantic_fields__', {})
1372 @property
1373 @typing_extensions.deprecated(
1374 'The `__fields_set__` attribute is deprecated, use `model_fields_set` instead.',
1375 category=None,
1376 )
1377 def __fields_set__(self) -> set[str]:
1378 warnings.warn(
1379 'The `__fields_set__` attribute is deprecated, use `model_fields_set` instead.',
1380 category=PydanticDeprecatedSince20,
1381 stacklevel=2,
1382 )
1383 return self.__pydantic_fields_set__
1385 @typing_extensions.deprecated('The `dict` method is deprecated; use `model_dump` instead.', category=None)
1386 def dict( # noqa: D102
1387 self,
1388 *,
1389 include: IncEx | None = None,
1390 exclude: IncEx | None = None,
1391 by_alias: bool = False,
1392 exclude_unset: bool = False,
1393 exclude_defaults: bool = False,
1394 exclude_none: bool = False,
1395 ) -> Dict[str, Any]: # noqa UP006
1396 warnings.warn(
1397 'The `dict` method is deprecated; use `model_dump` instead.',
1398 category=PydanticDeprecatedSince20,
1399 stacklevel=2,
1400 )
1401 return self.model_dump(
1402 include=include,
1403 exclude=exclude,
1404 by_alias=by_alias,
1405 exclude_unset=exclude_unset,
1406 exclude_defaults=exclude_defaults,
1407 exclude_none=exclude_none,
1408 )
1410 @typing_extensions.deprecated('The `json` method is deprecated; use `model_dump_json` instead.', category=None)
1411 def json( # noqa: D102
1412 self,
1413 *,
1414 include: IncEx | None = None,
1415 exclude: IncEx | None = None,
1416 by_alias: bool = False,
1417 exclude_unset: bool = False,
1418 exclude_defaults: bool = False,
1419 exclude_none: bool = False,
1420 encoder: Callable[[Any], Any] | None = PydanticUndefined, # type: ignore[assignment]
1421 models_as_dict: bool = PydanticUndefined, # type: ignore[assignment]
1422 **dumps_kwargs: Any,
1423 ) -> str:
1424 warnings.warn(
1425 'The `json` method is deprecated; use `model_dump_json` instead.',
1426 category=PydanticDeprecatedSince20,
1427 stacklevel=2,
1428 )
1429 if encoder is not PydanticUndefined:
1430 raise TypeError('The `encoder` argument is no longer supported; use field serializers instead.')
1431 if models_as_dict is not PydanticUndefined:
1432 raise TypeError('The `models_as_dict` argument is no longer supported; use a model serializer instead.')
1433 if dumps_kwargs:
1434 raise TypeError('`dumps_kwargs` keyword arguments are no longer supported.')
1435 return self.model_dump_json(
1436 include=include,
1437 exclude=exclude,
1438 by_alias=by_alias,
1439 exclude_unset=exclude_unset,
1440 exclude_defaults=exclude_defaults,
1441 exclude_none=exclude_none,
1442 )
1444 @classmethod
1445 @typing_extensions.deprecated('The `parse_obj` method is deprecated; use `model_validate` instead.', category=None)
1446 def parse_obj(cls, obj: Any) -> Self: # noqa: D102
1447 warnings.warn(
1448 'The `parse_obj` method is deprecated; use `model_validate` instead.',
1449 category=PydanticDeprecatedSince20,
1450 stacklevel=2,
1451 )
1452 return cls.model_validate(obj)
1454 @classmethod
1455 @typing_extensions.deprecated(
1456 'The `parse_raw` method is deprecated; if your data is JSON use `model_validate_json`, '
1457 'otherwise load the data then use `model_validate` instead.',
1458 category=None,
1459 )
1460 def parse_raw( # noqa: D102
1461 cls,
1462 b: str | bytes,
1463 *,
1464 content_type: str | None = None,
1465 encoding: str = 'utf8',
1466 proto: DeprecatedParseProtocol | None = None,
1467 allow_pickle: bool = False,
1468 ) -> Self: # pragma: no cover
1469 warnings.warn(
1470 'The `parse_raw` method is deprecated; if your data is JSON use `model_validate_json`, '
1471 'otherwise load the data then use `model_validate` instead.',
1472 category=PydanticDeprecatedSince20,
1473 stacklevel=2,
1474 )
1475 from .deprecated import parse
1477 try:
1478 obj = parse.load_str_bytes(
1479 b,
1480 proto=proto,
1481 content_type=content_type,
1482 encoding=encoding,
1483 allow_pickle=allow_pickle,
1484 )
1485 except (ValueError, TypeError) as exc:
1486 import json
1488 # try to match V1
1489 if isinstance(exc, UnicodeDecodeError):
1490 type_str = 'value_error.unicodedecode'
1491 elif isinstance(exc, json.JSONDecodeError):
1492 type_str = 'value_error.jsondecode'
1493 elif isinstance(exc, ValueError):
1494 type_str = 'value_error'
1495 else:
1496 type_str = 'type_error'
1498 # ctx is missing here, but since we've added `input` to the error, we're not pretending it's the same
1499 error: pydantic_core.InitErrorDetails = {
1500 # The type: ignore on the next line is to ignore the requirement of LiteralString
1501 'type': pydantic_core.PydanticCustomError(type_str, str(exc)), # type: ignore
1502 'loc': ('__root__',),
1503 'input': b,
1504 }
1505 raise pydantic_core.ValidationError.from_exception_data(cls.__name__, [error])
1506 return cls.model_validate(obj)
1508 @classmethod
1509 @typing_extensions.deprecated(
1510 'The `parse_file` method is deprecated; load the data from file, then if your data is JSON '
1511 'use `model_validate_json`, otherwise `model_validate` instead.',
1512 category=None,
1513 )
1514 def parse_file( # noqa: D102
1515 cls,
1516 path: str | Path,
1517 *,
1518 content_type: str | None = None,
1519 encoding: str = 'utf8',
1520 proto: DeprecatedParseProtocol | None = None,
1521 allow_pickle: bool = False,
1522 ) -> Self:
1523 warnings.warn(
1524 'The `parse_file` method is deprecated; load the data from file, then if your data is JSON '
1525 'use `model_validate_json`, otherwise `model_validate` instead.',
1526 category=PydanticDeprecatedSince20,
1527 stacklevel=2,
1528 )
1529 from .deprecated import parse
1531 obj = parse.load_file(
1532 path,
1533 proto=proto,
1534 content_type=content_type,
1535 encoding=encoding,
1536 allow_pickle=allow_pickle,
1537 )
1538 return cls.parse_obj(obj)
1540 @classmethod
1541 @typing_extensions.deprecated(
1542 'The `from_orm` method is deprecated; set '
1543 "`model_config['from_attributes']=True` and use `model_validate` instead.",
1544 category=None,
1545 )
1546 def from_orm(cls, obj: Any) -> Self: # noqa: D102
1547 warnings.warn(
1548 'The `from_orm` method is deprecated; set '
1549 "`model_config['from_attributes']=True` and use `model_validate` instead.",
1550 category=PydanticDeprecatedSince20,
1551 stacklevel=2,
1552 )
1553 if not cls.model_config.get('from_attributes', None):
1554 raise PydanticUserError(
1555 'You must set the config attribute `from_attributes=True` to use from_orm', code=None
1556 )
1557 return cls.model_validate(obj)
1559 @classmethod
1560 @typing_extensions.deprecated('The `construct` method is deprecated; use `model_construct` instead.', category=None)
1561 def construct(cls, _fields_set: set[str] | None = None, **values: Any) -> Self: # noqa: D102
1562 warnings.warn(
1563 'The `construct` method is deprecated; use `model_construct` instead.',
1564 category=PydanticDeprecatedSince20,
1565 stacklevel=2,
1566 )
1567 return cls.model_construct(_fields_set=_fields_set, **values)
1569 @typing_extensions.deprecated(
1570 'The `copy` method is deprecated; use `model_copy` instead. '
1571 'See the docstring of `BaseModel.copy` for details about how to handle `include` and `exclude`.',
1572 category=None,
1573 )
1574 def copy(
1575 self,
1576 *,
1577 include: AbstractSetIntStr | MappingIntStrAny | None = None,
1578 exclude: AbstractSetIntStr | MappingIntStrAny | None = None,
1579 update: Dict[str, Any] | None = None, # noqa UP006
1580 deep: bool = False,
1581 ) -> Self: # pragma: no cover
1582 """Returns a copy of the model.
1584 !!! warning "Deprecated"
1585 This method is now deprecated; use `model_copy` instead.
1587 If you need `include` or `exclude`, use:
1589 ```python {test="skip" lint="skip"}
1590 data = self.model_dump(include=include, exclude=exclude, round_trip=True)
1591 data = {**data, **(update or {})}
1592 copied = self.model_validate(data)
1593 ```
1595 Args:
1596 include: Optional set or mapping specifying which fields to include in the copied model.
1597 exclude: Optional set or mapping specifying which fields to exclude in the copied model.
1598 update: Optional dictionary of field-value pairs to override field values in the copied model.
1599 deep: If True, the values of fields that are Pydantic models will be deep-copied.
1601 Returns:
1602 A copy of the model with included, excluded and updated fields as specified.
1603 """
1604 warnings.warn(
1605 'The `copy` method is deprecated; use `model_copy` instead. '
1606 'See the docstring of `BaseModel.copy` for details about how to handle `include` and `exclude`.',
1607 category=PydanticDeprecatedSince20,
1608 stacklevel=2,
1609 )
1610 from .deprecated import copy_internals
1612 values = dict(
1613 copy_internals._iter(
1614 self, to_dict=False, by_alias=False, include=include, exclude=exclude, exclude_unset=False
1615 ),
1616 **(update or {}),
1617 )
1618 if self.__pydantic_private__ is None:
1619 private = None
1620 else:
1621 private = {k: v for k, v in self.__pydantic_private__.items() if v is not PydanticUndefined}
1623 if self.__pydantic_extra__ is None:
1624 extra: dict[str, Any] | None = None
1625 else:
1626 extra = self.__pydantic_extra__.copy()
1627 for k in list(self.__pydantic_extra__):
1628 if k not in values: # k was in the exclude
1629 extra.pop(k)
1630 for k in list(values):
1631 if k in self.__pydantic_extra__: # k must have come from extra
1632 extra[k] = values.pop(k)
1634 # new `__pydantic_fields_set__` can have unset optional fields with a set value in `update` kwarg
1635 if update:
1636 fields_set = self.__pydantic_fields_set__ | update.keys()
1637 else:
1638 fields_set = set(self.__pydantic_fields_set__)
1640 # removing excluded fields from `__pydantic_fields_set__`
1641 if exclude:
1642 fields_set -= set(exclude)
1644 return copy_internals._copy_and_set_values(self, values, fields_set, extra, private, deep=deep)
1646 @classmethod
1647 @typing_extensions.deprecated('The `schema` method is deprecated; use `model_json_schema` instead.', category=None)
1648 def schema( # noqa: D102
1649 cls, by_alias: bool = True, ref_template: str = DEFAULT_REF_TEMPLATE
1650 ) -> Dict[str, Any]: # noqa UP006
1651 warnings.warn(
1652 'The `schema` method is deprecated; use `model_json_schema` instead.',
1653 category=PydanticDeprecatedSince20,
1654 stacklevel=2,
1655 )
1656 return cls.model_json_schema(by_alias=by_alias, ref_template=ref_template)
1658 @classmethod
1659 @typing_extensions.deprecated(
1660 'The `schema_json` method is deprecated; use `model_json_schema` and json.dumps instead.',
1661 category=None,
1662 )
1663 def schema_json( # noqa: D102
1664 cls, *, by_alias: bool = True, ref_template: str = DEFAULT_REF_TEMPLATE, **dumps_kwargs: Any
1665 ) -> str: # pragma: no cover
1666 warnings.warn(
1667 'The `schema_json` method is deprecated; use `model_json_schema` and json.dumps instead.',
1668 category=PydanticDeprecatedSince20,
1669 stacklevel=2,
1670 )
1671 import json
1673 from .deprecated.json import pydantic_encoder
1675 return json.dumps(
1676 cls.model_json_schema(by_alias=by_alias, ref_template=ref_template),
1677 default=pydantic_encoder,
1678 **dumps_kwargs,
1679 )
1681 @classmethod
1682 @typing_extensions.deprecated('The `validate` method is deprecated; use `model_validate` instead.', category=None)
1683 def validate(cls, value: Any) -> Self: # noqa: D102
1684 warnings.warn(
1685 'The `validate` method is deprecated; use `model_validate` instead.',
1686 category=PydanticDeprecatedSince20,
1687 stacklevel=2,
1688 )
1689 return cls.model_validate(value)
1691 @classmethod
1692 @typing_extensions.deprecated(
1693 'The `update_forward_refs` method is deprecated; use `model_rebuild` instead.',
1694 category=None,
1695 )
1696 def update_forward_refs(cls, **localns: Any) -> None: # noqa: D102
1697 warnings.warn(
1698 'The `update_forward_refs` method is deprecated; use `model_rebuild` instead.',
1699 category=PydanticDeprecatedSince20,
1700 stacklevel=2,
1701 )
1702 if localns: # pragma: no cover
1703 raise TypeError('`localns` arguments are not longer accepted.')
1704 cls.model_rebuild(force=True)
1706 @typing_extensions.deprecated(
1707 'The private method `_iter` will be removed and should no longer be used.', category=None
1708 )
1709 def _iter(self, *args: Any, **kwargs: Any) -> Any:
1710 warnings.warn(
1711 'The private method `_iter` will be removed and should no longer be used.',
1712 category=PydanticDeprecatedSince20,
1713 stacklevel=2,
1714 )
1715 from .deprecated import copy_internals
1717 return copy_internals._iter(self, *args, **kwargs)
1719 @typing_extensions.deprecated(
1720 'The private method `_copy_and_set_values` will be removed and should no longer be used.',
1721 category=None,
1722 )
1723 def _copy_and_set_values(self, *args: Any, **kwargs: Any) -> Any:
1724 warnings.warn(
1725 'The private method `_copy_and_set_values` will be removed and should no longer be used.',
1726 category=PydanticDeprecatedSince20,
1727 stacklevel=2,
1728 )
1729 from .deprecated import copy_internals
1731 return copy_internals._copy_and_set_values(self, *args, **kwargs)
1733 @classmethod
1734 @typing_extensions.deprecated(
1735 'The private method `_get_value` will be removed and should no longer be used.',
1736 category=None,
1737 )
1738 def _get_value(cls, *args: Any, **kwargs: Any) -> Any:
1739 warnings.warn(
1740 'The private method `_get_value` will be removed and should no longer be used.',
1741 category=PydanticDeprecatedSince20,
1742 stacklevel=2,
1743 )
1744 from .deprecated import copy_internals
1746 return copy_internals._get_value(cls, *args, **kwargs)
1748 @typing_extensions.deprecated(
1749 'The private method `_calculate_keys` will be removed and should no longer be used.',
1750 category=None,
1751 )
1752 def _calculate_keys(self, *args: Any, **kwargs: Any) -> Any:
1753 warnings.warn(
1754 'The private method `_calculate_keys` will be removed and should no longer be used.',
1755 category=PydanticDeprecatedSince20,
1756 stacklevel=2,
1757 )
1758 from .deprecated import copy_internals
1760 return copy_internals._calculate_keys(self, *args, **kwargs)
1763ModelT = TypeVar('ModelT', bound=BaseModel)
1765_CREATE_MODEL_RESERVED_NAMESPACE_KEYS: dict[str, str] = {
1766 '__annotations__': 'field definitions',
1767 '__module__': 'the `__module__` argument',
1768 '__qualname__': 'the `__qualname__` argument',
1769 '__doc__': 'the `__doc__` argument',
1770 'model_config': 'the `__config__` argument',
1771}
1772"""Keys that can't be provided in the `__namespace__` argument of `create_model()`, mapped to the argument to use instead."""
1775@overload
1776def create_model(
1777 model_name: str,
1778 /,
1779 *,
1780 __config__: ConfigDict | None = None,
1781 __doc__: str | None = None,
1782 __base__: None = None,
1783 __module__: str = __name__,
1784 __validators__: dict[str, Callable[..., Any]] | None = None,
1785 __namespace__: dict[str, Any] | None = None,
1786 __cls_kwargs__: dict[str, Any] | None = None,
1787 __qualname__: str | None = None,
1788 **field_definitions: TypeForm[Any] | tuple[TypeForm[Any], Any],
1789) -> type[BaseModel]: ...
1792@overload
1793def create_model(
1794 model_name: str,
1795 /,
1796 *,
1797 __config__: ConfigDict | None = None,
1798 __doc__: str | None = None,
1799 __base__: type[ModelT] | tuple[type[ModelT], ...],
1800 __module__: str = __name__,
1801 __validators__: dict[str, Callable[..., Any]] | None = None,
1802 __namespace__: dict[str, Any] | None = None,
1803 __cls_kwargs__: dict[str, Any] | None = None,
1804 __qualname__: str | None = None,
1805 **field_definitions: TypeForm[Any] | tuple[TypeForm[Any], Any],
1806) -> type[ModelT]: ...
1809def create_model( # noqa: C901
1810 model_name: str,
1811 /,
1812 *,
1813 __config__: ConfigDict | None = None,
1814 __doc__: str | None = None,
1815 __base__: type[ModelT] | tuple[type[ModelT], ...] | None = None,
1816 __module__: str | None = None,
1817 __validators__: dict[str, Callable[..., Any]] | None = None,
1818 __namespace__: dict[str, Any] | None = None,
1819 __cls_kwargs__: dict[str, Any] | None = None,
1820 __qualname__: str | None = None,
1821 **field_definitions: TypeForm[Any] | tuple[TypeForm[Any], Any],
1822) -> type[ModelT]:
1823 """!!! abstract "Usage Documentation"
1824 [Dynamic Model Creation](../concepts/models.md#dynamic-model-creation)
1826 Dynamically creates and returns a new Pydantic model. In other words, `create_model()` dynamically creates a
1827 subclass of [`BaseModel`][pydantic.BaseModel].
1829 !!! warning
1830 This function may execute arbitrary code contained in field annotations, if string references need to be evaluated.
1832 See [Security implications of introspecting annotations](https://docs.python.org/3/library/annotationlib.html#annotationlib-security) for more information.
1834 Args:
1835 model_name: The name of the newly created model.
1836 __config__: The configuration of the new model.
1837 __doc__: The docstring of the new model.
1838 __base__: The base class or classes for the new model.
1839 __module__: The name of the module that the model belongs to;
1840 if `None`, the value is taken from `sys._getframe(1)`
1841 __validators__: A dictionary of methods that validate fields. The keys are the names of the validation methods to
1842 be added to the model, and the values are the validation methods themselves. You can read more about functional
1843 validators [here](../concepts/validators.md#field-validators).
1845 /// version-changed | v2.14
1846 It is now recommended to use the `__namespace__` argument, which isn't restricted to validators.
1847 `__validators__` will be deprecated in v3.
1848 ///
1849 __namespace__: A dictionary of attributes to add to the class namespace of the new model, such as
1850 [validators](../concepts/validators.md), methods or [computed fields][pydantic.computed_field].
1851 Keys take precedence over the ones from `__validators__`, and must not clash with any of the field names
1852 or with the attributes that have a dedicated argument (`__annotations__`, `__module__`, `__qualname__`,
1853 `__doc__` and `model_config`).
1855 /// version-added | v2.14
1856 This argument replaces `__validators__`, which will be deprecated in v3.
1857 ///
1858 __cls_kwargs__: A dictionary of keyword arguments for class creation, such as `metaclass`.
1859 __qualname__: The qualified name of the newly created model.
1860 **field_definitions: Field definitions of the new model. Either:
1862 - a single element, representing the type annotation of the field.
1863 - a two-tuple, the first element being the type and the second element the assigned value
1864 (either a default or the [`Field()`][pydantic.Field] function).
1866 Returns:
1867 The new [model][pydantic.BaseModel].
1869 Raises:
1870 PydanticUserError: If `__base__` and `__config__` are both passed,
1871 or if a key of `__namespace__` clashes with a field name or with an attribute that has a dedicated argument.
1872 """
1873 if __base__ is None:
1874 __base__ = (cast('type[ModelT]', BaseModel),)
1875 elif not isinstance(__base__, tuple):
1876 __base__ = (__base__,)
1878 __cls_kwargs__ = __cls_kwargs__ or {}
1880 fields: dict[str, Any] = {}
1881 annotations: dict[str, Any] = {}
1883 for f_name, f_def in field_definitions.items():
1884 if isinstance(f_def, tuple):
1885 if len(f_def) != 2:
1886 raise PydanticUserError(
1887 f'Field definition for {f_name!r} should a single element representing the type or a two-tuple, the first element '
1888 'being the type and the second element the assigned value (either a default or the `Field()` function).',
1889 code='create-model-field-definitions',
1890 )
1892 annotations[f_name] = f_def[0]
1893 fields[f_name] = f_def[1]
1894 else:
1895 annotations[f_name] = f_def
1897 if __namespace__:
1898 if clashing_names := field_definitions.keys() & __namespace__.keys():
1899 raise PydanticUserError(
1900 f'Field name(s) {", ".join(map(repr, sorted(clashing_names)))} clash with keys of the `__namespace__` argument.',
1901 code='create-model-namespace',
1902 )
1903 for key, argument in _CREATE_MODEL_RESERVED_NAMESPACE_KEYS.items():
1904 if key in __namespace__:
1905 raise PydanticUserError(
1906 f'{key!r} is not allowed as a key of the `__namespace__` argument, use {argument} instead.',
1907 code='create-model-namespace',
1908 )
1910 if __module__ is None:
1911 f = sys._getframe(1)
1912 __module__ = f.f_globals['__name__']
1914 namespace: dict[str, Any] = {'__annotations__': annotations, '__module__': __module__}
1915 if __doc__:
1916 namespace['__doc__'] = __doc__
1917 if __qualname__ is not None:
1918 namespace['__qualname__'] = __qualname__
1919 if __validators__:
1920 namespace.update(__validators__)
1921 if __namespace__:
1922 namespace.update(__namespace__)
1923 namespace.update(fields)
1924 if __config__:
1925 namespace['model_config'] = __config__
1926 resolved_bases = types.resolve_bases(__base__)
1927 meta, ns, kwds = types.prepare_class(model_name, resolved_bases, kwds=__cls_kwargs__)
1928 if resolved_bases is not __base__:
1929 ns['__orig_bases__'] = __base__
1930 namespace.update(ns)
1932 return meta(
1933 model_name,
1934 resolved_bases,
1935 namespace,
1936 __pydantic_reset_parent_namespace__=False,
1937 _create_model_module=__module__,
1938 **kwds,
1939 )
1942__getattr__ = getattr_migration(__name__)