Coverage for pydantic/_internal/_generate_schema.py: 95.63%

1260 statements  

« prev     ^ index     » next       coverage.py v7.6.12, created at 2025-02-13 19:35 +0000

1"""Convert python types to pydantic-core schema.""" 

2 

3from __future__ import annotations as _annotations 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

4 

5import collections.abc 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

6import dataclasses 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

7import datetime 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

8import inspect 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

9import os 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

10import pathlib 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

11import re 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

12import sys 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

13import typing 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

14import warnings 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

15from collections.abc import Generator, Iterable, Iterator, Mapping 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

16from contextlib import contextmanager 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

17from copy import copy 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

18from decimal import Decimal 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

19from enum import Enum 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

20from fractions import Fraction 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

21from functools import partial 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

22from inspect import Parameter, _ParameterKind, signature 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

23from ipaddress import IPv4Address, IPv4Interface, IPv4Network, IPv6Address, IPv6Interface, IPv6Network 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

24from itertools import chain 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

25from operator import attrgetter 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

26from types import FunctionType, GenericAlias, LambdaType, MethodType 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

27from typing import ( 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

28 TYPE_CHECKING, 

29 Any, 

30 Callable, 

31 Final, 

32 ForwardRef, 

33 Literal, 

34 TypeVar, 

35 Union, 

36 cast, 

37 overload, 

38) 

39from uuid import UUID 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

40from warnings import warn 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

41 

42import typing_extensions 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

43from pydantic_core import ( 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

44 CoreSchema, 

45 MultiHostUrl, 

46 PydanticCustomError, 

47 PydanticSerializationUnexpectedValue, 

48 PydanticUndefined, 

49 Url, 

50 core_schema, 

51 to_jsonable_python, 

52) 

53from typing_extensions import TypeAliasType, TypedDict, get_args, get_origin, is_typeddict 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

54 

55from ..aliases import AliasChoices, AliasGenerator, AliasPath 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

56from ..annotated_handlers import GetCoreSchemaHandler, GetJsonSchemaHandler 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

57from ..config import ConfigDict, JsonDict, JsonEncoder, JsonSchemaExtraCallable 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

58from ..errors import PydanticSchemaGenerationError, PydanticUndefinedAnnotation, PydanticUserError 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

59from ..functional_validators import AfterValidator, BeforeValidator, FieldValidatorModes, PlainValidator, WrapValidator 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

60from ..json_schema import JsonSchemaValue 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

61from ..version import version_short 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

62from ..warnings import PydanticDeprecatedSince20 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

63from . import _decorators, _discriminated_union, _known_annotated_metadata, _repr, _typing_extra 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

64from ._config import ConfigWrapper, ConfigWrapperStack 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

65from ._core_metadata import CoreMetadata, update_core_metadata 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

66from ._core_utils import ( 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

67 get_ref, 

68 get_type_ref, 

69 is_list_like_schema_with_items_schema, 

70 validate_core_schema, 

71) 

72from ._decorators import ( 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

73 Decorator, 

74 DecoratorInfos, 

75 FieldSerializerDecoratorInfo, 

76 FieldValidatorDecoratorInfo, 

77 ModelSerializerDecoratorInfo, 

78 ModelValidatorDecoratorInfo, 

79 RootValidatorDecoratorInfo, 

80 ValidatorDecoratorInfo, 

81 get_attribute_from_bases, 

82 inspect_field_serializer, 

83 inspect_model_serializer, 

84 inspect_validator, 

85) 

86from ._docs_extraction import extract_docstrings_from_cls 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

87from ._fields import collect_dataclass_fields, rebuild_model_fields, takes_validated_data_argument 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

88from ._forward_ref import PydanticRecursiveRef 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

89from ._generics import get_standard_typevars_map, replace_types 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

90from ._import_utils import import_cached_base_model, import_cached_field_info 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

91from ._mock_val_ser import MockCoreSchema 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

92from ._namespace_utils import NamespacesTuple, NsResolver 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

93from ._schema_gather import MissingDefinitionError, gather_schemas_for_cleaning 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

94from ._schema_generation_shared import CallbackGetCoreSchemaHandler 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

95from ._utils import lenient_issubclass, smart_deepcopy 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

96 

97if TYPE_CHECKING: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

98 from ..fields import ComputedFieldInfo, FieldInfo 

99 from ..main import BaseModel 

100 from ..types import Discriminator 

101 from ._dataclasses import StandardDataclass 

102 from ._schema_generation_shared import GetJsonSchemaFunction 

103 

104_SUPPORTS_TYPEDDICT = sys.version_info >= (3, 12) 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

105 

106FieldDecoratorInfo = Union[ValidatorDecoratorInfo, FieldValidatorDecoratorInfo, FieldSerializerDecoratorInfo] 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

107FieldDecoratorInfoType = TypeVar('FieldDecoratorInfoType', bound=FieldDecoratorInfo) 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

108AnyFieldDecorator = Union[ 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

109 Decorator[ValidatorDecoratorInfo], 

110 Decorator[FieldValidatorDecoratorInfo], 

111 Decorator[FieldSerializerDecoratorInfo], 

112] 

113 

114ModifyCoreSchemaWrapHandler = GetCoreSchemaHandler 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

115GetCoreSchemaFunction = Callable[[Any, ModifyCoreSchemaWrapHandler], core_schema.CoreSchema] 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

116 

117TUPLE_TYPES: list[type] = [typing.Tuple, tuple] # noqa: UP006 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

118LIST_TYPES: list[type] = [typing.List, list, collections.abc.MutableSequence] # noqa: UP006 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

119SET_TYPES: list[type] = [typing.Set, set, collections.abc.MutableSet] # noqa: UP006 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

120FROZEN_SET_TYPES: list[type] = [typing.FrozenSet, frozenset, collections.abc.Set] # noqa: UP006 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

121DICT_TYPES: list[type] = [typing.Dict, dict] # noqa: UP006 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

122IP_TYPES: list[type] = [IPv4Address, IPv4Interface, IPv4Network, IPv6Address, IPv6Interface, IPv6Network] 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

123SEQUENCE_TYPES: list[type] = [typing.Sequence, collections.abc.Sequence] 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

124ITERABLE_TYPES: list[type] = [typing.Iterable, collections.abc.Iterable, typing.Generator, collections.abc.Generator] 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

125TYPE_TYPES: list[type] = [typing.Type, type] # noqa: UP006 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

126PATTERN_TYPES: list[type] = [typing.Pattern, re.Pattern] 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

127PATH_TYPES: list[type] = [ 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

128 os.PathLike, 

129 pathlib.Path, 

130 pathlib.PurePath, 

131 pathlib.PosixPath, 

132 pathlib.PurePosixPath, 

133 pathlib.PureWindowsPath, 

134] 

135MAPPING_TYPES = [ 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

136 typing.Mapping, 

137 typing.MutableMapping, 

138 collections.abc.Mapping, 

139 collections.abc.MutableMapping, 

140 collections.OrderedDict, 

141 typing_extensions.OrderedDict, 

142 typing.DefaultDict, # noqa: UP006 

143 collections.defaultdict, 

144] 

145COUNTER_TYPES = [collections.Counter, typing.Counter] 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

146DEQUE_TYPES: list[type] = [collections.deque, typing.Deque] # noqa: UP006 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

147 

148# Note: This does not play very well with type checkers. For example, 

149# `a: LambdaType = lambda x: x` will raise a type error by Pyright. 

150ValidateCallSupportedTypes = Union[ 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

151 LambdaType, 

152 FunctionType, 

153 MethodType, 

154 partial, 

155] 

156 

157VALIDATE_CALL_SUPPORTED_TYPES = get_args(ValidateCallSupportedTypes) 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

158 

159_mode_to_validator: dict[ 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

160 FieldValidatorModes, type[BeforeValidator | AfterValidator | PlainValidator | WrapValidator] 

161] = {'before': BeforeValidator, 'after': AfterValidator, 'plain': PlainValidator, 'wrap': WrapValidator} 

162 

163 

164def check_validator_fields_against_field_name( 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

165 info: FieldDecoratorInfo, 

166 field: str, 

167) -> bool: 

168 """Check if field name is in validator fields. 

169 

170 Args: 

171 info: The field info. 

172 field: The field name to check. 

173 

174 Returns: 

175 `True` if field name is in validator fields, `False` otherwise. 

176 """ 

177 fields = info.fields 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

178 return '*' in fields or field in fields 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

179 

180 

181def check_decorator_fields_exist(decorators: Iterable[AnyFieldDecorator], fields: Iterable[str]) -> None: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

182 """Check if the defined fields in decorators exist in `fields` param. 

183 

184 It ignores the check for a decorator if the decorator has `*` as field or `check_fields=False`. 

185 

186 Args: 

187 decorators: An iterable of decorators. 

188 fields: An iterable of fields name. 

189 

190 Raises: 

191 PydanticUserError: If one of the field names does not exist in `fields` param. 

192 """ 

193 fields = set(fields) 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

194 for dec in decorators: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

195 if '*' in dec.info.fields: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

196 continue 1acekoquwxCfbhilmrsyzDEdjgnptvABF

197 if dec.info.check_fields is False: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

198 continue 1acekoquwxCfbhilmrsyzDEdjgnptvABF

199 for field in dec.info.fields: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

200 if field not in fields: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

201 raise PydanticUserError( 1acekoquwxCfbhilmrsyzDEdjgnptvABF

202 f'Decorators defined with incorrect fields: {dec.cls_ref}.{dec.cls_var_name}' 

203 " (use check_fields=False if you're inheriting from the model and intended this)", 

204 code='decorator-missing-field', 

205 ) 

206 

207 

208def filter_field_decorator_info_by_field( 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

209 validator_functions: Iterable[Decorator[FieldDecoratorInfoType]], field: str 

210) -> list[Decorator[FieldDecoratorInfoType]]: 

211 return [dec for dec in validator_functions if check_validator_fields_against_field_name(dec.info, field)] 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

212 

213 

214def apply_each_item_validators( 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

215 schema: core_schema.CoreSchema, 

216 each_item_validators: list[Decorator[ValidatorDecoratorInfo]], 

217 field_name: str | None, 

218) -> core_schema.CoreSchema: 

219 # This V1 compatibility shim should eventually be removed 

220 

221 # fail early if each_item_validators is empty 

222 if not each_item_validators: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

223 return schema 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

224 

225 # push down any `each_item=True` validators 

226 # note that this won't work for any Annotated types that get wrapped by a function validator 

227 # but that's okay because that didn't exist in V1 

228 if schema['type'] == 'nullable': 1acekoquwxCfbhilmrsyzDEdjgnptvABF

229 schema['schema'] = apply_each_item_validators(schema['schema'], each_item_validators, field_name) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

230 return schema 1acekoquwxCfbhilmrsyzDEdjgnptvABF

231 elif schema['type'] == 'tuple': 231 ↛ 232line 231 didn't jump to line 232 because the condition on line 231 was never true1acekoquwxCfbhilmrsyzDEdjgnptvABF

232 if (variadic_item_index := schema.get('variadic_item_index')) is not None: 

233 schema['items_schema'][variadic_item_index] = apply_validators( 

234 schema['items_schema'][variadic_item_index], 

235 each_item_validators, 

236 field_name, 

237 ) 

238 elif is_list_like_schema_with_items_schema(schema): 1acekoquwxCfbhilmrsyzDEdjgnptvABF

239 inner_schema = schema.get('items_schema', core_schema.any_schema()) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

240 schema['items_schema'] = apply_validators(inner_schema, each_item_validators, field_name) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

241 elif schema['type'] == 'dict': 1acekoquwxCfbhilmrsyzDEdjgnptvABF

242 inner_schema = schema.get('values_schema', core_schema.any_schema()) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

243 schema['values_schema'] = apply_validators(inner_schema, each_item_validators, field_name) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

244 else: 

245 raise TypeError( 1acekoquwxCfbhilmrsyzDEdjgnptvABF

246 f'`@validator(..., each_item=True)` cannot be applied to fields with a schema of {schema["type"]}' 

247 ) 

248 return schema 1acekoquwxCfbhilmrsyzDEdjgnptvABF

249 

250 

251def _extract_json_schema_info_from_field_info( 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

252 info: FieldInfo | ComputedFieldInfo, 

253) -> tuple[JsonDict | None, JsonDict | JsonSchemaExtraCallable | None]: 

254 json_schema_updates = { 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

255 'title': info.title, 

256 'description': info.description, 

257 'deprecated': bool(info.deprecated) or info.deprecated == '' or None, 

258 'examples': to_jsonable_python(info.examples), 

259 } 

260 json_schema_updates = {k: v for k, v in json_schema_updates.items() if v is not None} 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

261 return (json_schema_updates or None, info.json_schema_extra) 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

262 

263 

264JsonEncoders = dict[type[Any], JsonEncoder] 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

265 

266 

267def _add_custom_serialization_from_json_encoders( 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

268 json_encoders: JsonEncoders | None, tp: Any, schema: CoreSchema 

269) -> CoreSchema: 

270 """Iterate over the json_encoders and add the first matching encoder to the schema. 

271 

272 Args: 

273 json_encoders: A dictionary of types and their encoder functions. 

274 tp: The type to check for a matching encoder. 

275 schema: The schema to add the encoder to. 

276 """ 

277 if not json_encoders: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

278 return schema 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

279 if 'serialization' in schema: 1acekoquwxCfbhilmrsyzDEdjgnptvABF

280 return schema 1acekoquwxCfbhilmrsyzDEdjgnptvABF

281 # Check the class type and its superclasses for a matching encoder 

282 # Decimal.__class__.__mro__ (and probably other cases) doesn't include Decimal itself 

283 # if the type is a GenericAlias (e.g. from list[int]) we need to use __class__ instead of .__mro__ 

284 for base in (tp, *getattr(tp, '__mro__', tp.__class__.__mro__)[:-1]): 1acekoquwxCfbhilmrsyzDEdjgnptvABF

285 encoder = json_encoders.get(base) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

286 if encoder is None: 1acekoquwxCfbhilmrsyzDEdjgnptvABF

287 continue 1acekoquwxCfbhilmrsyzDEdjgnptvABF

288 

289 warnings.warn( 1acekoquwxCfbhilmrsyzDEdjgnptvABF

290 f'`json_encoders` is deprecated. See https://docs.pydantic.dev/{version_short()}/concepts/serialization/#custom-serializers for alternatives', 

291 PydanticDeprecatedSince20, 

292 ) 

293 

294 # TODO: in theory we should check that the schema accepts a serialization key 

295 schema['serialization'] = core_schema.plain_serializer_function_ser_schema(encoder, when_used='json') 1acekoquwxCfbhilmrsyzDEdjgnptvABF

296 return schema 1acekoquwxCfbhilmrsyzDEdjgnptvABF

297 

298 return schema 1acekoquwxCfbhilmrsyzDEdjgnptvABF

299 

300 

301def _get_first_non_null(a: Any, b: Any) -> Any: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

302 """Return the first argument if it is not None, otherwise return the second argument. 

303 

304 Use case: serialization_alias (argument a) and alias (argument b) are both defined, and serialization_alias is ''. 

305 This function will return serialization_alias, which is the first argument, even though it is an empty string. 

306 """ 

307 return a if a is not None else b 1acekoquwxCfbhilmrsyzDEdjgnptvABF

308 

309 

310class InvalidSchemaError(Exception): 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

311 """The core schema is invalid.""" 

312 

313 

314class GenerateSchema: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

315 """Generate core schema for a Pydantic model, dataclass and types like `str`, `datetime`, ... .""" 

316 

317 __slots__ = ( 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

318 '_config_wrapper_stack', 

319 '_ns_resolver', 

320 '_typevars_map', 

321 'field_name_stack', 

322 'model_type_stack', 

323 'defs', 

324 ) 

325 

326 def __init__( 1acekoquwxChilmrsyzDELGHIJKMdjgnptvABF

327 self, 

328 config_wrapper: ConfigWrapper, 

329 ns_resolver: NsResolver | None = None, 

330 typevars_map: Mapping[TypeVar, Any] | None = None, 

331 ) -> None: 

332 # we need a stack for recursing into nested models 

333 self._config_wrapper_stack = ConfigWrapperStack(config_wrapper) 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

334 self._ns_resolver = ns_resolver or NsResolver() 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

335 self._typevars_map = typevars_map 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

336 self.field_name_stack = _FieldNameStack() 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

337 self.model_type_stack = _ModelTypeStack() 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

338 self.defs = _Definitions() 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

339 

340 def __init_subclass__(cls) -> None: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

341 super().__init_subclass__() 1acekoquwxCfbhilmrsyzDEdjgnptvABF

342 warnings.warn( 1acekoquwxCfbhilmrsyzDEdjgnptvABF

343 'Subclassing `GenerateSchema` is not supported. The API is highly subject to change in minor versions.', 

344 UserWarning, 

345 stacklevel=2, 

346 ) 

347 

348 @property 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

349 def _config_wrapper(self) -> ConfigWrapper: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

350 return self._config_wrapper_stack.tail 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

351 

352 @property 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

353 def _types_namespace(self) -> NamespacesTuple: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

354 return self._ns_resolver.types_namespace 1acekoquwxCfbhilmrsyzDEdjgnptvABF

355 

356 @property 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

357 def _arbitrary_types(self) -> bool: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

358 return self._config_wrapper.arbitrary_types_allowed 1acekoquwxCfbhilmrsyzDEdjgnptvABF

359 

360 # the following methods can be overridden but should be considered 

361 # unstable / private APIs 

362 def _list_schema(self, items_type: Any) -> CoreSchema: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

363 return core_schema.list_schema(self.generate_schema(items_type)) 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

364 

365 def _dict_schema(self, keys_type: Any, values_type: Any) -> CoreSchema: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

366 return core_schema.dict_schema(self.generate_schema(keys_type), self.generate_schema(values_type)) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

367 

368 def _set_schema(self, items_type: Any) -> CoreSchema: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

369 return core_schema.set_schema(self.generate_schema(items_type)) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

370 

371 def _frozenset_schema(self, items_type: Any) -> CoreSchema: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

372 return core_schema.frozenset_schema(self.generate_schema(items_type)) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

373 

374 def _enum_schema(self, enum_type: type[Enum]) -> CoreSchema: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

375 cases: list[Any] = list(enum_type.__members__.values()) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

376 

377 enum_ref = get_type_ref(enum_type) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

378 description = None if not enum_type.__doc__ else inspect.cleandoc(enum_type.__doc__) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

379 if ( 1acfb

380 description == 'An enumeration.' 

381 ): # This is the default value provided by enum.EnumMeta.__new__; don't use it 

382 description = None 1acekfbhilmdjgn

383 js_updates = {'title': enum_type.__name__, 'description': description} 1acekoquwxCfbhilmrsyzDEdjgnptvABF

384 js_updates = {k: v for k, v in js_updates.items() if v is not None} 1acekoquwxCfbhilmrsyzDEdjgnptvABF

385 

386 sub_type: Literal['str', 'int', 'float'] | None = None 1acekoquwxCfbhilmrsyzDEdjgnptvABF

387 if issubclass(enum_type, int): 1acekoquwxCfbhilmrsyzDEdjgnptvABF

388 sub_type = 'int' 1acekoquwxCfbhilmrsyzDEdjgnptvABF

389 value_ser_type: core_schema.SerSchema = core_schema.simple_ser_schema('int') 1acekoquwxCfbhilmrsyzDEdjgnptvABF

390 elif issubclass(enum_type, str): 1acekoquwxCfbhilmrsyzDEdjgnptvABF

391 # this handles `StrEnum` (3.11 only), and also `Foobar(str, Enum)` 

392 sub_type = 'str' 1acekoquwxCfbhilmrsyzDEdjgnptvABF

393 value_ser_type = core_schema.simple_ser_schema('str') 1acekoquwxCfbhilmrsyzDEdjgnptvABF

394 elif issubclass(enum_type, float): 1acekoquwxCfbhilmrsyzDEdjgnptvABF

395 sub_type = 'float' 1acekoquwxCfbhilmrsyzDEdjgnptvABF

396 value_ser_type = core_schema.simple_ser_schema('float') 1acekoquwxCfbhilmrsyzDEdjgnptvABF

397 else: 

398 # TODO this is an ugly hack, how do we trigger an Any schema for serialization? 

399 value_ser_type = core_schema.plain_serializer_function_ser_schema(lambda x: x) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

400 

401 if cases: 1acekoquwxCfbhilmrsyzDEdjgnptvABF

402 

403 def get_json_schema(schema: CoreSchema, handler: GetJsonSchemaHandler) -> JsonSchemaValue: 1acekoquwxCfbhilmrsyzDEdjgnptvABF

404 json_schema = handler(schema) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

405 original_schema = handler.resolve_ref_schema(json_schema) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

406 original_schema.update(js_updates) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

407 return json_schema 1acekoquwxCfbhilmrsyzDEdjgnptvABF

408 

409 # we don't want to add the missing to the schema if it's the default one 

410 default_missing = getattr(enum_type._missing_, '__func__', None) is Enum._missing_.__func__ # pyright: ignore[reportFunctionMemberAccess] 1acekoquwxCfbhilmrsyzDEdjgnptvABF

411 enum_schema = core_schema.enum_schema( 1acekoquwxCfbhilmrsyzDEdjgnptvABF

412 enum_type, 

413 cases, 

414 sub_type=sub_type, 

415 missing=None if default_missing else enum_type._missing_, 

416 ref=enum_ref, 

417 metadata={'pydantic_js_functions': [get_json_schema]}, 

418 ) 

419 

420 if self._config_wrapper.use_enum_values: 1acekoquwxCfbhilmrsyzDEdjgnptvABF

421 enum_schema = core_schema.no_info_after_validator_function( 1acekoquwxCfbhilmrsyzDEdjgnptvABF

422 attrgetter('value'), enum_schema, serialization=value_ser_type 

423 ) 

424 

425 return enum_schema 1acekoquwxCfbhilmrsyzDEdjgnptvABF

426 

427 else: 

428 

429 def get_json_schema_no_cases(_, handler: GetJsonSchemaHandler) -> JsonSchemaValue: 1acekoquwxCfbhilmrsyzDEdjgnptvABF

430 json_schema = handler(core_schema.enum_schema(enum_type, cases, sub_type=sub_type, ref=enum_ref)) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

431 original_schema = handler.resolve_ref_schema(json_schema) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

432 original_schema.update(js_updates) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

433 return json_schema 1acekoquwxCfbhilmrsyzDEdjgnptvABF

434 

435 # Use an isinstance check for enums with no cases. 

436 # The most important use case for this is creating TypeVar bounds for generics that should 

437 # be restricted to enums. This is more consistent than it might seem at first, since you can only 

438 # subclass enum.Enum (or subclasses of enum.Enum) if all parent classes have no cases. 

439 # We use the get_json_schema function when an Enum subclass has been declared with no cases 

440 # so that we can still generate a valid json schema. 

441 return core_schema.is_instance_schema( 1acekoquwxCfbhilmrsyzDEdjgnptvABF

442 enum_type, 

443 metadata={'pydantic_js_functions': [get_json_schema_no_cases]}, 

444 ) 

445 

446 def _ip_schema(self, tp: Any) -> CoreSchema: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

447 from ._validators import IP_VALIDATOR_LOOKUP, IpType 1acekoquwxCfbhilmrsyzDEdjgnptvABF

448 

449 ip_type_json_schema_format: dict[type[IpType], str] = { 1acekoquwxCfbhilmrsyzDEdjgnptvABF

450 IPv4Address: 'ipv4', 

451 IPv4Network: 'ipv4network', 

452 IPv4Interface: 'ipv4interface', 

453 IPv6Address: 'ipv6', 

454 IPv6Network: 'ipv6network', 

455 IPv6Interface: 'ipv6interface', 

456 } 

457 

458 def ser_ip(ip: Any, info: core_schema.SerializationInfo) -> str | IpType: 1acekoquwxCfbhilmrsyzDEdjgnptvABF

459 if not isinstance(ip, (tp, str)): 1acekoquwxCfbhilmrsyzDEdjgnptvABF

460 raise PydanticSerializationUnexpectedValue( 1acekoquwxCfbhilmrsyzDEdjgnptvABF

461 f"Expected `{tp}` but got `{type(ip)}` with value `'{ip}'` - serialized value may not be as expected." 

462 ) 

463 if info.mode == 'python': 1acekoquwxCfbhilmrsyzDEdjgnptvABF

464 return ip 1acekoquwxCfbhilmrsyzDEdjgnptvABF

465 return str(ip) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

466 

467 return core_schema.lax_or_strict_schema( 1acekoquwxCfbhilmrsyzDEdjgnptvABF

468 lax_schema=core_schema.no_info_plain_validator_function(IP_VALIDATOR_LOOKUP[tp]), 

469 strict_schema=core_schema.json_or_python_schema( 

470 json_schema=core_schema.no_info_after_validator_function(tp, core_schema.str_schema()), 

471 python_schema=core_schema.is_instance_schema(tp), 

472 ), 

473 serialization=core_schema.plain_serializer_function_ser_schema(ser_ip, info_arg=True, when_used='always'), 

474 metadata={ 

475 'pydantic_js_functions': [lambda _1, _2: {'type': 'string', 'format': ip_type_json_schema_format[tp]}] 

476 }, 

477 ) 

478 

479 def _path_schema(self, tp: Any, path_type: Any) -> CoreSchema: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

480 if tp is os.PathLike and (path_type not in {str, bytes} and not _typing_extra.is_any(path_type)): 480 ↛ 481line 480 didn't jump to line 481 because the condition on line 480 was never true1acekoquwxCfbhilmrsyzDEdjgnptvABF

481 raise PydanticUserError( 

482 '`os.PathLike` can only be used with `str`, `bytes` or `Any`', code='schema-for-unknown-type' 

483 ) 

484 

485 path_constructor = pathlib.PurePath if tp is os.PathLike else tp 1acekoquwxCfbhilmrsyzDEdjgnptvABF

486 constrained_schema = core_schema.bytes_schema() if (path_type is bytes) else core_schema.str_schema() 1acekoquwxCfbhilmrsyzDEdjgnptvABF

487 

488 def path_validator(input_value: str | bytes) -> os.PathLike[Any]: # type: ignore 1acekoquwxCfbhilmrsyzDEdjgnptvABF

489 try: 1acekoquwxCfbhilmrsyzDEdjgnptvABF

490 if path_type is bytes: 1acekoquwxCfbhilmrsyzDEdjgnptvABF

491 if isinstance(input_value, bytes): 491 ↛ 497line 491 didn't jump to line 497 because the condition on line 491 was always true1acekoquwxCfbhilmrsyzDEdjgnptvABF

492 try: 1acekoquwxCfbhilmrsyzDEdjgnptvABF

493 input_value = input_value.decode() 1acekoquwxCfbhilmrsyzDEdjgnptvABF

494 except UnicodeDecodeError as e: 

495 raise PydanticCustomError('bytes_type', 'Input must be valid bytes') from e 

496 else: 

497 raise PydanticCustomError('bytes_type', 'Input must be bytes') 

498 elif not isinstance(input_value, str): 498 ↛ 499line 498 didn't jump to line 499 because the condition on line 498 was never true1acekoquwxCfbhilmrsyzDEdjgnptvABF

499 raise PydanticCustomError('path_type', 'Input is not a valid path') 

500 

501 return path_constructor(input_value) # type: ignore 1acekoquwxCfbhilmrsyzDEdjgnptvABF

502 except TypeError as e: 

503 raise PydanticCustomError('path_type', 'Input is not a valid path') from e 

504 

505 def ser_path(path: Any, info: core_schema.SerializationInfo) -> str | os.PathLike[Any]: 1acekoquwxCfbhilmrsyzDEdjgnptvABF

506 if not isinstance(path, (tp, str)): 1acekoquwxCfbhilmrsyzDEdjgnptvABF

507 raise PydanticSerializationUnexpectedValue( 1acekoquwxCfbhilmrsyzDEdjgnptvABF

508 f"Expected `{tp}` but got `{type(path)}` with value `'{path}'` - serialized value may not be as expected." 

509 ) 

510 if info.mode == 'python': 1acekoquwxCfbhilmrsyzDEdjgnptvABF

511 return path 1acekoquwxCfbhilmrsyzDEdjgnptvABF

512 return str(path) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

513 

514 instance_schema = core_schema.json_or_python_schema( 1acekoquwxCfbhilmrsyzDEdjgnptvABF

515 json_schema=core_schema.no_info_after_validator_function(path_validator, constrained_schema), 

516 python_schema=core_schema.is_instance_schema(tp), 

517 ) 

518 

519 schema = core_schema.lax_or_strict_schema( 1acekoquwxCfbhilmrsyzDEdjgnptvABF

520 lax_schema=core_schema.union_schema( 

521 [ 

522 instance_schema, 

523 core_schema.no_info_after_validator_function(path_validator, constrained_schema), 

524 ], 

525 custom_error_type='path_type', 

526 custom_error_message=f'Input is not a valid path for {tp}', 

527 strict=True, 

528 ), 

529 strict_schema=instance_schema, 

530 serialization=core_schema.plain_serializer_function_ser_schema(ser_path, info_arg=True, when_used='always'), 

531 metadata={'pydantic_js_functions': [lambda source, handler: {**handler(source), 'format': 'path'}]}, 

532 ) 

533 return schema 1acekoquwxCfbhilmrsyzDEdjgnptvABF

534 

535 def _deque_schema(self, items_type: Any) -> CoreSchema: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

536 from ._serializers import serialize_sequence_via_list 1acekoquwxCfbhilmrsyzDEdjgnptvABF

537 from ._validators import deque_validator 1acekoquwxCfbhilmrsyzDEdjgnptvABF

538 

539 item_type_schema = self.generate_schema(items_type) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

540 

541 # we have to use a lax list schema here, because we need to validate the deque's 

542 # items via a list schema, but it's ok if the deque itself is not a list 

543 list_schema = core_schema.list_schema(item_type_schema, strict=False) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

544 

545 check_instance = core_schema.json_or_python_schema( 1acekoquwxCfbhilmrsyzDEdjgnptvABF

546 json_schema=list_schema, 

547 python_schema=core_schema.is_instance_schema(collections.deque, cls_repr='Deque'), 

548 ) 

549 

550 lax_schema = core_schema.no_info_wrap_validator_function(deque_validator, list_schema) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

551 

552 return core_schema.lax_or_strict_schema( 1acekoquwxCfbhilmrsyzDEdjgnptvABF

553 lax_schema=lax_schema, 

554 strict_schema=core_schema.chain_schema([check_instance, lax_schema]), 

555 serialization=core_schema.wrap_serializer_function_ser_schema( 

556 serialize_sequence_via_list, schema=item_type_schema, info_arg=True 

557 ), 

558 ) 

559 

560 def _mapping_schema(self, tp: Any, keys_type: Any, values_type: Any) -> CoreSchema: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

561 from ._validators import MAPPING_ORIGIN_MAP, defaultdict_validator, get_defaultdict_default_default_factory 1acekoquwxCfbhilmrsyzDEdjgnptvABF

562 

563 keys_schema = self.generate_schema(keys_type) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

564 values_schema = self.generate_schema(values_type) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

565 

566 dict_schema = core_schema.dict_schema(keys_schema, values_schema) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

567 check_instance = core_schema.json_or_python_schema( 1acekoquwxCfbhilmrsyzDEdjgnptvABF

568 json_schema=dict_schema, 

569 python_schema=core_schema.is_instance_schema(tp), 

570 ) 

571 

572 if tp is collections.defaultdict: 1acekoquwxCfbhilmrsyzDEdjgnptvABF

573 default_default_factory = get_defaultdict_default_default_factory(values_type) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

574 coerce_instance_wrap = partial( 1acekoquwxCfbhilmrsyzDEdjgnptvABF

575 core_schema.no_info_wrap_validator_function, 

576 partial(defaultdict_validator, default_default_factory=default_default_factory), 

577 ) 

578 else: 

579 coerce_instance_wrap = partial(core_schema.no_info_after_validator_function, MAPPING_ORIGIN_MAP[tp]) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

580 

581 lax_schema = coerce_instance_wrap(dict_schema) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

582 schema = core_schema.lax_or_strict_schema( 1acekoquwxCfbhilmrsyzDEdjgnptvABF

583 lax_schema=lax_schema, 

584 strict_schema=core_schema.union_schema([check_instance, lax_schema]), 

585 serialization=core_schema.wrap_serializer_function_ser_schema( 

586 lambda v, h: h(v), schema=dict_schema, info_arg=False 

587 ), 

588 ) 

589 

590 return schema 1acekoquwxCfbhilmrsyzDEdjgnptvABF

591 

592 def _fraction_schema(self) -> CoreSchema: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

593 """Support for [`fractions.Fraction`][fractions.Fraction].""" 

594 from ._validators import fraction_validator 1acekoquwxCfbhilmrsyzDEdjgnptvABF

595 

596 # TODO: note, this is a fairly common pattern, re lax / strict for attempted type coercion, 

597 # can we use a helper function to reduce boilerplate? 

598 return core_schema.lax_or_strict_schema( 1acekoquwxCfbhilmrsyzDEdjgnptvABF

599 lax_schema=core_schema.no_info_plain_validator_function(fraction_validator), 

600 strict_schema=core_schema.json_or_python_schema( 

601 json_schema=core_schema.no_info_plain_validator_function(fraction_validator), 

602 python_schema=core_schema.is_instance_schema(Fraction), 

603 ), 

604 # use str serialization to guarantee round trip behavior 

605 serialization=core_schema.to_string_ser_schema(when_used='always'), 

606 metadata={'pydantic_js_functions': [lambda _1, _2: {'type': 'string', 'format': 'fraction'}]}, 

607 ) 

608 

609 def _arbitrary_type_schema(self, tp: Any) -> CoreSchema: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

610 if not isinstance(tp, type): 1acekoquwxCfbhilmrsyzDEdjgnptvABF

611 warn( 1acekoquwxCfbhilmrsyzDEdjgnptvABF

612 f'{tp!r} is not a Python type (it may be an instance of an object),' 

613 ' Pydantic will allow any object with no validation since we cannot even' 

614 ' enforce that the input is an instance of the given type.' 

615 ' To get rid of this error wrap the type with `pydantic.SkipValidation`.', 

616 UserWarning, 

617 ) 

618 return core_schema.any_schema() 1acekoquwxCfbhilmrsyzDEdjgnptvABF

619 return core_schema.is_instance_schema(tp) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

620 

621 def _unknown_type_schema(self, obj: Any) -> CoreSchema: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

622 raise PydanticSchemaGenerationError( 1acekoquwxCfbhilmrsyzDEdjgnptvABF

623 f'Unable to generate pydantic-core schema for {obj!r}. ' 

624 'Set `arbitrary_types_allowed=True` in the model_config to ignore this error' 

625 ' or implement `__get_pydantic_core_schema__` on your type to fully support it.' 

626 '\n\nIf you got this error by calling handler(<some type>) within' 

627 ' `__get_pydantic_core_schema__` then you likely need to call' 

628 ' `handler.generate_schema(<some type>)` since we do not call' 

629 ' `__get_pydantic_core_schema__` on `<some type>` otherwise to avoid infinite recursion.' 

630 ) 

631 

632 def _apply_discriminator_to_union( 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

633 self, schema: CoreSchema, discriminator: str | Discriminator | None 

634 ) -> CoreSchema: 

635 if discriminator is None: 635 ↛ 636line 635 didn't jump to line 636 because the condition on line 635 was never true1acekoquwxCfbhilmrsyzDEdjgnptvABF

636 return schema 

637 try: 1acekoquwxCfbhilmrsyzDEdjgnptvABF

638 return _discriminated_union.apply_discriminator( 1acekoquwxCfbhilmrsyzDEdjgnptvABF

639 schema, 

640 discriminator, 

641 ) 

642 except _discriminated_union.MissingDefinitionForUnionRef: 1acekoquwxCfbhilmrsyzDEdjgnptvABF

643 # defer until defs are resolved 

644 _discriminated_union.set_discriminator_in_metadata( 1acekoquwxCfbhilmrsyzDEdjgnptvABF

645 schema, 

646 discriminator, 

647 ) 

648 return schema 1acekoquwxCfbhilmrsyzDEdjgnptvABF

649 

650 def clean_schema(self, schema: CoreSchema) -> CoreSchema: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

651 schema = self.defs.finalize_schema(schema) 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

652 schema = validate_core_schema(schema) 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

653 return schema 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

654 

655 def _add_js_function(self, metadata_schema: CoreSchema, js_function: Callable[..., Any]) -> None: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

656 metadata = metadata_schema.get('metadata', {}) 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

657 pydantic_js_functions = metadata.setdefault('pydantic_js_functions', []) 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

658 # because of how we generate core schemas for nested generic models 

659 # we can end up adding `BaseModel.__get_pydantic_json_schema__` multiple times 

660 # this check may fail to catch duplicates if the function is a `functools.partial` 

661 # or something like that, but if it does it'll fail by inserting the duplicate 

662 if js_function not in pydantic_js_functions: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

663 pydantic_js_functions.append(js_function) 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

664 metadata_schema['metadata'] = metadata 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

665 

666 def generate_schema( 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

667 self, 

668 obj: Any, 

669 ) -> core_schema.CoreSchema: 

670 """Generate core schema. 

671 

672 Args: 

673 obj: The object to generate core schema for. 

674 

675 Returns: 

676 The generated core schema. 

677 

678 Raises: 

679 PydanticUndefinedAnnotation: 

680 If it is not possible to evaluate forward reference. 

681 PydanticSchemaGenerationError: 

682 If it is not possible to generate pydantic-core schema. 

683 TypeError: 

684 - If `alias_generator` returns a disallowed type (must be str, AliasPath or AliasChoices). 

685 - If V1 style validator with `each_item=True` applied on a wrong field. 

686 PydanticUserError: 

687 - If `typing.TypedDict` is used instead of `typing_extensions.TypedDict` on Python < 3.12. 

688 - If `__modify_schema__` method is used instead of `__get_pydantic_json_schema__`. 

689 """ 

690 schema = self._generate_schema_from_get_schema_method(obj, obj) 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

691 

692 if schema is None: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

693 schema = self._generate_schema_inner(obj) 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

694 

695 metadata_js_function = _extract_get_pydantic_json_schema(obj) 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

696 if metadata_js_function is not None: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

697 metadata_schema = resolve_original_schema(schema, self.defs) 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

698 if metadata_schema: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

699 self._add_js_function(metadata_schema, metadata_js_function) 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

700 

701 schema = _add_custom_serialization_from_json_encoders(self._config_wrapper.json_encoders, obj, schema) 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

702 

703 return schema 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

704 

705 def _model_schema(self, cls: type[BaseModel]) -> core_schema.CoreSchema: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

706 """Generate schema for a Pydantic model.""" 

707 BaseModel_ = import_cached_base_model() 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

708 

709 with self.defs.get_schema_or_ref(cls) as (model_ref, maybe_schema): 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

710 if maybe_schema is not None: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

711 return maybe_schema 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

712 

713 schema = cls.__dict__.get('__pydantic_core_schema__') 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

714 if schema is not None and not isinstance(schema, MockCoreSchema): 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

715 if schema['type'] == 'definitions': 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

716 schema = self.defs.unpack_definitions(schema) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

717 ref = get_ref(schema) 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

718 if ref: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

719 return self.defs.create_definition_reference_schema(schema) 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

720 else: 

721 return schema 1acekoquwxCfbhilmrsyzDEdjgnptvABF

722 

723 config_wrapper = ConfigWrapper(cls.model_config, check=False) 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

724 

725 with self._config_wrapper_stack.push(config_wrapper), self._ns_resolver.push(cls): 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

726 core_config = self._config_wrapper.core_config(title=cls.__name__) 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

727 

728 if cls.__pydantic_fields_complete__ or cls is BaseModel_: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

729 fields = getattr(cls, '__pydantic_fields__', {}) 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

730 else: 

731 try: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

732 fields = rebuild_model_fields( 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

733 cls, 

734 ns_resolver=self._ns_resolver, 

735 typevars_map=self._typevars_map or {}, 

736 ) 

737 except NameError as e: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

738 raise PydanticUndefinedAnnotation.from_name_error(e) from e 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

739 

740 decorators = cls.__pydantic_decorators__ 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

741 computed_fields = decorators.computed_fields 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

742 check_decorator_fields_exist( 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

743 chain( 

744 decorators.field_validators.values(), 

745 decorators.field_serializers.values(), 

746 decorators.validators.values(), 

747 ), 

748 {*fields.keys(), *computed_fields.keys()}, 

749 ) 

750 

751 model_validators = decorators.model_validators.values() 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

752 

753 extras_schema = None 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

754 if core_config.get('extra_fields_behavior') == 'allow': 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

755 assert cls.__mro__[0] is cls 1acekoquwxCfbhilmrsyzDEdjgnptvABF

756 assert cls.__mro__[-1] is object 1acekoquwxCfbhilmrsyzDEdjgnptvABF

757 for candidate_cls in cls.__mro__[:-1]: 1acekoquwxCfbhilmrsyzDEdjgnptvABF

758 extras_annotation = getattr(candidate_cls, '__annotations__', {}).get( 1acekoquwxCfbhilmrsyzDEdjgnptvABF

759 '__pydantic_extra__', None 

760 ) 

761 if extras_annotation is not None: 1acekoquwxCfbhilmrsyzDEdjgnptvABF

762 if isinstance(extras_annotation, str): 1acekoquwxCfbhilmrsyzDEdjgnptvABF

763 extras_annotation = _typing_extra.eval_type_backport( 1acekoquwxCfbhilmrsyzDEdjgnptvABF

764 _typing_extra._make_forward_ref( 

765 extras_annotation, is_argument=False, is_class=True 

766 ), 

767 *self._types_namespace, 

768 ) 

769 tp = get_origin(extras_annotation) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

770 if tp not in DICT_TYPES: 770 ↛ 771line 770 didn't jump to line 771 because the condition on line 770 was never true1acekoquwxCfbhilmrsyzDEdjgnptvABF

771 raise PydanticSchemaGenerationError( 

772 'The type annotation for `__pydantic_extra__` must be `dict[str, ...]`' 

773 ) 

774 extra_items_type = self._get_args_resolving_forward_refs( 1acekoquwxCfbhilmrsyzDEdjgnptvABF

775 extras_annotation, 

776 required=True, 

777 )[1] 

778 if not _typing_extra.is_any(extra_items_type): 778 ↛ 757line 778 didn't jump to line 757 because the condition on line 778 was always true1acekoquwxCfbhilmrsyzDEdjgnptvABF

779 extras_schema = self.generate_schema(extra_items_type) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

780 break 1acekoquwxCfbhilmrsyzDEdjgnptvABF

781 

782 generic_origin: type[BaseModel] | None = getattr(cls, '__pydantic_generic_metadata__', {}).get('origin') 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

783 

784 if cls.__pydantic_root_model__: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

785 root_field = self._common_field_schema('root', fields['root'], decorators) 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

786 inner_schema = root_field['schema'] 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

787 inner_schema = apply_model_validators(inner_schema, model_validators, 'inner') 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

788 model_schema = core_schema.model_schema( 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

789 cls, 

790 inner_schema, 

791 generic_origin=generic_origin, 

792 custom_init=getattr(cls, '__pydantic_custom_init__', None), 

793 root_model=True, 

794 post_init=getattr(cls, '__pydantic_post_init__', None), 

795 config=core_config, 

796 ref=model_ref, 

797 ) 

798 else: 

799 fields_schema: core_schema.CoreSchema = core_schema.model_fields_schema( 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

800 {k: self._generate_md_field_schema(k, v, decorators) for k, v in fields.items()}, 

801 computed_fields=[ 

802 self._computed_field_schema(d, decorators.field_serializers) 

803 for d in computed_fields.values() 

804 ], 

805 extras_schema=extras_schema, 

806 model_name=cls.__name__, 

807 ) 

808 inner_schema = apply_validators(fields_schema, decorators.root_validators.values(), None) 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

809 inner_schema = apply_model_validators(inner_schema, model_validators, 'inner') 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

810 

811 model_schema = core_schema.model_schema( 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

812 cls, 

813 inner_schema, 

814 generic_origin=generic_origin, 

815 custom_init=getattr(cls, '__pydantic_custom_init__', None), 

816 root_model=False, 

817 post_init=getattr(cls, '__pydantic_post_init__', None), 

818 config=core_config, 

819 ref=model_ref, 

820 ) 

821 

822 schema = self._apply_model_serializers(model_schema, decorators.model_serializers.values()) 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

823 schema = apply_model_validators(schema, model_validators, 'outer') 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

824 return self.defs.create_definition_reference_schema(schema) 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

825 

826 def _resolve_self_type(self, obj: Any) -> Any: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

827 obj = self.model_type_stack.get() 1acekoquwxCfbhilmrsyzDEdjgnptvABF

828 if obj is None: 1acekoquwxCfbhilmrsyzDEdjgnptvABF

829 raise PydanticUserError('`typing.Self` is invalid in this context', code='invalid-self-type') 1acekoquwxCfbhilmrsyzDEdjgnptvABF

830 return obj 1acekoquwxCfbhilmrsyzDEdjgnptvABF

831 

832 def _generate_schema_from_get_schema_method(self, obj: Any, source: Any) -> core_schema.CoreSchema | None: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

833 BaseModel_ = import_cached_base_model() 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

834 

835 get_schema = getattr(obj, '__get_pydantic_core_schema__', None) 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

836 is_base_model_get_schema = ( 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

837 getattr(get_schema, '__func__', None) is BaseModel_.__get_pydantic_core_schema__.__func__ # pyright: ignore[reportFunctionMemberAccess] 

838 ) 

839 

840 if ( 1acfbhiLdj

841 get_schema is not None 

842 # BaseModel.__get_pydantic_core_schema__ is defined for backwards compatibility, 

843 # to allow existing code to call `super().__get_pydantic_core_schema__` in Pydantic 

844 # model that overrides `__get_pydantic_core_schema__`. However, it raises a deprecation 

845 # warning stating that the method will be removed, and during the core schema gen we actually 

846 # don't call the method: 

847 and not is_base_model_get_schema 

848 ): 

849 # Some referenceable types might have a `__get_pydantic_core_schema__` method 

850 # defined on it by users (e.g. on a dataclass). This generally doesn't play well 

851 # as these types are already recognized by the `GenerateSchema` class and isn't ideal 

852 # as we might end up calling `get_schema_or_ref` (expensive) on types that are actually 

853 # not referenceable: 

854 with self.defs.get_schema_or_ref(obj) as (_, maybe_schema): 1acekoquwxCfbhilmrsyzDEdjgnptvABF

855 if maybe_schema is not None: 1acekoquwxCfbhilmrsyzDEdjgnptvABF

856 return maybe_schema 1acekoquwxCfbhilmrsyzDEdjgnptvABF

857 

858 if obj is source: 1acekoquwxCfbhilmrsyzDEdjgnptvABF

859 ref_mode = 'unpack' 1acekoquwxCfbhilmrsyzDEdjgnptvABF

860 else: 

861 ref_mode = 'to-def' 1acekoquwxCfbhilmrsyzDEdjgnptvABF

862 schema = get_schema( 1acekoquwxCfbhilmrsyzDEdjgnptvABF

863 source, CallbackGetCoreSchemaHandler(self._generate_schema_inner, self, ref_mode=ref_mode) 

864 ) 

865 if schema['type'] == 'definitions': 865 ↛ 866line 865 didn't jump to line 866 because the condition on line 865 was never true1acekoquwxCfbhilmrsyzDEdjgnptvABF

866 schema = self.defs.unpack_definitions(schema) 

867 

868 ref = get_ref(schema) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

869 if ref: 1acekoquwxCfbhilmrsyzDEdjgnptvABF

870 return self.defs.create_definition_reference_schema(schema) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

871 

872 # Note: if schema is of type `'definition-ref'`, we might want to copy it as a 

873 # safety measure (because these are inlined in place -- i.e. mutated directly) 

874 return schema 1acekoquwxCfbhilmrsyzDEdjgnptvABF

875 

876 if (validators := getattr(obj, '__get_validators__', None)) is not None: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

877 from pydantic.v1 import BaseModel as BaseModelV1 1acekoquwxCfbhilmrsyzDEdjgnptvABF

878 

879 if issubclass(obj, BaseModelV1): 1acekoquwxCfbhilmrsyzDEdjgnptvABF

880 warn( 1acekoquwxCfbhilmrsyzDEdjgnptvABF

881 f'Mixing V1 models and V2 models (or constructs, like `TypeAdapter`) is not supported. Please upgrade `{obj.__name__}` to V2.', 

882 UserWarning, 

883 ) 

884 else: 

885 warn( 1acekoquwxCfbhilmrsyzDEdjgnptvABF

886 '`__get_validators__` is deprecated and will be removed, use `__get_pydantic_core_schema__` instead.', 

887 PydanticDeprecatedSince20, 

888 ) 

889 return core_schema.chain_schema([core_schema.with_info_plain_validator_function(v) for v in validators()]) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

890 

891 def _resolve_forward_ref(self, obj: Any) -> Any: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

892 # we assume that types_namespace has the target of forward references in its scope, 

893 # but this could fail, for example, if calling Validator on an imported type which contains 

894 # forward references to other types only defined in the module from which it was imported 

895 # `Validator(SomeImportedTypeAliasWithAForwardReference)` 

896 # or the equivalent for BaseModel 

897 # class Model(BaseModel): 

898 # x: SomeImportedTypeAliasWithAForwardReference 

899 try: 1acekoquwxCfbhilmrsyzDEdjgnptvABF

900 obj = _typing_extra.eval_type_backport(obj, *self._types_namespace) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

901 except NameError as e: 1acekoquwxCfbhilmrsyzDEdjgnptvABF

902 raise PydanticUndefinedAnnotation.from_name_error(e) from e 1acekoquwxCfbhilmrsyzDEdjgnptvABF

903 

904 # if obj is still a ForwardRef, it means we can't evaluate it, raise PydanticUndefinedAnnotation 

905 if isinstance(obj, ForwardRef): 1acekoquwxCfbhilmrsyzDEdjgnptvABF

906 raise PydanticUndefinedAnnotation(obj.__forward_arg__, f'Unable to evaluate forward reference {obj}') 1acekoquwxCfbhilmrsyzDEdjgnptvABF

907 

908 if self._typevars_map: 1acekoquwxCfbhilmrsyzDEdjgnptvABF

909 obj = replace_types(obj, self._typevars_map) 1acekfbhilmdjgn

910 

911 return obj 1acekoquwxCfbhilmrsyzDEdjgnptvABF

912 

913 @overload 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

914 def _get_args_resolving_forward_refs(self, obj: Any, required: Literal[True]) -> tuple[Any, ...]: ... 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

915 

916 @overload 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

917 def _get_args_resolving_forward_refs(self, obj: Any) -> tuple[Any, ...] | None: ... 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

918 

919 def _get_args_resolving_forward_refs(self, obj: Any, required: bool = False) -> tuple[Any, ...] | None: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

920 args = get_args(obj) 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

921 if args: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

922 if isinstance(obj, GenericAlias): 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

923 # PEP 585 generic aliases don't convert args to ForwardRefs, unlike `typing.List/Dict` etc. 

924 args = (_typing_extra._make_forward_ref(a) if isinstance(a, str) else a for a in args) 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

925 args = tuple(self._resolve_forward_ref(a) if isinstance(a, ForwardRef) else a for a in args) 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

926 elif required: # pragma: no cover 1acekoquwxCfbhilmrsyzDEdjgnptvABF

927 raise TypeError(f'Expected {obj} to have generic parameters but it had none') 

928 return args 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

929 

930 def _get_first_arg_or_any(self, obj: Any) -> Any: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

931 args = self._get_args_resolving_forward_refs(obj) 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

932 if not args: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

933 return Any 1acekoquwxCfbhilmrsyzDEdjgnptvABF

934 return args[0] 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

935 

936 def _get_first_two_args_or_any(self, obj: Any) -> tuple[Any, Any]: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

937 args = self._get_args_resolving_forward_refs(obj) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

938 if not args: 938 ↛ 939line 938 didn't jump to line 939 because the condition on line 938 was never true1acekoquwxCfbhilmrsyzDEdjgnptvABF

939 return (Any, Any) 

940 if len(args) < 2: 940 ↛ 941line 940 didn't jump to line 941 because the condition on line 940 was never true1acekoquwxCfbhilmrsyzDEdjgnptvABF

941 origin = get_origin(obj) 

942 raise TypeError(f'Expected two type arguments for {origin}, got 1') 

943 return args[0], args[1] 1acekoquwxCfbhilmrsyzDEdjgnptvABF

944 

945 def _generate_schema_inner(self, obj: Any) -> core_schema.CoreSchema: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

946 if _typing_extra.is_self(obj): 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

947 obj = self._resolve_self_type(obj) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

948 

949 if _typing_extra.is_annotated(obj): 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

950 return self._annotated_schema(obj) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

951 

952 if isinstance(obj, dict): 952 ↛ 954line 952 didn't jump to line 954 because the condition on line 952 was never true1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

953 # we assume this is already a valid schema 

954 return obj # type: ignore[return-value] 

955 

956 if isinstance(obj, str): 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

957 obj = ForwardRef(obj) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

958 

959 if isinstance(obj, ForwardRef): 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

960 return self.generate_schema(self._resolve_forward_ref(obj)) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

961 

962 BaseModel = import_cached_base_model() 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

963 

964 if lenient_issubclass(obj, BaseModel): 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

965 with self.model_type_stack.push(obj): 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

966 return self._model_schema(obj) 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

967 

968 if isinstance(obj, PydanticRecursiveRef): 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

969 return core_schema.definition_reference_schema(schema_ref=obj.type_ref) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

970 

971 return self.match_type(obj) 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

972 

973 def match_type(self, obj: Any) -> core_schema.CoreSchema: # noqa: C901 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

974 """Main mapping of types to schemas. 

975 

976 The general structure is a series of if statements starting with the simple cases 

977 (non-generic primitive types) and then handling generics and other more complex cases. 

978 

979 Each case either generates a schema directly, calls into a public user-overridable method 

980 (like `GenerateSchema.tuple_variable_schema`) or calls into a private method that handles some 

981 boilerplate before calling into the user-facing method (e.g. `GenerateSchema._tuple_schema`). 

982 

983 The idea is that we'll evolve this into adding more and more user facing methods over time 

984 as they get requested and we figure out what the right API for them is. 

985 """ 

986 if obj is str: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

987 return core_schema.str_schema() 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

988 elif obj is bytes: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

989 return core_schema.bytes_schema() 1acekoquwxCfbhilmrsyzDEdjgnptvABF

990 elif obj is int: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

991 return core_schema.int_schema() 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

992 elif obj is float: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

993 return core_schema.float_schema() 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

994 elif obj is bool: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

995 return core_schema.bool_schema() 1acekoquwxCfbhilmrsyzDEdjgnptvABF

996 elif obj is complex: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

997 return core_schema.complex_schema() 1acekoquwxCfbhilmrsyzDEdjgnptvABF

998 elif _typing_extra.is_any(obj) or obj is object: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

999 return core_schema.any_schema() 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1000 elif obj is datetime.date: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1001 return core_schema.date_schema() 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1002 elif obj is datetime.datetime: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1003 return core_schema.datetime_schema() 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1004 elif obj is datetime.time: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1005 return core_schema.time_schema() 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1006 elif obj is datetime.timedelta: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1007 return core_schema.timedelta_schema() 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1008 elif obj is Decimal: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1009 return core_schema.decimal_schema() 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1010 elif obj is UUID: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1011 return core_schema.uuid_schema() 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1012 elif obj is Url: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1013 return core_schema.url_schema() 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1014 elif obj is Fraction: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1015 return self._fraction_schema() 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1016 elif obj is MultiHostUrl: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1017 return core_schema.multi_host_url_schema() 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1018 elif obj is None or obj is _typing_extra.NoneType: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1019 return core_schema.none_schema() 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1020 elif obj in IP_TYPES: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1021 return self._ip_schema(obj) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1022 elif obj in TUPLE_TYPES: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1023 return self._tuple_schema(obj) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1024 elif obj in LIST_TYPES: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1025 return self._list_schema(Any) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1026 elif obj in SET_TYPES: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1027 return self._set_schema(Any) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1028 elif obj in FROZEN_SET_TYPES: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1029 return self._frozenset_schema(Any) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1030 elif obj in SEQUENCE_TYPES: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1031 return self._sequence_schema(Any) 1aeouxdgpvB

1032 elif obj in ITERABLE_TYPES: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1033 return self._iterable_schema(obj) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1034 elif obj in DICT_TYPES: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1035 return self._dict_schema(Any, Any) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1036 elif obj in PATH_TYPES: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1037 return self._path_schema(obj, Any) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1038 elif obj in DEQUE_TYPES: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1039 return self._deque_schema(Any) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1040 elif obj in MAPPING_TYPES: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1041 return self._mapping_schema(obj, Any, Any) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1042 elif obj in COUNTER_TYPES: 1042 ↛ 1043line 1042 didn't jump to line 1043 because the condition on line 1042 was never true1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1043 return self._mapping_schema(obj, Any, int) 

1044 elif _typing_extra.is_type_alias_type(obj): 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1045 return self._type_alias_type_schema(obj) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1046 elif obj is type: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1047 return self._type_schema() 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1048 elif _typing_extra.is_callable(obj): 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1049 return core_schema.callable_schema() 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1050 elif _typing_extra.is_literal(obj): 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1051 return self._literal_schema(obj) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1052 elif is_typeddict(obj): 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1053 return self._typed_dict_schema(obj, None) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1054 elif _typing_extra.is_namedtuple(obj): 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1055 return self._namedtuple_schema(obj, None) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1056 elif _typing_extra.is_new_type(obj): 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1057 # NewType, can't use isinstance because it fails <3.10 

1058 return self.generate_schema(obj.__supertype__) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1059 elif obj in PATTERN_TYPES: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1060 return self._pattern_schema(obj) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1061 elif _typing_extra.is_hashable(obj): 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1062 return self._hashable_schema() 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1063 elif isinstance(obj, typing.TypeVar): 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1064 return self._unsubstituted_typevar_schema(obj) 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1065 elif _typing_extra.is_finalvar(obj): 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1066 if obj is Final: 1066 ↛ 1068line 1066 didn't jump to line 1068 because the condition on line 1066 was always true1acekoquwxCfbhilmrsyzDEdjgnptvABF

1067 return core_schema.any_schema() 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1068 return self.generate_schema( 

1069 self._get_first_arg_or_any(obj), 

1070 ) 

1071 elif isinstance(obj, VALIDATE_CALL_SUPPORTED_TYPES): 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1072 return self._call_schema(obj) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1073 elif inspect.isclass(obj) and issubclass(obj, Enum): 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1074 return self._enum_schema(obj) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1075 elif _typing_extra.is_zoneinfo_type(obj): 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1076 return self._zoneinfo_schema() 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1077 

1078 # dataclasses.is_dataclass coerces dc instances to types, but we only handle 

1079 # the case of a dc type here 

1080 if dataclasses.is_dataclass(obj): 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1081 return self._dataclass_schema(obj, None) # pyright: ignore[reportArgumentType] 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1082 

1083 origin = get_origin(obj) 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1084 if origin is not None: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1085 return self._match_generic_type(obj, origin) 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1086 

1087 if self._arbitrary_types: 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1088 return self._arbitrary_type_schema(obj) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1089 return self._unknown_type_schema(obj) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1090 

1091 def _match_generic_type(self, obj: Any, origin: Any) -> CoreSchema: # noqa: C901 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1092 # Need to handle generic dataclasses before looking for the schema properties because attribute accesses 

1093 # on _GenericAlias delegate to the origin type, so lose the information about the concrete parametrization 

1094 # As a result, currently, there is no way to cache the schema for generic dataclasses. This may be possible 

1095 # to resolve by modifying the value returned by `Generic.__class_getitem__`, but that is a dangerous game. 

1096 if dataclasses.is_dataclass(origin): 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1097 return self._dataclass_schema(obj, origin) # pyright: ignore[reportArgumentType] 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1098 if _typing_extra.is_namedtuple(origin): 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1099 return self._namedtuple_schema(obj, origin) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1100 

1101 schema = self._generate_schema_from_get_schema_method(origin, obj) 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1102 if schema is not None: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1103 return schema 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1104 

1105 if _typing_extra.is_type_alias_type(origin): 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1106 return self._type_alias_type_schema(obj) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1107 elif _typing_extra.origin_is_union(origin): 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1108 return self._union_schema(obj) 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1109 elif origin in TUPLE_TYPES: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1110 return self._tuple_schema(obj) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1111 elif origin in LIST_TYPES: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1112 return self._list_schema(self._get_first_arg_or_any(obj)) 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1113 elif origin in SET_TYPES: 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1114 return self._set_schema(self._get_first_arg_or_any(obj)) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1115 elif origin in FROZEN_SET_TYPES: 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1116 return self._frozenset_schema(self._get_first_arg_or_any(obj)) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1117 elif origin in DICT_TYPES: 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1118 return self._dict_schema(*self._get_first_two_args_or_any(obj)) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1119 elif origin in PATH_TYPES: 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1120 return self._path_schema(origin, self._get_first_arg_or_any(obj)) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1121 elif origin in DEQUE_TYPES: 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1122 return self._deque_schema(self._get_first_arg_or_any(obj)) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1123 elif origin in MAPPING_TYPES: 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1124 return self._mapping_schema(origin, *self._get_first_two_args_or_any(obj)) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1125 elif origin in COUNTER_TYPES: 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1126 return self._mapping_schema(origin, self._get_first_arg_or_any(obj), int) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1127 elif is_typeddict(origin): 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1128 return self._typed_dict_schema(obj, origin) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1129 elif origin in TYPE_TYPES: 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1130 return self._subclass_schema(obj) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1131 elif origin in SEQUENCE_TYPES: 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1132 return self._sequence_schema(self._get_first_arg_or_any(obj)) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1133 elif origin in ITERABLE_TYPES: 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1134 return self._iterable_schema(obj) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1135 elif origin in PATTERN_TYPES: 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1136 return self._pattern_schema(obj) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1137 

1138 if self._arbitrary_types: 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1139 return self._arbitrary_type_schema(origin) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1140 return self._unknown_type_schema(obj) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1141 

1142 def _generate_td_field_schema( 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1143 self, 

1144 name: str, 

1145 field_info: FieldInfo, 

1146 decorators: DecoratorInfos, 

1147 *, 

1148 required: bool = True, 

1149 ) -> core_schema.TypedDictField: 

1150 """Prepare a TypedDictField to represent a model or typeddict field.""" 

1151 common_field = self._common_field_schema(name, field_info, decorators) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1152 return core_schema.typed_dict_field( 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1153 common_field['schema'], 

1154 required=False if not field_info.is_required() else required, 

1155 serialization_exclude=common_field['serialization_exclude'], 

1156 validation_alias=common_field['validation_alias'], 

1157 serialization_alias=common_field['serialization_alias'], 

1158 metadata=common_field['metadata'], 

1159 ) 

1160 

1161 def _generate_md_field_schema( 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1162 self, 

1163 name: str, 

1164 field_info: FieldInfo, 

1165 decorators: DecoratorInfos, 

1166 ) -> core_schema.ModelField: 

1167 """Prepare a ModelField to represent a model field.""" 

1168 common_field = self._common_field_schema(name, field_info, decorators) 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1169 return core_schema.model_field( 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1170 common_field['schema'], 

1171 serialization_exclude=common_field['serialization_exclude'], 

1172 validation_alias=common_field['validation_alias'], 

1173 serialization_alias=common_field['serialization_alias'], 

1174 frozen=common_field['frozen'], 

1175 metadata=common_field['metadata'], 

1176 ) 

1177 

1178 def _generate_dc_field_schema( 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1179 self, 

1180 name: str, 

1181 field_info: FieldInfo, 

1182 decorators: DecoratorInfos, 

1183 ) -> core_schema.DataclassField: 

1184 """Prepare a DataclassField to represent the parameter/field, of a dataclass.""" 

1185 common_field = self._common_field_schema(name, field_info, decorators) 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1186 return core_schema.dataclass_field( 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1187 name, 

1188 common_field['schema'], 

1189 init=field_info.init, 

1190 init_only=field_info.init_var or None, 

1191 kw_only=None if field_info.kw_only else False, 

1192 serialization_exclude=common_field['serialization_exclude'], 

1193 validation_alias=common_field['validation_alias'], 

1194 serialization_alias=common_field['serialization_alias'], 

1195 frozen=common_field['frozen'], 

1196 metadata=common_field['metadata'], 

1197 ) 

1198 

1199 @staticmethod 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1200 def _apply_alias_generator_to_field_info( 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1201 alias_generator: Callable[[str], str] | AliasGenerator, field_info: FieldInfo, field_name: str 

1202 ) -> None: 

1203 """Apply an alias_generator to aliases on a FieldInfo instance if appropriate. 

1204 

1205 Args: 

1206 alias_generator: A callable that takes a string and returns a string, or an AliasGenerator instance. 

1207 field_info: The FieldInfo instance to which the alias_generator is (maybe) applied. 

1208 field_name: The name of the field from which to generate the alias. 

1209 """ 

1210 # Apply an alias_generator if 

1211 # 1. An alias is not specified 

1212 # 2. An alias is specified, but the priority is <= 1 

1213 if ( 1acfbhidj

1214 field_info.alias_priority is None 

1215 or field_info.alias_priority <= 1 

1216 or field_info.alias is None 

1217 or field_info.validation_alias is None 

1218 or field_info.serialization_alias is None 

1219 ): 

1220 alias, validation_alias, serialization_alias = None, None, None 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1221 

1222 if isinstance(alias_generator, AliasGenerator): 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1223 alias, validation_alias, serialization_alias = alias_generator.generate_aliases(field_name) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1224 elif isinstance(alias_generator, Callable): 1224 ↛ 1232line 1224 didn't jump to line 1232 because the condition on line 1224 was always true1acekoquwxCfbhilmrsyzDEdjgnptvABF

1225 alias = alias_generator(field_name) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1226 if not isinstance(alias, str): 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1227 raise TypeError(f'alias_generator {alias_generator} must return str, not {alias.__class__}') 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1228 

1229 # if priority is not set, we set to 1 

1230 # which supports the case where the alias_generator from a child class is used 

1231 # to generate an alias for a field in a parent class 

1232 if field_info.alias_priority is None or field_info.alias_priority <= 1: 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1233 field_info.alias_priority = 1 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1234 

1235 # if the priority is 1, then we set the aliases to the generated alias 

1236 if field_info.alias_priority == 1: 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1237 field_info.serialization_alias = _get_first_non_null(serialization_alias, alias) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1238 field_info.validation_alias = _get_first_non_null(validation_alias, alias) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1239 field_info.alias = alias 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1240 

1241 # if any of the aliases are not set, then we set them to the corresponding generated alias 

1242 if field_info.alias is None: 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1243 field_info.alias = alias 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1244 if field_info.serialization_alias is None: 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1245 field_info.serialization_alias = _get_first_non_null(serialization_alias, alias) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1246 if field_info.validation_alias is None: 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1247 field_info.validation_alias = _get_first_non_null(validation_alias, alias) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1248 

1249 @staticmethod 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1250 def _apply_alias_generator_to_computed_field_info( 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1251 alias_generator: Callable[[str], str] | AliasGenerator, 

1252 computed_field_info: ComputedFieldInfo, 

1253 computed_field_name: str, 

1254 ): 

1255 """Apply an alias_generator to alias on a ComputedFieldInfo instance if appropriate. 

1256 

1257 Args: 

1258 alias_generator: A callable that takes a string and returns a string, or an AliasGenerator instance. 

1259 computed_field_info: The ComputedFieldInfo instance to which the alias_generator is (maybe) applied. 

1260 computed_field_name: The name of the computed field from which to generate the alias. 

1261 """ 

1262 # Apply an alias_generator if 

1263 # 1. An alias is not specified 

1264 # 2. An alias is specified, but the priority is <= 1 

1265 

1266 if ( 1acfb

1267 computed_field_info.alias_priority is None 

1268 or computed_field_info.alias_priority <= 1 

1269 or computed_field_info.alias is None 

1270 ): 

1271 alias, validation_alias, serialization_alias = None, None, None 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1272 

1273 if isinstance(alias_generator, AliasGenerator): 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1274 alias, validation_alias, serialization_alias = alias_generator.generate_aliases(computed_field_name) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1275 elif isinstance(alias_generator, Callable): 1275 ↛ 1283line 1275 didn't jump to line 1283 because the condition on line 1275 was always true1acekoquwxCfbhilmrsyzDEdjgnptvABF

1276 alias = alias_generator(computed_field_name) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1277 if not isinstance(alias, str): 1277 ↛ 1278line 1277 didn't jump to line 1278 because the condition on line 1277 was never true1acekoquwxCfbhilmrsyzDEdjgnptvABF

1278 raise TypeError(f'alias_generator {alias_generator} must return str, not {alias.__class__}') 

1279 

1280 # if priority is not set, we set to 1 

1281 # which supports the case where the alias_generator from a child class is used 

1282 # to generate an alias for a field in a parent class 

1283 if computed_field_info.alias_priority is None or computed_field_info.alias_priority <= 1: 1283 ↛ 1289line 1283 didn't jump to line 1289 because the condition on line 1283 was always true1acekoquwxCfbhilmrsyzDEdjgnptvABF

1284 computed_field_info.alias_priority = 1 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1285 

1286 # if the priority is 1, then we set the aliases to the generated alias 

1287 # note that we use the serialization_alias with priority over alias, as computed_field 

1288 # aliases are used for serialization only (not validation) 

1289 if computed_field_info.alias_priority == 1: 1289 ↛ exitline 1289 didn't return from function '_apply_alias_generator_to_computed_field_info' because the condition on line 1289 was always true1acekoquwxCfbhilmrsyzDEdjgnptvABF

1290 computed_field_info.alias = _get_first_non_null(serialization_alias, alias) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1291 

1292 @staticmethod 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1293 def _apply_field_title_generator_to_field_info( 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1294 config_wrapper: ConfigWrapper, field_info: FieldInfo | ComputedFieldInfo, field_name: str 

1295 ) -> None: 

1296 """Apply a field_title_generator on a FieldInfo or ComputedFieldInfo instance if appropriate 

1297 Args: 

1298 config_wrapper: The config of the model 

1299 field_info: The FieldInfo or ComputedField instance to which the title_generator is (maybe) applied. 

1300 field_name: The name of the field from which to generate the title. 

1301 """ 

1302 field_title_generator = field_info.field_title_generator or config_wrapper.field_title_generator 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1303 

1304 if field_title_generator is None: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1305 return 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1306 

1307 if field_info.title is None: 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1308 title = field_title_generator(field_name, field_info) # type: ignore 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1309 if not isinstance(title, str): 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1310 raise TypeError(f'field_title_generator {field_title_generator} must return str, not {title.__class__}') 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1311 

1312 field_info.title = title 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1313 

1314 def _common_field_schema( # C901 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1315 self, name: str, field_info: FieldInfo, decorators: DecoratorInfos 

1316 ) -> _CommonField: 

1317 source_type, annotations = field_info.annotation, field_info.metadata 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1318 

1319 def set_discriminator(schema: CoreSchema) -> CoreSchema: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1320 schema = self._apply_discriminator_to_union(schema, field_info.discriminator) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1321 return schema 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1322 

1323 # Convert `@field_validator` decorators to `Before/After/Plain/WrapValidator` instances: 

1324 validators_from_decorators = [] 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1325 for decorator in filter_field_decorator_info_by_field(decorators.field_validators.values(), name): 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1326 validators_from_decorators.append(_mode_to_validator[decorator.info.mode]._from_decorator(decorator)) 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1327 

1328 with self.field_name_stack.push(name): 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1329 if field_info.discriminator is not None: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1330 schema = self._apply_annotations( 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1331 source_type, annotations + validators_from_decorators, transform_inner_schema=set_discriminator 

1332 ) 

1333 else: 

1334 schema = self._apply_annotations( 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1335 source_type, 

1336 annotations + validators_from_decorators, 

1337 ) 

1338 

1339 # This V1 compatibility shim should eventually be removed 

1340 # push down any `each_item=True` validators 

1341 # note that this won't work for any Annotated types that get wrapped by a function validator 

1342 # but that's okay because that didn't exist in V1 

1343 this_field_validators = filter_field_decorator_info_by_field(decorators.validators.values(), name) 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1344 if _validators_require_validate_default(this_field_validators): 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1345 field_info.validate_default = True 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1346 each_item_validators = [v for v in this_field_validators if v.info.each_item is True] 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1347 this_field_validators = [v for v in this_field_validators if v not in each_item_validators] 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1348 schema = apply_each_item_validators(schema, each_item_validators, name) 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1349 

1350 schema = apply_validators(schema, this_field_validators, name) 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1351 

1352 # the default validator needs to go outside of any other validators 

1353 # so that it is the topmost validator for the field validator 

1354 # which uses it to check if the field has a default value or not 

1355 if not field_info.is_required(): 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1356 schema = wrap_default(field_info, schema) 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1357 

1358 schema = self._apply_field_serializers( 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1359 schema, filter_field_decorator_info_by_field(decorators.field_serializers.values(), name) 

1360 ) 

1361 self._apply_field_title_generator_to_field_info(self._config_wrapper, field_info, name) 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1362 

1363 pydantic_js_updates, pydantic_js_extra = _extract_json_schema_info_from_field_info(field_info) 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1364 core_metadata: dict[str, Any] = {} 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1365 update_core_metadata( 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1366 core_metadata, pydantic_js_updates=pydantic_js_updates, pydantic_js_extra=pydantic_js_extra 

1367 ) 

1368 

1369 alias_generator = self._config_wrapper.alias_generator 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1370 if alias_generator is not None: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1371 self._apply_alias_generator_to_field_info(alias_generator, field_info, name) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1372 

1373 if isinstance(field_info.validation_alias, (AliasChoices, AliasPath)): 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1374 validation_alias = field_info.validation_alias.convert_to_aliases() 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1375 else: 

1376 validation_alias = field_info.validation_alias 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1377 

1378 return _common_field( 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1379 schema, 

1380 serialization_exclude=True if field_info.exclude else None, 

1381 validation_alias=validation_alias, 

1382 serialization_alias=field_info.serialization_alias, 

1383 frozen=field_info.frozen, 

1384 metadata=core_metadata, 

1385 ) 

1386 

1387 def _union_schema(self, union_type: Any) -> core_schema.CoreSchema: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1388 """Generate schema for a Union.""" 

1389 args = self._get_args_resolving_forward_refs(union_type, required=True) 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1390 choices: list[CoreSchema] = [] 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1391 nullable = False 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1392 for arg in args: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1393 if arg is None or arg is _typing_extra.NoneType: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1394 nullable = True 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1395 else: 

1396 choices.append(self.generate_schema(arg)) 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1397 

1398 if len(choices) == 1: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1399 s = choices[0] 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1400 else: 

1401 choices_with_tags: list[CoreSchema | tuple[CoreSchema, str]] = [] 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1402 for choice in choices: 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1403 tag = cast(CoreMetadata, choice.get('metadata', {})).get('pydantic_internal_union_tag_key') 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1404 if tag is not None: 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1405 choices_with_tags.append((choice, tag)) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1406 else: 

1407 choices_with_tags.append(choice) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1408 s = core_schema.union_schema(choices_with_tags) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1409 

1410 if nullable: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1411 s = core_schema.nullable_schema(s) 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1412 return s 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1413 

1414 def _type_alias_type_schema(self, obj: TypeAliasType) -> CoreSchema: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1415 with self.defs.get_schema_or_ref(obj) as (ref, maybe_schema): 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1416 if maybe_schema is not None: 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1417 return maybe_schema 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1418 

1419 origin: TypeAliasType = get_origin(obj) or obj 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1420 typevars_map = get_standard_typevars_map(obj) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1421 

1422 with self._ns_resolver.push(origin): 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1423 try: 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1424 annotation = _typing_extra.eval_type(origin.__value__, *self._types_namespace) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1425 except NameError as e: 

1426 raise PydanticUndefinedAnnotation.from_name_error(e) from e 

1427 annotation = replace_types(annotation, typevars_map) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1428 schema = self.generate_schema(annotation) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1429 assert schema['type'] != 'definitions' 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1430 schema['ref'] = ref # type: ignore 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1431 return self.defs.create_definition_reference_schema(schema) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1432 

1433 def _literal_schema(self, literal_type: Any) -> CoreSchema: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1434 """Generate schema for a Literal.""" 

1435 expected = _typing_extra.literal_values(literal_type) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1436 assert expected, f'literal "expected" cannot be empty, obj={literal_type}' 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1437 schema = core_schema.literal_schema(expected) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1438 

1439 if self._config_wrapper.use_enum_values and any(isinstance(v, Enum) for v in expected): 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1440 schema = core_schema.no_info_after_validator_function( 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1441 lambda v: v.value if isinstance(v, Enum) else v, schema 

1442 ) 

1443 

1444 return schema 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1445 

1446 def _typed_dict_schema(self, typed_dict_cls: Any, origin: Any) -> core_schema.CoreSchema: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1447 """Generate schema for a TypedDict. 

1448 

1449 It is not possible to track required/optional keys in TypedDict without __required_keys__ 

1450 since TypedDict.__new__ erases the base classes (it replaces them with just `dict`) 

1451 and thus we can track usage of total=True/False 

1452 __required_keys__ was added in Python 3.9 

1453 (https://github.com/miss-islington/cpython/blob/1e9939657dd1f8eb9f596f77c1084d2d351172fc/Doc/library/typing.rst?plain=1#L1546-L1548) 

1454 however it is buggy 

1455 (https://github.com/python/typing_extensions/blob/ac52ac5f2cb0e00e7988bae1e2a1b8257ac88d6d/src/typing_extensions.py#L657-L666). 

1456 

1457 On 3.11 but < 3.12 TypedDict does not preserve inheritance information. 

1458 

1459 Hence to avoid creating validators that do not do what users expect we only 

1460 support typing.TypedDict on Python >= 3.12 or typing_extension.TypedDict on all versions 

1461 """ 

1462 FieldInfo = import_cached_field_info() 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1463 

1464 with ( 1acekoqfbhilmrsdjgnpt

1465 self.model_type_stack.push(typed_dict_cls), 

1466 self.defs.get_schema_or_ref(typed_dict_cls) as ( 

1467 typed_dict_ref, 

1468 maybe_schema, 

1469 ), 

1470 ): 

1471 if maybe_schema is not None: 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1472 return maybe_schema 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1473 

1474 typevars_map = get_standard_typevars_map(typed_dict_cls) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1475 if origin is not None: 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1476 typed_dict_cls = origin 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1477 

1478 if not _SUPPORTS_TYPEDDICT and type(typed_dict_cls).__module__ == 'typing': 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1479 raise PydanticUserError( 1acekoqfbhilmrsdjgnpt

1480 'Please use `typing_extensions.TypedDict` instead of `typing.TypedDict` on Python < 3.12.', 

1481 code='typed-dict-version', 

1482 ) 

1483 

1484 try: 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1485 # if a typed dictionary class doesn't have config, we use the parent's config, hence a default of `None` 

1486 # see https://github.com/pydantic/pydantic/issues/10917 

1487 config: ConfigDict | None = get_attribute_from_bases(typed_dict_cls, '__pydantic_config__') 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1488 except AttributeError: 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1489 config = None 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1490 

1491 with self._config_wrapper_stack.push(config): 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1492 core_config = self._config_wrapper.core_config(title=typed_dict_cls.__name__) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1493 

1494 required_keys: frozenset[str] = typed_dict_cls.__required_keys__ 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1495 

1496 fields: dict[str, core_schema.TypedDictField] = {} 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1497 

1498 decorators = DecoratorInfos.build(typed_dict_cls) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1499 

1500 if self._config_wrapper.use_attribute_docstrings: 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1501 field_docstrings = extract_docstrings_from_cls(typed_dict_cls, use_inspect=True) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1502 else: 

1503 field_docstrings = None 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1504 

1505 try: 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1506 annotations = _typing_extra.get_cls_type_hints(typed_dict_cls, ns_resolver=self._ns_resolver) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1507 except NameError as e: 

1508 raise PydanticUndefinedAnnotation.from_name_error(e) from e 

1509 

1510 for field_name, annotation in annotations.items(): 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1511 annotation = replace_types(annotation, typevars_map) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1512 required = field_name in required_keys 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1513 

1514 if _typing_extra.is_required(annotation): 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1515 required = True 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1516 annotation = self._get_args_resolving_forward_refs( 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1517 annotation, 

1518 required=True, 

1519 )[0] 

1520 elif _typing_extra.is_not_required(annotation): 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1521 required = False 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1522 annotation = self._get_args_resolving_forward_refs( 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1523 annotation, 

1524 required=True, 

1525 )[0] 

1526 

1527 field_info = FieldInfo.from_annotation(annotation) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1528 if ( 1acfbhidj

1529 field_docstrings is not None 

1530 and field_info.description is None 

1531 and field_name in field_docstrings 

1532 ): 

1533 field_info.description = field_docstrings[field_name] 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1534 self._apply_field_title_generator_to_field_info(self._config_wrapper, field_info, field_name) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1535 fields[field_name] = self._generate_td_field_schema( 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1536 field_name, field_info, decorators, required=required 

1537 ) 

1538 

1539 td_schema = core_schema.typed_dict_schema( 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1540 fields, 

1541 cls=typed_dict_cls, 

1542 computed_fields=[ 

1543 self._computed_field_schema(d, decorators.field_serializers) 

1544 for d in decorators.computed_fields.values() 

1545 ], 

1546 ref=typed_dict_ref, 

1547 config=core_config, 

1548 ) 

1549 

1550 schema = self._apply_model_serializers(td_schema, decorators.model_serializers.values()) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1551 schema = apply_model_validators(schema, decorators.model_validators.values(), 'all') 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1552 return self.defs.create_definition_reference_schema(schema) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1553 

1554 def _namedtuple_schema(self, namedtuple_cls: Any, origin: Any) -> core_schema.CoreSchema: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1555 """Generate schema for a NamedTuple.""" 

1556 with ( 1acekoqfbhilmrsdjgnpt

1557 self.model_type_stack.push(namedtuple_cls), 

1558 self.defs.get_schema_or_ref(namedtuple_cls) as ( 

1559 namedtuple_ref, 

1560 maybe_schema, 

1561 ), 

1562 ): 

1563 if maybe_schema is not None: 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1564 return maybe_schema 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1565 typevars_map = get_standard_typevars_map(namedtuple_cls) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1566 if origin is not None: 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1567 namedtuple_cls = origin 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1568 

1569 try: 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1570 annotations = _typing_extra.get_cls_type_hints(namedtuple_cls, ns_resolver=self._ns_resolver) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1571 except NameError as e: 

1572 raise PydanticUndefinedAnnotation.from_name_error(e) from e 

1573 if not annotations: 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1574 # annotations is empty, happens if namedtuple_cls defined via collections.namedtuple(...) 

1575 annotations: dict[str, Any] = {k: Any for k in namedtuple_cls._fields} 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1576 

1577 if typevars_map: 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1578 annotations = { 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1579 field_name: replace_types(annotation, typevars_map) 

1580 for field_name, annotation in annotations.items() 

1581 } 

1582 

1583 arguments_schema = core_schema.arguments_schema( 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1584 [ 

1585 self._generate_parameter_schema( 

1586 field_name, 

1587 annotation, 

1588 default=namedtuple_cls._field_defaults.get(field_name, Parameter.empty), 

1589 ) 

1590 for field_name, annotation in annotations.items() 

1591 ], 

1592 metadata={'pydantic_js_prefer_positional_arguments': True}, 

1593 ) 

1594 schema = core_schema.call_schema(arguments_schema, namedtuple_cls, ref=namedtuple_ref) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1595 return self.defs.create_definition_reference_schema(schema) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1596 

1597 def _generate_parameter_schema( 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1598 self, 

1599 name: str, 

1600 annotation: type[Any], 

1601 default: Any = Parameter.empty, 

1602 mode: Literal['positional_only', 'positional_or_keyword', 'keyword_only'] | None = None, 

1603 ) -> core_schema.ArgumentsParameter: 

1604 """Prepare a ArgumentsParameter to represent a field in a namedtuple or function signature.""" 

1605 FieldInfo = import_cached_field_info() 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1606 

1607 if default is Parameter.empty: 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1608 field = FieldInfo.from_annotation(annotation) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1609 else: 

1610 field = FieldInfo.from_annotated_attribute(annotation, default) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1611 assert field.annotation is not None, 'field.annotation should not be None when generating a schema' 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1612 with self.field_name_stack.push(name): 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1613 schema = self._apply_annotations(field.annotation, [field]) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1614 

1615 if not field.is_required(): 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1616 schema = wrap_default(field, schema) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1617 

1618 parameter_schema = core_schema.arguments_parameter(name, schema) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1619 if mode is not None: 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1620 parameter_schema['mode'] = mode 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1621 if field.alias is not None: 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1622 parameter_schema['alias'] = field.alias 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1623 else: 

1624 alias_generator = self._config_wrapper.alias_generator 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1625 if isinstance(alias_generator, AliasGenerator) and alias_generator.alias is not None: 1625 ↛ 1626line 1625 didn't jump to line 1626 because the condition on line 1625 was never true1acekoquwxCfbhilmrsyzDEdjgnptvABF

1626 parameter_schema['alias'] = alias_generator.alias(name) 

1627 elif isinstance(alias_generator, Callable): 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1628 parameter_schema['alias'] = alias_generator(name) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1629 return parameter_schema 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1630 

1631 def _tuple_schema(self, tuple_type: Any) -> core_schema.CoreSchema: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1632 """Generate schema for a Tuple, e.g. `tuple[int, str]` or `tuple[int, ...]`.""" 

1633 # TODO: do we really need to resolve type vars here? 

1634 typevars_map = get_standard_typevars_map(tuple_type) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1635 params = self._get_args_resolving_forward_refs(tuple_type) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1636 

1637 if typevars_map and params: 1637 ↛ 1638line 1637 didn't jump to line 1638 because the condition on line 1637 was never true1acekoquwxCfbhilmrsyzDEdjgnptvABF

1638 params = tuple(replace_types(param, typevars_map) for param in params) 

1639 

1640 # NOTE: subtle difference: `tuple[()]` gives `params=()`, whereas `typing.Tuple[()]` gives `params=((),)` 

1641 # This is only true for <3.11, on Python 3.11+ `typing.Tuple[()]` gives `params=()` 

1642 if not params: 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1643 if tuple_type in TUPLE_TYPES: 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1644 return core_schema.tuple_schema([core_schema.any_schema()], variadic_item_index=0) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1645 else: 

1646 # special case for `tuple[()]` which means `tuple[]` - an empty tuple 

1647 return core_schema.tuple_schema([]) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1648 elif params[-1] is Ellipsis: 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1649 if len(params) == 2: 1649 ↛ 1653line 1649 didn't jump to line 1653 because the condition on line 1649 was always true1acekoquwxCfbhilmrsyzDEdjgnptvABF

1650 return core_schema.tuple_schema([self.generate_schema(params[0])], variadic_item_index=0) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1651 else: 

1652 # TODO: something like https://github.com/pydantic/pydantic/issues/5952 

1653 raise ValueError('Variable tuples can only have one type') 

1654 elif len(params) == 1 and params[0] == (): 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1655 # special case for `tuple[()]` which means `tuple[]` - an empty tuple 

1656 # NOTE: This conditional can be removed when we drop support for Python 3.10. 

1657 return core_schema.tuple_schema([]) 1acekfbhilmdjgn

1658 else: 

1659 return core_schema.tuple_schema([self.generate_schema(param) for param in params]) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1660 

1661 def _type_schema(self) -> core_schema.CoreSchema: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1662 return core_schema.custom_error_schema( 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1663 core_schema.is_instance_schema(type), 

1664 custom_error_type='is_type', 

1665 custom_error_message='Input should be a type', 

1666 ) 

1667 

1668 def _zoneinfo_schema(self) -> core_schema.CoreSchema: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1669 """Generate schema for a zone_info.ZoneInfo object""" 

1670 from ._validators import validate_str_is_valid_iana_tz 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1671 

1672 metadata = {'pydantic_js_functions': [lambda _1, _2: {'type': 'string', 'format': 'zoneinfo'}]} 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1673 return core_schema.no_info_plain_validator_function( 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1674 validate_str_is_valid_iana_tz, 

1675 serialization=core_schema.to_string_ser_schema(), 

1676 metadata=metadata, 

1677 ) 

1678 

1679 def _union_is_subclass_schema(self, union_type: Any) -> core_schema.CoreSchema: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1680 """Generate schema for `type[Union[X, ...]]`.""" 

1681 args = self._get_args_resolving_forward_refs(union_type, required=True) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1682 return core_schema.union_schema([self.generate_schema(type[args]) for args in args]) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1683 

1684 def _subclass_schema(self, type_: Any) -> core_schema.CoreSchema: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1685 """Generate schema for a type, e.g. `type[int]`.""" 

1686 type_param = self._get_first_arg_or_any(type_) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1687 

1688 # Assume `type[Annotated[<typ>, ...]]` is equivalent to `type[<typ>]`: 

1689 type_param = _typing_extra.annotated_type(type_param) or type_param 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1690 

1691 if _typing_extra.is_any(type_param): 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1692 return self._type_schema() 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1693 elif _typing_extra.is_type_alias_type(type_param): 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1694 return self.generate_schema(type[type_param.__value__]) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1695 elif isinstance(type_param, typing.TypeVar): 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1696 if type_param.__bound__: 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1697 if _typing_extra.origin_is_union(get_origin(type_param.__bound__)): 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1698 return self._union_is_subclass_schema(type_param.__bound__) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1699 return core_schema.is_subclass_schema(type_param.__bound__) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1700 elif type_param.__constraints__: 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1701 return core_schema.union_schema([self.generate_schema(type[c]) for c in type_param.__constraints__]) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1702 else: 

1703 return self._type_schema() 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1704 elif _typing_extra.origin_is_union(get_origin(type_param)): 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1705 return self._union_is_subclass_schema(type_param) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1706 else: 

1707 if _typing_extra.is_self(type_param): 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1708 type_param = self._resolve_self_type(type_param) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1709 if _typing_extra.is_generic_alias(type_param): 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1710 raise PydanticUserError( 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1711 'Subscripting `type[]` with an already parametrized type is not supported. ' 

1712 f'Instead of using type[{type_param!r}], use type[{_repr.display_as_type(get_origin(type_param))}].', 

1713 code=None, 

1714 ) 

1715 if not inspect.isclass(type_param): 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1716 # when using type[None], this doesn't type convert to type[NoneType], and None isn't a class 

1717 # so we handle it manually here 

1718 if type_param is None: 1718 ↛ 1720line 1718 didn't jump to line 1720 because the condition on line 1718 was always true1acekoquwxCfbhilmrsyzDEdjgnptvABF

1719 return core_schema.is_subclass_schema(_typing_extra.NoneType) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1720 raise TypeError(f'Expected a class, got {type_param!r}') 

1721 return core_schema.is_subclass_schema(type_param) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1722 

1723 def _sequence_schema(self, items_type: Any) -> core_schema.CoreSchema: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1724 """Generate schema for a Sequence, e.g. `Sequence[int]`.""" 

1725 from ._serializers import serialize_sequence_via_list 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1726 

1727 item_type_schema = self.generate_schema(items_type) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1728 list_schema = core_schema.list_schema(item_type_schema) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1729 

1730 json_schema = smart_deepcopy(list_schema) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1731 python_schema = core_schema.is_instance_schema(typing.Sequence, cls_repr='Sequence') 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1732 if not _typing_extra.is_any(items_type): 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1733 from ._validators import sequence_validator 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1734 

1735 python_schema = core_schema.chain_schema( 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1736 [python_schema, core_schema.no_info_wrap_validator_function(sequence_validator, list_schema)], 

1737 ) 

1738 

1739 serialization = core_schema.wrap_serializer_function_ser_schema( 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1740 serialize_sequence_via_list, schema=item_type_schema, info_arg=True 

1741 ) 

1742 return core_schema.json_or_python_schema( 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1743 json_schema=json_schema, python_schema=python_schema, serialization=serialization 

1744 ) 

1745 

1746 def _iterable_schema(self, type_: Any) -> core_schema.GeneratorSchema: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1747 """Generate a schema for an `Iterable`.""" 

1748 item_type = self._get_first_arg_or_any(type_) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1749 

1750 return core_schema.generator_schema(self.generate_schema(item_type)) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1751 

1752 def _pattern_schema(self, pattern_type: Any) -> core_schema.CoreSchema: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1753 from . import _validators 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1754 

1755 metadata = {'pydantic_js_functions': [lambda _1, _2: {'type': 'string', 'format': 'regex'}]} 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1756 ser = core_schema.plain_serializer_function_ser_schema( 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1757 attrgetter('pattern'), when_used='json', return_schema=core_schema.str_schema() 

1758 ) 

1759 if pattern_type is typing.Pattern or pattern_type is re.Pattern: 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1760 # bare type 

1761 return core_schema.no_info_plain_validator_function( 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1762 _validators.pattern_either_validator, serialization=ser, metadata=metadata 

1763 ) 

1764 

1765 param = self._get_args_resolving_forward_refs( 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1766 pattern_type, 

1767 required=True, 

1768 )[0] 

1769 if param is str: 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1770 return core_schema.no_info_plain_validator_function( 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1771 _validators.pattern_str_validator, serialization=ser, metadata=metadata 

1772 ) 

1773 elif param is bytes: 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1774 return core_schema.no_info_plain_validator_function( 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1775 _validators.pattern_bytes_validator, serialization=ser, metadata=metadata 

1776 ) 

1777 else: 

1778 raise PydanticSchemaGenerationError(f'Unable to generate pydantic-core schema for {pattern_type!r}.') 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1779 

1780 def _hashable_schema(self) -> core_schema.CoreSchema: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1781 return core_schema.custom_error_schema( 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1782 schema=core_schema.json_or_python_schema( 

1783 json_schema=core_schema.chain_schema( 

1784 [core_schema.any_schema(), core_schema.is_instance_schema(collections.abc.Hashable)] 

1785 ), 

1786 python_schema=core_schema.is_instance_schema(collections.abc.Hashable), 

1787 ), 

1788 custom_error_type='is_hashable', 

1789 custom_error_message='Input should be hashable', 

1790 ) 

1791 

1792 def _dataclass_schema( 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1793 self, dataclass: type[StandardDataclass], origin: type[StandardDataclass] | None 

1794 ) -> core_schema.CoreSchema: 

1795 """Generate schema for a dataclass.""" 

1796 with ( 1acekoqfbhilmrsLGHIJKdjgnpt

1797 self.model_type_stack.push(dataclass), 

1798 self.defs.get_schema_or_ref(dataclass) as ( 

1799 dataclass_ref, 

1800 maybe_schema, 

1801 ), 

1802 ): 

1803 if maybe_schema is not None: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1804 return maybe_schema 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1805 

1806 schema = dataclass.__dict__.get('__pydantic_core_schema__') 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1807 if schema is not None and not isinstance(schema, MockCoreSchema): 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1808 if schema['type'] == 'definitions': 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1809 schema = self.defs.unpack_definitions(schema) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1810 ref = get_ref(schema) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1811 if ref: 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1812 return self.defs.create_definition_reference_schema(schema) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1813 else: 

1814 return schema 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1815 

1816 typevars_map = get_standard_typevars_map(dataclass) 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1817 if origin is not None: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1818 dataclass = origin 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1819 

1820 # if (plain) dataclass doesn't have config, we use the parent's config, hence a default of `None` 

1821 # (Pydantic dataclasses have an empty dict config by default). 

1822 # see https://github.com/pydantic/pydantic/issues/10917 

1823 config = getattr(dataclass, '__pydantic_config__', None) 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1824 

1825 from ..dataclasses import is_pydantic_dataclass 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1826 

1827 with self._ns_resolver.push(dataclass), self._config_wrapper_stack.push(config): 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1828 if is_pydantic_dataclass(dataclass): 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1829 # Copy the field info instances to avoid mutating the `FieldInfo` instances 

1830 # of the generic dataclass generic origin (e.g. `apply_typevars_map` below). 

1831 # Note that we don't apply `deepcopy` on `__pydantic_fields__` because we 

1832 # don't want to copy the `FieldInfo` attributes: 

1833 fields = {f_name: copy(field_info) for f_name, field_info in dataclass.__pydantic_fields__.items()} 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1834 if typevars_map: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1835 for field in fields.values(): 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1836 field.apply_typevars_map(typevars_map, *self._types_namespace) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1837 else: 

1838 fields = collect_dataclass_fields( 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1839 dataclass, 

1840 typevars_map=typevars_map, 

1841 config_wrapper=self._config_wrapper, 

1842 ) 

1843 

1844 if self._config_wrapper.extra == 'allow': 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1845 # disallow combination of init=False on a dataclass field and extra='allow' on a dataclass 

1846 for field_name, field in fields.items(): 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1847 if field.init is False: 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1848 raise PydanticUserError( 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1849 f'Field {field_name} has `init=False` and dataclass has config setting `extra="allow"`. ' 

1850 f'This combination is not allowed.', 

1851 code='dataclass-init-false-extra-allow', 

1852 ) 

1853 

1854 decorators = dataclass.__dict__.get('__pydantic_decorators__') or DecoratorInfos.build(dataclass) 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1855 # Move kw_only=False args to the start of the list, as this is how vanilla dataclasses work. 

1856 # Note that when kw_only is missing or None, it is treated as equivalent to kw_only=True 

1857 args = sorted( 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1858 (self._generate_dc_field_schema(k, v, decorators) for k, v in fields.items()), 

1859 key=lambda a: a.get('kw_only') is not False, 

1860 ) 

1861 has_post_init = hasattr(dataclass, '__post_init__') 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1862 has_slots = hasattr(dataclass, '__slots__') 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1863 

1864 args_schema = core_schema.dataclass_args_schema( 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1865 dataclass.__name__, 

1866 args, 

1867 computed_fields=[ 

1868 self._computed_field_schema(d, decorators.field_serializers) 

1869 for d in decorators.computed_fields.values() 

1870 ], 

1871 collect_init_only=has_post_init, 

1872 ) 

1873 

1874 inner_schema = apply_validators(args_schema, decorators.root_validators.values(), None) 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1875 

1876 model_validators = decorators.model_validators.values() 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1877 inner_schema = apply_model_validators(inner_schema, model_validators, 'inner') 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1878 

1879 core_config = self._config_wrapper.core_config(title=dataclass.__name__) 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1880 

1881 dc_schema = core_schema.dataclass_schema( 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1882 dataclass, 

1883 inner_schema, 

1884 generic_origin=origin, 

1885 post_init=has_post_init, 

1886 ref=dataclass_ref, 

1887 fields=[field.name for field in dataclasses.fields(dataclass)], 

1888 slots=has_slots, 

1889 config=core_config, 

1890 # we don't use a custom __setattr__ for dataclasses, so we must 

1891 # pass along the frozen config setting to the pydantic-core schema 

1892 frozen=self._config_wrapper_stack.tail.frozen, 

1893 ) 

1894 schema = self._apply_model_serializers(dc_schema, decorators.model_serializers.values()) 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1895 schema = apply_model_validators(schema, model_validators, 'outer') 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1896 return self.defs.create_definition_reference_schema(schema) 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1897 

1898 def _call_schema(self, function: ValidateCallSupportedTypes) -> core_schema.CallSchema: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1899 """Generate schema for a Callable. 

1900 

1901 TODO support functional validators once we support them in Config 

1902 """ 

1903 sig = signature(function) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1904 globalns, localns = self._types_namespace 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1905 type_hints = _typing_extra.get_function_type_hints(function, globalns=globalns, localns=localns) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1906 

1907 mode_lookup: dict[_ParameterKind, Literal['positional_only', 'positional_or_keyword', 'keyword_only']] = { 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1908 Parameter.POSITIONAL_ONLY: 'positional_only', 

1909 Parameter.POSITIONAL_OR_KEYWORD: 'positional_or_keyword', 

1910 Parameter.KEYWORD_ONLY: 'keyword_only', 

1911 } 

1912 

1913 arguments_list: list[core_schema.ArgumentsParameter] = [] 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1914 var_args_schema: core_schema.CoreSchema | None = None 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1915 var_kwargs_schema: core_schema.CoreSchema | None = None 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1916 var_kwargs_mode: core_schema.VarKwargsMode | None = None 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1917 

1918 for name, p in sig.parameters.items(): 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1919 if p.annotation is sig.empty: 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1920 annotation = typing.cast(Any, Any) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1921 else: 

1922 annotation = type_hints[name] 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1923 

1924 parameter_mode = mode_lookup.get(p.kind) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1925 if parameter_mode is not None: 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1926 arg_schema = self._generate_parameter_schema(name, annotation, p.default, parameter_mode) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1927 arguments_list.append(arg_schema) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1928 elif p.kind == Parameter.VAR_POSITIONAL: 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1929 var_args_schema = self.generate_schema(annotation) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1930 else: 

1931 assert p.kind == Parameter.VAR_KEYWORD, p.kind 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1932 

1933 unpack_type = _typing_extra.unpack_type(annotation) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1934 if unpack_type is not None: 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1935 if not is_typeddict(unpack_type): 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1936 raise PydanticUserError( 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1937 f'Expected a `TypedDict` class, got {unpack_type.__name__!r}', code='unpack-typed-dict' 

1938 ) 

1939 non_pos_only_param_names = { 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1940 name for name, p in sig.parameters.items() if p.kind != Parameter.POSITIONAL_ONLY 

1941 } 

1942 overlapping_params = non_pos_only_param_names.intersection(unpack_type.__annotations__) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1943 if overlapping_params: 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1944 raise PydanticUserError( 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1945 f'Typed dictionary {unpack_type.__name__!r} overlaps with parameter' 

1946 f'{"s" if len(overlapping_params) >= 2 else ""} ' 

1947 f'{", ".join(repr(p) for p in sorted(overlapping_params))}', 

1948 code='overlapping-unpack-typed-dict', 

1949 ) 

1950 

1951 var_kwargs_mode = 'unpacked-typed-dict' 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1952 var_kwargs_schema = self._typed_dict_schema(unpack_type, None) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1953 else: 

1954 var_kwargs_mode = 'uniform' 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1955 var_kwargs_schema = self.generate_schema(annotation) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1956 

1957 return_schema: core_schema.CoreSchema | None = None 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1958 config_wrapper = self._config_wrapper 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1959 if config_wrapper.validate_return: 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1960 return_hint = sig.return_annotation 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1961 if return_hint is not sig.empty: 1961 ↛ 1964line 1961 didn't jump to line 1964 because the condition on line 1961 was always true1acekoquwxCfbhilmrsyzDEdjgnptvABF

1962 return_schema = self.generate_schema(return_hint) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1963 

1964 return core_schema.call_schema( 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1965 core_schema.arguments_schema( 

1966 arguments_list, 

1967 var_args_schema=var_args_schema, 

1968 var_kwargs_mode=var_kwargs_mode, 

1969 var_kwargs_schema=var_kwargs_schema, 

1970 populate_by_name=config_wrapper.populate_by_name, 

1971 ), 

1972 function, 

1973 return_schema=return_schema, 

1974 ) 

1975 

1976 def _unsubstituted_typevar_schema(self, typevar: typing.TypeVar) -> core_schema.CoreSchema: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1977 try: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1978 has_default = typevar.has_default() 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1979 except AttributeError: 1acekoquwfbhilmrsyzLGHIJKdjgnptvA

1980 # Happens if using `typing.TypeVar` (and not `typing_extensions`) on Python < 3.13 

1981 pass 1acekoquwfbhilmrsyzLGHIJKdjgnptvA

1982 else: 

1983 if has_default: 1acekoquwxCfbhilmrsyzDEMdjgnptvABF

1984 return self.generate_schema(typevar.__default__) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1985 

1986 if constraints := typevar.__constraints__: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1987 return self._union_schema(typing.Union[constraints]) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1988 

1989 if bound := typevar.__bound__: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1990 schema = self.generate_schema(bound) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1991 schema['serialization'] = core_schema.wrap_serializer_function_ser_schema( 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1992 lambda x, h: h(x), 

1993 schema=core_schema.any_schema(), 

1994 ) 

1995 return schema 1acekoquwxCfbhilmrsyzDEdjgnptvABF

1996 

1997 return core_schema.any_schema() 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

1998 

1999 def _computed_field_schema( 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2000 self, 

2001 d: Decorator[ComputedFieldInfo], 

2002 field_serializers: dict[str, Decorator[FieldSerializerDecoratorInfo]], 

2003 ) -> core_schema.ComputedField: 

2004 try: 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2005 # Do not pass in globals as the function could be defined in a different module. 

2006 # Instead, let `get_function_return_type` infer the globals to use, but still pass 

2007 # in locals that may contain a parent/rebuild namespace: 

2008 return_type = _decorators.get_function_return_type( 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2009 d.func, d.info.return_type, localns=self._types_namespace.locals 

2010 ) 

2011 except NameError as e: 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2012 raise PydanticUndefinedAnnotation.from_name_error(e) from e 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2013 if return_type is PydanticUndefined: 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2014 raise PydanticUserError( 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2015 'Computed field is missing return type annotation or specifying `return_type`' 

2016 ' to the `@computed_field` decorator (e.g. `@computed_field(return_type=int|str)`)', 

2017 code='model-field-missing-annotation', 

2018 ) 

2019 

2020 return_type = replace_types(return_type, self._typevars_map) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2021 # Create a new ComputedFieldInfo so that different type parametrizations of the same 

2022 # generic model's computed field can have different return types. 

2023 d.info = dataclasses.replace(d.info, return_type=return_type) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2024 return_type_schema = self.generate_schema(return_type) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2025 # Apply serializers to computed field if there exist 

2026 return_type_schema = self._apply_field_serializers( 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2027 return_type_schema, 

2028 filter_field_decorator_info_by_field(field_serializers.values(), d.cls_var_name), 

2029 ) 

2030 

2031 alias_generator = self._config_wrapper.alias_generator 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2032 if alias_generator is not None: 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2033 self._apply_alias_generator_to_computed_field_info( 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2034 alias_generator=alias_generator, computed_field_info=d.info, computed_field_name=d.cls_var_name 

2035 ) 

2036 self._apply_field_title_generator_to_field_info(self._config_wrapper, d.info, d.cls_var_name) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2037 

2038 pydantic_js_updates, pydantic_js_extra = _extract_json_schema_info_from_field_info(d.info) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2039 core_metadata: dict[str, Any] = {} 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2040 update_core_metadata( 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2041 core_metadata, 

2042 pydantic_js_updates={'readOnly': True, **(pydantic_js_updates if pydantic_js_updates else {})}, 

2043 pydantic_js_extra=pydantic_js_extra, 

2044 ) 

2045 return core_schema.computed_field( 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2046 d.cls_var_name, return_schema=return_type_schema, alias=d.info.alias, metadata=core_metadata 

2047 ) 

2048 

2049 def _annotated_schema(self, annotated_type: Any) -> core_schema.CoreSchema: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2050 """Generate schema for an Annotated type, e.g. `Annotated[int, Field(...)]` or `Annotated[int, Gt(0)]`.""" 

2051 FieldInfo = import_cached_field_info() 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2052 # Ideally, we should delegate all this to `_typing_extra.unpack_annotated`, e.g.: 

2053 # `typ, annotations = _typing_extra.unpack_annotated(annotated_type); schema = self.apply_annotations(...)` 

2054 # if it was able to use a `NsResolver`. But because `unpack_annotated` is also used 

2055 # when constructing `FieldInfo` instances (where we don't have access to a `NsResolver`), 

2056 # the implementation of the function does *not* resolve forward annotations. This could 

2057 # be solved by calling `unpack_annotated` directly inside `collect_model_fields`. 

2058 # For now, we at least resolve the annotated type if it is a forward ref, but note that 

2059 # unexpected results will happen if you have something like `Annotated[Alias, ...]` and 

2060 # `Alias` is a PEP 695 type alias containing forward references. 

2061 typ, *annotations = get_args(annotated_type) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2062 if isinstance(typ, str): 2062 ↛ 2063line 2062 didn't jump to line 2063 because the condition on line 2062 was never true1acekoquwxCfbhilmrsyzDEdjgnptvABF

2063 typ = _typing_extra._make_forward_ref(typ) 

2064 if isinstance(typ, ForwardRef): 2064 ↛ 2065line 2064 didn't jump to line 2065 because the condition on line 2064 was never true1acekoquwxCfbhilmrsyzDEdjgnptvABF

2065 typ = self._resolve_forward_ref(typ) 

2066 

2067 typ, sub_annotations = _typing_extra.unpack_annotated(typ) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2068 annotations = sub_annotations + annotations 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2069 

2070 schema = self._apply_annotations(typ, annotations) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2071 # put the default validator last so that TypeAdapter.get_default_value() works 

2072 # even if there are function validators involved 

2073 for annotation in annotations: 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2074 if isinstance(annotation, FieldInfo): 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2075 schema = wrap_default(annotation, schema) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2076 return schema 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2077 

2078 def _apply_annotations( 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2079 self, 

2080 source_type: Any, 

2081 annotations: list[Any], 

2082 transform_inner_schema: Callable[[CoreSchema], CoreSchema] = lambda x: x, 

2083 ) -> CoreSchema: 

2084 """Apply arguments from `Annotated` or from `FieldInfo` to a schema. 

2085 

2086 This gets called by `GenerateSchema._annotated_schema` but differs from it in that it does 

2087 not expect `source_type` to be an `Annotated` object, it expects it to be the first argument of that 

2088 (in other words, `GenerateSchema._annotated_schema` just unpacks `Annotated`, this process it). 

2089 """ 

2090 annotations = list(_known_annotated_metadata.expand_grouped_metadata(annotations)) 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2091 

2092 pydantic_js_annotation_functions: list[GetJsonSchemaFunction] = [] 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2093 

2094 def inner_handler(obj: Any) -> CoreSchema: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2095 schema = self._generate_schema_from_get_schema_method(obj, source_type) 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2096 

2097 if schema is None: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2098 schema = self._generate_schema_inner(obj) 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2099 

2100 metadata_js_function = _extract_get_pydantic_json_schema(obj) 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2101 if metadata_js_function is not None: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2102 metadata_schema = resolve_original_schema(schema, self.defs) 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2103 if metadata_schema is not None: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2104 self._add_js_function(metadata_schema, metadata_js_function) 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2105 return transform_inner_schema(schema) 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2106 

2107 get_inner_schema = CallbackGetCoreSchemaHandler(inner_handler, self) 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2108 

2109 for annotation in annotations: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2110 if annotation is None: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2111 continue 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2112 get_inner_schema = self._get_wrapped_inner_schema( 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2113 get_inner_schema, annotation, pydantic_js_annotation_functions 

2114 ) 

2115 

2116 schema = get_inner_schema(source_type) 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2117 if pydantic_js_annotation_functions: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2118 core_metadata = schema.setdefault('metadata', {}) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2119 update_core_metadata(core_metadata, pydantic_js_annotation_functions=pydantic_js_annotation_functions) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2120 return _add_custom_serialization_from_json_encoders(self._config_wrapper.json_encoders, source_type, schema) 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2121 

2122 def _apply_single_annotation(self, schema: core_schema.CoreSchema, metadata: Any) -> core_schema.CoreSchema: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2123 FieldInfo = import_cached_field_info() 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2124 

2125 if isinstance(metadata, FieldInfo): 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2126 for field_metadata in metadata.metadata: 2126 ↛ 2127line 2126 didn't jump to line 2127 because the loop on line 2126 never started1acekoquwxCfbhilmrsyzDEdjgnptvABF

2127 schema = self._apply_single_annotation(schema, field_metadata) 

2128 

2129 if metadata.discriminator is not None: 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2130 schema = self._apply_discriminator_to_union(schema, metadata.discriminator) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2131 return schema 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2132 

2133 if schema['type'] == 'nullable': 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2134 # for nullable schemas, metadata is automatically applied to the inner schema 

2135 inner = schema.get('schema', core_schema.any_schema()) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2136 inner = self._apply_single_annotation(inner, metadata) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2137 if inner: 2137 ↛ 2139line 2137 didn't jump to line 2139 because the condition on line 2137 was always true1acekoquwxCfbhilmrsyzDEdjgnptvABF

2138 schema['schema'] = inner 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2139 return schema 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2140 

2141 original_schema = schema 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2142 ref = schema.get('ref') 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2143 if ref is not None: 2143 ↛ 2144line 2143 didn't jump to line 2144 because the condition on line 2143 was never true1acekoquwxCfbhilmrsyzDEdjgnptvABF

2144 schema = schema.copy() 

2145 new_ref = ref + f'_{repr(metadata)}' 

2146 if (existing := self.defs.get_schema_from_ref(new_ref)) is not None: 

2147 return existing 

2148 schema['ref'] = new_ref # pyright: ignore[reportGeneralTypeIssues] 

2149 elif schema['type'] == 'definition-ref': 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2150 ref = schema['schema_ref'] 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2151 if (referenced_schema := self.defs.get_schema_from_ref(ref)) is not None: 2151 ↛ 2158line 2151 didn't jump to line 2158 because the condition on line 2151 was always true1acekoquwxCfbhilmrsyzDEdjgnptvABF

2152 schema = referenced_schema.copy() 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2153 new_ref = ref + f'_{repr(metadata)}' 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2154 if (existing := self.defs.get_schema_from_ref(new_ref)) is not None: 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2155 return existing 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2156 schema['ref'] = new_ref # pyright: ignore[reportGeneralTypeIssues] 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2157 

2158 maybe_updated_schema = _known_annotated_metadata.apply_known_metadata(metadata, schema) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2159 

2160 if maybe_updated_schema is not None: 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2161 return maybe_updated_schema 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2162 return original_schema 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2163 

2164 def _apply_single_annotation_json_schema( 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2165 self, schema: core_schema.CoreSchema, metadata: Any 

2166 ) -> core_schema.CoreSchema: 

2167 FieldInfo = import_cached_field_info() 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2168 

2169 if isinstance(metadata, FieldInfo): 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2170 for field_metadata in metadata.metadata: 2170 ↛ 2171line 2170 didn't jump to line 2171 because the loop on line 2170 never started1acekoquwxCfbhilmrsyzDEdjgnptvABF

2171 schema = self._apply_single_annotation_json_schema(schema, field_metadata) 

2172 

2173 pydantic_js_updates, pydantic_js_extra = _extract_json_schema_info_from_field_info(metadata) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2174 core_metadata = schema.setdefault('metadata', {}) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2175 update_core_metadata( 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2176 core_metadata, pydantic_js_updates=pydantic_js_updates, pydantic_js_extra=pydantic_js_extra 

2177 ) 

2178 return schema 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2179 

2180 def _get_wrapped_inner_schema( 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2181 self, 

2182 get_inner_schema: GetCoreSchemaHandler, 

2183 annotation: Any, 

2184 pydantic_js_annotation_functions: list[GetJsonSchemaFunction], 

2185 ) -> CallbackGetCoreSchemaHandler: 

2186 annotation_get_schema: GetCoreSchemaFunction | None = getattr(annotation, '__get_pydantic_core_schema__', None) 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2187 

2188 def new_handler(source: Any) -> core_schema.CoreSchema: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2189 if annotation_get_schema is not None: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2190 schema = annotation_get_schema(source, get_inner_schema) 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2191 else: 

2192 schema = get_inner_schema(source) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2193 schema = self._apply_single_annotation(schema, annotation) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2194 schema = self._apply_single_annotation_json_schema(schema, annotation) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2195 

2196 metadata_js_function = _extract_get_pydantic_json_schema(annotation) 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2197 if metadata_js_function is not None: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2198 pydantic_js_annotation_functions.append(metadata_js_function) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2199 return schema 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2200 

2201 return CallbackGetCoreSchemaHandler(new_handler, self) 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2202 

2203 def _apply_field_serializers( 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2204 self, 

2205 schema: core_schema.CoreSchema, 

2206 serializers: list[Decorator[FieldSerializerDecoratorInfo]], 

2207 ) -> core_schema.CoreSchema: 

2208 """Apply field serializers to a schema.""" 

2209 if serializers: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2210 schema = copy(schema) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2211 if schema['type'] == 'definitions': 2211 ↛ 2212line 2211 didn't jump to line 2212 because the condition on line 2211 was never true1acekoquwxCfbhilmrsyzDEdjgnptvABF

2212 inner_schema = schema['schema'] 

2213 schema['schema'] = self._apply_field_serializers(inner_schema, serializers) 

2214 return schema 

2215 elif 'ref' in schema: 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2216 schema = self.defs.create_definition_reference_schema(schema) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2217 

2218 # use the last serializer to make it easy to override a serializer set on a parent model 

2219 serializer = serializers[-1] 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2220 is_field_serializer, info_arg = inspect_field_serializer(serializer.func, serializer.info.mode) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2221 

2222 try: 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2223 # Do not pass in globals as the function could be defined in a different module. 

2224 # Instead, let `get_function_return_type` infer the globals to use, but still pass 

2225 # in locals that may contain a parent/rebuild namespace: 

2226 return_type = _decorators.get_function_return_type( 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2227 serializer.func, serializer.info.return_type, localns=self._types_namespace.locals 

2228 ) 

2229 except NameError as e: 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2230 raise PydanticUndefinedAnnotation.from_name_error(e) from e 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2231 

2232 if return_type is PydanticUndefined: 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2233 return_schema = None 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2234 else: 

2235 return_schema = self.generate_schema(return_type) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2236 

2237 if serializer.info.mode == 'wrap': 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2238 schema['serialization'] = core_schema.wrap_serializer_function_ser_schema( 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2239 serializer.func, 

2240 is_field_serializer=is_field_serializer, 

2241 info_arg=info_arg, 

2242 return_schema=return_schema, 

2243 when_used=serializer.info.when_used, 

2244 ) 

2245 else: 

2246 assert serializer.info.mode == 'plain' 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2247 schema['serialization'] = core_schema.plain_serializer_function_ser_schema( 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2248 serializer.func, 

2249 is_field_serializer=is_field_serializer, 

2250 info_arg=info_arg, 

2251 return_schema=return_schema, 

2252 when_used=serializer.info.when_used, 

2253 ) 

2254 return schema 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2255 

2256 def _apply_model_serializers( 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2257 self, schema: core_schema.CoreSchema, serializers: Iterable[Decorator[ModelSerializerDecoratorInfo]] 

2258 ) -> core_schema.CoreSchema: 

2259 """Apply model serializers to a schema.""" 

2260 ref: str | None = schema.pop('ref', None) # type: ignore 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2261 if serializers: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2262 serializer = list(serializers)[-1] 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2263 info_arg = inspect_model_serializer(serializer.func, serializer.info.mode) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2264 

2265 try: 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2266 # Do not pass in globals as the function could be defined in a different module. 

2267 # Instead, let `get_function_return_type` infer the globals to use, but still pass 

2268 # in locals that may contain a parent/rebuild namespace: 

2269 return_type = _decorators.get_function_return_type( 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2270 serializer.func, serializer.info.return_type, localns=self._types_namespace.locals 

2271 ) 

2272 except NameError as e: 

2273 raise PydanticUndefinedAnnotation.from_name_error(e) from e 

2274 if return_type is PydanticUndefined: 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2275 return_schema = None 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2276 else: 

2277 return_schema = self.generate_schema(return_type) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2278 

2279 if serializer.info.mode == 'wrap': 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2280 ser_schema: core_schema.SerSchema = core_schema.wrap_serializer_function_ser_schema( 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2281 serializer.func, 

2282 info_arg=info_arg, 

2283 return_schema=return_schema, 

2284 when_used=serializer.info.when_used, 

2285 ) 

2286 else: 

2287 # plain 

2288 ser_schema = core_schema.plain_serializer_function_ser_schema( 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2289 serializer.func, 

2290 info_arg=info_arg, 

2291 return_schema=return_schema, 

2292 when_used=serializer.info.when_used, 

2293 ) 

2294 schema['serialization'] = ser_schema 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2295 if ref: 2295 ↛ 2297line 2295 didn't jump to line 2297 because the condition on line 2295 was always true1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2296 schema['ref'] = ref # type: ignore 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2297 return schema 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2298 

2299 

2300_VALIDATOR_F_MATCH: Mapping[ 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2301 tuple[FieldValidatorModes, Literal['no-info', 'with-info']], 

2302 Callable[[Callable[..., Any], core_schema.CoreSchema, str | None], core_schema.CoreSchema], 

2303] = { 

2304 ('before', 'no-info'): lambda f, schema, _: core_schema.no_info_before_validator_function(f, schema), 

2305 ('after', 'no-info'): lambda f, schema, _: core_schema.no_info_after_validator_function(f, schema), 

2306 ('plain', 'no-info'): lambda f, _1, _2: core_schema.no_info_plain_validator_function(f), 

2307 ('wrap', 'no-info'): lambda f, schema, _: core_schema.no_info_wrap_validator_function(f, schema), 

2308 ('before', 'with-info'): lambda f, schema, field_name: core_schema.with_info_before_validator_function( 

2309 f, schema, field_name=field_name 

2310 ), 

2311 ('after', 'with-info'): lambda f, schema, field_name: core_schema.with_info_after_validator_function( 

2312 f, schema, field_name=field_name 

2313 ), 

2314 ('plain', 'with-info'): lambda f, _, field_name: core_schema.with_info_plain_validator_function( 

2315 f, field_name=field_name 

2316 ), 

2317 ('wrap', 'with-info'): lambda f, schema, field_name: core_schema.with_info_wrap_validator_function( 

2318 f, schema, field_name=field_name 

2319 ), 

2320} 

2321 

2322 

2323# TODO V3: this function is only used for deprecated decorators. It should 

2324# be removed once we drop support for those. 

2325def apply_validators( 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2326 schema: core_schema.CoreSchema, 

2327 validators: Iterable[Decorator[RootValidatorDecoratorInfo]] 

2328 | Iterable[Decorator[ValidatorDecoratorInfo]] 

2329 | Iterable[Decorator[FieldValidatorDecoratorInfo]], 

2330 field_name: str | None, 

2331) -> core_schema.CoreSchema: 

2332 """Apply validators to a schema. 

2333 

2334 Args: 

2335 schema: The schema to apply validators on. 

2336 validators: An iterable of validators. 

2337 field_name: The name of the field if validators are being applied to a model field. 

2338 

2339 Returns: 

2340 The updated schema. 

2341 """ 

2342 for validator in validators: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2343 info_arg = inspect_validator(validator.func, validator.info.mode) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2344 val_type = 'with-info' if info_arg else 'no-info' 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2345 

2346 schema = _VALIDATOR_F_MATCH[(validator.info.mode, val_type)](validator.func, schema, field_name) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2347 return schema 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2348 

2349 

2350def _validators_require_validate_default(validators: Iterable[Decorator[ValidatorDecoratorInfo]]) -> bool: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2351 """In v1, if any of the validators for a field had `always=True`, the default value would be validated. 

2352 

2353 This serves as an auxiliary function for re-implementing that logic, by looping over a provided 

2354 collection of (v1-style) ValidatorDecoratorInfo's and checking if any of them have `always=True`. 

2355 

2356 We should be able to drop this function and the associated logic calling it once we drop support 

2357 for v1-style validator decorators. (Or we can extend it and keep it if we add something equivalent 

2358 to the v1-validator `always` kwarg to `field_validator`.) 

2359 """ 

2360 for validator in validators: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2361 if validator.info.always: 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2362 return True 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2363 return False 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2364 

2365 

2366def apply_model_validators( 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2367 schema: core_schema.CoreSchema, 

2368 validators: Iterable[Decorator[ModelValidatorDecoratorInfo]], 

2369 mode: Literal['inner', 'outer', 'all'], 

2370) -> core_schema.CoreSchema: 

2371 """Apply model validators to a schema. 

2372 

2373 If mode == 'inner', only "before" validators are applied 

2374 If mode == 'outer', validators other than "before" are applied 

2375 If mode == 'all', all validators are applied 

2376 

2377 Args: 

2378 schema: The schema to apply validators on. 

2379 validators: An iterable of validators. 

2380 mode: The validator mode. 

2381 

2382 Returns: 

2383 The updated schema. 

2384 """ 

2385 ref: str | None = schema.pop('ref', None) # type: ignore 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2386 for validator in validators: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2387 if mode == 'inner' and validator.info.mode != 'before': 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2388 continue 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2389 if mode == 'outer' and validator.info.mode == 'before': 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2390 continue 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2391 info_arg = inspect_validator(validator.func, validator.info.mode) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2392 if validator.info.mode == 'wrap': 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2393 if info_arg: 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2394 schema = core_schema.with_info_wrap_validator_function(function=validator.func, schema=schema) 1uwxCyzDEvABF

2395 else: 

2396 schema = core_schema.no_info_wrap_validator_function(function=validator.func, schema=schema) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2397 elif validator.info.mode == 'before': 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2398 if info_arg: 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2399 schema = core_schema.with_info_before_validator_function(function=validator.func, schema=schema) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2400 else: 

2401 schema = core_schema.no_info_before_validator_function(function=validator.func, schema=schema) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2402 else: 

2403 assert validator.info.mode == 'after' 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2404 if info_arg: 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2405 schema = core_schema.with_info_after_validator_function(function=validator.func, schema=schema) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2406 else: 

2407 schema = core_schema.no_info_after_validator_function(function=validator.func, schema=schema) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2408 if ref: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2409 schema['ref'] = ref # type: ignore 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2410 return schema 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2411 

2412 

2413def wrap_default(field_info: FieldInfo, schema: core_schema.CoreSchema) -> core_schema.CoreSchema: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2414 """Wrap schema with default schema if default value or `default_factory` are available. 

2415 

2416 Args: 

2417 field_info: The field info object. 

2418 schema: The schema to apply default on. 

2419 

2420 Returns: 

2421 Updated schema by default value or `default_factory`. 

2422 """ 

2423 if field_info.default_factory: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2424 return core_schema.with_default_schema( 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2425 schema, 

2426 default_factory=field_info.default_factory, 

2427 default_factory_takes_data=takes_validated_data_argument(field_info.default_factory), 

2428 validate_default=field_info.validate_default, 

2429 ) 

2430 elif field_info.default is not PydanticUndefined: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2431 return core_schema.with_default_schema( 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2432 schema, default=field_info.default, validate_default=field_info.validate_default 

2433 ) 

2434 else: 

2435 return schema 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2436 

2437 

2438def _extract_get_pydantic_json_schema(tp: Any) -> GetJsonSchemaFunction | None: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2439 """Extract `__get_pydantic_json_schema__` from a type, handling the deprecated `__modify_schema__`.""" 

2440 js_modify_function = getattr(tp, '__get_pydantic_json_schema__', None) 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2441 

2442 if hasattr(tp, '__modify_schema__'): 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2443 BaseModel = import_cached_base_model() 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2444 

2445 has_custom_v2_modify_js_func = ( 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2446 js_modify_function is not None 

2447 and BaseModel.__get_pydantic_json_schema__.__func__ # type: ignore 

2448 not in (js_modify_function, getattr(js_modify_function, '__func__', None)) 

2449 ) 

2450 

2451 if not has_custom_v2_modify_js_func: 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2452 cls_name = getattr(tp, '__name__', None) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2453 raise PydanticUserError( 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2454 f'The `__modify_schema__` method is not supported in Pydantic v2. ' 

2455 f'Use `__get_pydantic_json_schema__` instead{f" in class `{cls_name}`" if cls_name else ""}.', 

2456 code='custom-json-schema', 

2457 ) 

2458 

2459 # handle GenericAlias' but ignore Annotated which "lies" about its origin (in this case it would be `int`) 

2460 if hasattr(tp, '__origin__') and not _typing_extra.is_annotated(tp): 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2461 # Generic aliases proxy attribute access to the origin, *except* dunder attributes, 

2462 # such as `__get_pydantic_json_schema__`, hence the explicit check. 

2463 return _extract_get_pydantic_json_schema(tp.__origin__) 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2464 

2465 if js_modify_function is None: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2466 return None 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2467 

2468 return js_modify_function 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2469 

2470 

2471class _CommonField(TypedDict): 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2472 schema: core_schema.CoreSchema 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2473 validation_alias: str | list[str | int] | list[list[str | int]] | None 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2474 serialization_alias: str | None 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2475 serialization_exclude: bool | None 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2476 frozen: bool | None 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2477 metadata: dict[str, Any] 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2478 

2479 

2480def _common_field( 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2481 schema: core_schema.CoreSchema, 

2482 *, 

2483 validation_alias: str | list[str | int] | list[list[str | int]] | None = None, 

2484 serialization_alias: str | None = None, 

2485 serialization_exclude: bool | None = None, 

2486 frozen: bool | None = None, 

2487 metadata: Any = None, 

2488) -> _CommonField: 

2489 return { 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2490 'schema': schema, 

2491 'validation_alias': validation_alias, 

2492 'serialization_alias': serialization_alias, 

2493 'serialization_exclude': serialization_exclude, 

2494 'frozen': frozen, 

2495 'metadata': metadata, 

2496 } 

2497 

2498 

2499def resolve_original_schema(schema: CoreSchema, definitions: _Definitions) -> CoreSchema | None: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2500 if schema['type'] == 'definition-ref': 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2501 return definitions.get_schema_from_ref(schema['schema_ref']) 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2502 elif schema['type'] == 'definitions': 2502 ↛ 2503line 2502 didn't jump to line 2503 because the condition on line 2502 was never true1acekoquwxCfbhilmrsyzDEdjgnptvABF

2503 return schema['schema'] 

2504 else: 

2505 return schema 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2506 

2507 

2508def _can_be_inlined(def_ref: core_schema.DefinitionReferenceSchema) -> bool: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2509 """Return whether the `'definition-ref'` schema can be replaced by its definition. 

2510 

2511 This is true if no `'serialization'` schema is attached, or if it has at least one metadata entry. 

2512 Inlining such schemas would remove the `'serialization'` schema or metadata. 

2513 """ 

2514 return 'serialization' not in def_ref and not def_ref.get('metadata') 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2515 

2516 

2517class _Definitions: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2518 """Keeps track of references and definitions.""" 

2519 

2520 _recursively_seen: set[str] 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2521 """A set of recursively seen references. 1ekoquwxCblmrsyzDEGHIJKMgnptvABF

2522 

2523 When a referenceable type is encountered, the `get_schema_or_ref` context manager is 

2524 entered to compute the reference. If the type references itself by some way (e.g. for 

2525 a dataclass a Pydantic model, the class can be referenced as a field annotation), 

2526 entering the context manager again will yield a `'definition-ref'` schema that should 

2527 short-circuit the normal generation process, as the reference was already in this set. 

2528 """ 

2529 

2530 _definitions: dict[str, core_schema.CoreSchema] 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2531 """A mapping of references to their corresponding schema. 1ekoquwxCblmrsyzDEGHIJKMgnptvABF

2532 

2533 When a schema for a referenceable type is generated, it is stored in this mapping. If the 

2534 same type is encountered again, the reference is yielded by the `get_schema_or_ref` context 

2535 manager. 

2536 """ 

2537 

2538 def __init__(self) -> None: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2539 self._recursively_seen = set() 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2540 self._definitions = {} 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2541 

2542 @contextmanager 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2543 def get_schema_or_ref(self, tp: Any, /) -> Generator[tuple[str, core_schema.DefinitionReferenceSchema | None]]: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2544 """Get a definition for `tp` if one exists. 

2545 

2546 If a definition exists, a tuple of `(ref_string, CoreSchema)` is returned. 

2547 If no definition exists yet, a tuple of `(ref_string, None)` is returned. 

2548 

2549 Note that the returned `CoreSchema` will always be a `DefinitionReferenceSchema`, 

2550 not the actual definition itself. 

2551 

2552 This should be called for any type that can be identified by reference. 

2553 This includes any recursive types. 

2554 

2555 At present the following types can be named/recursive: 

2556 

2557 - Pydantic model 

2558 - Pydantic and stdlib dataclasses 

2559 - Typed dictionaries 

2560 - Named tuples 

2561 - `TypeAliasType` instances 

2562 - Enums 

2563 """ 

2564 ref = get_type_ref(tp) 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2565 # return the reference if we're either (1) in a cycle or (2) it the reference was already encountered: 

2566 if ref in self._recursively_seen or ref in self._definitions: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2567 yield (ref, core_schema.definition_reference_schema(ref)) 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2568 else: 

2569 self._recursively_seen.add(ref) 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2570 try: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2571 yield (ref, None) 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2572 finally: 

2573 self._recursively_seen.discard(ref) 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2574 

2575 def get_schema_from_ref(self, ref: str) -> CoreSchema | None: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2576 """Resolve the schema from the given reference.""" 

2577 return self._definitions.get(ref) 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2578 

2579 def create_definition_reference_schema(self, schema: CoreSchema) -> core_schema.DefinitionReferenceSchema: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2580 """Store the schema as a definition and return a `'definition-reference'` schema pointing to it. 

2581 

2582 The schema must have a reference attached to it. 

2583 """ 

2584 ref = schema['ref'] # pyright: ignore 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2585 self._definitions[ref] = schema 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2586 return core_schema.definition_reference_schema(ref) 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2587 

2588 def unpack_definitions(self, schema: core_schema.DefinitionsSchema) -> CoreSchema: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2589 """Store the definitions of the `'definitions'` core schema and return the inner core schema.""" 

2590 for def_schema in schema['definitions']: 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2591 self._definitions[def_schema['ref']] = def_schema # pyright: ignore 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2592 return schema['schema'] 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2593 

2594 def finalize_schema(self, schema: CoreSchema) -> CoreSchema: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2595 """Finalize the core schema. 

2596 

2597 This traverses the core schema and referenced definitions, replaces `'definition-ref'` schemas 

2598 by the referenced definition if possible, and applies deferred discriminators. 

2599 """ 

2600 definitions = self._definitions 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2601 try: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2602 gather_result = gather_schemas_for_cleaning( 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2603 schema, 

2604 definitions=definitions, 

2605 ) 

2606 except MissingDefinitionError as e: 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2607 raise InvalidSchemaError from e 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2608 

2609 remaining_defs: dict[str, CoreSchema] = {} 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2610 

2611 for ref, inlinable_def_ref in gather_result['collected_references'].items(): 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2612 if inlinable_def_ref is not None and _can_be_inlined(inlinable_def_ref): 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2613 # `ref` was encountered, and only once: 

2614 # - `inlinable_def_ref` is a `'definition-ref'` schema and is guaranteed to be 

2615 # the only one. Transform it into the definition it points to. 

2616 # - Do not store the definition in the `remaining_defs`. 

2617 inlinable_def_ref.clear() # pyright: ignore[reportAttributeAccessIssue] 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2618 inlinable_def_ref.update(self._resolve_definition(ref, definitions)) # pyright: ignore 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2619 else: 

2620 # `ref` was encountered, at least two times: 

2621 # - Do not inline the `'definition-ref'` schemas (they are not provided in the gather result anyway). 

2622 # - Store the the definition in the `remaining_defs` 

2623 remaining_defs[ref] = self._resolve_definition(ref, definitions) 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2624 

2625 for cs in gather_result['deferred_discriminator_schemas']: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2626 discriminator = cs['metadata']['pydantic_internal_union_discriminator'] # pyright: ignore[reportTypedDictNotRequiredAccess] 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2627 applied = _discriminated_union.apply_discriminator(cs.copy(), discriminator, remaining_defs) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2628 # Mutate the schema directly to have the discriminator applied 

2629 cs.clear() # pyright: ignore[reportAttributeAccessIssue] 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2630 cs.update(applied) # pyright: ignore 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2631 

2632 if remaining_defs: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2633 schema = core_schema.definitions_schema(schema=schema, definitions=[*remaining_defs.values()]) 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2634 return schema 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2635 

2636 def _resolve_definition(self, ref: str, definitions: dict[str, CoreSchema]) -> CoreSchema: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2637 definition = definitions[ref] 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2638 if definition['type'] != 'definition-ref': 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2639 return definition 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2640 

2641 # Some `'definition-ref'` schemas might act as "intermediate" references (e.g. when using 

2642 # a PEP 695 type alias (which is referenceable) that references another PEP 695 type alias): 

2643 visited: set[str] = set() 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2644 while definition['type'] == 'definition-ref': 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2645 schema_ref = definition['schema_ref'] 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2646 if schema_ref in visited: 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2647 raise PydanticUserError( 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2648 f'{ref} contains a circular reference to itself.', code='circular-reference-schema' 

2649 ) 

2650 visited.add(schema_ref) 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2651 definition = definitions[schema_ref] 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2652 return {**definition, 'ref': ref} # pyright: ignore[reportReturnType] 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2653 

2654 

2655class _FieldNameStack: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2656 __slots__ = ('_stack',) 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2657 

2658 def __init__(self) -> None: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2659 self._stack: list[str] = [] 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2660 

2661 @contextmanager 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2662 def push(self, field_name: str) -> Iterator[None]: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2663 self._stack.append(field_name) 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2664 yield 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2665 self._stack.pop() 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2666 

2667 def get(self) -> str | None: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2668 if self._stack: 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2669 return self._stack[-1] 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2670 else: 

2671 return None 1aeouxdgpvB

2672 

2673 

2674class _ModelTypeStack: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2675 __slots__ = ('_stack',) 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2676 

2677 def __init__(self) -> None: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2678 self._stack: list[type] = [] 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2679 

2680 @contextmanager 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2681 def push(self, type_obj: type) -> Iterator[None]: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2682 self._stack.append(type_obj) 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2683 yield 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2684 self._stack.pop() 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2685 

2686 def get(self) -> type | None: 1acekoquwxCfbhilmrsyzDELGHIJKMdjgnptvABF

2687 if self._stack: 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2688 return self._stack[-1] 1acekoquwxCfbhilmrsyzDEdjgnptvABF

2689 else: 

2690 return None 1acekoquwxCfbhilmrsyzDEdjgnptvABF