Coverage for pydantic/fields.py: 99.68%
434 statements
« prev ^ index » next coverage.py v7.5.4, created at 2024-07-03 19:29 +0000
« prev ^ index » next coverage.py v7.5.4, created at 2024-07-03 19:29 +0000
1"""Defining fields on models."""
3from __future__ import annotations as _annotations 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
5import dataclasses 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
6import inspect 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
7import sys 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
8import typing 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
9from copy import copy 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
10from dataclasses import Field as DataclassField 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
11from functools import cached_property 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
12from typing import Any, ClassVar 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
13from warnings import warn 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
15import annotated_types 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
16import typing_extensions 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
17from pydantic_core import PydanticUndefined 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
18from typing_extensions import Literal, TypeAlias, Unpack, deprecated 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
20from . import types 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
21from ._internal import _decorators, _fields, _generics, _internal_dataclass, _repr, _typing_extra, _utils 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
22from .aliases import AliasChoices, AliasPath 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
23from .config import JsonDict 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
24from .errors import PydanticUserError 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
25from .warnings import PydanticDeprecatedSince20 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
27if typing.TYPE_CHECKING: 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
28 from ._internal._repr import ReprArgs 1c
29else:
30 # See PyCharm issues https://youtrack.jetbrains.com/issue/PY-21915
31 # and https://youtrack.jetbrains.com/issue/PY-51428
32 DeprecationWarning = PydanticDeprecatedSince20 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
34__all__ = 'Field', 'PrivateAttr', 'computed_field' 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
37_Unset: Any = PydanticUndefined 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
39if sys.version_info >= (3, 13): 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
40 import warnings 1abdeMfg
42 Deprecated: TypeAlias = warnings.deprecated | deprecated 1abdeMfg
43else:
44 Deprecated: TypeAlias = deprecated 1hijklmnopqrcstuvwxyzABNOPQRSTUVCDEFGHIJKL
47class _FromFieldInfoInputs(typing_extensions.TypedDict, total=False): 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
48 """This class exists solely to add type checking for the `**kwargs` in `FieldInfo.from_field`."""
50 annotation: type[Any] | None 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
51 default_factory: typing.Callable[[], Any] | None 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
52 alias: str | None 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
53 alias_priority: int | None 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
54 validation_alias: str | AliasPath | AliasChoices | None 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
55 serialization_alias: str | None 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
56 title: str | None 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
57 field_title_generator: typing_extensions.Callable[[str, FieldInfo], str] | None 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
58 description: str | None 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
59 examples: list[Any] | None 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
60 exclude: bool | None 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
61 gt: annotated_types.SupportsGt | None 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
62 ge: annotated_types.SupportsGe | None 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
63 lt: annotated_types.SupportsLt | None 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
64 le: annotated_types.SupportsLe | None 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
65 multiple_of: float | None 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
66 strict: bool | None 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
67 min_length: int | None 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
68 max_length: int | None 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
69 pattern: str | typing.Pattern[str] | None 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
70 allow_inf_nan: bool | None 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
71 max_digits: int | None 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
72 decimal_places: int | None 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
73 union_mode: Literal['smart', 'left_to_right'] | None 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
74 discriminator: str | types.Discriminator | None 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
75 deprecated: Deprecated | str | bool | None 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
76 json_schema_extra: JsonDict | typing.Callable[[JsonDict], None] | None 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
77 frozen: bool | None 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
78 validate_default: bool | None 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
79 repr: bool 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
80 init: bool | None 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
81 init_var: bool | None 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
82 kw_only: bool | None 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
83 coerce_numbers_to_str: bool | None 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
84 fail_fast: bool | None 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
87class _FieldInfoInputs(_FromFieldInfoInputs, total=False): 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
88 """This class exists solely to add type checking for the `**kwargs` in `FieldInfo.__init__`."""
90 default: Any 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
93class FieldInfo(_repr.Representation): 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
94 """This class holds information about a field.
96 `FieldInfo` is used for any field definition regardless of whether the [`Field()`][pydantic.fields.Field]
97 function is explicitly used.
99 !!! warning
100 You generally shouldn't be creating `FieldInfo` directly, you'll only need to use it when accessing
101 [`BaseModel`][pydantic.main.BaseModel] `.model_fields` internals.
103 Attributes:
104 annotation: The type annotation of the field.
105 default: The default value of the field.
106 default_factory: The factory function used to construct the default for the field.
107 alias: The alias name of the field.
108 alias_priority: The priority of the field's alias.
109 validation_alias: The validation alias of the field.
110 serialization_alias: The serialization alias of the field.
111 title: The title of the field.
112 field_title_generator: A callable that takes a field name and returns title for it.
113 description: The description of the field.
114 examples: List of examples of the field.
115 exclude: Whether to exclude the field from the model serialization.
116 discriminator: Field name or Discriminator for discriminating the type in a tagged union.
117 deprecated: A deprecation message, an instance of `warnings.deprecated` or the `typing_extensions.deprecated` backport,
118 or a boolean. If `True`, a default deprecation message will be emitted when accessing the field.
119 json_schema_extra: A dict or callable to provide extra JSON schema properties.
120 frozen: Whether the field is frozen.
121 validate_default: Whether to validate the default value of the field.
122 repr: Whether to include the field in representation of the model.
123 init: Whether the field should be included in the constructor of the dataclass.
124 init_var: Whether the field should _only_ be included in the constructor of the dataclass, and not stored.
125 kw_only: Whether the field should be a keyword-only argument in the constructor of the dataclass.
126 metadata: List of metadata constraints.
127 """
129 annotation: type[Any] | None 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
130 default: Any 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
131 default_factory: typing.Callable[[], Any] | None 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
132 alias: str | None 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
133 alias_priority: int | None 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
134 validation_alias: str | AliasPath | AliasChoices | None 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
135 serialization_alias: str | None 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
136 title: str | None 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
137 field_title_generator: typing.Callable[[str, FieldInfo], str] | None 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
138 description: str | None 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
139 examples: list[Any] | None 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
140 exclude: bool | None 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
141 discriminator: str | types.Discriminator | None 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
142 deprecated: Deprecated | str | bool | None 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
143 json_schema_extra: JsonDict | typing.Callable[[JsonDict], None] | None 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
144 frozen: bool | None 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
145 validate_default: bool | None 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
146 repr: bool 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
147 init: bool | None 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
148 init_var: bool | None 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
149 kw_only: bool | None 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
150 metadata: list[Any] 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
152 __slots__ = ( 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
153 'annotation',
154 'default',
155 'default_factory',
156 'alias',
157 'alias_priority',
158 'validation_alias',
159 'serialization_alias',
160 'title',
161 'field_title_generator',
162 'description',
163 'examples',
164 'exclude',
165 'discriminator',
166 'deprecated',
167 'json_schema_extra',
168 'frozen',
169 'validate_default',
170 'repr',
171 'init',
172 'init_var',
173 'kw_only',
174 'metadata',
175 '_attributes_set',
176 )
178 # used to convert kwargs to metadata/constraints,
179 # None has a special meaning - these items are collected into a `PydanticGeneralMetadata`
180 metadata_lookup: ClassVar[dict[str, typing.Callable[[Any], Any] | None]] = { 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
181 'strict': types.Strict,
182 'gt': annotated_types.Gt,
183 'ge': annotated_types.Ge,
184 'lt': annotated_types.Lt,
185 'le': annotated_types.Le,
186 'multiple_of': annotated_types.MultipleOf,
187 'min_length': annotated_types.MinLen,
188 'max_length': annotated_types.MaxLen,
189 'pattern': None,
190 'allow_inf_nan': None,
191 'max_digits': None,
192 'decimal_places': None,
193 'union_mode': None,
194 'coerce_numbers_to_str': None,
195 'fail_fast': types.FailFast,
196 }
198 def __init__(self, **kwargs: Unpack[_FieldInfoInputs]) -> None: 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
199 """This class should generally not be initialized directly; instead, use the `pydantic.fields.Field` function
200 or one of the constructor classmethods.
202 See the signature of `pydantic.fields.Field` for more details about the expected arguments.
203 """
204 self._attributes_set = {k: v for k, v in kwargs.items() if v is not _Unset} 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
205 kwargs = {k: _DefaultValues.get(k) if v is _Unset else v for k, v in kwargs.items()} # type: ignore 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
206 self.annotation, annotation_metadata = self._extract_metadata(kwargs.get('annotation')) 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
208 default = kwargs.pop('default', PydanticUndefined) 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
209 if default is Ellipsis: 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
210 self.default = PydanticUndefined 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
211 else:
212 self.default = default 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
214 self.default_factory = kwargs.pop('default_factory', None) 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
216 if self.default is not PydanticUndefined and self.default_factory is not None: 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
217 raise TypeError('cannot specify both default and default_factory') 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
219 self.alias = kwargs.pop('alias', None) 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
220 self.validation_alias = kwargs.pop('validation_alias', None) 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
221 self.serialization_alias = kwargs.pop('serialization_alias', None) 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
222 alias_is_set = any(alias is not None for alias in (self.alias, self.validation_alias, self.serialization_alias)) 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
223 self.alias_priority = kwargs.pop('alias_priority', None) or 2 if alias_is_set else None 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
224 self.title = kwargs.pop('title', None) 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
225 self.field_title_generator = kwargs.pop('field_title_generator', None) 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
226 self.description = kwargs.pop('description', None) 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
227 self.examples = kwargs.pop('examples', None) 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
228 self.exclude = kwargs.pop('exclude', None) 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
229 self.discriminator = kwargs.pop('discriminator', None) 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
230 # For compatibility with FastAPI<=0.110.0, we preserve the existing value if it is not overridden
231 self.deprecated = kwargs.pop('deprecated', getattr(self, 'deprecated', None)) 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
232 self.repr = kwargs.pop('repr', True) 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
233 self.json_schema_extra = kwargs.pop('json_schema_extra', None) 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
234 self.validate_default = kwargs.pop('validate_default', None) 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
235 self.frozen = kwargs.pop('frozen', None) 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
236 # currently only used on dataclasses
237 self.init = kwargs.pop('init', None) 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
238 self.init_var = kwargs.pop('init_var', None) 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
239 self.kw_only = kwargs.pop('kw_only', None) 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
241 self.metadata = self._collect_metadata(kwargs) + annotation_metadata # type: ignore 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
243 @staticmethod 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
244 def from_field(default: Any = PydanticUndefined, **kwargs: Unpack[_FromFieldInfoInputs]) -> FieldInfo: 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
245 """Create a new `FieldInfo` object with the `Field` function.
247 Args:
248 default: The default value for the field. Defaults to Undefined.
249 **kwargs: Additional arguments dictionary.
251 Raises:
252 TypeError: If 'annotation' is passed as a keyword argument.
254 Returns:
255 A new FieldInfo object with the given parameters.
257 Example:
258 This is how you can create a field with default value like this:
260 ```python
261 import pydantic
263 class MyModel(pydantic.BaseModel):
264 foo: int = pydantic.Field(4)
265 ```
266 """
267 if 'annotation' in kwargs: 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
268 raise TypeError('"annotation" is not permitted as a Field keyword argument') 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
269 return FieldInfo(default=default, **kwargs) 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
271 @staticmethod 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
272 def from_annotation(annotation: type[Any]) -> FieldInfo: 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
273 """Creates a `FieldInfo` instance from a bare annotation.
275 This function is used internally to create a `FieldInfo` from a bare annotation like this:
277 ```python
278 import pydantic
280 class MyModel(pydantic.BaseModel):
281 foo: int # <-- like this
282 ```
284 We also account for the case where the annotation can be an instance of `Annotated` and where
285 one of the (not first) arguments in `Annotated` is an instance of `FieldInfo`, e.g.:
287 ```python
288 import annotated_types
289 from typing_extensions import Annotated
291 import pydantic
293 class MyModel(pydantic.BaseModel):
294 foo: Annotated[int, annotated_types.Gt(42)]
295 bar: Annotated[int, pydantic.Field(gt=42)]
296 ```
298 Args:
299 annotation: An annotation object.
301 Returns:
302 An instance of the field metadata.
303 """
304 final = False 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
305 if _typing_extra.is_finalvar(annotation): 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
306 final = True 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
307 if annotation is not typing_extensions.Final: 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
308 annotation = typing_extensions.get_args(annotation)[0] 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
310 if _typing_extra.is_annotated(annotation): 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
311 first_arg, *extra_args = typing_extensions.get_args(annotation) 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
312 if _typing_extra.is_finalvar(first_arg): 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
313 final = True 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
314 field_info_annotations = [a for a in extra_args if isinstance(a, FieldInfo)] 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
315 field_info = FieldInfo.merge_field_infos(*field_info_annotations, annotation=first_arg) 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
316 if field_info: 316 ↛ 331line 316 didn't jump to line 331 because the condition on line 316 was always true1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
317 new_field_info = copy(field_info) 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
318 new_field_info.annotation = first_arg 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
319 new_field_info.frozen = final or field_info.frozen 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
320 metadata: list[Any] = [] 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
321 for a in extra_args: 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
322 if _typing_extra.is_deprecated_instance(a): 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
323 new_field_info.deprecated = a.message 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
324 elif not isinstance(a, FieldInfo): 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
325 metadata.append(a) 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
326 else:
327 metadata.extend(a.metadata) 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
328 new_field_info.metadata = metadata 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
329 return new_field_info 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
331 return FieldInfo(annotation=annotation, frozen=final or None) # pyright: ignore[reportArgumentType] 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
333 @staticmethod 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
334 def from_annotated_attribute(annotation: type[Any], default: Any) -> FieldInfo: 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
335 """Create `FieldInfo` from an annotation with a default value.
337 This is used in cases like the following:
339 ```python
340 import annotated_types
341 from typing_extensions import Annotated
343 import pydantic
345 class MyModel(pydantic.BaseModel):
346 foo: int = 4 # <-- like this
347 bar: Annotated[int, annotated_types.Gt(4)] = 4 # <-- or this
348 spam: Annotated[int, pydantic.Field(gt=4)] = 4 # <-- or this
349 ```
351 Args:
352 annotation: The type annotation of the field.
353 default: The default value of the field.
355 Returns:
356 A field object with the passed values.
357 """
358 if annotation is default: 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
359 raise PydanticUserError( 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
360 'Error when building FieldInfo from annotated attribute. '
361 "Make sure you don't have any field name clashing with a type annotation ",
362 code='unevaluable-type-annotation',
363 )
365 final = False 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
366 if _typing_extra.is_finalvar(annotation): 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
367 final = True 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
368 if annotation is not typing_extensions.Final: 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
369 annotation = typing_extensions.get_args(annotation)[0] 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
371 if isinstance(default, FieldInfo): 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
372 default.annotation, annotation_metadata = FieldInfo._extract_metadata(annotation) # pyright: ignore[reportArgumentType] 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
373 default.metadata += annotation_metadata 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
374 default = default.merge_field_infos( 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
375 *[x for x in annotation_metadata if isinstance(x, FieldInfo)], default, annotation=default.annotation
376 )
377 default.frozen = final or default.frozen 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
378 return default 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
379 elif isinstance(default, dataclasses.Field): 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
380 init_var = False 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
381 if annotation is dataclasses.InitVar: 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
382 init_var = True 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
383 annotation = typing.cast(Any, Any) 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
384 elif isinstance(annotation, dataclasses.InitVar): 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
385 init_var = True 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
386 annotation = annotation.type 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
387 pydantic_field = FieldInfo._from_dataclass_field(default) 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
388 pydantic_field.annotation, annotation_metadata = FieldInfo._extract_metadata(annotation) # pyright: ignore[reportArgumentType] 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
389 pydantic_field.metadata += annotation_metadata 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
390 pydantic_field = pydantic_field.merge_field_infos( 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
391 *[x for x in annotation_metadata if isinstance(x, FieldInfo)],
392 pydantic_field,
393 annotation=pydantic_field.annotation,
394 )
395 pydantic_field.frozen = final or pydantic_field.frozen 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
396 pydantic_field.init_var = init_var 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
397 pydantic_field.init = getattr(default, 'init', None) 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
398 pydantic_field.kw_only = getattr(default, 'kw_only', None) 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
399 return pydantic_field 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
400 else:
401 if _typing_extra.is_annotated(annotation): 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
402 first_arg, *extra_args = typing_extensions.get_args(annotation) 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
403 field_infos = [a for a in extra_args if isinstance(a, FieldInfo)] 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
404 field_info = FieldInfo.merge_field_infos(*field_infos, annotation=first_arg, default=default) 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
405 metadata: list[Any] = [] 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
406 for a in extra_args: 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
407 if _typing_extra.is_deprecated_instance(a): 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
408 field_info.deprecated = a.message 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
409 elif not isinstance(a, FieldInfo): 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
410 metadata.append(a) 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
411 else:
412 metadata.extend(a.metadata) 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
413 field_info.metadata = metadata 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
414 return field_info 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
416 return FieldInfo(annotation=annotation, default=default, frozen=final or None) # pyright: ignore[reportArgumentType] 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
418 @staticmethod 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
419 def merge_field_infos(*field_infos: FieldInfo, **overrides: Any) -> FieldInfo: 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
420 """Merge `FieldInfo` instances keeping only explicitly set attributes.
422 Later `FieldInfo` instances override earlier ones.
424 Returns:
425 FieldInfo: A merged FieldInfo instance.
426 """
427 flattened_field_infos: list[FieldInfo] = [] 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
428 for field_info in field_infos: 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
429 flattened_field_infos.extend(x for x in field_info.metadata if isinstance(x, FieldInfo)) 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
430 flattened_field_infos.append(field_info) 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
431 field_infos = tuple(flattened_field_infos) 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
432 if len(field_infos) == 1: 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
433 # No merging necessary, but we still need to make a copy and apply the overrides
434 field_info = copy(field_infos[0]) 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
435 field_info._attributes_set.update(overrides) 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
437 default_override = overrides.pop('default', PydanticUndefined) 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
438 if default_override is Ellipsis: 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
439 default_override = PydanticUndefined 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
440 if default_override is not PydanticUndefined: 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
441 field_info.default = default_override 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
443 for k, v in overrides.items(): 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
444 setattr(field_info, k, v) 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
445 return field_info # type: ignore 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
447 merged_field_info_kwargs: dict[str, Any] = {} 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
448 metadata = {} 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
449 for field_info in field_infos: 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
450 attributes_set = field_info._attributes_set.copy() 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
452 try: 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
453 json_schema_extra = attributes_set.pop('json_schema_extra') 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
454 existing_json_schema_extra = merged_field_info_kwargs.get('json_schema_extra', {}) 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
456 if isinstance(existing_json_schema_extra, dict) and isinstance(json_schema_extra, dict): 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
457 merged_field_info_kwargs['json_schema_extra'] = {**existing_json_schema_extra, **json_schema_extra} 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
458 else:
459 # if ever there's a case of a callable, we'll just keep the last json schema extra spec
460 merged_field_info_kwargs['json_schema_extra'] = json_schema_extra 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
461 except KeyError: 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
462 pass 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
464 # later FieldInfo instances override everything except json_schema_extra from earlier FieldInfo instances
465 merged_field_info_kwargs.update(attributes_set) 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
467 for x in field_info.metadata: 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
468 if not isinstance(x, FieldInfo): 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
469 metadata[type(x)] = x 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
471 merged_field_info_kwargs.update(overrides) 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
472 field_info = FieldInfo(**merged_field_info_kwargs) 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
473 field_info.metadata = list(metadata.values()) 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
474 return field_info 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
476 @staticmethod 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
477 def _from_dataclass_field(dc_field: DataclassField[Any]) -> FieldInfo: 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
478 """Return a new `FieldInfo` instance from a `dataclasses.Field` instance.
480 Args:
481 dc_field: The `dataclasses.Field` instance to convert.
483 Returns:
484 The corresponding `FieldInfo` instance.
486 Raises:
487 TypeError: If any of the `FieldInfo` kwargs does not match the `dataclass.Field` kwargs.
488 """
489 default = dc_field.default 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
490 if default is dataclasses.MISSING: 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
491 default = PydanticUndefined 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
493 if dc_field.default_factory is dataclasses.MISSING: 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
494 default_factory: typing.Callable[[], Any] | None = None 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
495 else:
496 default_factory = dc_field.default_factory 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
498 # use the `Field` function so in correct kwargs raise the correct `TypeError`
499 dc_field_metadata = {k: v for k, v in dc_field.metadata.items() if k in _FIELD_ARG_NAMES} 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
500 return Field(default=default, default_factory=default_factory, repr=dc_field.repr, **dc_field_metadata) 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
502 @staticmethod 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
503 def _extract_metadata(annotation: type[Any] | None) -> tuple[type[Any] | None, list[Any]]: 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
504 """Tries to extract metadata/constraints from an annotation if it uses `Annotated`.
506 Args:
507 annotation: The type hint annotation for which metadata has to be extracted.
509 Returns:
510 A tuple containing the extracted metadata type and the list of extra arguments.
511 """
512 if annotation is not None: 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
513 if _typing_extra.is_annotated(annotation): 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
514 first_arg, *extra_args = typing_extensions.get_args(annotation) 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
515 return first_arg, list(extra_args) 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
517 return annotation, [] 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
519 @staticmethod 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
520 def _collect_metadata(kwargs: dict[str, Any]) -> list[Any]: 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
521 """Collect annotations from kwargs.
523 Args:
524 kwargs: Keyword arguments passed to the function.
526 Returns:
527 A list of metadata objects - a combination of `annotated_types.BaseMetadata` and
528 `PydanticMetadata`.
529 """
530 metadata: list[Any] = [] 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
531 general_metadata = {} 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
532 for key, value in list(kwargs.items()): 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
533 try: 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
534 marker = FieldInfo.metadata_lookup[key] 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
535 except KeyError: 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
536 continue 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
538 del kwargs[key] 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
539 if value is not None: 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
540 if marker is None: 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
541 general_metadata[key] = value 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
542 else:
543 metadata.append(marker(value)) 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
544 if general_metadata: 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
545 metadata.append(_fields.pydantic_general_metadata(**general_metadata)) 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
546 return metadata 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
548 @property 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
549 def deprecation_message(self) -> str | None: 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
550 """The deprecation message to be emitted, or `None` if not set."""
551 if self.deprecated is None: 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
552 return None 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
553 if isinstance(self.deprecated, bool): 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
554 return 'deprecated' if self.deprecated else None 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
555 return self.deprecated if isinstance(self.deprecated, str) else self.deprecated.message 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
557 def get_default(self, *, call_default_factory: bool = False) -> Any: 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
558 """Get the default value.
560 We expose an option for whether to call the default_factory (if present), as calling it may
561 result in side effects that we want to avoid. However, there are times when it really should
562 be called (namely, when instantiating a model via `model_construct`).
564 Args:
565 call_default_factory: Whether to call the default_factory or not. Defaults to `False`.
567 Returns:
568 The default value, calling the default factory if requested or `None` if not set.
569 """
570 if self.default_factory is None: 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
571 return _utils.smart_deepcopy(self.default) 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
572 elif call_default_factory: 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
573 return self.default_factory() 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
574 else:
575 return None 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
577 def is_required(self) -> bool: 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
578 """Check if the field is required (i.e., does not have a default value or factory).
580 Returns:
581 `True` if the field is required, `False` otherwise.
582 """
583 return self.default is PydanticUndefined and self.default_factory is None 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
585 def rebuild_annotation(self) -> Any: 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
586 """Attempts to rebuild the original annotation for use in function signatures.
588 If metadata is present, it adds it to the original annotation using
589 `Annotated`. Otherwise, it returns the original annotation as-is.
591 Note that because the metadata has been flattened, the original annotation
592 may not be reconstructed exactly as originally provided, e.g. if the original
593 type had unrecognized annotations, or was annotated with a call to `pydantic.Field`.
595 Returns:
596 The rebuilt annotation.
597 """
598 if not self.metadata: 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
599 return self.annotation 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
600 else:
601 # Annotated arguments must be a tuple
602 return typing_extensions.Annotated[(self.annotation, *self.metadata)] # type: ignore 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
604 def apply_typevars_map(self, typevars_map: dict[Any, Any] | None, types_namespace: dict[str, Any] | None) -> None: 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
605 """Apply a `typevars_map` to the annotation.
607 This method is used when analyzing parametrized generic types to replace typevars with their concrete types.
609 This method applies the `typevars_map` to the annotation in place.
611 Args:
612 typevars_map: A dictionary mapping type variables to their concrete types.
613 types_namespace (dict | None): A dictionary containing related types to the annotated type.
615 See Also:
616 pydantic._internal._generics.replace_types is used for replacing the typevars with
617 their concrete types.
618 """
619 annotation = _typing_extra.eval_type_lenient(self.annotation, types_namespace) 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
620 self.annotation = _generics.replace_types(annotation, typevars_map) 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
622 def __repr_args__(self) -> ReprArgs: 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
623 yield 'annotation', _repr.PlainRepr(_repr.display_as_type(self.annotation)) 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
624 yield 'required', self.is_required() 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
626 for s in self.__slots__: 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
627 if s == '_attributes_set': 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
628 continue 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
629 if s == 'annotation': 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
630 continue 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
631 elif s == 'metadata' and not self.metadata: 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
632 continue 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
633 elif s == 'repr' and self.repr is True: 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
634 continue 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
635 if s == 'frozen' and self.frozen is False: 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
636 continue 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
637 if s == 'validation_alias' and self.validation_alias == self.alias: 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
638 continue 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
639 if s == 'serialization_alias' and self.serialization_alias == self.alias: 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
640 continue 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
641 if s == 'default' and self.default is not PydanticUndefined: 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
642 yield 'default', self.default 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
643 elif s == 'default_factory' and self.default_factory is not None: 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
644 yield 'default_factory', _repr.PlainRepr(_repr.display_as_type(self.default_factory)) 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
645 else:
646 value = getattr(self, s) 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
647 if value is not None and value is not PydanticUndefined: 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
648 yield s, value 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
651class _EmptyKwargs(typing_extensions.TypedDict): 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
652 """This class exists solely to ensure that type checking warns about passing `**extra` in `Field`."""
655_DefaultValues = dict( 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
656 default=...,
657 default_factory=None,
658 alias=None,
659 alias_priority=None,
660 validation_alias=None,
661 serialization_alias=None,
662 title=None,
663 description=None,
664 examples=None,
665 exclude=None,
666 discriminator=None,
667 json_schema_extra=None,
668 frozen=None,
669 validate_default=None,
670 repr=True,
671 init=None,
672 init_var=None,
673 kw_only=None,
674 pattern=None,
675 strict=None,
676 gt=None,
677 ge=None,
678 lt=None,
679 le=None,
680 multiple_of=None,
681 allow_inf_nan=None,
682 max_digits=None,
683 decimal_places=None,
684 min_length=None,
685 max_length=None,
686 coerce_numbers_to_str=None,
687)
690def Field( # noqa: C901 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
691 default: Any = PydanticUndefined,
692 *,
693 default_factory: typing.Callable[[], Any] | None = _Unset,
694 alias: str | None = _Unset,
695 alias_priority: int | None = _Unset,
696 validation_alias: str | AliasPath | AliasChoices | None = _Unset,
697 serialization_alias: str | None = _Unset,
698 title: str | None = _Unset,
699 field_title_generator: typing_extensions.Callable[[str, FieldInfo], str] | None = _Unset,
700 description: str | None = _Unset,
701 examples: list[Any] | None = _Unset,
702 exclude: bool | None = _Unset,
703 discriminator: str | types.Discriminator | None = _Unset,
704 deprecated: Deprecated | str | bool | None = _Unset,
705 json_schema_extra: JsonDict | typing.Callable[[JsonDict], None] | None = _Unset,
706 frozen: bool | None = _Unset,
707 validate_default: bool | None = _Unset,
708 repr: bool = _Unset,
709 init: bool | None = _Unset,
710 init_var: bool | None = _Unset,
711 kw_only: bool | None = _Unset,
712 pattern: str | typing.Pattern[str] | None = _Unset,
713 strict: bool | None = _Unset,
714 coerce_numbers_to_str: bool | None = _Unset,
715 gt: annotated_types.SupportsGt | None = _Unset,
716 ge: annotated_types.SupportsGe | None = _Unset,
717 lt: annotated_types.SupportsLt | None = _Unset,
718 le: annotated_types.SupportsLe | None = _Unset,
719 multiple_of: float | None = _Unset,
720 allow_inf_nan: bool | None = _Unset,
721 max_digits: int | None = _Unset,
722 decimal_places: int | None = _Unset,
723 min_length: int | None = _Unset,
724 max_length: int | None = _Unset,
725 union_mode: Literal['smart', 'left_to_right'] = _Unset,
726 fail_fast: bool | None = _Unset,
727 **extra: Unpack[_EmptyKwargs],
728) -> Any:
729 """Usage docs: https://docs.pydantic.dev/2.8/concepts/fields
731 Create a field for objects that can be configured.
733 Used to provide extra information about a field, either for the model schema or complex validation. Some arguments
734 apply only to number fields (`int`, `float`, `Decimal`) and some apply only to `str`.
736 Note:
737 - 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`
739 Args:
740 default: Default value if the field is not set.
741 default_factory: A callable to generate the default value, such as :func:`~datetime.utcnow`.
742 alias: The name to use for the attribute when validating or serializing by alias.
743 This is often used for things like converting between snake and camel case.
744 alias_priority: Priority of the alias. This affects whether an alias generator is used.
745 validation_alias: Like `alias`, but only affects validation, not serialization.
746 serialization_alias: Like `alias`, but only affects serialization, not validation.
747 title: Human-readable title.
748 field_title_generator: A callable that takes a field name and returns title for it.
749 description: Human-readable description.
750 examples: Example values for this field.
751 exclude: Whether to exclude the field from the model serialization.
752 discriminator: Field name or Discriminator for discriminating the type in a tagged union.
753 deprecated: A deprecation message, an instance of `warnings.deprecated` or the `typing_extensions.deprecated` backport,
754 or a boolean. If `True`, a default deprecation message will be emitted when accessing the field.
755 json_schema_extra: A dict or callable to provide extra JSON schema properties.
756 frozen: Whether the field is frozen. If true, attempts to change the value on an instance will raise an error.
757 validate_default: If `True`, apply validation to the default value every time you create an instance.
758 Otherwise, for performance reasons, the default value of the field is trusted and not validated.
759 repr: A boolean indicating whether to include the field in the `__repr__` output.
760 init: Whether the field should be included in the constructor of the dataclass.
761 (Only applies to dataclasses.)
762 init_var: Whether the field should _only_ be included in the constructor of the dataclass.
763 (Only applies to dataclasses.)
764 kw_only: Whether the field should be a keyword-only argument in the constructor of the dataclass.
765 (Only applies to dataclasses.)
766 coerce_numbers_to_str: Whether to enable coercion of any `Number` type to `str` (not applicable in `strict` mode).
767 strict: If `True`, strict validation is applied to the field.
768 See [Strict Mode](../concepts/strict_mode.md) for details.
769 gt: Greater than. If set, value must be greater than this. Only applicable to numbers.
770 ge: Greater than or equal. If set, value must be greater than or equal to this. Only applicable to numbers.
771 lt: Less than. If set, value must be less than this. Only applicable to numbers.
772 le: Less than or equal. If set, value must be less than or equal to this. Only applicable to numbers.
773 multiple_of: Value must be a multiple of this. Only applicable to numbers.
774 min_length: Minimum length for iterables.
775 max_length: Maximum length for iterables.
776 pattern: Pattern for strings (a regular expression).
777 allow_inf_nan: Allow `inf`, `-inf`, `nan`. Only applicable to numbers.
778 max_digits: Maximum number of allow digits for strings.
779 decimal_places: Maximum number of decimal places allowed for numbers.
780 union_mode: The strategy to apply when validating a union. Can be `smart` (the default), or `left_to_right`.
781 See [Union Mode](../concepts/unions.md#union-modes) for details.
782 fail_fast: If `True`, validation will stop on the first error. If `False`, all validation errors will be collected.
783 This option can be applied only to iterable types (list, tuple, set, and frozenset).
784 extra: (Deprecated) Extra fields that will be included in the JSON schema.
786 !!! warning Deprecated
787 The `extra` kwargs is deprecated. Use `json_schema_extra` instead.
789 Returns:
790 A new [`FieldInfo`][pydantic.fields.FieldInfo]. The return annotation is `Any` so `Field` can be used on
791 type-annotated fields without causing a type error.
792 """
793 # Check deprecated and removed params from V1. This logic should eventually be removed.
794 const = extra.pop('const', None) # type: ignore 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
795 if const is not None: 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
796 raise PydanticUserError('`const` is removed, use `Literal` instead', code='removed-kwargs') 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
798 min_items = extra.pop('min_items', None) # type: ignore 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
799 if min_items is not None: 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
800 warn('`min_items` is deprecated and will be removed, use `min_length` instead', DeprecationWarning) 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
801 if min_length in (None, _Unset): 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
802 min_length = min_items # type: ignore 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
804 max_items = extra.pop('max_items', None) # type: ignore 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
805 if max_items is not None: 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
806 warn('`max_items` is deprecated and will be removed, use `max_length` instead', DeprecationWarning) 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
807 if max_length in (None, _Unset): 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
808 max_length = max_items # type: ignore 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
810 unique_items = extra.pop('unique_items', None) # type: ignore 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
811 if unique_items is not None: 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
812 raise PydanticUserError( 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
813 (
814 '`unique_items` is removed, use `Set` instead'
815 '(this feature is discussed in https://github.com/pydantic/pydantic-core/issues/296)'
816 ),
817 code='removed-kwargs',
818 )
820 allow_mutation = extra.pop('allow_mutation', None) # type: ignore 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
821 if allow_mutation is not None: 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
822 warn('`allow_mutation` is deprecated and will be removed. use `frozen` instead', DeprecationWarning) 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
823 if allow_mutation is False: 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
824 frozen = True 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
826 regex = extra.pop('regex', None) # type: ignore 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
827 if regex is not None: 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
828 raise PydanticUserError('`regex` is removed. use `pattern` instead', code='removed-kwargs') 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
830 if extra: 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
831 warn( 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
832 'Using extra keyword arguments on `Field` is deprecated and will be removed.'
833 ' Use `json_schema_extra` instead.'
834 f' (Extra keys: {", ".join(k.__repr__() for k in extra.keys())})',
835 DeprecationWarning,
836 )
837 if not json_schema_extra or json_schema_extra is _Unset: 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
838 json_schema_extra = extra # type: ignore 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
840 if ( 1hijklmnorcstuvwxyzNOPQRSTUCDEFGHIJ
841 validation_alias
842 and validation_alias is not _Unset
843 and not isinstance(validation_alias, (str, AliasChoices, AliasPath))
844 ):
845 raise TypeError('Invalid `validation_alias` type. it should be `str`, `AliasChoices`, or `AliasPath`') 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
847 if serialization_alias in (_Unset, None) and isinstance(alias, str): 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
848 serialization_alias = alias 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
850 if validation_alias in (_Unset, None): 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
851 validation_alias = alias 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
853 include = extra.pop('include', None) # type: ignore 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
854 if include is not None: 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
855 warn('`include` is deprecated and does nothing. It will be removed, use `exclude` instead', DeprecationWarning) 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
857 return FieldInfo.from_field( 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
858 default,
859 default_factory=default_factory,
860 alias=alias,
861 alias_priority=alias_priority,
862 validation_alias=validation_alias,
863 serialization_alias=serialization_alias,
864 title=title,
865 field_title_generator=field_title_generator,
866 description=description,
867 examples=examples,
868 exclude=exclude,
869 discriminator=discriminator,
870 deprecated=deprecated,
871 json_schema_extra=json_schema_extra,
872 frozen=frozen,
873 pattern=pattern,
874 validate_default=validate_default,
875 repr=repr,
876 init=init,
877 init_var=init_var,
878 kw_only=kw_only,
879 coerce_numbers_to_str=coerce_numbers_to_str,
880 strict=strict,
881 gt=gt,
882 ge=ge,
883 lt=lt,
884 le=le,
885 multiple_of=multiple_of,
886 min_length=min_length,
887 max_length=max_length,
888 allow_inf_nan=allow_inf_nan,
889 max_digits=max_digits,
890 decimal_places=decimal_places,
891 union_mode=union_mode,
892 fail_fast=fail_fast,
893 )
896_FIELD_ARG_NAMES = set(inspect.signature(Field).parameters) 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
897_FIELD_ARG_NAMES.remove('extra') # do not include the varkwargs parameter 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
900class ModelPrivateAttr(_repr.Representation): 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
901 """A descriptor for private attributes in class models.
903 !!! warning
904 You generally shouldn't be creating `ModelPrivateAttr` instances directly, instead use
905 `pydantic.fields.PrivateAttr`. (This is similar to `FieldInfo` vs. `Field`.)
907 Attributes:
908 default: The default value of the attribute if not provided.
909 default_factory: A callable function that generates the default value of the
910 attribute if not provided.
911 """
913 __slots__ = 'default', 'default_factory' 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
915 def __init__( 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
916 self, default: Any = PydanticUndefined, *, default_factory: typing.Callable[[], Any] | None = None
917 ) -> None:
918 self.default = default 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
919 self.default_factory = default_factory 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
921 if not typing.TYPE_CHECKING: 921 ↛ 933line 921 didn't jump to line 933 because the condition on line 921 was always true1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
922 # We put `__getattr__` in a non-TYPE_CHECKING block because otherwise, mypy allows arbitrary attribute access
924 def __getattr__(self, item: str) -> Any: 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
925 """This function improves compatibility with custom descriptors by ensuring delegation happens
926 as expected when the default value of a private attribute is a descriptor.
927 """
928 if item in {'__get__', '__set__', '__delete__'}: 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
929 if hasattr(self.default, item): 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
930 return getattr(self.default, item) 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
931 raise AttributeError(f'{type(self).__name__!r} object has no attribute {item!r}') 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
933 def __set_name__(self, cls: type[Any], name: str) -> None: 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
934 """Preserve `__set_name__` protocol defined in https://peps.python.org/pep-0487."""
935 if self.default is PydanticUndefined: 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
936 return 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
937 if not hasattr(self.default, '__set_name__'): 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
938 return 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
939 set_name = self.default.__set_name__ 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
940 if callable(set_name): 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
941 set_name(cls, name) 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
943 def get_default(self) -> Any: 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
944 """Retrieve the default value of the object.
946 If `self.default_factory` is `None`, the method will return a deep copy of the `self.default` object.
948 If `self.default_factory` is not `None`, it will call `self.default_factory` and return the value returned.
950 Returns:
951 The default value of the object.
952 """
953 return _utils.smart_deepcopy(self.default) if self.default_factory is None else self.default_factory() 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
955 def __eq__(self, other: Any) -> bool: 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
956 return isinstance(other, self.__class__) and (self.default, self.default_factory) == ( 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
957 other.default,
958 other.default_factory,
959 )
962def PrivateAttr( 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
963 default: Any = PydanticUndefined,
964 *,
965 default_factory: typing.Callable[[], Any] | None = None,
966 init: Literal[False] = False,
967) -> Any:
968 """Usage docs: https://docs.pydantic.dev/2.8/concepts/models/#private-model-attributes
970 Indicates that an attribute is intended for private use and not handled during normal validation/serialization.
972 Private attributes are not validated by Pydantic, so it's up to you to ensure they are used in a type-safe manner.
974 Private attributes are stored in `__private_attributes__` on the model.
976 Args:
977 default: The attribute's default value. Defaults to Undefined.
978 default_factory: Callable that will be
979 called when a default value is needed for this attribute.
980 If both `default` and `default_factory` are set, an error will be raised.
981 init: Whether the attribute should be included in the constructor of the dataclass. Always `False`.
983 Returns:
984 An instance of [`ModelPrivateAttr`][pydantic.fields.ModelPrivateAttr] class.
986 Raises:
987 ValueError: If both `default` and `default_factory` are set.
988 """
989 if default is not PydanticUndefined and default_factory is not None: 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
990 raise TypeError('cannot specify both default and default_factory') 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
992 return ModelPrivateAttr( 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
993 default,
994 default_factory=default_factory,
995 )
998@dataclasses.dataclass(**_internal_dataclass.slots_true) 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
999class ComputedFieldInfo: 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
1000 """A container for data from `@computed_field` so that we can access it while building the pydantic-core schema.
1002 Attributes:
1003 decorator_repr: A class variable representing the decorator string, '@computed_field'.
1004 wrapped_property: The wrapped computed field property.
1005 return_type: The type of the computed field property's return value.
1006 alias: The alias of the property to be used during serialization.
1007 alias_priority: The priority of the alias. This affects whether an alias generator is used.
1008 title: Title of the computed field to include in the serialization JSON schema.
1009 field_title_generator: A callable that takes a field name and returns title for it.
1010 description: Description of the computed field to include in the serialization JSON schema.
1011 deprecated: A deprecation message, an instance of `warnings.deprecated` or the `typing_extensions.deprecated` backport,
1012 or a boolean. If `True`, a default deprecation message will be emitted when accessing the field.
1013 examples: Example values of the computed field to include in the serialization JSON schema.
1014 json_schema_extra: A dict or callable to provide extra JSON schema properties.
1015 repr: A boolean indicating whether to include the field in the __repr__ output.
1016 """
1018 decorator_repr: ClassVar[str] = '@computed_field' 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
1019 wrapped_property: property 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
1020 return_type: Any 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
1021 alias: str | None 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
1022 alias_priority: int | None 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
1023 title: str | None 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
1024 field_title_generator: typing.Callable[[str, ComputedFieldInfo], str] | None 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
1025 description: str | None 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
1026 deprecated: Deprecated | str | bool | None 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
1027 examples: list[Any] | None 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
1028 json_schema_extra: JsonDict | typing.Callable[[JsonDict], None] | None 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
1029 repr: bool 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
1031 @property 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
1032 def deprecation_message(self) -> str | None: 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
1033 """The deprecation message to be emitted, or `None` if not set."""
1034 if self.deprecated is None: 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
1035 return None 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
1036 if isinstance(self.deprecated, bool): 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
1037 return 'deprecated' if self.deprecated else None 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
1038 return self.deprecated if isinstance(self.deprecated, str) else self.deprecated.message 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
1041def _wrapped_property_is_private(property_: cached_property | property) -> bool: # type: ignore 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
1042 """Returns true if provided property is private, False otherwise."""
1043 wrapped_name: str = '' 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
1045 if isinstance(property_, property): 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
1046 wrapped_name = getattr(property_.fget, '__name__', '') 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
1047 elif isinstance(property_, cached_property): # type: ignore 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
1048 wrapped_name = getattr(property_.func, '__name__', '') # type: ignore 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
1050 return wrapped_name.startswith('_') and not wrapped_name.startswith('__') 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
1053# this should really be `property[T], cached_property[T]` but property is not generic unlike cached_property
1054# See https://github.com/python/typing/issues/985 and linked issues
1055PropertyT = typing.TypeVar('PropertyT') 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
1058@typing.overload 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
1059def computed_field( 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
1060 *,
1061 alias: str | None = None, 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
1062 alias_priority: int | None = None, 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
1063 title: str | None = None, 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
1064 field_title_generator: typing.Callable[[str, ComputedFieldInfo], str] | None = None, 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
1065 description: str | None = None, 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
1066 deprecated: Deprecated | str | bool | None = None, 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
1067 examples: list[Any] | None = None, 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
1068 json_schema_extra: JsonDict | typing.Callable[[JsonDict], None] | None = None, 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
1069 repr: bool = True, 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
1070 return_type: Any = PydanticUndefined, 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
1071) -> typing.Callable[[PropertyT], PropertyT]: ... 1pqabrcABdeVMKLfg
1074@typing.overload 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
1075def computed_field(__func: PropertyT) -> PropertyT: ... 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
1078def computed_field( 1hijklmnopqabstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg
1079 func: PropertyT | None = None,
1080 /,
1081 *,
1082 alias: str | None = None,
1083 alias_priority: int | None = None,
1084 title: str | None = None,
1085 field_title_generator: typing.Callable[[str, ComputedFieldInfo], str] | None = None,
1086 description: str | None = None,
1087 deprecated: Deprecated | str | bool | None = None,
1088 examples: list[Any] | None = None,
1089 json_schema_extra: JsonDict | typing.Callable[[JsonDict], None] | None = None,
1090 repr: bool | None = None,
1091 return_type: Any = PydanticUndefined,
1092) -> PropertyT | typing.Callable[[PropertyT], PropertyT]:
1093 """Usage docs: https://docs.pydantic.dev/2.8/concepts/fields#the-computed_field-decorator
1095 Decorator to include `property` and `cached_property` when serializing models or dataclasses.
1097 This is useful for fields that are computed from other fields, or for fields that are expensive to compute and should be cached.
1099 ```py
1100 from pydantic import BaseModel, computed_field
1102 class Rectangle(BaseModel):
1103 width: int
1104 length: int
1106 @computed_field
1107 @property
1108 def area(self) -> int:
1109 return self.width * self.length
1111 print(Rectangle(width=3, length=2).model_dump())
1112 #> {'width': 3, 'length': 2, 'area': 6}
1113 ```
1115 If applied to functions not yet decorated with `@property` or `@cached_property`, the function is
1116 automatically wrapped with `property`. Although this is more concise, you will lose IntelliSense in your IDE,
1117 and confuse static type checkers, thus explicit use of `@property` is recommended.
1119 !!! warning "Mypy Warning"
1120 Even with the `@property` or `@cached_property` applied to your function before `@computed_field`,
1121 mypy may throw a `Decorated property not supported` error.
1122 See [mypy issue #1362](https://github.com/python/mypy/issues/1362), for more information.
1123 To avoid this error message, add `# type: ignore[misc]` to the `@computed_field` line.
1125 [pyright](https://github.com/microsoft/pyright) supports `@computed_field` without error.
1127 ```py
1128 import random
1130 from pydantic import BaseModel, computed_field
1132 class Square(BaseModel):
1133 width: float
1135 @computed_field
1136 def area(self) -> float: # converted to a `property` by `computed_field`
1137 return round(self.width**2, 2)
1139 @area.setter
1140 def area(self, new_area: float) -> None:
1141 self.width = new_area**0.5
1143 @computed_field(alias='the magic number', repr=False)
1144 def random_number(self) -> int:
1145 return random.randint(0, 1_000)
1147 square = Square(width=1.3)
1149 # `random_number` does not appear in representation
1150 print(repr(square))
1151 #> Square(width=1.3, area=1.69)
1153 print(square.random_number)
1154 #> 3
1156 square.area = 4
1158 print(square.model_dump_json(by_alias=True))
1159 #> {"width":2.0,"area":4.0,"the magic number":3}
1160 ```
1162 !!! warning "Overriding with `computed_field`"
1163 You can't override a field from a parent class with a `computed_field` in the child class.
1164 `mypy` complains about this behavior if allowed, and `dataclasses` doesn't allow this pattern either.
1165 See the example below:
1167 ```py
1168 from pydantic import BaseModel, computed_field
1170 class Parent(BaseModel):
1171 a: str
1173 try:
1175 class Child(Parent):
1176 @computed_field
1177 @property
1178 def a(self) -> str:
1179 return 'new a'
1181 except ValueError as e:
1182 print(repr(e))
1183 #> ValueError("you can't override a field with a computed field")
1184 ```
1186 Private properties decorated with `@computed_field` have `repr=False` by default.
1188 ```py
1189 from functools import cached_property
1191 from pydantic import BaseModel, computed_field
1193 class Model(BaseModel):
1194 foo: int
1196 @computed_field
1197 @cached_property
1198 def _private_cached_property(self) -> int:
1199 return -self.foo
1201 @computed_field
1202 @property
1203 def _private_property(self) -> int:
1204 return -self.foo
1206 m = Model(foo=1)
1207 print(repr(m))
1208 #> M(foo=1)
1209 ```
1211 Args:
1212 func: the function to wrap.
1213 alias: alias to use when serializing this computed field, only used when `by_alias=True`
1214 alias_priority: priority of the alias. This affects whether an alias generator is used
1215 title: Title to use when including this computed field in JSON Schema
1216 field_title_generator: A callable that takes a field name and returns title for it.
1217 description: Description to use when including this computed field in JSON Schema, defaults to the function's
1218 docstring
1219 deprecated: A deprecation message (or an instance of `warnings.deprecated` or the `typing_extensions.deprecated` backport).
1220 to be emitted when accessing the field. Or a boolean. This will automatically be set if the property is decorated with the
1221 `deprecated` decorator.
1222 examples: Example values to use when including this computed field in JSON Schema
1223 json_schema_extra: A dict or callable to provide extra JSON schema properties.
1224 repr: whether to include this computed field in model repr.
1225 Default is `False` for private properties and `True` for public properties.
1226 return_type: optional return for serialization logic to expect when serializing to JSON, if included
1227 this must be correct, otherwise a `TypeError` is raised.
1228 If you don't include a return type Any is used, which does runtime introspection to handle arbitrary
1229 objects.
1231 Returns:
1232 A proxy wrapper for the property.
1233 """
1235 def dec(f: Any) -> Any: 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
1236 nonlocal description, deprecated, return_type, alias_priority
1237 unwrapped = _decorators.unwrap_wrapped_function(f) 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
1239 if description is None and unwrapped.__doc__: 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
1240 description = inspect.cleandoc(unwrapped.__doc__) 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
1242 if deprecated is None and hasattr(unwrapped, '__deprecated__'): 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
1243 deprecated = unwrapped.__deprecated__ 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
1245 # if the function isn't already decorated with `@property` (or another descriptor), then we wrap it now
1246 f = _decorators.ensure_property(f) 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
1247 alias_priority = (alias_priority or 2) if alias is not None else None 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
1249 if repr is None: 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
1250 repr_: bool = not _wrapped_property_is_private(property_=f) 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
1251 else:
1252 repr_ = repr 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
1254 dec_info = ComputedFieldInfo( 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
1255 f,
1256 return_type,
1257 alias,
1258 alias_priority,
1259 title,
1260 field_title_generator,
1261 description,
1262 deprecated,
1263 examples,
1264 json_schema_extra,
1265 repr_,
1266 )
1267 return _decorators.PydanticDescriptorProxy(f, dec_info) 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
1269 if func is None: 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
1270 return dec 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg
1271 else:
1272 return dec(func) 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg