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

1"""Defining fields on models.""" 

2 

3from __future__ import annotations as _annotations 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg

4 

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

14 

15import annotated_types 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg

16import typing_extensions 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg

17from pydantic_core import PydanticUndefined 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg

18from typing_extensions import Literal, TypeAlias, Unpack, deprecated 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg

19 

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

26 

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

33 

34__all__ = 'Field', 'PrivateAttr', 'computed_field' 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg

35 

36 

37_Unset: Any = PydanticUndefined 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg

38 

39if sys.version_info >= (3, 13): 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg

40 import warnings 1abdeMfg

41 

42 Deprecated: TypeAlias = warnings.deprecated | deprecated 1abdeMfg

43else: 

44 Deprecated: TypeAlias = deprecated 1hijklmnopqrcstuvwxyzABNOPQRSTUVCDEFGHIJKL

45 

46 

47class _FromFieldInfoInputs(typing_extensions.TypedDict, total=False): 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg

48 """This class exists solely to add type checking for the `**kwargs` in `FieldInfo.from_field`.""" 

49 

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

85 

86 

87class _FieldInfoInputs(_FromFieldInfoInputs, total=False): 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg

88 """This class exists solely to add type checking for the `**kwargs` in `FieldInfo.__init__`.""" 

89 

90 default: Any 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg

91 

92 

93class FieldInfo(_repr.Representation): 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg

94 """This class holds information about a field. 

95 

96 `FieldInfo` is used for any field definition regardless of whether the [`Field()`][pydantic.fields.Field] 

97 function is explicitly used. 

98 

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. 

102 

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 """ 

128 

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

151 

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 ) 

177 

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 } 

197 

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. 

201 

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

207 

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

213 

214 self.default_factory = kwargs.pop('default_factory', None) 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg

215 

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

218 

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

240 

241 self.metadata = self._collect_metadata(kwargs) + annotation_metadata # type: ignore 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg

242 

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. 

246 

247 Args: 

248 default: The default value for the field. Defaults to Undefined. 

249 **kwargs: Additional arguments dictionary. 

250 

251 Raises: 

252 TypeError: If 'annotation' is passed as a keyword argument. 

253 

254 Returns: 

255 A new FieldInfo object with the given parameters. 

256 

257 Example: 

258 This is how you can create a field with default value like this: 

259 

260 ```python 

261 import pydantic 

262 

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

270 

271 @staticmethod 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg

272 def from_annotation(annotation: type[Any]) -> FieldInfo: 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg

273 """Creates a `FieldInfo` instance from a bare annotation. 

274 

275 This function is used internally to create a `FieldInfo` from a bare annotation like this: 

276 

277 ```python 

278 import pydantic 

279 

280 class MyModel(pydantic.BaseModel): 

281 foo: int # <-- like this 

282 ``` 

283 

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.: 

286 

287 ```python 

288 import annotated_types 

289 from typing_extensions import Annotated 

290 

291 import pydantic 

292 

293 class MyModel(pydantic.BaseModel): 

294 foo: Annotated[int, annotated_types.Gt(42)] 

295 bar: Annotated[int, pydantic.Field(gt=42)] 

296 ``` 

297 

298 Args: 

299 annotation: An annotation object. 

300 

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

309 

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

330 

331 return FieldInfo(annotation=annotation, frozen=final or None) # pyright: ignore[reportArgumentType] 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg

332 

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. 

336 

337 This is used in cases like the following: 

338 

339 ```python 

340 import annotated_types 

341 from typing_extensions import Annotated 

342 

343 import pydantic 

344 

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 ``` 

350 

351 Args: 

352 annotation: The type annotation of the field. 

353 default: The default value of the field. 

354 

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 ) 

364 

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

370 

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

415 

416 return FieldInfo(annotation=annotation, default=default, frozen=final or None) # pyright: ignore[reportArgumentType] 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg

417 

418 @staticmethod 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg

419 def merge_field_infos(*field_infos: FieldInfo, **overrides: Any) -> FieldInfo: 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg

420 """Merge `FieldInfo` instances keeping only explicitly set attributes. 

421 

422 Later `FieldInfo` instances override earlier ones. 

423 

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

436 

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

442 

443 for k, v in overrides.items(): 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg

444 setattr(field_info, k, v) 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg

445 return field_info # type: ignore 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg

446 

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

451 

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

455 

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

463 

464 # later FieldInfo instances override everything except json_schema_extra from earlier FieldInfo instances 

465 merged_field_info_kwargs.update(attributes_set) 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg

466 

467 for x in field_info.metadata: 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg

468 if not isinstance(x, FieldInfo): 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg

469 metadata[type(x)] = x 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg

470 

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

475 

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. 

479 

480 Args: 

481 dc_field: The `dataclasses.Field` instance to convert. 

482 

483 Returns: 

484 The corresponding `FieldInfo` instance. 

485 

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

492 

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

497 

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

501 

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`. 

505 

506 Args: 

507 annotation: The type hint annotation for which metadata has to be extracted. 

508 

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

516 

517 return annotation, [] 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg

518 

519 @staticmethod 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg

520 def _collect_metadata(kwargs: dict[str, Any]) -> list[Any]: 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg

521 """Collect annotations from kwargs. 

522 

523 Args: 

524 kwargs: Keyword arguments passed to the function. 

525 

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

537 

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

547 

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

556 

557 def get_default(self, *, call_default_factory: bool = False) -> Any: 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg

558 """Get the default value. 

559 

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`). 

563 

564 Args: 

565 call_default_factory: Whether to call the default_factory or not. Defaults to `False`. 

566 

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

576 

577 def is_required(self) -> bool: 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg

578 """Check if the field is required (i.e., does not have a default value or factory). 

579 

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

584 

585 def rebuild_annotation(self) -> Any: 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg

586 """Attempts to rebuild the original annotation for use in function signatures. 

587 

588 If metadata is present, it adds it to the original annotation using 

589 `Annotated`. Otherwise, it returns the original annotation as-is. 

590 

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`. 

594 

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

603 

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. 

606 

607 This method is used when analyzing parametrized generic types to replace typevars with their concrete types. 

608 

609 This method applies the `typevars_map` to the annotation in place. 

610 

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. 

614 

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

621 

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

625 

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

649 

650 

651class _EmptyKwargs(typing_extensions.TypedDict): 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg

652 """This class exists solely to ensure that type checking warns about passing `**extra` in `Field`.""" 

653 

654 

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) 

688 

689 

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 

730 

731 Create a field for objects that can be configured. 

732 

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`. 

735 

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` 

738 

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. 

785 

786 !!! warning Deprecated 

787 The `extra` kwargs is deprecated. Use `json_schema_extra` instead. 

788 

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

797 

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

803 

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

809 

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 ) 

819 

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

825 

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

829 

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

839 

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

846 

847 if serialization_alias in (_Unset, None) and isinstance(alias, str): 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg

848 serialization_alias = alias 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg

849 

850 if validation_alias in (_Unset, None): 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg

851 validation_alias = alias 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg

852 

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

856 

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 ) 

894 

895 

896_FIELD_ARG_NAMES = set(inspect.signature(Field).parameters) 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg

897_FIELD_ARG_NAMES.remove('extra') # do not include the varkwargs parameter 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg

898 

899 

900class ModelPrivateAttr(_repr.Representation): 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg

901 """A descriptor for private attributes in class models. 

902 

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`.) 

906 

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 """ 

912 

913 __slots__ = 'default', 'default_factory' 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg

914 

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

920 

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 

923 

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

932 

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

942 

943 def get_default(self) -> Any: 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg

944 """Retrieve the default value of the object. 

945 

946 If `self.default_factory` is `None`, the method will return a deep copy of the `self.default` object. 

947 

948 If `self.default_factory` is not `None`, it will call `self.default_factory` and return the value returned. 

949 

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

954 

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 ) 

960 

961 

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 

969 

970 Indicates that an attribute is intended for private use and not handled during normal validation/serialization. 

971 

972 Private attributes are not validated by Pydantic, so it's up to you to ensure they are used in a type-safe manner. 

973 

974 Private attributes are stored in `__private_attributes__` on the model. 

975 

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`. 

982 

983 Returns: 

984 An instance of [`ModelPrivateAttr`][pydantic.fields.ModelPrivateAttr] class. 

985 

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

991 

992 return ModelPrivateAttr( 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg

993 default, 

994 default_factory=default_factory, 

995 ) 

996 

997 

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. 

1001 

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 """ 

1017 

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

1030 

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

1039 

1040 

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

1044 

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

1049 

1050 return wrapped_name.startswith('_') and not wrapped_name.startswith('__') 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg

1051 

1052 

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

1056 

1057 

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

1072 

1073 

1074@typing.overload 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg

1075def computed_field(__func: PropertyT) -> PropertyT: ... 1hijklmnopqabrcstuvwxyzABdeNOPQRSTUVMCDEFGHIJKLfg

1076 

1077 

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 

1094 

1095 Decorator to include `property` and `cached_property` when serializing models or dataclasses. 

1096 

1097 This is useful for fields that are computed from other fields, or for fields that are expensive to compute and should be cached. 

1098 

1099 ```py 

1100 from pydantic import BaseModel, computed_field 

1101 

1102 class Rectangle(BaseModel): 

1103 width: int 

1104 length: int 

1105 

1106 @computed_field 

1107 @property 

1108 def area(self) -> int: 

1109 return self.width * self.length 

1110 

1111 print(Rectangle(width=3, length=2).model_dump()) 

1112 #> {'width': 3, 'length': 2, 'area': 6} 

1113 ``` 

1114 

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. 

1118 

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. 

1124 

1125 [pyright](https://github.com/microsoft/pyright) supports `@computed_field` without error. 

1126 

1127 ```py 

1128 import random 

1129 

1130 from pydantic import BaseModel, computed_field 

1131 

1132 class Square(BaseModel): 

1133 width: float 

1134 

1135 @computed_field 

1136 def area(self) -> float: # converted to a `property` by `computed_field` 

1137 return round(self.width**2, 2) 

1138 

1139 @area.setter 

1140 def area(self, new_area: float) -> None: 

1141 self.width = new_area**0.5 

1142 

1143 @computed_field(alias='the magic number', repr=False) 

1144 def random_number(self) -> int: 

1145 return random.randint(0, 1_000) 

1146 

1147 square = Square(width=1.3) 

1148 

1149 # `random_number` does not appear in representation 

1150 print(repr(square)) 

1151 #> Square(width=1.3, area=1.69) 

1152 

1153 print(square.random_number) 

1154 #> 3 

1155 

1156 square.area = 4 

1157 

1158 print(square.model_dump_json(by_alias=True)) 

1159 #> {"width":2.0,"area":4.0,"the magic number":3} 

1160 ``` 

1161 

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: 

1166 

1167 ```py 

1168 from pydantic import BaseModel, computed_field 

1169 

1170 class Parent(BaseModel): 

1171 a: str 

1172 

1173 try: 

1174 

1175 class Child(Parent): 

1176 @computed_field 

1177 @property 

1178 def a(self) -> str: 

1179 return 'new a' 

1180 

1181 except ValueError as e: 

1182 print(repr(e)) 

1183 #> ValueError("you can't override a field with a computed field") 

1184 ``` 

1185 

1186 Private properties decorated with `@computed_field` have `repr=False` by default. 

1187 

1188 ```py 

1189 from functools import cached_property 

1190 

1191 from pydantic import BaseModel, computed_field 

1192 

1193 class Model(BaseModel): 

1194 foo: int 

1195 

1196 @computed_field 

1197 @cached_property 

1198 def _private_cached_property(self) -> int: 

1199 return -self.foo 

1200 

1201 @computed_field 

1202 @property 

1203 def _private_property(self) -> int: 

1204 return -self.foo 

1205 

1206 m = Model(foo=1) 

1207 print(repr(m)) 

1208 #> M(foo=1) 

1209 ``` 

1210 

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. 

1230 

1231 Returns: 

1232 A proxy wrapper for the property. 

1233 """ 

1234 

1235 def dec(f: Any) -> Any: 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg

1236 nonlocal description, deprecated, return_type, alias_priority 

1237 unwrapped = _decorators.unwrap_wrapped_function(f) 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg

1238 

1239 if description is None and unwrapped.__doc__: 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg

1240 description = inspect.cleandoc(unwrapped.__doc__) 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg

1241 

1242 if deprecated is None and hasattr(unwrapped, '__deprecated__'): 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg

1243 deprecated = unwrapped.__deprecated__ 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg

1244 

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

1248 

1249 if repr is None: 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg

1250 repr_: bool = not _wrapped_property_is_private(property_=f) 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg

1251 else: 

1252 repr_ = repr 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg

1253 

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

1268 

1269 if func is None: 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg

1270 return dec 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg

1271 else: 

1272 return dec(func) 1hijklmnopqabrcstuvwxyzABdeCDEFGHIJKLfg