Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/pydantic/fields.py: 62%
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 re
8import sys
9from collections.abc import Callable, Mapping
10from copy import copy
11from dataclasses import Field as DataclassField
12from functools import cached_property
13from typing import TYPE_CHECKING, Annotated, Any, ClassVar, Literal, TypeVar, final, overload
14from warnings import warn
16import annotated_types
17import typing_extensions
18from pydantic_core import MISSING, PydanticUndefined
19from typing_extensions import Self, TypeAlias, TypedDict, 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, AliasGenerator, AliasPath
27from .config import JsonDict
28from .errors import PydanticForbiddenQualifier, PydanticUserError
29from .json_schema import PydanticJsonSchemaWarning
30from .warnings import PydanticDeprecatedSince20
32if TYPE_CHECKING:
33 from ._internal._config import ConfigWrapper
34 from ._internal._repr import ReprArgs
37__all__ = 'Field', 'FieldInfo', 'PrivateAttr', 'computed_field'
40_Unset: Any = PydanticUndefined
42if sys.version_info >= (3, 13):
43 import warnings
45 Deprecated: TypeAlias = warnings.deprecated | deprecated
46else:
47 Deprecated: TypeAlias = deprecated
50class _FromFieldInfoInputs(TypedDict, total=False):
51 """This class exists solely to add type checking for the `**kwargs` in `FieldInfo.from_field`."""
53 # TODO PEP 747: use TypeForm:
54 annotation: type[Any] | None
55 default_factory: Callable[[], Any] | Callable[[dict[str, Any]], Any] | None
56 alias: str | None
57 alias_priority: int | None
58 validation_alias: str | AliasPath | AliasChoices | None
59 serialization_alias: str | None
60 title: str | None
61 field_title_generator: Callable[[str, FieldInfo], str] | None
62 description: str | None
63 examples: list[Any] | None
64 exclude: bool | None
65 exclude_if: Callable[[Any], bool] | None
66 gt: annotated_types.SupportsGt | None
67 ge: annotated_types.SupportsGe | None
68 lt: annotated_types.SupportsLt | None
69 le: annotated_types.SupportsLe | None
70 multiple_of: float | None
71 strict: bool | None
72 min_length: int | None
73 max_length: int | None
74 pattern: str | re.Pattern[str] | None
75 allow_inf_nan: bool | None
76 max_digits: int | None
77 decimal_places: int | None
78 union_mode: Literal['smart', 'left_to_right'] | None
79 discriminator: str | types.Discriminator | None
80 deprecated: Deprecated | str | bool | None
81 json_schema_extra: JsonDict | Callable[[JsonDict], None] | None
82 frozen: bool | None
83 validate_default: bool | None
84 repr: bool
85 init: bool | None
86 init_var: bool | None
87 kw_only: bool | None
88 coerce_numbers_to_str: bool | None
89 fail_fast: bool | None
92class _FieldInfoInputs(_FromFieldInfoInputs, total=False):
93 """This class exists solely to add type checking for the `**kwargs` in `FieldInfo.__init__`."""
95 default: Any
98class _FieldInfoAsDict(TypedDict, closed=True):
99 # TODO PEP 747: use TypeForm:
100 annotation: Any
101 metadata: list[Any]
102 attributes: dict[str, Any]
105@final
106class FieldInfo(_repr.Representation):
107 """This class holds information about a field.
109 `FieldInfo` is used for any field definition regardless of whether the [`Field()`][pydantic.fields.Field]
110 function is explicitly used.
112 !!! warning
113 The `FieldInfo` class is meant to expose information about a field in a Pydantic model or dataclass.
114 `FieldInfo` instances shouldn't be instantiated directly, nor mutated.
116 If you need to derive a new model from another one and are willing to alter `FieldInfo` instances,
117 refer to this [dynamic model example](../examples/dynamic_models.md).
119 Attributes:
120 annotation: The type annotation of the field.
121 default: The default value of the field.
122 default_factory: A callable to generate the default value. The callable can either take 0 arguments
123 (in which case it is called as is) or a single argument containing the already validated data.
124 alias: The alias name of the field.
125 alias_priority: The priority of the field's alias.
126 validation_alias: The validation alias of the field.
127 serialization_alias: The serialization alias of the field.
128 title: The title of the field.
129 field_title_generator: A callable that takes a field name and returns title for it.
130 description: The description of the field.
131 examples: List of examples of the field.
132 exclude: Whether to exclude the field from the model serialization.
133 exclude_if: A callable that determines whether to exclude a field during serialization based on its value.
134 discriminator: Field name or Discriminator for discriminating the type in a tagged union.
135 deprecated: A deprecation message, an instance of `warnings.deprecated` or the `typing_extensions.deprecated` backport,
136 or a boolean. If `True`, a default deprecation message will be emitted when accessing the field.
137 json_schema_extra: A dict or callable to provide extra JSON schema properties.
138 frozen: Whether the field is frozen.
139 validate_default: Whether to validate the default value of the field.
140 repr: Whether to include the field in representation of the model.
141 init: Whether the field should be included in the constructor of the dataclass.
142 init_var: Whether the field should _only_ be included in the constructor of the dataclass, and not stored.
143 kw_only: Whether the field should be a keyword-only argument in the constructor of the dataclass.
144 metadata: The metadata list. Contains all the data that isn't expressed as direct `FieldInfo` attributes, including:
146 * Type-specific constraints, such as `gt` or `min_length` (these are converted to metadata classes such as `annotated_types.Gt`).
147 * Any other arbitrary object used within [`Annotated`][typing.Annotated] metadata
148 (e.g. [custom types handlers](../concepts/types.md#as-an-annotation) or any object not recognized by Pydantic).
149 """
151 # TODO PEP 747: use TypeForm:
152 annotation: type[Any] | None
153 default: Any
154 default_factory: Callable[[], Any] | Callable[[dict[str, Any]], Any] | None
155 alias: str | None
156 alias_priority: int | None
157 validation_alias: str | AliasPath | AliasChoices | None
158 serialization_alias: str | None
159 title: str | None
160 field_title_generator: Callable[[str, FieldInfo], str] | None
161 description: str | None
162 examples: list[Any] | None
163 exclude: bool | None
164 exclude_if: Callable[[Any], bool] | None
165 discriminator: str | types.Discriminator | None
166 deprecated: Deprecated | str | bool | None
167 json_schema_extra: JsonDict | Callable[[JsonDict], None] | None
168 frozen: bool | None
169 validate_default: bool | None
170 repr: bool
171 init: bool | None
172 init_var: bool | None
173 kw_only: bool | None
174 metadata: list[Any]
176 __slots__ = (
177 'annotation',
178 'default',
179 'default_factory',
180 'alias',
181 'alias_priority',
182 'validation_alias',
183 'serialization_alias',
184 'title',
185 'field_title_generator',
186 'description',
187 'examples',
188 'exclude',
189 'exclude_if',
190 'discriminator',
191 'deprecated',
192 'json_schema_extra',
193 'frozen',
194 'validate_default',
195 'repr',
196 'init',
197 'init_var',
198 'kw_only',
199 'metadata',
200 '_attributes_set',
201 '_qualifiers',
202 '_complete',
203 '_original_assignment',
204 '_original_annotation',
205 '_final',
206 )
208 # used to convert kwargs to metadata/constraints,
209 # None has a special meaning - these items are collected into a `PydanticGeneralMetadata`
210 metadata_lookup: ClassVar[dict[str, Callable[[Any], Any] | None]] = {
211 'strict': types.Strict,
212 'gt': annotated_types.Gt,
213 'ge': annotated_types.Ge,
214 'lt': annotated_types.Lt,
215 'le': annotated_types.Le,
216 'multiple_of': annotated_types.MultipleOf,
217 'min_length': annotated_types.MinLen,
218 'max_length': annotated_types.MaxLen,
219 'pattern': None,
220 'allow_inf_nan': None,
221 'max_digits': None,
222 'decimal_places': None,
223 'union_mode': None,
224 'coerce_numbers_to_str': None,
225 'fail_fast': types.FailFast,
226 }
228 def __init__(self, **kwargs: Unpack[_FieldInfoInputs]) -> None:
229 """This class should generally not be initialized directly; instead, use the `pydantic.fields.Field` function
230 or one of the constructor classmethods.
232 See the signature of `pydantic.fields.Field` for more details about the expected arguments.
233 """
234 # Tracking the explicitly set attributes is necessary to correctly merge `Field()` functions
235 # (e.g. with `Annotated[int, Field(alias='a'), Field(alias=None)]`, even though `None` is the default value,
236 # we need to track that `alias=None` was explicitly set):
237 self._attributes_set = {k: v for k, v in kwargs.items() if v is not _Unset and k not in self.metadata_lookup}
238 kwargs = {k: _DefaultValues.get(k) if v is _Unset else v for k, v in kwargs.items()} # type: ignore
239 self.annotation = kwargs.get('annotation')
241 # Note: in theory, the second `pop()` arguments are not required below, as defaults are already set from `_DefaultsValues`.
242 default = kwargs.pop('default', PydanticUndefined)
243 if default is Ellipsis:
244 self.default = PydanticUndefined
245 self._attributes_set.pop('default', None)
246 else:
247 self.default = default
249 self.default_factory = kwargs.pop('default_factory', None)
251 if self.default is not PydanticUndefined and self.default_factory is not None:
252 raise TypeError('cannot specify both default and default_factory')
254 self.alias = kwargs.pop('alias', None)
255 self.validation_alias = kwargs.pop('validation_alias', None)
256 self.serialization_alias = kwargs.pop('serialization_alias', None)
257 alias_is_set = any(alias is not None for alias in (self.alias, self.validation_alias, self.serialization_alias))
258 self.alias_priority = kwargs.pop('alias_priority', None) or 2 if alias_is_set else None
259 self.title = kwargs.pop('title', None)
260 self.field_title_generator = kwargs.pop('field_title_generator', None)
261 self.description = kwargs.pop('description', None)
262 self.examples = kwargs.pop('examples', None)
263 self.exclude = kwargs.pop('exclude', None)
264 self.exclude_if = kwargs.pop('exclude_if', None)
265 self.discriminator = kwargs.pop('discriminator', None)
266 # For compatibility with FastAPI<=0.110.0, we preserve the existing value if it is not overridden
267 self.deprecated = kwargs.pop('deprecated', getattr(self, 'deprecated', None))
268 self.repr = kwargs.pop('repr', True)
269 self.json_schema_extra = kwargs.pop('json_schema_extra', None)
270 self.validate_default = kwargs.pop('validate_default', None)
271 self.frozen = kwargs.pop('frozen', None)
272 # currently only used on dataclasses
273 self.init = kwargs.pop('init', None)
274 self.init_var = kwargs.pop('init_var', None)
275 self.kw_only = kwargs.pop('kw_only', None)
277 self.metadata = self._collect_metadata(kwargs) # type: ignore
279 # Private attributes:
280 self._qualifiers: set[Qualifier] = set()
281 # Used to rebuild FieldInfo instances:
282 self._complete = True
283 self._original_annotation: Any = PydanticUndefined
284 self._original_assignment: Any = PydanticUndefined
285 # Used to track whether the `FieldInfo` instance represents the data about a field (and is exposed in `model_fields`/`__pydantic_fields__`),
286 # or if it is the result of the `Field()` function being used as metadata in an `Annotated` type/as an assignment
287 # (not an ideal pattern, see https://github.com/pydantic/pydantic/issues/11122):
288 self._final = False
290 @staticmethod
291 def from_field(default: Any = PydanticUndefined, **kwargs: Unpack[_FromFieldInfoInputs]) -> FieldInfo:
292 """Create a new `FieldInfo` object with the `Field` function.
294 Args:
295 default: The default value for the field. Defaults to Undefined.
296 **kwargs: Additional arguments dictionary.
298 Raises:
299 TypeError: If 'annotation' is passed as a keyword argument.
301 Returns:
302 A new FieldInfo object with the given parameters.
304 Example:
305 This is how you can create a field with default value like this:
307 ```python
308 import pydantic
310 class MyModel(pydantic.BaseModel):
311 foo: int = pydantic.Field(4)
312 ```
313 """
314 if 'annotation' in kwargs:
315 raise TypeError('"annotation" is not permitted as a Field keyword argument')
316 return FieldInfo(default=default, **kwargs)
318 @staticmethod
319 def from_annotation(annotation: type[Any], *, _source: AnnotationSource = AnnotationSource.ANY) -> FieldInfo:
320 """Creates a `FieldInfo` instance from a bare annotation.
322 This function is used internally to create a `FieldInfo` from a bare annotation like this:
324 ```python
325 import pydantic
327 class MyModel(pydantic.BaseModel):
328 foo: int # <-- like this
329 ```
331 We also account for the case where the annotation can be an instance of `Annotated` and where
332 one of the (not first) arguments in `Annotated` is an instance of `FieldInfo`, e.g.:
334 ```python
335 from typing import Annotated
337 import annotated_types
339 import pydantic
341 class MyModel(pydantic.BaseModel):
342 foo: Annotated[int, annotated_types.Gt(42)]
343 bar: Annotated[int, pydantic.Field(gt=42)]
344 ```
346 Args:
347 annotation: An annotation object.
349 Returns:
350 An instance of the field metadata.
351 """
352 try:
353 inspected_ann = inspect_annotation(
354 annotation,
355 annotation_source=_source,
356 unpack_type_aliases='skip',
357 )
358 except ForbiddenQualifier as e:
359 raise PydanticForbiddenQualifier(e.qualifier, annotation)
361 # TODO check for classvar and error?
363 # No assigned value, this happens when using a bare `Final` qualifier (also for other
364 # qualifiers, but they shouldn't appear here). In this case we infer the type as `Any`
365 # because we don't have any assigned value.
366 type_expr: Any = Any if inspected_ann.type is UNKNOWN else inspected_ann.type
367 final = 'final' in inspected_ann.qualifiers
368 metadata = inspected_ann.metadata
370 attr_overrides = {'annotation': type_expr}
371 if final:
372 attr_overrides['frozen'] = True
373 field_info = FieldInfo._construct(metadata, **attr_overrides)
374 field_info._qualifiers = inspected_ann.qualifiers
375 field_info._final = True
376 return field_info
378 @staticmethod
379 def from_annotated_attribute(
380 annotation: type[Any], default: Any, *, _source: AnnotationSource = AnnotationSource.ANY
381 ) -> FieldInfo:
382 """Create `FieldInfo` from an annotation with a default value.
384 This is used in cases like the following:
386 ```python
387 from typing import Annotated
389 import annotated_types
391 import pydantic
393 class MyModel(pydantic.BaseModel):
394 foo: int = 4 # <-- like this
395 bar: Annotated[int, annotated_types.Gt(4)] = 4 # <-- or this
396 spam: Annotated[int, pydantic.Field(gt=4)] = 4 # <-- or this
397 ```
399 Args:
400 annotation: The type annotation of the field.
401 default: The default value of the field.
403 Returns:
404 A field object with the passed values.
405 """
406 if annotation is not MISSING and annotation is default:
407 raise PydanticUserError(
408 'Error when building FieldInfo from annotated attribute. '
409 "Make sure you don't have any field name clashing with a type annotation.",
410 code='unevaluable-type-annotation',
411 )
413 try:
414 inspected_ann = inspect_annotation(
415 annotation,
416 annotation_source=_source,
417 unpack_type_aliases='skip',
418 )
419 except ForbiddenQualifier as e:
420 raise PydanticForbiddenQualifier(e.qualifier, annotation)
422 # TODO check for classvar and error?
424 # TODO infer from the default, this can be done in v3 once we treat final fields with
425 # a default as proper fields and not class variables:
426 type_expr: Any = Any if inspected_ann.type is UNKNOWN else inspected_ann.type
427 final = 'final' in inspected_ann.qualifiers
428 metadata = inspected_ann.metadata
430 # HACK 1: the order in which the metadata is merged is inconsistent; we need to prepend
431 # metadata from the assignment at the beginning of the metadata. Changing this is only
432 # possible in v3 (at least). See https://github.com/pydantic/pydantic/issues/10507
433 prepend_metadata: list[Any] | None = None
434 attr_overrides = {'annotation': type_expr}
435 if final:
436 attr_overrides['frozen'] = True
438 # HACK 2: FastAPI is subclassing `FieldInfo` and historically expected the actual
439 # instance's type to be preserved when constructing new models with its subclasses as assignments.
440 # This code is never reached by Pydantic itself, and in an ideal world this shouldn't be necessary.
441 if not metadata and isinstance(default, FieldInfo) and type(default) is not FieldInfo:
442 field_info = default._copy()
443 field_info._attributes_set.update(attr_overrides)
444 for k, v in attr_overrides.items():
445 setattr(field_info, k, v)
446 return field_info
448 if isinstance(default, FieldInfo):
449 default_copy = default._copy() # Copy unnecessary when we remove HACK 1.
450 prepend_metadata = default_copy.metadata
451 default_copy.metadata = []
452 metadata = metadata + [default_copy]
453 if 'init_var' in inspected_ann.qualifiers:
454 # Only relevant for dataclasses, when `f: InitVar[<type>] = Field(...)`
455 # is used:
456 attr_overrides['init_var'] = True
457 elif isinstance(default, dataclasses.Field):
458 from_field = FieldInfo._from_dataclass_field(default)
459 prepend_metadata = from_field.metadata # Unnecessary when we remove HACK 1.
460 from_field.metadata = []
461 metadata = metadata + [from_field]
462 if 'init_var' in inspected_ann.qualifiers:
463 attr_overrides['init_var'] = True
464 if (init := getattr(default, 'init', None)) is not None:
465 attr_overrides['init'] = init
466 if (kw_only := getattr(default, 'kw_only', None)) is not None:
467 attr_overrides['kw_only'] = kw_only
468 else:
469 # `default` is the actual default value
470 attr_overrides['default'] = default
472 field_info = FieldInfo._construct(
473 prepend_metadata + metadata if prepend_metadata is not None else metadata, **attr_overrides
474 )
475 field_info._qualifiers = inspected_ann.qualifiers
476 field_info._final = True
477 return field_info
479 @classmethod
480 def _construct(cls, metadata: list[Any], **attr_overrides: Any) -> Self:
481 """Construct the final `FieldInfo` instance, by merging the possibly existing `FieldInfo` instances from the metadata.
483 With the following example:
485 ```python {test="skip" lint="skip"}
486 class Model(BaseModel):
487 f: Annotated[int, Gt(1), Field(description='desc', lt=2)]
488 ```
490 `metadata` refers to the metadata elements of the `Annotated` form. This metadata is iterated over from left to right:
492 - If the element is a `Field()` function (which is itself a `FieldInfo` instance), the field attributes (such as
493 `description`) are saved to be set on the final `FieldInfo` instance.
494 On the other hand, some kwargs (such as `lt`) are stored as `metadata` (see `FieldInfo.__init__()`, calling
495 `FieldInfo._collect_metadata()`). In this case, the final metadata list is extended with the one from this instance.
496 - Else, the element is considered as a single metadata object, and is appended to the final metadata list.
498 Args:
499 metadata: The list of metadata elements to merge together. If the `FieldInfo` instance to be constructed is for
500 a field with an assigned `Field()`, this `Field()` assignment should be added as the last element of the
501 provided metadata.
502 **attr_overrides: Extra attributes that should be set on the final merged `FieldInfo` instance.
504 Returns:
505 The final merged `FieldInfo` instance.
506 """
507 merged_metadata: list[Any] = []
508 merged_kwargs: dict[str, Any] = {}
510 for meta in metadata:
511 if isinstance(meta, FieldInfo):
512 merged_metadata.extend(meta.metadata)
514 new_js_extra: JsonDict | None = None
515 current_js_extra = meta.json_schema_extra
516 if current_js_extra is not None and 'json_schema_extra' in merged_kwargs:
517 # We need to merge `json_schema_extra`'s:
518 existing_js_extra = merged_kwargs['json_schema_extra']
519 if isinstance(existing_js_extra, dict):
520 if isinstance(current_js_extra, dict):
521 new_js_extra = {
522 **existing_js_extra,
523 **current_js_extra,
524 }
525 elif callable(current_js_extra):
526 warn(
527 'Composing `dict` and `callable` type `json_schema_extra` is not supported. '
528 'The `callable` type is being ignored. '
529 "If you'd like support for this behavior, please open an issue on pydantic.",
530 UserWarning,
531 )
532 elif callable(existing_js_extra) and isinstance(current_js_extra, dict):
533 warn(
534 'Composing `dict` and `callable` type `json_schema_extra` is not supported. '
535 'The `callable` type is being ignored. '
536 "If you'd like support for this behavior, please open an issue on pydantic.",
537 UserWarning,
538 )
540 # HACK: It is common for users to define "make model partial" (or similar) utilities, that
541 # convert all model fields to be optional (i.e. have a default value). To do so, they mutate
542 # each `FieldInfo` instance from `model_fields` to set a `default`, and use `create_model()`
543 # with `Annotated[<orig_type> | None, mutated_field_info]`` as an annotation. However, such
544 # mutations (by doing simple assignments) are only accidentally working, because we also
545 # need to track attributes explicitly set in `_attributes_set` (relying on default values for
546 # each attribute is *not* enough, for instance with `Annotated[int, Field(alias='a'), Field(alias=None)]`
547 # the resulting `FieldInfo` should have `alias=None`).
548 # To mitigate this, we add a special case when a "final" `FieldInfo` instance (that is an instance coming
549 # from `model_fields`) is used in annotated metadata (or assignment). In this case, we assume *all* attributes
550 # were explicitly set, and as such we use all of them (and this will correctly pick up the mutations).
551 # In theory, this shouldn't really be supported, you are only supposed to use the `Field()` function, not
552 # a `FieldInfo` instance directly (granted, `Field()` returns a `FieldInfo`, see
553 # https://github.com/pydantic/pydantic/issues/11122):
554 if meta._final:
555 merged_kwargs.update({attr: getattr(meta, attr) for attr in _Attrs})
556 else:
557 merged_kwargs.update(meta._attributes_set)
559 if new_js_extra is not None:
560 merged_kwargs['json_schema_extra'] = new_js_extra
561 elif typing_objects.is_deprecated(meta):
562 merged_kwargs['deprecated'] = meta
563 else:
564 merged_metadata.append(meta)
566 merged_kwargs.update(attr_overrides)
567 merged_field_info = cls(**merged_kwargs)
568 merged_field_info.metadata = merged_metadata
569 return merged_field_info
571 @staticmethod
572 @typing_extensions.deprecated(
573 "The 'merge_field_infos()' method is deprecated and will be removed in a future version. "
574 'If you relied on this method, please open an issue in the Pydantic issue tracker.',
575 category=None,
576 )
577 def merge_field_infos(*field_infos: FieldInfo, **overrides: Any) -> FieldInfo:
578 """Merge `FieldInfo` instances keeping only explicitly set attributes.
580 Later `FieldInfo` instances override earlier ones.
582 Returns:
583 FieldInfo: A merged FieldInfo instance.
584 """
585 if len(field_infos) == 1:
586 # No merging necessary, but we still need to make a copy and apply the overrides
587 field_info = field_infos[0]._copy()
588 field_info._attributes_set.update(overrides)
590 default_override = overrides.pop('default', PydanticUndefined)
591 if default_override is Ellipsis:
592 default_override = PydanticUndefined
593 if default_override is not PydanticUndefined:
594 field_info.default = default_override
596 for k, v in overrides.items():
597 setattr(field_info, k, v)
598 return field_info # type: ignore
600 merged_field_info_kwargs: dict[str, Any] = {}
601 metadata = {}
602 for field_info in field_infos:
603 attributes_set = field_info._attributes_set.copy()
605 try:
606 json_schema_extra = attributes_set.pop('json_schema_extra')
607 existing_json_schema_extra = merged_field_info_kwargs.get('json_schema_extra')
609 if existing_json_schema_extra is None:
610 merged_field_info_kwargs['json_schema_extra'] = json_schema_extra
611 if isinstance(existing_json_schema_extra, dict):
612 if isinstance(json_schema_extra, dict):
613 merged_field_info_kwargs['json_schema_extra'] = {
614 **existing_json_schema_extra,
615 **json_schema_extra,
616 }
617 if callable(json_schema_extra):
618 warn(
619 'Composing `dict` and `callable` type `json_schema_extra` is not supported.'
620 'The `callable` type is being ignored.'
621 "If you'd like support for this behavior, please open an issue on pydantic.",
622 PydanticJsonSchemaWarning,
623 )
624 elif callable(json_schema_extra):
625 # if ever there's a case of a callable, we'll just keep the last json schema extra spec
626 merged_field_info_kwargs['json_schema_extra'] = json_schema_extra
627 except KeyError:
628 pass
630 # later FieldInfo instances override everything except json_schema_extra from earlier FieldInfo instances
631 merged_field_info_kwargs.update(attributes_set)
633 for x in field_info.metadata:
634 if not isinstance(x, FieldInfo):
635 metadata[type(x)] = x
637 merged_field_info_kwargs.update(overrides)
638 field_info = FieldInfo(**merged_field_info_kwargs)
639 field_info.metadata = list(metadata.values())
640 return field_info
642 @staticmethod
643 def _from_dataclass_field(dc_field: DataclassField[Any]) -> FieldInfo:
644 """Return a new `FieldInfo` instance from a `dataclasses.Field` instance.
646 Args:
647 dc_field: The `dataclasses.Field` instance to convert.
649 Returns:
650 The corresponding `FieldInfo` instance.
652 Raises:
653 TypeError: If any of the `FieldInfo` kwargs does not match the `dataclass.Field` kwargs.
654 """
655 default = dc_field.default
656 if default is dataclasses.MISSING:
657 default = _Unset
659 if dc_field.default_factory is dataclasses.MISSING:
660 default_factory = _Unset
661 else:
662 default_factory = dc_field.default_factory
664 # use the `Field` function so in correct kwargs raise the correct `TypeError`
665 dc_field_metadata = {k: v for k, v in dc_field.metadata.items() if k in _FIELD_ARG_NAMES}
666 if sys.version_info >= (3, 14) and dc_field.doc is not None:
667 dc_field_metadata['description'] = dc_field.doc
668 return Field(default=default, default_factory=default_factory, repr=dc_field.repr, **dc_field_metadata) # pyright: ignore[reportCallIssue]
670 @staticmethod
671 def _collect_metadata(kwargs: dict[str, Any]) -> list[Any]:
672 """Collect annotations from kwargs.
674 Args:
675 kwargs: Keyword arguments passed to the function.
677 Returns:
678 A list of metadata objects - a combination of `annotated_types.BaseMetadata` and
679 `PydanticMetadata`.
680 """
681 metadata: list[Any] = []
682 general_metadata = {}
683 for key, value in list(kwargs.items()):
684 try:
685 marker = FieldInfo.metadata_lookup[key]
686 except KeyError:
687 continue
689 del kwargs[key]
690 if value is not None:
691 if marker is None:
692 general_metadata[key] = value
693 else:
694 metadata.append(marker(value))
695 if general_metadata:
696 metadata.append(_fields.pydantic_general_metadata(**general_metadata))
697 return metadata
699 @property
700 def deprecation_message(self) -> str | None:
701 """The deprecation message to be emitted, or `None` if not set."""
702 if self.deprecated is None:
703 return None
704 if isinstance(self.deprecated, bool):
705 return 'deprecated' if self.deprecated else None
706 return self.deprecated if isinstance(self.deprecated, str) else self.deprecated.message
708 @property
709 def default_factory_takes_validated_data(self) -> bool | None:
710 """Whether the provided default factory callable has a validated data parameter.
712 Returns `None` if no default factory is set.
713 """
714 if self.default_factory is not None:
715 return _fields.takes_validated_data_argument(self.default_factory)
717 @overload
718 def get_default(
719 self, *, call_default_factory: Literal[True], validated_data: dict[str, Any] | None = None
720 ) -> Any: ...
722 @overload
723 def get_default(self, *, call_default_factory: Literal[False] = ...) -> Any: ...
725 def get_default(self, *, call_default_factory: bool = False, validated_data: dict[str, Any] | None = None) -> Any:
726 """Get the default value.
728 We expose an option for whether to call the default_factory (if present), as calling it may
729 result in side effects that we want to avoid. However, there are times when it really should
730 be called (namely, when instantiating a model via `model_construct`).
732 Args:
733 call_default_factory: Whether to call the default factory or not.
734 validated_data: The already validated data to be passed to the default factory.
736 Returns:
737 The default value, calling the default factory if requested or `PydanticUndefined` if not set.
738 """
739 return _fields.resolve_default_value(
740 default=self.default,
741 default_factory=self.default_factory,
742 validated_data=validated_data,
743 call_default_factory=call_default_factory,
744 )
746 def is_required(self) -> bool:
747 """Check if the field is required (i.e., does not have a default value or factory).
749 Returns:
750 `True` if the field is required, `False` otherwise.
751 """
752 return self.default is PydanticUndefined and self.default_factory is None
754 def rebuild_annotation(self) -> Any:
755 """Attempts to rebuild the original annotation for use in function signatures.
757 If metadata is present, it adds it to the original annotation using
758 `Annotated`. Otherwise, it returns the original annotation as-is.
760 Note that because the metadata has been flattened, the original annotation
761 may not be reconstructed exactly as originally provided, e.g. if the original
762 type had unrecognized annotations, or was annotated with a call to `pydantic.Field`.
764 Returns:
765 The rebuilt annotation.
766 """
767 if not self.metadata:
768 return self.annotation
769 else:
770 # Annotated arguments must be a tuple
771 return Annotated[(self.annotation, *self.metadata)] # type: ignore
773 def apply_typevars_map(
774 self,
775 typevars_map: Mapping[TypeVar, Any] | None,
776 globalns: GlobalsNamespace | None = None,
777 localns: MappingNamespace | None = None,
778 ) -> None:
779 """Apply a `typevars_map` to the annotation.
781 This method is used when analyzing parametrized generic types to replace typevars with their concrete types.
783 This method applies the `typevars_map` to the annotation in place.
785 Args:
786 typevars_map: A dictionary mapping type variables to their concrete types.
787 globalns: The globals namespace to use during type annotation evaluation.
788 localns: The locals namespace to use during type annotation evaluation.
790 See Also:
791 pydantic._internal._generics.replace_types is used for replacing the typevars with
792 their concrete types.
793 """
794 annotation = _generics.replace_types(self.annotation, typevars_map)
795 annotation, evaluated = _typing_extra.try_eval_type(annotation, globalns, localns)
796 self.annotation = annotation
797 if not evaluated:
798 self._complete = False
799 self._original_annotation = self.annotation
801 def asdict(self) -> _FieldInfoAsDict:
802 """Return a dictionary representation of the `FieldInfo` instance.
804 The returned value is a dictionary with three items:
806 * `annotation`: The type annotation of the field.
807 * `metadata`: The metadata list.
808 * `attributes`: A mapping of the remaining `FieldInfo` attributes to their values (e.g. `alias`, `title`).
809 """
810 return {
811 'annotation': self.annotation,
812 'metadata': self.metadata,
813 'attributes': {attr: getattr(self, attr) for attr in _Attrs},
814 }
816 def _copy(self) -> Self:
817 """Return a copy of the `FieldInfo` instance."""
818 # Note: we can't define a custom `__copy__()`, as `FieldInfo` is being subclassed
819 # by some third-party libraries with extra attributes defined (and as `FieldInfo`
820 # is slotted, we can't make a copy of the `__dict__`).
821 if type(self) is FieldInfo:
822 # Fast-path if the instance isn't a subclass (`copy.copy()` relies on pickling which is slower):
823 copied = FieldInfo.__new__(FieldInfo)
824 for attr_name in FieldInfo.__slots__:
825 setattr(copied, attr_name, getattr(self, attr_name))
826 else:
827 copied = copy(self)
829 for attr_name in ('metadata', '_attributes_set', '_qualifiers'):
830 # Apply "deep-copy" behavior on collections attributes:
831 setattr(copied, attr_name, getattr(copied, attr_name).copy())
833 return copied # pyright: ignore[reportReturnType]
835 def __repr_args__(self) -> ReprArgs:
836 yield 'annotation', _repr.PlainRepr(_repr.display_as_type(self.annotation))
837 yield 'required', self.is_required()
839 for s in self.__slots__:
840 # TODO: properly make use of the protocol (https://rich.readthedocs.io/en/stable/pretty.html#rich-repr-protocol)
841 # By yielding a three-tuple:
842 if s in (
843 'annotation',
844 '_attributes_set',
845 '_qualifiers',
846 '_complete',
847 '_original_assignment',
848 '_original_annotation',
849 '_final',
850 ):
851 continue
852 elif s == 'metadata' and not self.metadata:
853 continue
854 elif s == 'repr' and self.repr is True:
855 continue
856 if s == 'frozen' and self.frozen is False:
857 continue
858 if s == 'validation_alias' and self.validation_alias == self.alias:
859 continue
860 if s == 'serialization_alias' and self.serialization_alias == self.alias:
861 continue
862 if s == 'default' and self.default is not PydanticUndefined:
863 yield 'default', self.default
864 elif s == 'default_factory' and self.default_factory is not None:
865 yield 'default_factory', _repr.PlainRepr(_repr.display_as_type(self.default_factory))
866 else:
867 value = getattr(self, s)
868 if value is not None and value is not PydanticUndefined:
869 yield s, value
872class _EmptyKwargs(TypedDict):
873 """This class exists solely to ensure that type checking warns about passing `**extra` in `Field`."""
876_Attrs = {
877 'default': ...,
878 'default_factory': None,
879 'alias': None,
880 'alias_priority': None,
881 'validation_alias': None,
882 'serialization_alias': None,
883 'title': None,
884 'field_title_generator': None,
885 'description': None,
886 'examples': None,
887 'exclude': None,
888 'exclude_if': None,
889 'discriminator': None,
890 'deprecated': None,
891 'json_schema_extra': None,
892 'frozen': None,
893 'validate_default': None,
894 'repr': True,
895 'init': None,
896 'init_var': None,
897 'kw_only': None,
898}
900_DefaultValues = {
901 **_Attrs,
902 'kw_only': None,
903 'pattern': None,
904 'strict': None,
905 'gt': None,
906 'ge': None,
907 'lt': None,
908 'le': None,
909 'multiple_of': None,
910 'allow_inf_nan': None,
911 'max_digits': None,
912 'decimal_places': None,
913 'min_length': None,
914 'max_length': None,
915 'coerce_numbers_to_str': None,
916}
919_T = TypeVar('_T')
922# NOTE: Actual return type is 'FieldInfo', but we want to help type checkers
923# to understand the magic that happens at runtime with the following overloads:
924@overload # type hint the return value as `Any` to avoid type checking regressions when using `...`.
925def Field(
926 default: ellipsis, # noqa: F821 # TODO: use `_typing_extra.EllipsisType` when we drop Py3.9
927 *,
928 alias: str | None = _Unset,
929 alias_priority: int | None = _Unset,
930 validation_alias: str | AliasPath | AliasChoices | None = _Unset,
931 serialization_alias: str | None = _Unset,
932 title: str | None = _Unset,
933 field_title_generator: Callable[[str, FieldInfo], str] | None = _Unset,
934 description: str | None = _Unset,
935 examples: list[Any] | None = _Unset,
936 exclude: bool | None = _Unset,
937 exclude_if: Callable[[Any], bool] | None = _Unset,
938 discriminator: str | types.Discriminator | None = _Unset,
939 deprecated: Deprecated | str | bool | None = _Unset,
940 json_schema_extra: JsonDict | Callable[[JsonDict], None] | None = _Unset,
941 frozen: bool | None = _Unset,
942 validate_default: bool | None = _Unset,
943 repr: bool = _Unset,
944 init: bool | None = _Unset,
945 init_var: bool | None = _Unset,
946 kw_only: bool | None = _Unset,
947 pattern: str | re.Pattern[str] | None = _Unset,
948 strict: bool | None = _Unset,
949 coerce_numbers_to_str: bool | None = _Unset,
950 gt: annotated_types.SupportsGt | None = _Unset,
951 ge: annotated_types.SupportsGe | None = _Unset,
952 lt: annotated_types.SupportsLt | None = _Unset,
953 le: annotated_types.SupportsLe | None = _Unset,
954 multiple_of: float | None = _Unset,
955 allow_inf_nan: bool | None = _Unset,
956 max_digits: int | None = _Unset,
957 decimal_places: int | None = _Unset,
958 min_length: int | None = _Unset,
959 max_length: int | None = _Unset,
960 union_mode: Literal['smart', 'left_to_right'] = _Unset,
961 fail_fast: bool | None = _Unset,
962 **extra: Unpack[_EmptyKwargs],
963) -> Any: ...
964@overload # `default` argument set, validate_default=True (no type checking on the default value)
965def Field(
966 default: Any,
967 *,
968 alias: str | None = _Unset,
969 alias_priority: int | None = _Unset,
970 validation_alias: str | AliasPath | AliasChoices | None = _Unset,
971 serialization_alias: str | None = _Unset,
972 title: str | None = _Unset,
973 field_title_generator: Callable[[str, FieldInfo], str] | None = _Unset,
974 description: str | None = _Unset,
975 examples: list[Any] | None = _Unset,
976 exclude: bool | None = _Unset,
977 exclude_if: Callable[[Any], bool] | None = _Unset,
978 discriminator: str | types.Discriminator | None = _Unset,
979 deprecated: Deprecated | str | bool | None = _Unset,
980 json_schema_extra: JsonDict | Callable[[JsonDict], None] | None = _Unset,
981 frozen: bool | None = _Unset,
982 validate_default: Literal[True],
983 repr: bool = _Unset,
984 init: bool | None = _Unset,
985 init_var: bool | None = _Unset,
986 kw_only: bool | None = _Unset,
987 pattern: str | re.Pattern[str] | None = _Unset,
988 strict: bool | None = _Unset,
989 coerce_numbers_to_str: bool | None = _Unset,
990 gt: annotated_types.SupportsGt | None = _Unset,
991 ge: annotated_types.SupportsGe | None = _Unset,
992 lt: annotated_types.SupportsLt | None = _Unset,
993 le: annotated_types.SupportsLe | None = _Unset,
994 multiple_of: float | None = _Unset,
995 allow_inf_nan: bool | None = _Unset,
996 max_digits: int | None = _Unset,
997 decimal_places: int | None = _Unset,
998 min_length: int | None = _Unset,
999 max_length: int | None = _Unset,
1000 union_mode: Literal['smart', 'left_to_right'] = _Unset,
1001 fail_fast: bool | None = _Unset,
1002 **extra: Unpack[_EmptyKwargs],
1003) -> Any: ...
1004@overload # `default` argument set, validate_default=False or unset
1005def Field(
1006 default: _T,
1007 *,
1008 alias: str | None = _Unset,
1009 alias_priority: int | None = _Unset,
1010 validation_alias: str | AliasPath | AliasChoices | None = _Unset,
1011 serialization_alias: str | None = _Unset,
1012 title: str | None = _Unset,
1013 field_title_generator: Callable[[str, FieldInfo], str] | None = _Unset,
1014 description: str | None = _Unset,
1015 examples: list[Any] | None = _Unset,
1016 exclude: bool | None = _Unset,
1017 # NOTE: to get proper type checking on `exclude_if`'s argument, we could use `_T` instead of `Any`. However,
1018 # this requires (at least for pyright) adding an additional overload where `exclude_if` is required (otherwise
1019 # `a: int = Field(default_factory=str)` results in a false negative).
1020 exclude_if: Callable[[Any], bool] | None = _Unset,
1021 discriminator: str | types.Discriminator | None = _Unset,
1022 deprecated: Deprecated | str | bool | None = _Unset,
1023 json_schema_extra: JsonDict | Callable[[JsonDict], None] | None = _Unset,
1024 frozen: bool | None = _Unset,
1025 validate_default: Literal[False] = ...,
1026 repr: bool = _Unset,
1027 init: bool | None = _Unset,
1028 init_var: bool | None = _Unset,
1029 kw_only: bool | None = _Unset,
1030 pattern: str | re.Pattern[str] | None = _Unset,
1031 strict: bool | None = _Unset,
1032 coerce_numbers_to_str: bool | None = _Unset,
1033 gt: annotated_types.SupportsGt | None = _Unset,
1034 ge: annotated_types.SupportsGe | None = _Unset,
1035 lt: annotated_types.SupportsLt | None = _Unset,
1036 le: annotated_types.SupportsLe | None = _Unset,
1037 multiple_of: float | None = _Unset,
1038 allow_inf_nan: bool | None = _Unset,
1039 max_digits: int | None = _Unset,
1040 decimal_places: int | None = _Unset,
1041 min_length: int | None = _Unset,
1042 max_length: int | None = _Unset,
1043 union_mode: Literal['smart', 'left_to_right'] = _Unset,
1044 fail_fast: bool | None = _Unset,
1045 **extra: Unpack[_EmptyKwargs],
1046) -> _T: ...
1047@overload # `default_factory` argument set, validate_default=True (no type checking on the default value)
1048def Field( # pyright: ignore[reportOverlappingOverload]
1049 *,
1050 default_factory: Callable[[], Any] | Callable[[dict[str, Any]], Any],
1051 alias: str | None = _Unset,
1052 alias_priority: int | None = _Unset,
1053 validation_alias: str | AliasPath | AliasChoices | None = _Unset,
1054 serialization_alias: str | None = _Unset,
1055 title: str | None = _Unset,
1056 field_title_generator: Callable[[str, FieldInfo], str] | None = _Unset,
1057 description: str | None = _Unset,
1058 examples: list[Any] | None = _Unset,
1059 exclude: bool | None = _Unset,
1060 exclude_if: Callable[[Any], bool] | None = _Unset,
1061 discriminator: str | types.Discriminator | None = _Unset,
1062 deprecated: Deprecated | str | bool | None = _Unset,
1063 json_schema_extra: JsonDict | Callable[[JsonDict], None] | None = _Unset,
1064 frozen: bool | None = _Unset,
1065 validate_default: Literal[True],
1066 repr: bool = _Unset,
1067 init: bool | None = _Unset,
1068 init_var: bool | None = _Unset,
1069 kw_only: bool | None = _Unset,
1070 pattern: str | re.Pattern[str] | None = _Unset,
1071 strict: bool | None = _Unset,
1072 coerce_numbers_to_str: bool | None = _Unset,
1073 gt: annotated_types.SupportsGt | None = _Unset,
1074 ge: annotated_types.SupportsGe | None = _Unset,
1075 lt: annotated_types.SupportsLt | None = _Unset,
1076 le: annotated_types.SupportsLe | None = _Unset,
1077 multiple_of: float | None = _Unset,
1078 allow_inf_nan: bool | None = _Unset,
1079 max_digits: int | None = _Unset,
1080 decimal_places: int | None = _Unset,
1081 min_length: int | None = _Unset,
1082 max_length: int | None = _Unset,
1083 union_mode: Literal['smart', 'left_to_right'] = _Unset,
1084 fail_fast: bool | None = _Unset,
1085 **extra: Unpack[_EmptyKwargs],
1086) -> Any: ...
1087@overload # `default_factory` argument set, validate_default=False or unset
1088def Field(
1089 *,
1090 default_factory: Callable[[], _T] | Callable[[dict[str, Any]], _T],
1091 alias: str | None = _Unset,
1092 alias_priority: int | None = _Unset,
1093 validation_alias: str | AliasPath | AliasChoices | None = _Unset,
1094 serialization_alias: str | None = _Unset,
1095 title: str | None = _Unset,
1096 field_title_generator: Callable[[str, FieldInfo], str] | None = _Unset,
1097 description: str | None = _Unset,
1098 examples: list[Any] | None = _Unset,
1099 exclude: bool | None = _Unset,
1100 # NOTE: to get proper type checking on `exclude_if`'s argument, we could use `_T` instead of `Any`. However,
1101 # this requires (at least for pyright) adding an additional overload where `exclude_if` is required (otherwise
1102 # `a: int = Field(default_factory=str)` results in a false negative).
1103 exclude_if: Callable[[Any], bool] | None = _Unset,
1104 discriminator: str | types.Discriminator | None = _Unset,
1105 deprecated: Deprecated | str | bool | None = _Unset,
1106 json_schema_extra: JsonDict | Callable[[JsonDict], None] | None = _Unset,
1107 frozen: bool | None = _Unset,
1108 validate_default: Literal[False] | None = _Unset,
1109 repr: bool = _Unset,
1110 init: bool | None = _Unset,
1111 init_var: bool | None = _Unset,
1112 kw_only: bool | None = _Unset,
1113 pattern: str | re.Pattern[str] | None = _Unset,
1114 strict: bool | None = _Unset,
1115 coerce_numbers_to_str: bool | None = _Unset,
1116 gt: annotated_types.SupportsGt | None = _Unset,
1117 ge: annotated_types.SupportsGe | None = _Unset,
1118 lt: annotated_types.SupportsLt | None = _Unset,
1119 le: annotated_types.SupportsLe | None = _Unset,
1120 multiple_of: float | None = _Unset,
1121 allow_inf_nan: bool | None = _Unset,
1122 max_digits: int | None = _Unset,
1123 decimal_places: int | None = _Unset,
1124 min_length: int | None = _Unset,
1125 max_length: int | None = _Unset,
1126 union_mode: Literal['smart', 'left_to_right'] = _Unset,
1127 fail_fast: bool | None = _Unset,
1128 **extra: Unpack[_EmptyKwargs],
1129) -> _T: ...
1130@overload
1131def Field( # No default set
1132 *,
1133 alias: str | None = _Unset,
1134 alias_priority: int | None = _Unset,
1135 validation_alias: str | AliasPath | AliasChoices | None = _Unset,
1136 serialization_alias: str | None = _Unset,
1137 title: str | None = _Unset,
1138 field_title_generator: Callable[[str, FieldInfo], str] | None = _Unset,
1139 description: str | None = _Unset,
1140 examples: list[Any] | None = _Unset,
1141 exclude: bool | None = _Unset,
1142 exclude_if: Callable[[Any], bool] | None = _Unset,
1143 discriminator: str | types.Discriminator | None = _Unset,
1144 deprecated: Deprecated | str | bool | None = _Unset,
1145 json_schema_extra: JsonDict | Callable[[JsonDict], None] | None = _Unset,
1146 frozen: bool | None = _Unset,
1147 validate_default: bool | None = _Unset,
1148 repr: bool = _Unset,
1149 init: bool | None = _Unset,
1150 init_var: bool | None = _Unset,
1151 kw_only: bool | None = _Unset,
1152 pattern: str | re.Pattern[str] | None = _Unset,
1153 strict: bool | None = _Unset,
1154 coerce_numbers_to_str: bool | None = _Unset,
1155 gt: annotated_types.SupportsGt | None = _Unset,
1156 ge: annotated_types.SupportsGe | None = _Unset,
1157 lt: annotated_types.SupportsLt | None = _Unset,
1158 le: annotated_types.SupportsLe | None = _Unset,
1159 multiple_of: float | None = _Unset,
1160 allow_inf_nan: bool | None = _Unset,
1161 max_digits: int | None = _Unset,
1162 decimal_places: int | None = _Unset,
1163 min_length: int | None = _Unset,
1164 max_length: int | None = _Unset,
1165 union_mode: Literal['smart', 'left_to_right'] = _Unset,
1166 fail_fast: bool | None = _Unset,
1167 **extra: Unpack[_EmptyKwargs],
1168) -> Any: ...
1169def Field( # noqa: C901
1170 default: Any = PydanticUndefined,
1171 *,
1172 default_factory: Callable[[], Any] | Callable[[dict[str, Any]], Any] | None = _Unset,
1173 alias: str | None = _Unset,
1174 alias_priority: int | None = _Unset,
1175 validation_alias: str | AliasPath | AliasChoices | None = _Unset,
1176 serialization_alias: str | None = _Unset,
1177 title: str | None = _Unset,
1178 field_title_generator: Callable[[str, FieldInfo], str] | None = _Unset,
1179 description: str | None = _Unset,
1180 examples: list[Any] | None = _Unset,
1181 exclude: bool | None = _Unset,
1182 exclude_if: Callable[[Any], bool] | None = _Unset,
1183 discriminator: str | types.Discriminator | None = _Unset,
1184 deprecated: Deprecated | str | bool | None = _Unset,
1185 json_schema_extra: JsonDict | Callable[[JsonDict], None] | None = _Unset,
1186 frozen: bool | None = _Unset,
1187 validate_default: bool | None = _Unset,
1188 repr: bool = _Unset,
1189 init: bool | None = _Unset,
1190 init_var: bool | None = _Unset,
1191 kw_only: bool | None = _Unset,
1192 pattern: str | re.Pattern[str] | None = _Unset,
1193 strict: bool | None = _Unset,
1194 coerce_numbers_to_str: bool | None = _Unset,
1195 gt: annotated_types.SupportsGt | None = _Unset,
1196 ge: annotated_types.SupportsGe | None = _Unset,
1197 lt: annotated_types.SupportsLt | None = _Unset,
1198 le: annotated_types.SupportsLe | None = _Unset,
1199 multiple_of: float | None = _Unset,
1200 allow_inf_nan: bool | None = _Unset,
1201 max_digits: int | None = _Unset,
1202 decimal_places: int | None = _Unset,
1203 min_length: int | None = _Unset,
1204 max_length: int | None = _Unset,
1205 union_mode: Literal['smart', 'left_to_right'] = _Unset,
1206 fail_fast: bool | None = _Unset,
1207 **extra: Unpack[_EmptyKwargs],
1208) -> Any:
1209 """!!! abstract "Usage Documentation"
1210 [Fields](../concepts/fields.md)
1212 Create a field for objects that can be configured.
1214 Used to provide extra information about a field, either for the model schema or complex validation. Some arguments
1215 apply only to number fields (`int`, `float`, `Decimal`) and some apply only to `str`.
1217 Note:
1218 - 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`
1220 Args:
1221 default: Default value if the field is not set.
1222 default_factory: A callable to generate the default value. The callable can either take 0 arguments
1223 (in which case it is called as is) or a single argument containing the already validated data.
1224 alias: The name to use for the attribute when validating or serializing by alias.
1225 This is often used for things like converting between snake and camel case.
1226 alias_priority: Priority of the alias. This affects whether an alias generator is used.
1227 validation_alias: Like `alias`, but only affects validation, not serialization.
1228 serialization_alias: Like `alias`, but only affects serialization, not validation.
1229 title: Human-readable title.
1230 field_title_generator: A callable that takes a field name and returns title for it.
1231 description: Human-readable description.
1232 examples: Example values for this field.
1233 exclude: Whether to exclude the field from the model serialization.
1234 exclude_if: A callable that determines whether to exclude a field during serialization based on its value.
1235 discriminator: Field name or Discriminator for discriminating the type in a tagged union.
1236 deprecated: A deprecation message, an instance of `warnings.deprecated` or the `typing_extensions.deprecated` backport,
1237 or a boolean. If `True`, a default deprecation message will be emitted when accessing the field.
1238 json_schema_extra: A dict or callable to provide extra JSON schema properties.
1239 frozen: Whether the field is frozen. If true, attempts to change the value on an instance will raise an error.
1240 validate_default: If `True`, apply validation to the default value every time you create an instance.
1241 Otherwise, for performance reasons, the default value of the field is trusted and not validated.
1242 repr: A boolean indicating whether to include the field in the `__repr__` output.
1243 init: Whether the field should be included in the constructor of the dataclass.
1244 (Only applies to dataclasses.)
1245 init_var: Whether the field should _only_ be included in the constructor of the dataclass.
1246 (Only applies to dataclasses.)
1247 kw_only: Whether the field should be a keyword-only argument in the constructor of the dataclass.
1248 (Only applies to dataclasses.)
1249 coerce_numbers_to_str: Whether to enable coercion of any `Number` type to `str` (not applicable in `strict` mode).
1250 strict: If `True`, strict validation is applied to the field.
1251 See [Strict Mode](../concepts/strict_mode.md) for details.
1252 gt: Greater than. If set, value must be greater than this. Only applicable to numbers.
1253 ge: Greater than or equal. If set, value must be greater than or equal to this. Only applicable to numbers.
1254 lt: Less than. If set, value must be less than this. Only applicable to numbers.
1255 le: Less than or equal. If set, value must be less than or equal to this. Only applicable to numbers.
1256 multiple_of: Value must be a multiple of this. Only applicable to numbers.
1257 min_length: Minimum length for iterables.
1258 max_length: Maximum length for iterables.
1259 pattern: Pattern for strings (a regular expression).
1260 allow_inf_nan: Allow `inf`, `-inf`, `nan`. Only applicable to float and [`Decimal`][decimal.Decimal] numbers.
1261 max_digits: Maximum number of allow digits for strings.
1262 decimal_places: Maximum number of decimal places allowed for numbers.
1263 union_mode: The strategy to apply when validating a union. Can be `smart` (the default), or `left_to_right`.
1264 See [Union Mode](../concepts/unions.md#union-modes) for details.
1265 fail_fast: If `True`, validation will stop on the first error. If `False`, all validation errors will be collected.
1266 This option can be applied only to iterable types (list, tuple, set, and frozenset).
1267 extra: (Deprecated) Extra fields that will be included in the JSON schema.
1269 !!! warning Deprecated
1270 The `extra` kwargs is deprecated. Use `json_schema_extra` instead.
1272 Returns:
1273 A new [`FieldInfo`][pydantic.fields.FieldInfo]. The return annotation is `Any` so `Field` can be used on
1274 type-annotated fields without causing a type error.
1275 """
1276 # Check deprecated and removed params from V1. This logic should eventually be removed.
1277 const = extra.pop('const', None) # type: ignore
1278 if const is not None:
1279 raise PydanticUserError('`const` is removed, use `Literal` instead', code='removed-kwargs')
1281 min_items = extra.pop('min_items', None) # type: ignore
1282 if min_items is not None:
1283 warn(
1284 '`min_items` is deprecated and will be removed, use `min_length` instead',
1285 PydanticDeprecatedSince20,
1286 stacklevel=2,
1287 )
1288 if min_length in (None, _Unset):
1289 min_length = min_items # type: ignore
1291 max_items = extra.pop('max_items', None) # type: ignore
1292 if max_items is not None:
1293 warn(
1294 '`max_items` is deprecated and will be removed, use `max_length` instead',
1295 PydanticDeprecatedSince20,
1296 stacklevel=2,
1297 )
1298 if max_length in (None, _Unset):
1299 max_length = max_items # type: ignore
1301 unique_items = extra.pop('unique_items', None) # type: ignore
1302 if unique_items is not None:
1303 raise PydanticUserError(
1304 (
1305 '`unique_items` is removed, use `Set` instead'
1306 '(this feature is discussed in https://github.com/pydantic/pydantic-core/issues/296)'
1307 ),
1308 code='removed-kwargs',
1309 )
1311 allow_mutation = extra.pop('allow_mutation', None) # type: ignore
1312 if allow_mutation is not None:
1313 warn(
1314 '`allow_mutation` is deprecated and will be removed. use `frozen` instead',
1315 PydanticDeprecatedSince20,
1316 stacklevel=2,
1317 )
1318 if allow_mutation is False:
1319 frozen = True
1321 regex = extra.pop('regex', None) # type: ignore
1322 if regex is not None:
1323 raise PydanticUserError('`regex` is removed. use `pattern` instead', code='removed-kwargs')
1325 if extra:
1326 warn(
1327 'Using extra keyword arguments on `Field` is deprecated and will be removed.'
1328 ' Use `json_schema_extra` instead.'
1329 f' (Extra keys: {", ".join(k.__repr__() for k in extra.keys())})',
1330 PydanticDeprecatedSince20,
1331 stacklevel=2,
1332 )
1333 if not json_schema_extra or json_schema_extra is _Unset:
1334 json_schema_extra = extra # type: ignore
1336 if (
1337 validation_alias
1338 and validation_alias is not _Unset
1339 and not isinstance(validation_alias, (str, AliasChoices, AliasPath))
1340 ):
1341 raise TypeError('Invalid `validation_alias` type. it should be `str`, `AliasChoices`, or `AliasPath`')
1343 if serialization_alias in (_Unset, None) and isinstance(alias, str):
1344 serialization_alias = alias
1346 if validation_alias in (_Unset, None):
1347 validation_alias = alias
1349 include = extra.pop('include', None) # type: ignore
1350 if include is not None:
1351 warn(
1352 '`include` is deprecated and does nothing. It will be removed, use `exclude` instead',
1353 PydanticDeprecatedSince20,
1354 stacklevel=2,
1355 )
1357 return FieldInfo.from_field(
1358 default,
1359 default_factory=default_factory,
1360 alias=alias,
1361 alias_priority=alias_priority,
1362 validation_alias=validation_alias,
1363 serialization_alias=serialization_alias,
1364 title=title,
1365 field_title_generator=field_title_generator,
1366 description=description,
1367 examples=examples,
1368 exclude=exclude,
1369 exclude_if=exclude_if,
1370 discriminator=discriminator,
1371 deprecated=deprecated,
1372 json_schema_extra=json_schema_extra,
1373 frozen=frozen,
1374 pattern=pattern,
1375 validate_default=validate_default,
1376 repr=repr,
1377 init=init,
1378 init_var=init_var,
1379 kw_only=kw_only,
1380 coerce_numbers_to_str=coerce_numbers_to_str,
1381 strict=strict,
1382 gt=gt,
1383 ge=ge,
1384 lt=lt,
1385 le=le,
1386 multiple_of=multiple_of,
1387 min_length=min_length,
1388 max_length=max_length,
1389 allow_inf_nan=allow_inf_nan,
1390 max_digits=max_digits,
1391 decimal_places=decimal_places,
1392 union_mode=union_mode,
1393 fail_fast=fail_fast,
1394 )
1397_FIELD_ARG_NAMES = set(inspect.signature(Field).parameters)
1398_FIELD_ARG_NAMES.remove('extra') # do not include the varkwargs parameter
1401class ModelPrivateAttr(_repr.Representation):
1402 """A descriptor for private attributes in class models.
1404 !!! warning
1405 You generally shouldn't be creating `ModelPrivateAttr` instances directly, instead use
1406 `pydantic.fields.PrivateAttr`. (This is similar to `FieldInfo` vs. `Field`.)
1408 Attributes:
1409 default: The default value of the attribute if not provided.
1410 default_factory: A callable to generate the default value. The callable can either take 0 arguments
1411 (in which case it is called as is) or a single argument containing the validated data (the model's
1412 [`__dict__`][object.__dict__]) and the already initialized private attributes.
1413 """
1415 __slots__ = ('default', 'default_factory')
1417 def __init__(
1418 self,
1419 default: Any = PydanticUndefined,
1420 *,
1421 default_factory: Callable[[], Any] | Callable[[dict[str, Any]], Any] | None = None,
1422 ) -> None:
1423 if default is Ellipsis:
1424 self.default = PydanticUndefined
1425 else:
1426 self.default = default
1427 self.default_factory = default_factory
1429 if not TYPE_CHECKING:
1430 # We put `__getattr__` in a non-TYPE_CHECKING block because otherwise, mypy allows arbitrary attribute access
1432 def __getattr__(self, item: str) -> Any:
1433 """This function improves compatibility with custom descriptors by ensuring delegation happens
1434 as expected when the default value of a private attribute is a descriptor.
1435 """
1436 if item in {'__get__', '__set__', '__delete__'}:
1437 if hasattr(self.default, item):
1438 return getattr(self.default, item)
1439 raise AttributeError(f'{type(self).__name__!r} object has no attribute {item!r}')
1441 def __set_name__(self, cls: type[Any], name: str) -> None:
1442 """Preserve `__set_name__` protocol defined in https://peps.python.org/pep-0487."""
1443 default = self.default
1444 if default is PydanticUndefined:
1445 return
1446 set_name = getattr(default, '__set_name__', None)
1447 if callable(set_name):
1448 set_name(cls, name)
1450 @property
1451 def default_factory_takes_validated_data(self) -> bool | None:
1452 """Whether the provided default factory callable has a validated data parameter.
1454 Returns `None` if no default factory is set.
1455 """
1456 if self.default_factory is not None:
1457 return _fields.takes_validated_data_argument(self.default_factory)
1459 @overload
1460 def get_default(
1461 self, *, call_default_factory: Literal[True], validated_data: dict[str, Any] | None = None
1462 ) -> Any: ...
1464 @overload
1465 def get_default(self, *, call_default_factory: Literal[False] = ...) -> Any: ...
1467 def get_default(self, *, call_default_factory: bool = False, validated_data: dict[str, Any] | None = None) -> Any:
1468 """Get the default value.
1470 We expose an option for whether to call the default_factory (if present), as calling it may
1471 result in side effects that we want to avoid. However, there are times when it really should
1472 be called (namely, when instantiating a model via `model_construct`).
1474 Args:
1475 call_default_factory: Whether to call the default factory or not.
1476 validated_data: The already validated data to be passed to the default factory.
1478 Returns:
1479 The default value, calling the default factory if requested or `None` if not set.
1480 """
1481 return _fields.resolve_default_value(
1482 default=self.default,
1483 default_factory=self.default_factory,
1484 validated_data=validated_data,
1485 call_default_factory=call_default_factory,
1486 )
1488 def __eq__(self, other: Any) -> bool:
1489 return isinstance(other, self.__class__) and (self.default, self.default_factory) == (
1490 other.default,
1491 other.default_factory,
1492 )
1495# NOTE: Actual return type is 'ModelPrivateAttr', but we want to help type checkers
1496# to understand the magic that happens at runtime.
1497@overload # `default` argument set
1498def PrivateAttr(
1499 default: _T,
1500 *,
1501 init: Literal[False] = False,
1502) -> _T: ...
1503@overload # `default_factory` argument set
1504def PrivateAttr(
1505 *,
1506 default_factory: Callable[[], _T] | Callable[[dict[str, Any]], _T],
1507 init: Literal[False] = False,
1508) -> _T: ...
1509@overload # No default set
1510def PrivateAttr(
1511 *,
1512 init: Literal[False] = False,
1513) -> Any: ...
1514def PrivateAttr(
1515 default: Any = PydanticUndefined,
1516 *,
1517 default_factory: Callable[[], Any] | Callable[[dict[str, Any]], Any] | None = None,
1518 init: Literal[False] = False,
1519) -> Any:
1520 """!!! abstract "Usage Documentation"
1521 [Private Model Attributes](../concepts/models.md#private-model-attributes)
1523 Indicates that an attribute is intended for private use and not handled during normal validation/serialization.
1525 Private attributes are not validated by Pydantic, so it's up to you to ensure they are used in a type-safe manner.
1527 Private attributes are stored in `__private_attributes__` on the model.
1529 Args:
1530 default: The attribute's default value. Defaults to Undefined.
1531 default_factory: A callable to generate the default value. The callable can either take 0 arguments
1532 (in which case it is called as is) or a single argument containing the validated data (the model's
1533 [`__dict__`][object.__dict__]) and the already initialized private attributes.
1534 If both `default` and `default_factory` are set, an error will be raised.
1535 init: Whether the attribute should be included in the constructor of the dataclass. Always `False`.
1537 Returns:
1538 An instance of [`ModelPrivateAttr`][pydantic.fields.ModelPrivateAttr] class.
1540 Raises:
1541 ValueError: If both `default` and `default_factory` are set.
1542 """
1543 if default is not PydanticUndefined and default_factory is not None:
1544 raise TypeError('cannot specify both default and default_factory')
1546 return ModelPrivateAttr(
1547 default,
1548 default_factory=default_factory,
1549 )
1552@dataclasses.dataclass(**_internal_dataclass.slots_true)
1553class ComputedFieldInfo:
1554 """A container for data from `@computed_field` so that we can access it while building the pydantic-core schema.
1556 Attributes:
1557 decorator_repr: A class variable representing the decorator string, '@computed_field'.
1558 wrapped_property: The wrapped computed field property.
1559 return_type: The type of the computed field property's return value.
1560 alias: The alias of the property to be used during serialization.
1561 alias_priority: The priority of the alias. This affects whether an alias generator is used.
1562 title: Title of the computed field to include in the serialization JSON schema.
1563 field_title_generator: A callable that takes a field name and returns title for it.
1564 description: Description of the computed field to include in the serialization JSON schema.
1565 deprecated: A deprecation message, an instance of `warnings.deprecated` or the `typing_extensions.deprecated` backport,
1566 or a boolean. If `True`, a default deprecation message will be emitted when accessing the field.
1567 examples: Example values of the computed field to include in the serialization JSON schema.
1568 json_schema_extra: A dict or callable to provide extra JSON schema properties.
1569 repr: A boolean indicating whether to include the field in the __repr__ output.
1570 """
1572 decorator_repr: ClassVar[str] = '@computed_field'
1573 wrapped_property: property
1574 return_type: Any
1575 alias: str | None
1576 alias_priority: int | None
1577 exclude_if: Callable[[Any], bool] | None
1578 title: str | None
1579 field_title_generator: Callable[[str, ComputedFieldInfo], str] | None
1580 description: str | None
1581 deprecated: Deprecated | str | bool | None
1582 examples: list[Any] | None
1583 json_schema_extra: JsonDict | Callable[[JsonDict], None] | None
1584 repr: bool
1585 # NOTE: if you add a new field, add it to the `__copy__()` implementation.
1587 def __copy__(self) -> Self:
1588 return type(self)(
1589 wrapped_property=self.wrapped_property,
1590 return_type=self.return_type,
1591 alias=self.alias,
1592 alias_priority=self.alias_priority,
1593 exclude_if=self.exclude_if,
1594 title=self.title,
1595 field_title_generator=self.field_title_generator,
1596 description=self.description,
1597 deprecated=self.deprecated,
1598 examples=self.examples.copy() if isinstance(self.examples, list) else self.examples,
1599 json_schema_extra=self.json_schema_extra.copy()
1600 if isinstance(self.json_schema_extra, dict)
1601 else self.json_schema_extra,
1602 repr=self.repr,
1603 )
1605 @property
1606 def deprecation_message(self) -> str | None:
1607 """The deprecation message to be emitted, or `None` if not set."""
1608 if self.deprecated is None:
1609 return None
1610 if isinstance(self.deprecated, bool):
1611 return 'deprecated' if self.deprecated else None
1612 return self.deprecated if isinstance(self.deprecated, str) else self.deprecated.message
1614 def _update_from_config(self, config_wrapper: ConfigWrapper, name: str) -> None:
1615 """Update the instance from the configuration set on the class this computed field belongs to."""
1616 title_generator = self.field_title_generator or config_wrapper.field_title_generator
1617 if title_generator is not None and self.title is None:
1618 self.title = title_generator(name, self)
1619 if config_wrapper.alias_generator is not None:
1620 self._apply_alias_generator(config_wrapper.alias_generator, name)
1622 def _apply_alias_generator(self, alias_generator: Callable[[str], str] | AliasGenerator, name: str) -> None:
1623 """Apply an alias generator to aliases if appropriate.
1625 Args:
1626 alias_generator: A callable that takes a string and returns a string, or an `AliasGenerator` instance.
1627 name: The name of the computed field from which to generate the alias.
1628 """
1629 # Apply an alias_generator if
1630 # 1. An alias is not specified
1631 # 2. An alias is specified, but the priority is <= 1
1633 if self.alias_priority is None or self.alias_priority <= 1 or self.alias is None:
1634 alias, _, serialization_alias = None, None, None
1636 if isinstance(alias_generator, AliasGenerator):
1637 alias, _, serialization_alias = alias_generator.generate_aliases(name)
1638 elif callable(alias_generator):
1639 alias = alias_generator(name)
1641 # if priority is not set, we set to 1
1642 # which supports the case where the alias_generator from a child class is used
1643 # to generate an alias for a field in a parent class
1644 if self.alias_priority is None or self.alias_priority <= 1:
1645 self.alias_priority = 1
1647 # if the priority is 1, then we set the aliases to the generated alias
1648 # note that we use the serialization_alias with priority over alias, as computed_field
1649 # aliases are used for serialization only (not validation)
1650 if self.alias_priority == 1:
1651 self.alias = _utils.get_first_not_none(serialization_alias, alias)
1654def _wrapped_property_is_private(property_: cached_property | property) -> bool: # type: ignore
1655 """Returns true if provided property is private, False otherwise."""
1656 wrapped_name: str = ''
1658 if isinstance(property_, property):
1659 wrapped_name = getattr(property_.fget, '__name__', '')
1660 elif isinstance(property_, cached_property): # type: ignore
1661 wrapped_name = getattr(property_.func, '__name__', '') # type: ignore
1663 return wrapped_name.startswith('_') and not wrapped_name.startswith('__')
1666# this should really be `property[T], cached_property[T]` but property is not generic unlike cached_property
1667# See https://github.com/python/typing/issues/985 and linked issues
1668PropertyT = TypeVar('PropertyT')
1671@overload
1672def computed_field(func: PropertyT, /) -> PropertyT: ...
1675@overload
1676def computed_field(
1677 *,
1678 alias: str | None = None,
1679 alias_priority: int | None = None,
1680 exclude_if: Callable[[Any], bool] | None = None,
1681 title: str | None = None,
1682 field_title_generator: Callable[[str, ComputedFieldInfo], str] | None = None,
1683 description: str | None = None,
1684 deprecated: Deprecated | str | bool | None = None,
1685 examples: list[Any] | None = None,
1686 json_schema_extra: JsonDict | Callable[[JsonDict], None] | None = None,
1687 repr: bool = True,
1688 return_type: Any = PydanticUndefined,
1689) -> Callable[[PropertyT], PropertyT]: ...
1692def computed_field(
1693 func: PropertyT | None = None,
1694 /,
1695 *,
1696 alias: str | None = None,
1697 alias_priority: int | None = None,
1698 exclude_if: Callable[[Any], bool] | None = None,
1699 title: str | None = None,
1700 field_title_generator: Callable[[str, ComputedFieldInfo], str] | None = None,
1701 description: str | None = None,
1702 deprecated: Deprecated | str | bool | None = None,
1703 examples: list[Any] | None = None,
1704 json_schema_extra: JsonDict | Callable[[JsonDict], None] | None = None,
1705 repr: bool | None = None,
1706 return_type: Any = PydanticUndefined,
1707) -> PropertyT | Callable[[PropertyT], PropertyT]:
1708 """!!! abstract "Usage Documentation"
1709 [The `computed_field` decorator](../concepts/fields.md#the-computed_field-decorator)
1711 Decorator to include `property` and `cached_property` when serializing models or dataclasses.
1713 This is useful for fields that are computed from other fields, or for fields that are expensive to compute and should be cached.
1715 ```python
1716 from pydantic import BaseModel, computed_field
1718 class Rectangle(BaseModel):
1719 width: int
1720 length: int
1722 @computed_field
1723 @property
1724 def area(self) -> int:
1725 return self.width * self.length
1727 print(Rectangle(width=3, length=2).model_dump())
1728 #> {'width': 3, 'length': 2, 'area': 6}
1729 ```
1731 If applied to functions not yet decorated with `@property` or `@cached_property`, the function is
1732 automatically wrapped with `property`. Although this is more concise, you will lose IntelliSense in your IDE,
1733 and confuse static type checkers, thus explicit use of `@property` is recommended.
1735 !!! warning "Mypy Warning"
1736 Even with the `@property` or `@cached_property` applied to your function before `@computed_field`,
1737 mypy may throw a `Decorated property not supported` error.
1738 See [mypy issue #1362](https://github.com/python/mypy/issues/1362), for more information.
1739 To avoid this error message, add `# type: ignore[prop-decorator]` to the `@computed_field` line.
1741 [pyright](https://github.com/microsoft/pyright) supports `@computed_field` without error.
1743 ```python
1744 import random
1746 from pydantic import BaseModel, computed_field
1748 class Square(BaseModel):
1749 width: float
1751 @computed_field
1752 def area(self) -> float: # converted to a `property` by `computed_field`
1753 return round(self.width**2, 2)
1755 @area.setter
1756 def area(self, new_area: float) -> None:
1757 self.width = new_area**0.5
1759 @computed_field(alias='the magic number', repr=False)
1760 def random_number(self) -> int:
1761 return random.randint(0, 1_000)
1763 square = Square(width=1.3)
1765 # `random_number` does not appear in representation
1766 print(repr(square))
1767 #> Square(width=1.3, area=1.69)
1769 print(square.random_number)
1770 #> 3
1772 square.area = 4
1774 print(square.model_dump_json(by_alias=True))
1775 #> {"width":2.0,"area":4.0,"the magic number":3}
1776 ```
1778 !!! warning "Overriding with `computed_field`"
1779 You can't override a field from a parent class with a `computed_field` in the child class.
1780 `mypy` complains about this behavior if allowed, and `dataclasses` doesn't allow this pattern either.
1781 See the example below:
1783 ```python
1784 from pydantic import BaseModel, computed_field
1786 class Parent(BaseModel):
1787 a: str
1789 try:
1791 class Child(Parent):
1792 @computed_field
1793 @property
1794 def a(self) -> str:
1795 return 'new a'
1797 except TypeError as e:
1798 print(e)
1799 '''
1800 Field 'a' of class 'Child' overrides symbol of same name in a parent class. This override with a computed_field is incompatible.
1801 '''
1802 ```
1804 Private properties decorated with `@computed_field` have `repr=False` by default.
1806 ```python
1807 from functools import cached_property
1809 from pydantic import BaseModel, computed_field
1811 class Model(BaseModel):
1812 foo: int
1814 @computed_field
1815 @cached_property
1816 def _private_cached_property(self) -> int:
1817 return -self.foo
1819 @computed_field
1820 @property
1821 def _private_property(self) -> int:
1822 return -self.foo
1824 m = Model(foo=1)
1825 print(repr(m))
1826 #> Model(foo=1)
1827 ```
1829 Args:
1830 func: the function to wrap.
1831 alias: alias to use when serializing this computed field, only used when `by_alias=True`
1832 alias_priority: priority of the alias. This affects whether an alias generator is used
1833 exclude_if: A callable that determines whether to exclude this computed field during serialization based on its value.
1834 title: Title to use when including this computed field in JSON Schema
1835 field_title_generator: A callable that takes a field name and returns title for it.
1836 description: Description to use when including this computed field in JSON Schema, defaults to the function's
1837 docstring
1838 deprecated: A deprecation message (or an instance of `warnings.deprecated` or the `typing_extensions.deprecated` backport).
1839 to be emitted when accessing the field. Or a boolean. This will automatically be set if the property is decorated with the
1840 `deprecated` decorator.
1841 examples: Example values to use when including this computed field in JSON Schema
1842 json_schema_extra: A dict or callable to provide extra JSON schema properties.
1843 repr: whether to include this computed field in model repr.
1844 Default is `False` for private properties and `True` for public properties.
1845 return_type: optional return for serialization logic to expect when serializing to JSON, if included
1846 this must be correct, otherwise a `TypeError` is raised.
1847 If you don't include a return type Any is used, which does runtime introspection to handle arbitrary
1848 objects.
1850 Returns:
1851 A proxy wrapper for the property.
1852 """
1854 def dec(f: Any) -> Any:
1855 nonlocal description, deprecated, return_type, alias_priority
1856 unwrapped = _decorators.unwrap_wrapped_function(f)
1858 if description is None and unwrapped.__doc__:
1859 description = inspect.cleandoc(unwrapped.__doc__)
1861 if deprecated is None and hasattr(unwrapped, '__deprecated__'):
1862 deprecated = unwrapped.__deprecated__
1864 # if the function isn't already decorated with `@property` (or another descriptor), then we wrap it now
1865 f = _decorators.ensure_property(f)
1866 alias_priority = (alias_priority or 2) if alias is not None else None
1868 if repr is None:
1869 repr_: bool = not _wrapped_property_is_private(property_=f)
1870 else:
1871 repr_ = repr
1873 dec_info = ComputedFieldInfo(
1874 f,
1875 return_type,
1876 alias,
1877 alias_priority,
1878 exclude_if,
1879 title,
1880 field_title_generator,
1881 description,
1882 deprecated,
1883 examples,
1884 json_schema_extra,
1885 repr_,
1886 )
1887 return _decorators.PydanticDescriptorProxy(f, dec_info)
1889 if func is None:
1890 return dec
1891 else:
1892 return dec(func)