Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/pydantic/fields.py: 69%
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"""Defining fields on models."""
3from __future__ import annotations as _annotations
5import dataclasses
6import inspect
7import sys
8import typing
9from collections.abc import Mapping
10from copy import copy
11from dataclasses import Field as DataclassField
12from functools import cached_property
13from typing import Annotated, Any, Callable, ClassVar, Literal, TypeVar, cast, overload
14from warnings import warn
16import annotated_types
17import typing_extensions
18from pydantic_core import PydanticUndefined
19from typing_extensions import Self, TypeAlias, Unpack, deprecated
20from typing_inspection import typing_objects
21from typing_inspection.introspection import UNKNOWN, AnnotationSource, ForbiddenQualifier, Qualifier, inspect_annotation
23from . import types
24from ._internal import _decorators, _fields, _generics, _internal_dataclass, _repr, _typing_extra, _utils
25from ._internal._namespace_utils import GlobalsNamespace, MappingNamespace
26from .aliases import AliasChoices, AliasPath
27from .config import JsonDict
28from .errors import PydanticForbiddenQualifier, PydanticUserError
29from .json_schema import PydanticJsonSchemaWarning
30from .warnings import PydanticDeprecatedSince20
32if typing.TYPE_CHECKING:
33 from ._internal._repr import ReprArgs
34else:
35 # See PyCharm issues https://youtrack.jetbrains.com/issue/PY-21915
36 # and https://youtrack.jetbrains.com/issue/PY-51428
37 DeprecationWarning = PydanticDeprecatedSince20
39__all__ = 'Field', 'PrivateAttr', 'computed_field'
42_Unset: Any = PydanticUndefined
44if sys.version_info >= (3, 13):
45 import warnings
47 Deprecated: TypeAlias = warnings.deprecated | deprecated
48else:
49 Deprecated: TypeAlias = deprecated
52class _FromFieldInfoInputs(typing_extensions.TypedDict, total=False):
53 """This class exists solely to add type checking for the `**kwargs` in `FieldInfo.from_field`."""
55 # TODO PEP 747: use TypeForm:
56 annotation: type[Any] | None
57 default_factory: Callable[[], Any] | Callable[[dict[str, Any]], Any] | None
58 alias: str | None
59 alias_priority: int | None
60 validation_alias: str | AliasPath | AliasChoices | None
61 serialization_alias: str | None
62 title: str | None
63 field_title_generator: Callable[[str, FieldInfo], str] | None
64 description: str | None
65 examples: list[Any] | None
66 exclude: bool | None
67 gt: annotated_types.SupportsGt | None
68 ge: annotated_types.SupportsGe | None
69 lt: annotated_types.SupportsLt | None
70 le: annotated_types.SupportsLe | None
71 multiple_of: float | None
72 strict: bool | None
73 min_length: int | None
74 max_length: int | None
75 pattern: str | typing.Pattern[str] | None
76 allow_inf_nan: bool | None
77 max_digits: int | None
78 decimal_places: int | None
79 union_mode: Literal['smart', 'left_to_right'] | None
80 discriminator: str | types.Discriminator | None
81 deprecated: Deprecated | str | bool | None
82 json_schema_extra: JsonDict | Callable[[JsonDict], None] | None
83 frozen: bool | None
84 validate_default: bool | None
85 repr: bool
86 init: bool | None
87 init_var: bool | None
88 kw_only: bool | None
89 coerce_numbers_to_str: bool | None
90 fail_fast: bool | None
93class _FieldInfoInputs(_FromFieldInfoInputs, total=False):
94 """This class exists solely to add type checking for the `**kwargs` in `FieldInfo.__init__`."""
96 default: Any
99class FieldInfo(_repr.Representation):
100 """This class holds information about a field.
102 `FieldInfo` is used for any field definition regardless of whether the [`Field()`][pydantic.fields.Field]
103 function is explicitly used.
105 !!! warning
106 You generally shouldn't be creating `FieldInfo` directly, you'll only need to use it when accessing
107 [`BaseModel`][pydantic.main.BaseModel] `.model_fields` internals.
109 Attributes:
110 annotation: The type annotation of the field.
111 default: The default value of the field.
112 default_factory: A callable to generate the default value. The callable can either take 0 arguments
113 (in which case it is called as is) or a single argument containing the already validated data.
114 alias: The alias name of the field.
115 alias_priority: The priority of the field's alias.
116 validation_alias: The validation alias of the field.
117 serialization_alias: The serialization alias of the field.
118 title: The title of the field.
119 field_title_generator: A callable that takes a field name and returns title for it.
120 description: The description of the field.
121 examples: List of examples of the field.
122 exclude: Whether to exclude the field from the model serialization.
123 discriminator: Field name or Discriminator for discriminating the type in a tagged union.
124 deprecated: A deprecation message, an instance of `warnings.deprecated` or the `typing_extensions.deprecated` backport,
125 or a boolean. If `True`, a default deprecation message will be emitted when accessing the field.
126 json_schema_extra: A dict or callable to provide extra JSON schema properties.
127 frozen: Whether the field is frozen.
128 validate_default: Whether to validate the default value of the field.
129 repr: Whether to include the field in representation of the model.
130 init: Whether the field should be included in the constructor of the dataclass.
131 init_var: Whether the field should _only_ be included in the constructor of the dataclass, and not stored.
132 kw_only: Whether the field should be a keyword-only argument in the constructor of the dataclass.
133 metadata: List of metadata constraints.
134 """
136 annotation: type[Any] | None
137 default: Any
138 default_factory: Callable[[], Any] | Callable[[dict[str, Any]], Any] | None
139 alias: str | None
140 alias_priority: int | None
141 validation_alias: str | AliasPath | AliasChoices | None
142 serialization_alias: str | None
143 title: str | None
144 field_title_generator: Callable[[str, FieldInfo], str] | None
145 description: str | None
146 examples: list[Any] | None
147 exclude: bool | None
148 discriminator: str | types.Discriminator | None
149 deprecated: Deprecated | str | bool | None
150 json_schema_extra: JsonDict | Callable[[JsonDict], None] | None
151 frozen: bool | None
152 validate_default: bool | None
153 repr: bool
154 init: bool | None
155 init_var: bool | None
156 kw_only: bool | None
157 metadata: list[Any]
159 __slots__ = (
160 'annotation',
161 'default',
162 'default_factory',
163 'alias',
164 'alias_priority',
165 'validation_alias',
166 'serialization_alias',
167 'title',
168 'field_title_generator',
169 'description',
170 'examples',
171 'exclude',
172 'discriminator',
173 'deprecated',
174 'json_schema_extra',
175 'frozen',
176 'validate_default',
177 'repr',
178 'init',
179 'init_var',
180 'kw_only',
181 'metadata',
182 '_attributes_set',
183 '_qualifiers',
184 '_complete',
185 '_original_assignment',
186 '_original_annotation',
187 )
189 # used to convert kwargs to metadata/constraints,
190 # None has a special meaning - these items are collected into a `PydanticGeneralMetadata`
191 metadata_lookup: ClassVar[dict[str, typing.Callable[[Any], Any] | None]] = {
192 'strict': types.Strict,
193 'gt': annotated_types.Gt,
194 'ge': annotated_types.Ge,
195 'lt': annotated_types.Lt,
196 'le': annotated_types.Le,
197 'multiple_of': annotated_types.MultipleOf,
198 'min_length': annotated_types.MinLen,
199 'max_length': annotated_types.MaxLen,
200 'pattern': None,
201 'allow_inf_nan': None,
202 'max_digits': None,
203 'decimal_places': None,
204 'union_mode': None,
205 'coerce_numbers_to_str': None,
206 'fail_fast': types.FailFast,
207 }
209 def __init__(self, **kwargs: Unpack[_FieldInfoInputs]) -> None:
210 """This class should generally not be initialized directly; instead, use the `pydantic.fields.Field` function
211 or one of the constructor classmethods.
213 See the signature of `pydantic.fields.Field` for more details about the expected arguments.
214 """
215 self._attributes_set = {k: v for k, v in kwargs.items() if v is not _Unset}
216 kwargs = {k: _DefaultValues.get(k) if v is _Unset else v for k, v in kwargs.items()} # type: ignore
217 self.annotation = kwargs.get('annotation')
219 default = kwargs.pop('default', PydanticUndefined)
220 if default is Ellipsis:
221 self.default = PydanticUndefined
222 self._attributes_set.pop('default', None)
223 else:
224 self.default = default
226 self.default_factory = kwargs.pop('default_factory', None)
228 if self.default is not PydanticUndefined and self.default_factory is not None:
229 raise TypeError('cannot specify both default and default_factory')
231 self.alias = kwargs.pop('alias', None)
232 self.validation_alias = kwargs.pop('validation_alias', None)
233 self.serialization_alias = kwargs.pop('serialization_alias', None)
234 alias_is_set = any(alias is not None for alias in (self.alias, self.validation_alias, self.serialization_alias))
235 self.alias_priority = kwargs.pop('alias_priority', None) or 2 if alias_is_set else None
236 self.title = kwargs.pop('title', None)
237 self.field_title_generator = kwargs.pop('field_title_generator', None)
238 self.description = kwargs.pop('description', None)
239 self.examples = kwargs.pop('examples', None)
240 self.exclude = kwargs.pop('exclude', None)
241 self.discriminator = kwargs.pop('discriminator', None)
242 # For compatibility with FastAPI<=0.110.0, we preserve the existing value if it is not overridden
243 self.deprecated = kwargs.pop('deprecated', getattr(self, 'deprecated', None))
244 self.repr = kwargs.pop('repr', True)
245 self.json_schema_extra = kwargs.pop('json_schema_extra', None)
246 self.validate_default = kwargs.pop('validate_default', None)
247 self.frozen = kwargs.pop('frozen', None)
248 # currently only used on dataclasses
249 self.init = kwargs.pop('init', None)
250 self.init_var = kwargs.pop('init_var', None)
251 self.kw_only = kwargs.pop('kw_only', None)
253 self.metadata = self._collect_metadata(kwargs) # type: ignore
255 # Private attributes:
256 self._qualifiers: set[Qualifier] = set()
257 # Used to rebuild FieldInfo instances:
258 self._complete = True
259 self._original_annotation: Any = PydanticUndefined
260 self._original_assignment: Any = PydanticUndefined
262 @staticmethod
263 def from_field(default: Any = PydanticUndefined, **kwargs: Unpack[_FromFieldInfoInputs]) -> FieldInfo:
264 """Create a new `FieldInfo` object with the `Field` function.
266 Args:
267 default: The default value for the field. Defaults to Undefined.
268 **kwargs: Additional arguments dictionary.
270 Raises:
271 TypeError: If 'annotation' is passed as a keyword argument.
273 Returns:
274 A new FieldInfo object with the given parameters.
276 Example:
277 This is how you can create a field with default value like this:
279 ```python
280 import pydantic
282 class MyModel(pydantic.BaseModel):
283 foo: int = pydantic.Field(4)
284 ```
285 """
286 if 'annotation' in kwargs:
287 raise TypeError('"annotation" is not permitted as a Field keyword argument')
288 return FieldInfo(default=default, **kwargs)
290 @staticmethod
291 def from_annotation(annotation: type[Any], *, _source: AnnotationSource = AnnotationSource.ANY) -> FieldInfo:
292 """Creates a `FieldInfo` instance from a bare annotation.
294 This function is used internally to create a `FieldInfo` from a bare annotation like this:
296 ```python
297 import pydantic
299 class MyModel(pydantic.BaseModel):
300 foo: int # <-- like this
301 ```
303 We also account for the case where the annotation can be an instance of `Annotated` and where
304 one of the (not first) arguments in `Annotated` is an instance of `FieldInfo`, e.g.:
306 ```python
307 from typing import Annotated
309 import annotated_types
311 import pydantic
313 class MyModel(pydantic.BaseModel):
314 foo: Annotated[int, annotated_types.Gt(42)]
315 bar: Annotated[int, pydantic.Field(gt=42)]
316 ```
318 Args:
319 annotation: An annotation object.
321 Returns:
322 An instance of the field metadata.
323 """
324 try:
325 inspected_ann = inspect_annotation(
326 annotation,
327 annotation_source=_source,
328 unpack_type_aliases='skip',
329 )
330 except ForbiddenQualifier as e:
331 raise PydanticForbiddenQualifier(e.qualifier, annotation)
333 # TODO check for classvar and error?
335 # No assigned value, this happens when using a bare `Final` qualifier (also for other
336 # qualifiers, but they shouldn't appear here). In this case we infer the type as `Any`
337 # because we don't have any assigned value.
338 type_expr: Any = Any if inspected_ann.type is UNKNOWN else inspected_ann.type
339 final = 'final' in inspected_ann.qualifiers
340 metadata = inspected_ann.metadata
342 if not metadata:
343 # No metadata, e.g. `field: int`, or `field: Final[str]`:
344 field_info = FieldInfo(annotation=type_expr, frozen=final or None)
345 field_info._qualifiers = inspected_ann.qualifiers
346 return field_info
348 # With metadata, e.g. `field: Annotated[int, Field(...), Gt(1)]`:
349 field_info_annotations = [a for a in metadata if isinstance(a, FieldInfo)]
350 field_info = FieldInfo.merge_field_infos(*field_info_annotations, annotation=type_expr)
352 new_field_info = field_info._copy()
353 new_field_info.annotation = type_expr
354 new_field_info.frozen = final or field_info.frozen
355 field_metadata: list[Any] = []
356 for a in metadata:
357 if typing_objects.is_deprecated(a):
358 new_field_info.deprecated = a.message
359 elif not isinstance(a, FieldInfo):
360 field_metadata.append(a)
361 else:
362 field_metadata.extend(a.metadata)
363 new_field_info.metadata = field_metadata
364 new_field_info._qualifiers = inspected_ann.qualifiers
365 return new_field_info
367 @staticmethod
368 def from_annotated_attribute(
369 annotation: type[Any], default: Any, *, _source: AnnotationSource = AnnotationSource.ANY
370 ) -> FieldInfo:
371 """Create `FieldInfo` from an annotation with a default value.
373 This is used in cases like the following:
375 ```python
376 from typing import Annotated
378 import annotated_types
380 import pydantic
382 class MyModel(pydantic.BaseModel):
383 foo: int = 4 # <-- like this
384 bar: Annotated[int, annotated_types.Gt(4)] = 4 # <-- or this
385 spam: Annotated[int, pydantic.Field(gt=4)] = 4 # <-- or this
386 ```
388 Args:
389 annotation: The type annotation of the field.
390 default: The default value of the field.
392 Returns:
393 A field object with the passed values.
394 """
395 if annotation is default:
396 raise PydanticUserError(
397 'Error when building FieldInfo from annotated attribute. '
398 "Make sure you don't have any field name clashing with a type annotation.",
399 code='unevaluable-type-annotation',
400 )
402 try:
403 inspected_ann = inspect_annotation(
404 annotation,
405 annotation_source=_source,
406 unpack_type_aliases='skip',
407 )
408 except ForbiddenQualifier as e:
409 raise PydanticForbiddenQualifier(e.qualifier, annotation)
411 # TODO check for classvar and error?
413 # TODO infer from the default, this can be done in v3 once we treat final fields with
414 # a default as proper fields and not class variables:
415 type_expr: Any = Any if inspected_ann.type is UNKNOWN else inspected_ann.type
416 final = 'final' in inspected_ann.qualifiers
417 metadata = inspected_ann.metadata
419 if isinstance(default, FieldInfo):
420 # e.g. `field: int = Field(...)`
421 default_metadata = default.metadata.copy()
422 default = copy(default)
423 default.metadata = default_metadata
425 default.annotation = type_expr
426 default.metadata += metadata
427 merged_default = FieldInfo.merge_field_infos(
428 *[x for x in metadata if isinstance(x, FieldInfo)],
429 default,
430 annotation=default.annotation,
431 )
432 merged_default.frozen = final or merged_default.frozen
433 merged_default._qualifiers = inspected_ann.qualifiers
434 return merged_default
436 if isinstance(default, dataclasses.Field):
437 # `collect_dataclass_fields()` passes the dataclass Field as a default.
438 pydantic_field = FieldInfo._from_dataclass_field(default)
439 pydantic_field.annotation = type_expr
440 pydantic_field.metadata += metadata
441 pydantic_field = FieldInfo.merge_field_infos(
442 *[x for x in metadata if isinstance(x, FieldInfo)],
443 pydantic_field,
444 annotation=pydantic_field.annotation,
445 )
446 pydantic_field.frozen = final or pydantic_field.frozen
447 pydantic_field.init_var = 'init_var' in inspected_ann.qualifiers
448 pydantic_field.init = getattr(default, 'init', None)
449 pydantic_field.kw_only = getattr(default, 'kw_only', None)
450 pydantic_field._qualifiers = inspected_ann.qualifiers
451 return pydantic_field
453 if not metadata:
454 # No metadata, e.g. `field: int = ...`, or `field: Final[str] = ...`:
455 field_info = FieldInfo(annotation=type_expr, default=default, frozen=final or None)
456 field_info._qualifiers = inspected_ann.qualifiers
457 return field_info
459 # With metadata, e.g. `field: Annotated[int, Field(...), Gt(1)] = ...`:
460 field_infos = [a for a in metadata if isinstance(a, FieldInfo)]
461 field_info = FieldInfo.merge_field_infos(*field_infos, annotation=type_expr, default=default)
462 field_metadata: list[Any] = []
463 for a in metadata:
464 if typing_objects.is_deprecated(a):
465 field_info.deprecated = a.message
466 elif not isinstance(a, FieldInfo):
467 field_metadata.append(a)
468 else:
469 field_metadata.extend(a.metadata)
470 field_info.metadata = field_metadata
471 field_info._qualifiers = inspected_ann.qualifiers
472 return field_info
474 @staticmethod
475 def merge_field_infos(*field_infos: FieldInfo, **overrides: Any) -> FieldInfo:
476 """Merge `FieldInfo` instances keeping only explicitly set attributes.
478 Later `FieldInfo` instances override earlier ones.
480 Returns:
481 FieldInfo: A merged FieldInfo instance.
482 """
483 if len(field_infos) == 1:
484 # No merging necessary, but we still need to make a copy and apply the overrides
485 field_info = field_infos[0]._copy()
486 field_info._attributes_set.update(overrides)
488 default_override = overrides.pop('default', PydanticUndefined)
489 if default_override is Ellipsis:
490 default_override = PydanticUndefined
491 if default_override is not PydanticUndefined:
492 field_info.default = default_override
494 for k, v in overrides.items():
495 setattr(field_info, k, v)
496 return field_info # type: ignore
498 merged_field_info_kwargs: dict[str, Any] = {}
499 metadata = {}
500 for field_info in field_infos:
501 attributes_set = field_info._attributes_set.copy()
503 try:
504 json_schema_extra = attributes_set.pop('json_schema_extra')
505 existing_json_schema_extra = merged_field_info_kwargs.get('json_schema_extra')
507 if existing_json_schema_extra is None:
508 merged_field_info_kwargs['json_schema_extra'] = json_schema_extra
509 if isinstance(existing_json_schema_extra, dict):
510 if isinstance(json_schema_extra, dict):
511 merged_field_info_kwargs['json_schema_extra'] = {
512 **existing_json_schema_extra,
513 **json_schema_extra,
514 }
515 if callable(json_schema_extra):
516 warn(
517 'Composing `dict` and `callable` type `json_schema_extra` is not supported.'
518 'The `callable` type is being ignored.'
519 "If you'd like support for this behavior, please open an issue on pydantic.",
520 PydanticJsonSchemaWarning,
521 )
522 elif callable(json_schema_extra):
523 # if ever there's a case of a callable, we'll just keep the last json schema extra spec
524 merged_field_info_kwargs['json_schema_extra'] = json_schema_extra
525 except KeyError:
526 pass
528 # later FieldInfo instances override everything except json_schema_extra from earlier FieldInfo instances
529 merged_field_info_kwargs.update(attributes_set)
531 for x in field_info.metadata:
532 if not isinstance(x, FieldInfo):
533 metadata[type(x)] = x
535 merged_field_info_kwargs.update(overrides)
536 field_info = FieldInfo(**merged_field_info_kwargs)
537 field_info.metadata = list(metadata.values())
538 return field_info
540 @staticmethod
541 def _from_dataclass_field(dc_field: DataclassField[Any]) -> FieldInfo:
542 """Return a new `FieldInfo` instance from a `dataclasses.Field` instance.
544 Args:
545 dc_field: The `dataclasses.Field` instance to convert.
547 Returns:
548 The corresponding `FieldInfo` instance.
550 Raises:
551 TypeError: If any of the `FieldInfo` kwargs does not match the `dataclass.Field` kwargs.
552 """
553 default = dc_field.default
554 if default is dataclasses.MISSING:
555 default = _Unset
557 if dc_field.default_factory is dataclasses.MISSING:
558 default_factory = _Unset
559 else:
560 default_factory = dc_field.default_factory
562 # use the `Field` function so in correct kwargs raise the correct `TypeError`
563 dc_field_metadata = {k: v for k, v in dc_field.metadata.items() if k in _FIELD_ARG_NAMES}
564 return Field(default=default, default_factory=default_factory, repr=dc_field.repr, **dc_field_metadata) # pyright: ignore[reportCallIssue]
566 @staticmethod
567 def _collect_metadata(kwargs: dict[str, Any]) -> list[Any]:
568 """Collect annotations from kwargs.
570 Args:
571 kwargs: Keyword arguments passed to the function.
573 Returns:
574 A list of metadata objects - a combination of `annotated_types.BaseMetadata` and
575 `PydanticMetadata`.
576 """
577 metadata: list[Any] = []
578 general_metadata = {}
579 for key, value in list(kwargs.items()):
580 try:
581 marker = FieldInfo.metadata_lookup[key]
582 except KeyError:
583 continue
585 del kwargs[key]
586 if value is not None:
587 if marker is None:
588 general_metadata[key] = value
589 else:
590 metadata.append(marker(value))
591 if general_metadata:
592 metadata.append(_fields.pydantic_general_metadata(**general_metadata))
593 return metadata
595 def _copy(self) -> Self:
596 copied = copy(self)
597 for attr_name in ('metadata', '_attributes_set', '_qualifiers'):
598 # Apply "deep-copy" behavior on collections attributes:
599 value = getattr(copied, attr_name).copy()
600 setattr(copied, attr_name, value)
602 return copied
604 @property
605 def deprecation_message(self) -> str | None:
606 """The deprecation message to be emitted, or `None` if not set."""
607 if self.deprecated is None:
608 return None
609 if isinstance(self.deprecated, bool):
610 return 'deprecated' if self.deprecated else None
611 return self.deprecated if isinstance(self.deprecated, str) else self.deprecated.message
613 @property
614 def default_factory_takes_validated_data(self) -> bool | None:
615 """Whether the provided default factory callable has a validated data parameter.
617 Returns `None` if no default factory is set.
618 """
619 if self.default_factory is not None:
620 return _fields.takes_validated_data_argument(self.default_factory)
622 @overload
623 def get_default(
624 self, *, call_default_factory: Literal[True], validated_data: dict[str, Any] | None = None
625 ) -> Any: ...
627 @overload
628 def get_default(self, *, call_default_factory: Literal[False] = ...) -> Any: ...
630 def get_default(self, *, call_default_factory: bool = False, validated_data: dict[str, Any] | None = None) -> Any:
631 """Get the default value.
633 We expose an option for whether to call the default_factory (if present), as calling it may
634 result in side effects that we want to avoid. However, there are times when it really should
635 be called (namely, when instantiating a model via `model_construct`).
637 Args:
638 call_default_factory: Whether to call the default factory or not.
639 validated_data: The already validated data to be passed to the default factory.
641 Returns:
642 The default value, calling the default factory if requested or `None` if not set.
643 """
644 if self.default_factory is None:
645 return _utils.smart_deepcopy(self.default)
646 elif call_default_factory:
647 if self.default_factory_takes_validated_data:
648 fac = cast('Callable[[dict[str, Any]], Any]', self.default_factory)
649 if validated_data is None:
650 raise ValueError(
651 "The default factory requires the 'validated_data' argument, which was not provided when calling 'get_default'."
652 )
653 return fac(validated_data)
654 else:
655 fac = cast('Callable[[], Any]', self.default_factory)
656 return fac()
657 else:
658 return None
660 def is_required(self) -> bool:
661 """Check if the field is required (i.e., does not have a default value or factory).
663 Returns:
664 `True` if the field is required, `False` otherwise.
665 """
666 return self.default is PydanticUndefined and self.default_factory is None
668 def rebuild_annotation(self) -> Any:
669 """Attempts to rebuild the original annotation for use in function signatures.
671 If metadata is present, it adds it to the original annotation using
672 `Annotated`. Otherwise, it returns the original annotation as-is.
674 Note that because the metadata has been flattened, the original annotation
675 may not be reconstructed exactly as originally provided, e.g. if the original
676 type had unrecognized annotations, or was annotated with a call to `pydantic.Field`.
678 Returns:
679 The rebuilt annotation.
680 """
681 if not self.metadata:
682 return self.annotation
683 else:
684 # Annotated arguments must be a tuple
685 return Annotated[(self.annotation, *self.metadata)] # type: ignore
687 def apply_typevars_map(
688 self,
689 typevars_map: Mapping[TypeVar, Any] | None,
690 globalns: GlobalsNamespace | None = None,
691 localns: MappingNamespace | None = None,
692 ) -> None:
693 """Apply a `typevars_map` to the annotation.
695 This method is used when analyzing parametrized generic types to replace typevars with their concrete types.
697 This method applies the `typevars_map` to the annotation in place.
699 Args:
700 typevars_map: A dictionary mapping type variables to their concrete types.
701 globalns: The globals namespace to use during type annotation evaluation.
702 localns: The locals namespace to use during type annotation evaluation.
704 See Also:
705 pydantic._internal._generics.replace_types is used for replacing the typevars with
706 their concrete types.
707 """
708 annotation = _generics.replace_types(self.annotation, typevars_map)
709 annotation, evaluated = _typing_extra.try_eval_type(annotation, globalns, localns)
710 self.annotation = annotation
711 if not evaluated:
712 self._complete = False
713 self._original_annotation = self.annotation
715 def __repr_args__(self) -> ReprArgs:
716 yield 'annotation', _repr.PlainRepr(_repr.display_as_type(self.annotation))
717 yield 'required', self.is_required()
719 for s in self.__slots__:
720 # TODO: properly make use of the protocol (https://rich.readthedocs.io/en/stable/pretty.html#rich-repr-protocol)
721 # By yielding a three-tuple:
722 if s in (
723 'annotation',
724 '_attributes_set',
725 '_qualifiers',
726 '_complete',
727 '_original_assignment',
728 '_original_annotation',
729 ):
730 continue
731 elif s == 'metadata' and not self.metadata:
732 continue
733 elif s == 'repr' and self.repr is True:
734 continue
735 if s == 'frozen' and self.frozen is False:
736 continue
737 if s == 'validation_alias' and self.validation_alias == self.alias:
738 continue
739 if s == 'serialization_alias' and self.serialization_alias == self.alias:
740 continue
741 if s == 'default' and self.default is not PydanticUndefined:
742 yield 'default', self.default
743 elif s == 'default_factory' and self.default_factory is not None:
744 yield 'default_factory', _repr.PlainRepr(_repr.display_as_type(self.default_factory))
745 else:
746 value = getattr(self, s)
747 if value is not None and value is not PydanticUndefined:
748 yield s, value
751class _EmptyKwargs(typing_extensions.TypedDict):
752 """This class exists solely to ensure that type checking warns about passing `**extra` in `Field`."""
755_DefaultValues = {
756 'default': ...,
757 'default_factory': None,
758 'alias': None,
759 'alias_priority': None,
760 'validation_alias': None,
761 'serialization_alias': None,
762 'title': None,
763 'description': None,
764 'examples': None,
765 'exclude': None,
766 'discriminator': None,
767 'json_schema_extra': None,
768 'frozen': None,
769 'validate_default': None,
770 'repr': True,
771 'init': None,
772 'init_var': None,
773 'kw_only': None,
774 'pattern': None,
775 'strict': None,
776 'gt': None,
777 'ge': None,
778 'lt': None,
779 'le': None,
780 'multiple_of': None,
781 'allow_inf_nan': None,
782 'max_digits': None,
783 'decimal_places': None,
784 'min_length': None,
785 'max_length': None,
786 'coerce_numbers_to_str': None,
787}
790_T = TypeVar('_T')
793# NOTE: Actual return type is 'FieldInfo', but we want to help type checkers
794# to understand the magic that happens at runtime with the following overloads:
795@overload # type hint the return value as `Any` to avoid type checking regressions when using `...`.
796def Field(
797 default: ellipsis, # noqa: F821 # TODO: use `_typing_extra.EllipsisType` when we drop Py3.9
798 *,
799 alias: str | None = _Unset,
800 alias_priority: int | None = _Unset,
801 validation_alias: str | AliasPath | AliasChoices | None = _Unset,
802 serialization_alias: str | None = _Unset,
803 title: str | None = _Unset,
804 field_title_generator: Callable[[str, FieldInfo], str] | None = _Unset,
805 description: str | None = _Unset,
806 examples: list[Any] | None = _Unset,
807 exclude: bool | None = _Unset,
808 discriminator: str | types.Discriminator | None = _Unset,
809 deprecated: Deprecated | str | bool | None = _Unset,
810 json_schema_extra: JsonDict | Callable[[JsonDict], None] | None = _Unset,
811 frozen: bool | None = _Unset,
812 validate_default: bool | None = _Unset,
813 repr: bool = _Unset,
814 init: bool | None = _Unset,
815 init_var: bool | None = _Unset,
816 kw_only: bool | None = _Unset,
817 pattern: str | typing.Pattern[str] | None = _Unset,
818 strict: bool | None = _Unset,
819 coerce_numbers_to_str: bool | None = _Unset,
820 gt: annotated_types.SupportsGt | None = _Unset,
821 ge: annotated_types.SupportsGe | None = _Unset,
822 lt: annotated_types.SupportsLt | None = _Unset,
823 le: annotated_types.SupportsLe | None = _Unset,
824 multiple_of: float | None = _Unset,
825 allow_inf_nan: bool | None = _Unset,
826 max_digits: int | None = _Unset,
827 decimal_places: int | None = _Unset,
828 min_length: int | None = _Unset,
829 max_length: int | None = _Unset,
830 union_mode: Literal['smart', 'left_to_right'] = _Unset,
831 fail_fast: bool | None = _Unset,
832 **extra: Unpack[_EmptyKwargs],
833) -> Any: ...
834@overload # `default` argument set
835def Field(
836 default: _T,
837 *,
838 alias: str | None = _Unset,
839 alias_priority: int | None = _Unset,
840 validation_alias: str | AliasPath | AliasChoices | None = _Unset,
841 serialization_alias: str | None = _Unset,
842 title: str | None = _Unset,
843 field_title_generator: Callable[[str, FieldInfo], str] | None = _Unset,
844 description: str | None = _Unset,
845 examples: list[Any] | None = _Unset,
846 exclude: bool | None = _Unset,
847 discriminator: str | types.Discriminator | None = _Unset,
848 deprecated: Deprecated | str | bool | None = _Unset,
849 json_schema_extra: JsonDict | Callable[[JsonDict], None] | None = _Unset,
850 frozen: bool | None = _Unset,
851 validate_default: bool | None = _Unset,
852 repr: bool = _Unset,
853 init: bool | None = _Unset,
854 init_var: bool | None = _Unset,
855 kw_only: bool | None = _Unset,
856 pattern: str | typing.Pattern[str] | None = _Unset,
857 strict: bool | None = _Unset,
858 coerce_numbers_to_str: bool | None = _Unset,
859 gt: annotated_types.SupportsGt | None = _Unset,
860 ge: annotated_types.SupportsGe | None = _Unset,
861 lt: annotated_types.SupportsLt | None = _Unset,
862 le: annotated_types.SupportsLe | None = _Unset,
863 multiple_of: float | None = _Unset,
864 allow_inf_nan: bool | None = _Unset,
865 max_digits: int | None = _Unset,
866 decimal_places: int | None = _Unset,
867 min_length: int | None = _Unset,
868 max_length: int | None = _Unset,
869 union_mode: Literal['smart', 'left_to_right'] = _Unset,
870 fail_fast: bool | None = _Unset,
871 **extra: Unpack[_EmptyKwargs],
872) -> _T: ...
873@overload # `default_factory` argument set
874def Field(
875 *,
876 default_factory: Callable[[], _T] | Callable[[dict[str, Any]], _T],
877 alias: str | None = _Unset,
878 alias_priority: int | None = _Unset,
879 validation_alias: str | AliasPath | AliasChoices | None = _Unset,
880 serialization_alias: str | None = _Unset,
881 title: str | None = _Unset,
882 field_title_generator: Callable[[str, FieldInfo], str] | None = _Unset,
883 description: str | None = _Unset,
884 examples: list[Any] | None = _Unset,
885 exclude: bool | None = _Unset,
886 discriminator: str | types.Discriminator | None = _Unset,
887 deprecated: Deprecated | str | bool | None = _Unset,
888 json_schema_extra: JsonDict | Callable[[JsonDict], None] | None = _Unset,
889 frozen: bool | None = _Unset,
890 validate_default: bool | None = _Unset,
891 repr: bool = _Unset,
892 init: bool | None = _Unset,
893 init_var: bool | None = _Unset,
894 kw_only: bool | None = _Unset,
895 pattern: str | typing.Pattern[str] | None = _Unset,
896 strict: bool | None = _Unset,
897 coerce_numbers_to_str: bool | None = _Unset,
898 gt: annotated_types.SupportsGt | None = _Unset,
899 ge: annotated_types.SupportsGe | None = _Unset,
900 lt: annotated_types.SupportsLt | None = _Unset,
901 le: annotated_types.SupportsLe | None = _Unset,
902 multiple_of: float | None = _Unset,
903 allow_inf_nan: bool | None = _Unset,
904 max_digits: int | None = _Unset,
905 decimal_places: int | None = _Unset,
906 min_length: int | None = _Unset,
907 max_length: int | None = _Unset,
908 union_mode: Literal['smart', 'left_to_right'] = _Unset,
909 fail_fast: bool | None = _Unset,
910 **extra: Unpack[_EmptyKwargs],
911) -> _T: ...
912@overload
913def Field( # No default set
914 *,
915 alias: str | None = _Unset,
916 alias_priority: int | None = _Unset,
917 validation_alias: str | AliasPath | AliasChoices | None = _Unset,
918 serialization_alias: str | None = _Unset,
919 title: str | None = _Unset,
920 field_title_generator: Callable[[str, FieldInfo], str] | None = _Unset,
921 description: str | None = _Unset,
922 examples: list[Any] | None = _Unset,
923 exclude: bool | None = _Unset,
924 discriminator: str | types.Discriminator | None = _Unset,
925 deprecated: Deprecated | str | bool | None = _Unset,
926 json_schema_extra: JsonDict | Callable[[JsonDict], None] | None = _Unset,
927 frozen: bool | None = _Unset,
928 validate_default: bool | None = _Unset,
929 repr: bool = _Unset,
930 init: bool | None = _Unset,
931 init_var: bool | None = _Unset,
932 kw_only: bool | None = _Unset,
933 pattern: str | typing.Pattern[str] | None = _Unset,
934 strict: bool | None = _Unset,
935 coerce_numbers_to_str: bool | None = _Unset,
936 gt: annotated_types.SupportsGt | None = _Unset,
937 ge: annotated_types.SupportsGe | None = _Unset,
938 lt: annotated_types.SupportsLt | None = _Unset,
939 le: annotated_types.SupportsLe | None = _Unset,
940 multiple_of: float | None = _Unset,
941 allow_inf_nan: bool | None = _Unset,
942 max_digits: int | None = _Unset,
943 decimal_places: int | None = _Unset,
944 min_length: int | None = _Unset,
945 max_length: int | None = _Unset,
946 union_mode: Literal['smart', 'left_to_right'] = _Unset,
947 fail_fast: bool | None = _Unset,
948 **extra: Unpack[_EmptyKwargs],
949) -> Any: ...
950def Field( # noqa: C901
951 default: Any = PydanticUndefined,
952 *,
953 default_factory: Callable[[], Any] | Callable[[dict[str, Any]], Any] | None = _Unset,
954 alias: str | None = _Unset,
955 alias_priority: int | None = _Unset,
956 validation_alias: str | AliasPath | AliasChoices | None = _Unset,
957 serialization_alias: str | None = _Unset,
958 title: str | None = _Unset,
959 field_title_generator: Callable[[str, FieldInfo], str] | None = _Unset,
960 description: str | None = _Unset,
961 examples: list[Any] | None = _Unset,
962 exclude: bool | None = _Unset,
963 discriminator: str | types.Discriminator | None = _Unset,
964 deprecated: Deprecated | str | bool | None = _Unset,
965 json_schema_extra: JsonDict | Callable[[JsonDict], None] | None = _Unset,
966 frozen: bool | None = _Unset,
967 validate_default: bool | None = _Unset,
968 repr: bool = _Unset,
969 init: bool | None = _Unset,
970 init_var: bool | None = _Unset,
971 kw_only: bool | None = _Unset,
972 pattern: str | typing.Pattern[str] | None = _Unset,
973 strict: bool | None = _Unset,
974 coerce_numbers_to_str: bool | None = _Unset,
975 gt: annotated_types.SupportsGt | None = _Unset,
976 ge: annotated_types.SupportsGe | None = _Unset,
977 lt: annotated_types.SupportsLt | None = _Unset,
978 le: annotated_types.SupportsLe | None = _Unset,
979 multiple_of: float | None = _Unset,
980 allow_inf_nan: bool | None = _Unset,
981 max_digits: int | None = _Unset,
982 decimal_places: int | None = _Unset,
983 min_length: int | None = _Unset,
984 max_length: int | None = _Unset,
985 union_mode: Literal['smart', 'left_to_right'] = _Unset,
986 fail_fast: bool | None = _Unset,
987 **extra: Unpack[_EmptyKwargs],
988) -> Any:
989 """!!! abstract "Usage Documentation"
990 [Fields](../concepts/fields.md)
992 Create a field for objects that can be configured.
994 Used to provide extra information about a field, either for the model schema or complex validation. Some arguments
995 apply only to number fields (`int`, `float`, `Decimal`) and some apply only to `str`.
997 Note:
998 - Any `_Unset` objects will be replaced by the corresponding value defined in the `_DefaultValues` dictionary. If a key for the `_Unset` object is not found in the `_DefaultValues` dictionary, it will default to `None`
1000 Args:
1001 default: Default value if the field is not set.
1002 default_factory: A callable to generate the default value. The callable can either take 0 arguments
1003 (in which case it is called as is) or a single argument containing the already validated data.
1004 alias: The name to use for the attribute when validating or serializing by alias.
1005 This is often used for things like converting between snake and camel case.
1006 alias_priority: Priority of the alias. This affects whether an alias generator is used.
1007 validation_alias: Like `alias`, but only affects validation, not serialization.
1008 serialization_alias: Like `alias`, but only affects serialization, not validation.
1009 title: Human-readable title.
1010 field_title_generator: A callable that takes a field name and returns title for it.
1011 description: Human-readable description.
1012 examples: Example values for this field.
1013 exclude: Whether to exclude the field from the model serialization.
1014 discriminator: Field name or Discriminator for discriminating the type in a tagged union.
1015 deprecated: A deprecation message, an instance of `warnings.deprecated` or the `typing_extensions.deprecated` backport,
1016 or a boolean. If `True`, a default deprecation message will be emitted when accessing the field.
1017 json_schema_extra: A dict or callable to provide extra JSON schema properties.
1018 frozen: Whether the field is frozen. If true, attempts to change the value on an instance will raise an error.
1019 validate_default: If `True`, apply validation to the default value every time you create an instance.
1020 Otherwise, for performance reasons, the default value of the field is trusted and not validated.
1021 repr: A boolean indicating whether to include the field in the `__repr__` output.
1022 init: Whether the field should be included in the constructor of the dataclass.
1023 (Only applies to dataclasses.)
1024 init_var: Whether the field should _only_ be included in the constructor of the dataclass.
1025 (Only applies to dataclasses.)
1026 kw_only: Whether the field should be a keyword-only argument in the constructor of the dataclass.
1027 (Only applies to dataclasses.)
1028 coerce_numbers_to_str: Whether to enable coercion of any `Number` type to `str` (not applicable in `strict` mode).
1029 strict: If `True`, strict validation is applied to the field.
1030 See [Strict Mode](../concepts/strict_mode.md) for details.
1031 gt: Greater than. If set, value must be greater than this. Only applicable to numbers.
1032 ge: Greater than or equal. If set, value must be greater than or equal to this. Only applicable to numbers.
1033 lt: Less than. If set, value must be less than this. Only applicable to numbers.
1034 le: Less than or equal. If set, value must be less than or equal to this. Only applicable to numbers.
1035 multiple_of: Value must be a multiple of this. Only applicable to numbers.
1036 min_length: Minimum length for iterables.
1037 max_length: Maximum length for iterables.
1038 pattern: Pattern for strings (a regular expression).
1039 allow_inf_nan: Allow `inf`, `-inf`, `nan`. Only applicable to float and [`Decimal`][decimal.Decimal] numbers.
1040 max_digits: Maximum number of allow digits for strings.
1041 decimal_places: Maximum number of decimal places allowed for numbers.
1042 union_mode: The strategy to apply when validating a union. Can be `smart` (the default), or `left_to_right`.
1043 See [Union Mode](../concepts/unions.md#union-modes) for details.
1044 fail_fast: If `True`, validation will stop on the first error. If `False`, all validation errors will be collected.
1045 This option can be applied only to iterable types (list, tuple, set, and frozenset).
1046 extra: (Deprecated) Extra fields that will be included in the JSON schema.
1048 !!! warning Deprecated
1049 The `extra` kwargs is deprecated. Use `json_schema_extra` instead.
1051 Returns:
1052 A new [`FieldInfo`][pydantic.fields.FieldInfo]. The return annotation is `Any` so `Field` can be used on
1053 type-annotated fields without causing a type error.
1054 """
1055 # Check deprecated and removed params from V1. This logic should eventually be removed.
1056 const = extra.pop('const', None) # type: ignore
1057 if const is not None:
1058 raise PydanticUserError('`const` is removed, use `Literal` instead', code='removed-kwargs')
1060 min_items = extra.pop('min_items', None) # type: ignore
1061 if min_items is not None:
1062 warn('`min_items` is deprecated and will be removed, use `min_length` instead', DeprecationWarning)
1063 if min_length in (None, _Unset):
1064 min_length = min_items # type: ignore
1066 max_items = extra.pop('max_items', None) # type: ignore
1067 if max_items is not None:
1068 warn('`max_items` is deprecated and will be removed, use `max_length` instead', DeprecationWarning)
1069 if max_length in (None, _Unset):
1070 max_length = max_items # type: ignore
1072 unique_items = extra.pop('unique_items', None) # type: ignore
1073 if unique_items is not None:
1074 raise PydanticUserError(
1075 (
1076 '`unique_items` is removed, use `Set` instead'
1077 '(this feature is discussed in https://github.com/pydantic/pydantic-core/issues/296)'
1078 ),
1079 code='removed-kwargs',
1080 )
1082 allow_mutation = extra.pop('allow_mutation', None) # type: ignore
1083 if allow_mutation is not None:
1084 warn('`allow_mutation` is deprecated and will be removed. use `frozen` instead', DeprecationWarning)
1085 if allow_mutation is False:
1086 frozen = True
1088 regex = extra.pop('regex', None) # type: ignore
1089 if regex is not None:
1090 raise PydanticUserError('`regex` is removed. use `pattern` instead', code='removed-kwargs')
1092 if extra:
1093 warn(
1094 'Using extra keyword arguments on `Field` is deprecated and will be removed.'
1095 ' Use `json_schema_extra` instead.'
1096 f' (Extra keys: {", ".join(k.__repr__() for k in extra.keys())})',
1097 DeprecationWarning,
1098 )
1099 if not json_schema_extra or json_schema_extra is _Unset:
1100 json_schema_extra = extra # type: ignore
1102 if (
1103 validation_alias
1104 and validation_alias is not _Unset
1105 and not isinstance(validation_alias, (str, AliasChoices, AliasPath))
1106 ):
1107 raise TypeError('Invalid `validation_alias` type. it should be `str`, `AliasChoices`, or `AliasPath`')
1109 if serialization_alias in (_Unset, None) and isinstance(alias, str):
1110 serialization_alias = alias
1112 if validation_alias in (_Unset, None):
1113 validation_alias = alias
1115 include = extra.pop('include', None) # type: ignore
1116 if include is not None:
1117 warn('`include` is deprecated and does nothing. It will be removed, use `exclude` instead', DeprecationWarning)
1119 return FieldInfo.from_field(
1120 default,
1121 default_factory=default_factory,
1122 alias=alias,
1123 alias_priority=alias_priority,
1124 validation_alias=validation_alias,
1125 serialization_alias=serialization_alias,
1126 title=title,
1127 field_title_generator=field_title_generator,
1128 description=description,
1129 examples=examples,
1130 exclude=exclude,
1131 discriminator=discriminator,
1132 deprecated=deprecated,
1133 json_schema_extra=json_schema_extra,
1134 frozen=frozen,
1135 pattern=pattern,
1136 validate_default=validate_default,
1137 repr=repr,
1138 init=init,
1139 init_var=init_var,
1140 kw_only=kw_only,
1141 coerce_numbers_to_str=coerce_numbers_to_str,
1142 strict=strict,
1143 gt=gt,
1144 ge=ge,
1145 lt=lt,
1146 le=le,
1147 multiple_of=multiple_of,
1148 min_length=min_length,
1149 max_length=max_length,
1150 allow_inf_nan=allow_inf_nan,
1151 max_digits=max_digits,
1152 decimal_places=decimal_places,
1153 union_mode=union_mode,
1154 fail_fast=fail_fast,
1155 )
1158_FIELD_ARG_NAMES = set(inspect.signature(Field).parameters)
1159_FIELD_ARG_NAMES.remove('extra') # do not include the varkwargs parameter
1162class ModelPrivateAttr(_repr.Representation):
1163 """A descriptor for private attributes in class models.
1165 !!! warning
1166 You generally shouldn't be creating `ModelPrivateAttr` instances directly, instead use
1167 `pydantic.fields.PrivateAttr`. (This is similar to `FieldInfo` vs. `Field`.)
1169 Attributes:
1170 default: The default value of the attribute if not provided.
1171 default_factory: A callable function that generates the default value of the
1172 attribute if not provided.
1173 """
1175 __slots__ = ('default', 'default_factory')
1177 def __init__(
1178 self, default: Any = PydanticUndefined, *, default_factory: typing.Callable[[], Any] | None = None
1179 ) -> None:
1180 if default is Ellipsis:
1181 self.default = PydanticUndefined
1182 else:
1183 self.default = default
1184 self.default_factory = default_factory
1186 if not typing.TYPE_CHECKING:
1187 # We put `__getattr__` in a non-TYPE_CHECKING block because otherwise, mypy allows arbitrary attribute access
1189 def __getattr__(self, item: str) -> Any:
1190 """This function improves compatibility with custom descriptors by ensuring delegation happens
1191 as expected when the default value of a private attribute is a descriptor.
1192 """
1193 if item in {'__get__', '__set__', '__delete__'}:
1194 if hasattr(self.default, item):
1195 return getattr(self.default, item)
1196 raise AttributeError(f'{type(self).__name__!r} object has no attribute {item!r}')
1198 def __set_name__(self, cls: type[Any], name: str) -> None:
1199 """Preserve `__set_name__` protocol defined in https://peps.python.org/pep-0487."""
1200 default = self.default
1201 if default is PydanticUndefined:
1202 return
1203 set_name = getattr(default, '__set_name__', None)
1204 if callable(set_name):
1205 set_name(cls, name)
1207 def get_default(self) -> Any:
1208 """Retrieve the default value of the object.
1210 If `self.default_factory` is `None`, the method will return a deep copy of the `self.default` object.
1212 If `self.default_factory` is not `None`, it will call `self.default_factory` and return the value returned.
1214 Returns:
1215 The default value of the object.
1216 """
1217 return _utils.smart_deepcopy(self.default) if self.default_factory is None else self.default_factory()
1219 def __eq__(self, other: Any) -> bool:
1220 return isinstance(other, self.__class__) and (self.default, self.default_factory) == (
1221 other.default,
1222 other.default_factory,
1223 )
1226# NOTE: Actual return type is 'ModelPrivateAttr', but we want to help type checkers
1227# to understand the magic that happens at runtime.
1228@overload # `default` argument set
1229def PrivateAttr(
1230 default: _T,
1231 *,
1232 init: Literal[False] = False,
1233) -> _T: ...
1234@overload # `default_factory` argument set
1235def PrivateAttr(
1236 *,
1237 default_factory: Callable[[], _T],
1238 init: Literal[False] = False,
1239) -> _T: ...
1240@overload # No default set
1241def PrivateAttr(
1242 *,
1243 init: Literal[False] = False,
1244) -> Any: ...
1245def PrivateAttr(
1246 default: Any = PydanticUndefined,
1247 *,
1248 default_factory: Callable[[], Any] | None = None,
1249 init: Literal[False] = False,
1250) -> Any:
1251 """!!! abstract "Usage Documentation"
1252 [Private Model Attributes](../concepts/models.md#private-model-attributes)
1254 Indicates that an attribute is intended for private use and not handled during normal validation/serialization.
1256 Private attributes are not validated by Pydantic, so it's up to you to ensure they are used in a type-safe manner.
1258 Private attributes are stored in `__private_attributes__` on the model.
1260 Args:
1261 default: The attribute's default value. Defaults to Undefined.
1262 default_factory: Callable that will be
1263 called when a default value is needed for this attribute.
1264 If both `default` and `default_factory` are set, an error will be raised.
1265 init: Whether the attribute should be included in the constructor of the dataclass. Always `False`.
1267 Returns:
1268 An instance of [`ModelPrivateAttr`][pydantic.fields.ModelPrivateAttr] class.
1270 Raises:
1271 ValueError: If both `default` and `default_factory` are set.
1272 """
1273 if default is not PydanticUndefined and default_factory is not None:
1274 raise TypeError('cannot specify both default and default_factory')
1276 return ModelPrivateAttr(
1277 default,
1278 default_factory=default_factory,
1279 )
1282@dataclasses.dataclass(**_internal_dataclass.slots_true)
1283class ComputedFieldInfo:
1284 """A container for data from `@computed_field` so that we can access it while building the pydantic-core schema.
1286 Attributes:
1287 decorator_repr: A class variable representing the decorator string, '@computed_field'.
1288 wrapped_property: The wrapped computed field property.
1289 return_type: The type of the computed field property's return value.
1290 alias: The alias of the property to be used during serialization.
1291 alias_priority: The priority of the alias. This affects whether an alias generator is used.
1292 title: Title of the computed field to include in the serialization JSON schema.
1293 field_title_generator: A callable that takes a field name and returns title for it.
1294 description: Description of the computed field to include in the serialization JSON schema.
1295 deprecated: A deprecation message, an instance of `warnings.deprecated` or the `typing_extensions.deprecated` backport,
1296 or a boolean. If `True`, a default deprecation message will be emitted when accessing the field.
1297 examples: Example values of the computed field to include in the serialization JSON schema.
1298 json_schema_extra: A dict or callable to provide extra JSON schema properties.
1299 repr: A boolean indicating whether to include the field in the __repr__ output.
1300 """
1302 decorator_repr: ClassVar[str] = '@computed_field'
1303 wrapped_property: property
1304 return_type: Any
1305 alias: str | None
1306 alias_priority: int | None
1307 title: str | None
1308 field_title_generator: typing.Callable[[str, ComputedFieldInfo], str] | None
1309 description: str | None
1310 deprecated: Deprecated | str | bool | None
1311 examples: list[Any] | None
1312 json_schema_extra: JsonDict | typing.Callable[[JsonDict], None] | None
1313 repr: bool
1315 @property
1316 def deprecation_message(self) -> str | None:
1317 """The deprecation message to be emitted, or `None` if not set."""
1318 if self.deprecated is None:
1319 return None
1320 if isinstance(self.deprecated, bool):
1321 return 'deprecated' if self.deprecated else None
1322 return self.deprecated if isinstance(self.deprecated, str) else self.deprecated.message
1325def _wrapped_property_is_private(property_: cached_property | property) -> bool: # type: ignore
1326 """Returns true if provided property is private, False otherwise."""
1327 wrapped_name: str = ''
1329 if isinstance(property_, property):
1330 wrapped_name = getattr(property_.fget, '__name__', '')
1331 elif isinstance(property_, cached_property): # type: ignore
1332 wrapped_name = getattr(property_.func, '__name__', '') # type: ignore
1334 return wrapped_name.startswith('_') and not wrapped_name.startswith('__')
1337# this should really be `property[T], cached_property[T]` but property is not generic unlike cached_property
1338# See https://github.com/python/typing/issues/985 and linked issues
1339PropertyT = typing.TypeVar('PropertyT')
1342@typing.overload
1343def computed_field(func: PropertyT, /) -> PropertyT: ...
1346@typing.overload
1347def computed_field(
1348 *,
1349 alias: str | None = None,
1350 alias_priority: int | None = None,
1351 title: str | None = None,
1352 field_title_generator: typing.Callable[[str, ComputedFieldInfo], str] | None = None,
1353 description: str | None = None,
1354 deprecated: Deprecated | str | bool | None = None,
1355 examples: list[Any] | None = None,
1356 json_schema_extra: JsonDict | typing.Callable[[JsonDict], None] | None = None,
1357 repr: bool = True,
1358 return_type: Any = PydanticUndefined,
1359) -> typing.Callable[[PropertyT], PropertyT]: ...
1362def computed_field(
1363 func: PropertyT | None = None,
1364 /,
1365 *,
1366 alias: str | None = None,
1367 alias_priority: int | None = None,
1368 title: str | None = None,
1369 field_title_generator: typing.Callable[[str, ComputedFieldInfo], str] | None = None,
1370 description: str | None = None,
1371 deprecated: Deprecated | str | bool | None = None,
1372 examples: list[Any] | None = None,
1373 json_schema_extra: JsonDict | typing.Callable[[JsonDict], None] | None = None,
1374 repr: bool | None = None,
1375 return_type: Any = PydanticUndefined,
1376) -> PropertyT | typing.Callable[[PropertyT], PropertyT]:
1377 """!!! abstract "Usage Documentation"
1378 [The `computed_field` decorator](../concepts/fields.md#the-computed_field-decorator)
1380 Decorator to include `property` and `cached_property` when serializing models or dataclasses.
1382 This is useful for fields that are computed from other fields, or for fields that are expensive to compute and should be cached.
1384 ```python
1385 from pydantic import BaseModel, computed_field
1387 class Rectangle(BaseModel):
1388 width: int
1389 length: int
1391 @computed_field
1392 @property
1393 def area(self) -> int:
1394 return self.width * self.length
1396 print(Rectangle(width=3, length=2).model_dump())
1397 #> {'width': 3, 'length': 2, 'area': 6}
1398 ```
1400 If applied to functions not yet decorated with `@property` or `@cached_property`, the function is
1401 automatically wrapped with `property`. Although this is more concise, you will lose IntelliSense in your IDE,
1402 and confuse static type checkers, thus explicit use of `@property` is recommended.
1404 !!! warning "Mypy Warning"
1405 Even with the `@property` or `@cached_property` applied to your function before `@computed_field`,
1406 mypy may throw a `Decorated property not supported` error.
1407 See [mypy issue #1362](https://github.com/python/mypy/issues/1362), for more information.
1408 To avoid this error message, add `# type: ignore[prop-decorator]` to the `@computed_field` line.
1410 [pyright](https://github.com/microsoft/pyright) supports `@computed_field` without error.
1412 ```python
1413 import random
1415 from pydantic import BaseModel, computed_field
1417 class Square(BaseModel):
1418 width: float
1420 @computed_field
1421 def area(self) -> float: # converted to a `property` by `computed_field`
1422 return round(self.width**2, 2)
1424 @area.setter
1425 def area(self, new_area: float) -> None:
1426 self.width = new_area**0.5
1428 @computed_field(alias='the magic number', repr=False)
1429 def random_number(self) -> int:
1430 return random.randint(0, 1_000)
1432 square = Square(width=1.3)
1434 # `random_number` does not appear in representation
1435 print(repr(square))
1436 #> Square(width=1.3, area=1.69)
1438 print(square.random_number)
1439 #> 3
1441 square.area = 4
1443 print(square.model_dump_json(by_alias=True))
1444 #> {"width":2.0,"area":4.0,"the magic number":3}
1445 ```
1447 !!! warning "Overriding with `computed_field`"
1448 You can't override a field from a parent class with a `computed_field` in the child class.
1449 `mypy` complains about this behavior if allowed, and `dataclasses` doesn't allow this pattern either.
1450 See the example below:
1452 ```python
1453 from pydantic import BaseModel, computed_field
1455 class Parent(BaseModel):
1456 a: str
1458 try:
1460 class Child(Parent):
1461 @computed_field
1462 @property
1463 def a(self) -> str:
1464 return 'new a'
1466 except TypeError as e:
1467 print(e)
1468 '''
1469 Field 'a' of class 'Child' overrides symbol of same name in a parent class. This override with a computed_field is incompatible.
1470 '''
1471 ```
1473 Private properties decorated with `@computed_field` have `repr=False` by default.
1475 ```python
1476 from functools import cached_property
1478 from pydantic import BaseModel, computed_field
1480 class Model(BaseModel):
1481 foo: int
1483 @computed_field
1484 @cached_property
1485 def _private_cached_property(self) -> int:
1486 return -self.foo
1488 @computed_field
1489 @property
1490 def _private_property(self) -> int:
1491 return -self.foo
1493 m = Model(foo=1)
1494 print(repr(m))
1495 #> Model(foo=1)
1496 ```
1498 Args:
1499 func: the function to wrap.
1500 alias: alias to use when serializing this computed field, only used when `by_alias=True`
1501 alias_priority: priority of the alias. This affects whether an alias generator is used
1502 title: Title to use when including this computed field in JSON Schema
1503 field_title_generator: A callable that takes a field name and returns title for it.
1504 description: Description to use when including this computed field in JSON Schema, defaults to the function's
1505 docstring
1506 deprecated: A deprecation message (or an instance of `warnings.deprecated` or the `typing_extensions.deprecated` backport).
1507 to be emitted when accessing the field. Or a boolean. This will automatically be set if the property is decorated with the
1508 `deprecated` decorator.
1509 examples: Example values to use when including this computed field in JSON Schema
1510 json_schema_extra: A dict or callable to provide extra JSON schema properties.
1511 repr: whether to include this computed field in model repr.
1512 Default is `False` for private properties and `True` for public properties.
1513 return_type: optional return for serialization logic to expect when serializing to JSON, if included
1514 this must be correct, otherwise a `TypeError` is raised.
1515 If you don't include a return type Any is used, which does runtime introspection to handle arbitrary
1516 objects.
1518 Returns:
1519 A proxy wrapper for the property.
1520 """
1522 def dec(f: Any) -> Any:
1523 nonlocal description, deprecated, return_type, alias_priority
1524 unwrapped = _decorators.unwrap_wrapped_function(f)
1526 if description is None and unwrapped.__doc__:
1527 description = inspect.cleandoc(unwrapped.__doc__)
1529 if deprecated is None and hasattr(unwrapped, '__deprecated__'):
1530 deprecated = unwrapped.__deprecated__
1532 # if the function isn't already decorated with `@property` (or another descriptor), then we wrap it now
1533 f = _decorators.ensure_property(f)
1534 alias_priority = (alias_priority or 2) if alias is not None else None
1536 if repr is None:
1537 repr_: bool = not _wrapped_property_is_private(property_=f)
1538 else:
1539 repr_ = repr
1541 dec_info = ComputedFieldInfo(
1542 f,
1543 return_type,
1544 alias,
1545 alias_priority,
1546 title,
1547 field_title_generator,
1548 description,
1549 deprecated,
1550 examples,
1551 json_schema_extra,
1552 repr_,
1553 )
1554 return _decorators.PydanticDescriptorProxy(f, dec_info)
1556 if func is None:
1557 return dec
1558 else:
1559 return dec(func)