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

1349 statements  

« prev     ^ index     » next       coverage.py v7.8.0, created at 2025-04-26 07:45 +0000

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

2 

3from __future__ import annotations as _annotations 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

4 

5import collections.abc 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

6import dataclasses 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

7import datetime 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

8import inspect 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

9import os 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

10import pathlib 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

11import re 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

12import sys 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

13import typing 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

14import warnings 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

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

16from contextlib import contextmanager 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

17from copy import copy 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

18from decimal import Decimal 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

19from enum import Enum 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

20from fractions import Fraction 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

21from functools import partial 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

22from inspect import Parameter, _ParameterKind, signature 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

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

24from itertools import chain 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

25from operator import attrgetter 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

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

27from typing import ( 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

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 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

40from warnings import warn 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

41from zoneinfo import ZoneInfo 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

42 

43import typing_extensions 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

44from pydantic_core import ( 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

45 CoreSchema, 

46 MultiHostUrl, 

47 PydanticCustomError, 

48 PydanticSerializationUnexpectedValue, 

49 PydanticUndefined, 

50 Url, 

51 core_schema, 

52 to_jsonable_python, 

53) 

54from typing_extensions import TypeAlias, TypeAliasType, TypedDict, get_args, get_origin, is_typeddict 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

55from typing_inspection import typing_objects 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

56from typing_inspection.introspection import AnnotationSource, get_literal_values, is_union_origin 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

57 

58from ..aliases import AliasChoices, AliasGenerator, AliasPath 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

59from ..annotated_handlers import GetCoreSchemaHandler, GetJsonSchemaHandler 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

60from ..config import ConfigDict, JsonDict, JsonEncoder, JsonSchemaExtraCallable 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

61from ..errors import PydanticSchemaGenerationError, PydanticUndefinedAnnotation, PydanticUserError 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

62from ..functional_validators import AfterValidator, BeforeValidator, FieldValidatorModes, PlainValidator, WrapValidator 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

63from ..json_schema import JsonSchemaValue 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

64from ..version import version_short 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

65from ..warnings import PydanticDeprecatedSince20 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

66from . import _decorators, _discriminated_union, _known_annotated_metadata, _repr, _typing_extra 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

67from ._config import ConfigWrapper, ConfigWrapperStack 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

68from ._core_metadata import CoreMetadata, update_core_metadata 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

69from ._core_utils import ( 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

70 get_ref, 

71 get_type_ref, 

72 is_list_like_schema_with_items_schema, 

73 validate_core_schema, 

74) 

75from ._decorators import ( 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

76 Decorator, 

77 DecoratorInfos, 

78 FieldSerializerDecoratorInfo, 

79 FieldValidatorDecoratorInfo, 

80 ModelSerializerDecoratorInfo, 

81 ModelValidatorDecoratorInfo, 

82 RootValidatorDecoratorInfo, 

83 ValidatorDecoratorInfo, 

84 get_attribute_from_bases, 

85 inspect_field_serializer, 

86 inspect_model_serializer, 

87 inspect_validator, 

88) 

89from ._docs_extraction import extract_docstrings_from_cls 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

90from ._fields import collect_dataclass_fields, rebuild_model_fields, takes_validated_data_argument 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

91from ._forward_ref import PydanticRecursiveRef 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

92from ._generics import get_standard_typevars_map, replace_types 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

93from ._import_utils import import_cached_base_model, import_cached_field_info 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

94from ._mock_val_ser import MockCoreSchema 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

95from ._namespace_utils import NamespacesTuple, NsResolver 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

96from ._schema_gather import MissingDefinitionError, gather_schemas_for_cleaning 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

97from ._schema_generation_shared import CallbackGetCoreSchemaHandler 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

98from ._utils import lenient_issubclass, smart_deepcopy 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

99 

100if TYPE_CHECKING: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

101 from ..fields import ComputedFieldInfo, FieldInfo 

102 from ..main import BaseModel 

103 from ..types import Discriminator 

104 from ._dataclasses import StandardDataclass 

105 from ._schema_generation_shared import GetJsonSchemaFunction 

106 

107_SUPPORTS_TYPEDDICT = sys.version_info >= (3, 12) 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

108 

109FieldDecoratorInfo = Union[ValidatorDecoratorInfo, FieldValidatorDecoratorInfo, FieldSerializerDecoratorInfo] 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

110FieldDecoratorInfoType = TypeVar('FieldDecoratorInfoType', bound=FieldDecoratorInfo) 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

111AnyFieldDecorator = Union[ 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

112 Decorator[ValidatorDecoratorInfo], 

113 Decorator[FieldValidatorDecoratorInfo], 

114 Decorator[FieldSerializerDecoratorInfo], 

115] 

116 

117ModifyCoreSchemaWrapHandler: TypeAlias = GetCoreSchemaHandler 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

118GetCoreSchemaFunction: TypeAlias = Callable[[Any, ModifyCoreSchemaWrapHandler], core_schema.CoreSchema] 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

119ParametersCallback: TypeAlias = "Callable[[int, str, Any], Literal['skip'] | None]" 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

120 

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

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

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

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

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

126IP_TYPES: list[type] = [IPv4Address, IPv4Interface, IPv4Network, IPv6Address, IPv6Interface, IPv6Network] 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

127SEQUENCE_TYPES: list[type] = [typing.Sequence, collections.abc.Sequence] 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

128ITERABLE_TYPES: list[type] = [typing.Iterable, collections.abc.Iterable, typing.Generator, collections.abc.Generator] 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

129TYPE_TYPES: list[type] = [typing.Type, type] # noqa: UP006 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

130PATTERN_TYPES: list[type] = [typing.Pattern, re.Pattern] 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

131PATH_TYPES: list[type] = [ 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

132 os.PathLike, 

133 pathlib.Path, 

134 pathlib.PurePath, 

135 pathlib.PosixPath, 

136 pathlib.PurePosixPath, 

137 pathlib.PureWindowsPath, 

138] 

139MAPPING_TYPES = [ 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

140 typing.Mapping, 

141 typing.MutableMapping, 

142 collections.abc.Mapping, 

143 collections.abc.MutableMapping, 

144 collections.OrderedDict, 

145 typing_extensions.OrderedDict, 

146 typing.DefaultDict, # noqa: UP006 

147 collections.defaultdict, 

148] 

149COUNTER_TYPES = [collections.Counter, typing.Counter] 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

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

151 

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

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

154ValidateCallSupportedTypes = Union[ 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

155 LambdaType, 

156 FunctionType, 

157 MethodType, 

158 partial, 

159] 

160 

161VALIDATE_CALL_SUPPORTED_TYPES = get_args(ValidateCallSupportedTypes) 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

162 

163_mode_to_validator: dict[ 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

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

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

166 

167 

168def check_validator_fields_against_field_name( 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

169 info: FieldDecoratorInfo, 

170 field: str, 

171) -> bool: 

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

173 

174 Args: 

175 info: The field info. 

176 field: The field name to check. 

177 

178 Returns: 

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

180 """ 

181 fields = info.fields 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

182 return '*' in fields or field in fields 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

183 

184 

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

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

187 

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

189 

190 Args: 

191 decorators: An iterable of decorators. 

192 fields: An iterable of fields name. 

193 

194 Raises: 

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

196 """ 

197 fields = set(fields) 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

198 for dec in decorators: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

199 if '*' in dec.info.fields: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

200 continue 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

201 if dec.info.check_fields is False: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

202 continue 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

203 for field in dec.info.fields: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

204 if field not in fields: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

205 raise PydanticUserError( 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

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

208 code='decorator-missing-field', 

209 ) 

210 

211 

212def filter_field_decorator_info_by_field( 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

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

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

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

216 

217 

218def apply_each_item_validators( 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

219 schema: core_schema.CoreSchema, 

220 each_item_validators: list[Decorator[ValidatorDecoratorInfo]], 

221) -> core_schema.CoreSchema: 

222 # This V1 compatibility shim should eventually be removed 

223 

224 # fail early if each_item_validators is empty 

225 if not each_item_validators: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

226 return schema 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

227 

228 # push down any `each_item=True` validators 

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

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

231 if schema['type'] == 'nullable': 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

232 schema['schema'] = apply_each_item_validators(schema['schema'], each_item_validators) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

233 return schema 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

234 elif schema['type'] == 'tuple': 234 ↛ 235line 234 didn't jump to line 235 because the condition on line 234 was never true1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

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

237 schema['items_schema'][variadic_item_index], 

238 each_item_validators, 

239 ) 

240 elif is_list_like_schema_with_items_schema(schema): 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

241 inner_schema = schema.get('items_schema', core_schema.any_schema()) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

242 schema['items_schema'] = apply_validators(inner_schema, each_item_validators) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

243 elif schema['type'] == 'dict': 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

244 inner_schema = schema.get('values_schema', core_schema.any_schema()) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

245 schema['values_schema'] = apply_validators(inner_schema, each_item_validators) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

246 else: 

247 raise TypeError( 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

249 ) 

250 return schema 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

251 

252 

253def _extract_json_schema_info_from_field_info( 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

254 info: FieldInfo | ComputedFieldInfo, 

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

256 json_schema_updates = { 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

257 'title': info.title, 

258 'description': info.description, 

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

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

261 } 

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

263 return (json_schema_updates or None, info.json_schema_extra) 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

264 

265 

266JsonEncoders = dict[type[Any], JsonEncoder] 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

267 

268 

269def _add_custom_serialization_from_json_encoders( 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

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

271) -> CoreSchema: 

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

273 

274 Args: 

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

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

277 schema: The schema to add the encoder to. 

278 """ 

279 if not json_encoders: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

280 return schema 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

281 if 'serialization' in schema: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

282 return schema 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

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

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

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

287 encoder = json_encoders.get(base) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

288 if encoder is None: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

289 continue 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

290 

291 warnings.warn( 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

293 PydanticDeprecatedSince20, 

294 ) 

295 

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

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

298 return schema 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

299 

300 return schema 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

301 

302 

303def _get_first_non_null(a: Any, b: Any) -> Any: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

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

305 

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

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

308 """ 

309 return a if a is not None else b 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

310 

311 

312class InvalidSchemaError(Exception): 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

313 """The core schema is invalid.""" 

314 

315 

316class GenerateSchema: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

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

318 

319 __slots__ = ( 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

320 '_config_wrapper_stack', 

321 '_ns_resolver', 

322 '_typevars_map', 

323 'field_name_stack', 

324 'model_type_stack', 

325 'defs', 

326 ) 

327 

328 def __init__( 1abejoquwACDfglmrsxyEFGOJKLMNPdhinptvzBHI

329 self, 

330 config_wrapper: ConfigWrapper, 

331 ns_resolver: NsResolver | None = None, 

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

333 ) -> None: 

334 # we need a stack for recursing into nested models 

335 self._config_wrapper_stack = ConfigWrapperStack(config_wrapper) 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

336 self._ns_resolver = ns_resolver or NsResolver() 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

337 self._typevars_map = typevars_map 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

338 self.field_name_stack = _FieldNameStack() 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

339 self.model_type_stack = _ModelTypeStack() 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

340 self.defs = _Definitions() 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

341 

342 def __init_subclass__(cls) -> None: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

343 super().__init_subclass__() 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

344 warnings.warn( 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

346 UserWarning, 

347 stacklevel=2, 

348 ) 

349 

350 @property 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

351 def _config_wrapper(self) -> ConfigWrapper: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

352 return self._config_wrapper_stack.tail 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

353 

354 @property 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

355 def _types_namespace(self) -> NamespacesTuple: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

356 return self._ns_resolver.types_namespace 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

357 

358 @property 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

359 def _arbitrary_types(self) -> bool: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

360 return self._config_wrapper.arbitrary_types_allowed 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

361 

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

363 # unstable / private APIs 

364 def _list_schema(self, items_type: Any) -> CoreSchema: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

365 return core_schema.list_schema(self.generate_schema(items_type)) 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

366 

367 def _dict_schema(self, keys_type: Any, values_type: Any) -> CoreSchema: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

368 return core_schema.dict_schema(self.generate_schema(keys_type), self.generate_schema(values_type)) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

369 

370 def _set_schema(self, items_type: Any) -> CoreSchema: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

371 return core_schema.set_schema(self.generate_schema(items_type)) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

372 

373 def _frozenset_schema(self, items_type: Any) -> CoreSchema: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

374 return core_schema.frozenset_schema(self.generate_schema(items_type)) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

375 

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

377 cases: list[Any] = list(enum_type.__members__.values()) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

378 

379 enum_ref = get_type_ref(enum_type) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

380 description = None if not enum_type.__doc__ else inspect.cleandoc(enum_type.__doc__) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

381 if ( 1abkc

382 description == 'An enumeration.' 

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

384 description = None 1abejkcfglmdhin

385 js_updates = {'title': enum_type.__name__, 'description': description} 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

387 

388 sub_type: Literal['str', 'int', 'float'] | None = None 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

389 if issubclass(enum_type, int): 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

390 sub_type = 'int' 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

391 value_ser_type: core_schema.SerSchema = core_schema.simple_ser_schema('int') 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

392 elif issubclass(enum_type, str): 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

394 sub_type = 'str' 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

395 value_ser_type = core_schema.simple_ser_schema('str') 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

396 elif issubclass(enum_type, float): 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

397 sub_type = 'float' 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

398 value_ser_type = core_schema.simple_ser_schema('float') 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

399 else: 

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

401 value_ser_type = core_schema.plain_serializer_function_ser_schema(lambda x: x) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

402 

403 if cases: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

404 

405 def get_json_schema(schema: CoreSchema, handler: GetJsonSchemaHandler) -> JsonSchemaValue: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

406 json_schema = handler(schema) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

407 original_schema = handler.resolve_ref_schema(json_schema) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

408 original_schema.update(js_updates) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

409 return json_schema 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

410 

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

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

413 enum_schema = core_schema.enum_schema( 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

414 enum_type, 

415 cases, 

416 sub_type=sub_type, 

417 missing=None if default_missing else enum_type._missing_, 

418 ref=enum_ref, 

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

420 ) 

421 

422 if self._config_wrapper.use_enum_values: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

423 enum_schema = core_schema.no_info_after_validator_function( 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

425 ) 

426 

427 return enum_schema 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

428 

429 else: 

430 

431 def get_json_schema_no_cases(_, handler: GetJsonSchemaHandler) -> JsonSchemaValue: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

432 json_schema = handler(core_schema.enum_schema(enum_type, cases, sub_type=sub_type, ref=enum_ref)) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

433 original_schema = handler.resolve_ref_schema(json_schema) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

434 original_schema.update(js_updates) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

435 return json_schema 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

436 

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

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

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

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

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

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

443 return core_schema.is_instance_schema( 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

444 enum_type, 

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

446 ) 

447 

448 def _ip_schema(self, tp: Any) -> CoreSchema: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

449 from ._validators import IP_VALIDATOR_LOOKUP, IpType 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

450 

451 ip_type_json_schema_format: dict[type[IpType], str] = { 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

452 IPv4Address: 'ipv4', 

453 IPv4Network: 'ipv4network', 

454 IPv4Interface: 'ipv4interface', 

455 IPv6Address: 'ipv6', 

456 IPv6Network: 'ipv6network', 

457 IPv6Interface: 'ipv6interface', 

458 } 

459 

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

461 if not isinstance(ip, (tp, str)): 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

462 raise PydanticSerializationUnexpectedValue( 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

464 ) 

465 if info.mode == 'python': 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

466 return ip 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

467 return str(ip) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

468 

469 return core_schema.lax_or_strict_schema( 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

471 strict_schema=core_schema.json_or_python_schema( 

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

473 python_schema=core_schema.is_instance_schema(tp), 

474 ), 

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

476 metadata={ 

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

478 }, 

479 ) 

480 

481 def _path_schema(self, tp: Any, path_type: Any) -> CoreSchema: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

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

483 raise PydanticUserError( 

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

485 ) 

486 

487 path_constructor = pathlib.PurePath if tp is os.PathLike else tp 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

488 strict_inner_schema = ( 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

489 core_schema.bytes_schema(strict=True) if (path_type is bytes) else core_schema.str_schema(strict=True) 

490 ) 

491 lax_inner_schema = core_schema.bytes_schema() if (path_type is bytes) else core_schema.str_schema() 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

492 

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

494 try: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

495 if path_type is bytes: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

496 if isinstance(input_value, bytes): 496 ↛ 502line 496 didn't jump to line 502 because the condition on line 496 was always true1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

497 try: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

498 input_value = input_value.decode() 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

499 except UnicodeDecodeError as e: 

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

501 else: 

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

503 elif not isinstance(input_value, str): 503 ↛ 504line 503 didn't jump to line 504 because the condition on line 503 was never true1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

505 

506 return path_constructor(input_value) # type: ignore 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

507 except TypeError as e: 

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

509 

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

511 if not isinstance(path, (tp, str)): 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

512 raise PydanticSerializationUnexpectedValue( 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

514 ) 

515 if info.mode == 'python': 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

516 return path 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

517 return str(path) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

518 

519 instance_schema = core_schema.json_or_python_schema( 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

520 json_schema=core_schema.no_info_after_validator_function(path_validator, lax_inner_schema), 

521 python_schema=core_schema.is_instance_schema(tp), 

522 ) 

523 

524 schema = core_schema.lax_or_strict_schema( 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

525 lax_schema=core_schema.union_schema( 

526 [ 

527 instance_schema, 

528 core_schema.no_info_after_validator_function(path_validator, strict_inner_schema), 

529 ], 

530 custom_error_type='path_type', 

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

532 ), 

533 strict_schema=instance_schema, 

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

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

536 ) 

537 return schema 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

538 

539 def _deque_schema(self, items_type: Any) -> CoreSchema: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

540 from ._serializers import serialize_sequence_via_list 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

541 from ._validators import deque_validator 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

542 

543 item_type_schema = self.generate_schema(items_type) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

544 

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

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

547 list_schema = core_schema.list_schema(item_type_schema, strict=False) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

548 

549 check_instance = core_schema.json_or_python_schema( 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

550 json_schema=list_schema, 

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

552 ) 

553 

554 lax_schema = core_schema.no_info_wrap_validator_function(deque_validator, list_schema) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

555 

556 return core_schema.lax_or_strict_schema( 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

557 lax_schema=lax_schema, 

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

559 serialization=core_schema.wrap_serializer_function_ser_schema( 

560 serialize_sequence_via_list, schema=item_type_schema, info_arg=True 

561 ), 

562 ) 

563 

564 def _mapping_schema(self, tp: Any, keys_type: Any, values_type: Any) -> CoreSchema: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

565 from ._validators import MAPPING_ORIGIN_MAP, defaultdict_validator, get_defaultdict_default_default_factory 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

566 

567 mapped_origin = MAPPING_ORIGIN_MAP[tp] 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

568 keys_schema = self.generate_schema(keys_type) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

569 values_schema = self.generate_schema(values_type) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

570 dict_schema = core_schema.dict_schema(keys_schema, values_schema, strict=False) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

571 

572 if mapped_origin is dict: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

573 schema = dict_schema 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

574 else: 

575 check_instance = core_schema.json_or_python_schema( 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

576 json_schema=dict_schema, 

577 python_schema=core_schema.is_instance_schema(mapped_origin), 

578 ) 

579 

580 if tp is collections.defaultdict: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

581 default_default_factory = get_defaultdict_default_default_factory(values_type) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

582 coerce_instance_wrap = partial( 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

583 core_schema.no_info_wrap_validator_function, 

584 partial(defaultdict_validator, default_default_factory=default_default_factory), 

585 ) 

586 else: 

587 coerce_instance_wrap = partial(core_schema.no_info_after_validator_function, mapped_origin) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

588 

589 lax_schema = coerce_instance_wrap(dict_schema) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

590 strict_schema = core_schema.chain_schema([check_instance, lax_schema]) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

591 

592 schema = core_schema.lax_or_strict_schema( 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

593 lax_schema=lax_schema, 

594 strict_schema=strict_schema, 

595 serialization=core_schema.wrap_serializer_function_ser_schema( 

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

597 ), 

598 ) 

599 

600 return schema 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

601 

602 def _fraction_schema(self) -> CoreSchema: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

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

604 from ._validators import fraction_validator 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

605 

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

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

608 return core_schema.lax_or_strict_schema( 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

609 lax_schema=core_schema.no_info_plain_validator_function(fraction_validator), 

610 strict_schema=core_schema.json_or_python_schema( 

611 json_schema=core_schema.no_info_plain_validator_function(fraction_validator), 

612 python_schema=core_schema.is_instance_schema(Fraction), 

613 ), 

614 # use str serialization to guarantee round trip behavior 

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

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

617 ) 

618 

619 def _arbitrary_type_schema(self, tp: Any) -> CoreSchema: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

620 if not isinstance(tp, type): 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

621 warn( 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

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

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

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

626 UserWarning, 

627 ) 

628 return core_schema.any_schema() 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

629 return core_schema.is_instance_schema(tp) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

630 

631 def _unknown_type_schema(self, obj: Any) -> CoreSchema: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

632 raise PydanticSchemaGenerationError( 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

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

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

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

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

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

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

640 ) 

641 

642 def _apply_discriminator_to_union( 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

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

644 ) -> CoreSchema: 

645 if discriminator is None: 645 ↛ 646line 645 didn't jump to line 646 because the condition on line 645 was never true1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

646 return schema 

647 try: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

648 return _discriminated_union.apply_discriminator( 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

649 schema, 

650 discriminator, 

651 self.defs._definitions, 

652 ) 

653 except _discriminated_union.MissingDefinitionForUnionRef: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

654 # defer until defs are resolved 

655 _discriminated_union.set_discriminator_in_metadata( 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

656 schema, 

657 discriminator, 

658 ) 

659 return schema 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

660 

661 def clean_schema(self, schema: CoreSchema) -> CoreSchema: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

662 schema = self.defs.finalize_schema(schema) 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

663 schema = validate_core_schema(schema) 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

664 return schema 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

665 

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

667 metadata = metadata_schema.get('metadata', {}) 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

668 pydantic_js_functions = metadata.setdefault('pydantic_js_functions', []) 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

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

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

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

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

673 if js_function not in pydantic_js_functions: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

674 pydantic_js_functions.append(js_function) 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

675 metadata_schema['metadata'] = metadata 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

676 

677 def generate_schema( 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

678 self, 

679 obj: Any, 

680 ) -> core_schema.CoreSchema: 

681 """Generate core schema. 

682 

683 Args: 

684 obj: The object to generate core schema for. 

685 

686 Returns: 

687 The generated core schema. 

688 

689 Raises: 

690 PydanticUndefinedAnnotation: 

691 If it is not possible to evaluate forward reference. 

692 PydanticSchemaGenerationError: 

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

694 TypeError: 

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

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

697 PydanticUserError: 

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

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

700 """ 

701 schema = self._generate_schema_from_get_schema_method(obj, obj) 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

702 

703 if schema is None: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

704 schema = self._generate_schema_inner(obj) 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

705 

706 metadata_js_function = _extract_get_pydantic_json_schema(obj) 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

707 if metadata_js_function is not None: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

708 metadata_schema = resolve_original_schema(schema, self.defs) 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

709 if metadata_schema: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

710 self._add_js_function(metadata_schema, metadata_js_function) 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

711 

712 schema = _add_custom_serialization_from_json_encoders(self._config_wrapper.json_encoders, obj, schema) 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

713 

714 return schema 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

715 

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

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

718 BaseModel_ = import_cached_base_model() 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

719 

720 with self.defs.get_schema_or_ref(cls) as (model_ref, maybe_schema): 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

721 if maybe_schema is not None: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

722 return maybe_schema 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

723 

724 schema = cls.__dict__.get('__pydantic_core_schema__') 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

725 if schema is not None and not isinstance(schema, MockCoreSchema): 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

726 if schema['type'] == 'definitions': 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

727 schema = self.defs.unpack_definitions(schema) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

728 ref = get_ref(schema) 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

729 if ref: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

730 return self.defs.create_definition_reference_schema(schema) 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

731 else: 

732 return schema 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

733 

734 config_wrapper = ConfigWrapper(cls.model_config, check=False) 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

735 

736 with self._config_wrapper_stack.push(config_wrapper), self._ns_resolver.push(cls): 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

737 core_config = self._config_wrapper.core_config(title=cls.__name__) 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

738 

739 if cls.__pydantic_fields_complete__ or cls is BaseModel_: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

740 fields = getattr(cls, '__pydantic_fields__', {}) 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

741 else: 

742 try: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

743 fields = rebuild_model_fields( 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

744 cls, 

745 ns_resolver=self._ns_resolver, 

746 typevars_map=self._typevars_map or {}, 

747 ) 

748 except NameError as e: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

749 raise PydanticUndefinedAnnotation.from_name_error(e) from e 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

750 

751 decorators = cls.__pydantic_decorators__ 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

752 computed_fields = decorators.computed_fields 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

753 check_decorator_fields_exist( 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

754 chain( 

755 decorators.field_validators.values(), 

756 decorators.field_serializers.values(), 

757 decorators.validators.values(), 

758 ), 

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

760 ) 

761 

762 model_validators = decorators.model_validators.values() 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

763 

764 extras_schema = None 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

765 extras_keys_schema = None 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

766 if core_config.get('extra_fields_behavior') == 'allow': 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

767 assert cls.__mro__[0] is cls 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

768 assert cls.__mro__[-1] is object 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

769 for candidate_cls in cls.__mro__[:-1]: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

770 extras_annotation = getattr(candidate_cls, '__annotations__', {}).get( 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

771 '__pydantic_extra__', None 

772 ) 

773 if extras_annotation is not None: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

774 if isinstance(extras_annotation, str): 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

775 extras_annotation = _typing_extra.eval_type_backport( 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

776 _typing_extra._make_forward_ref( 

777 extras_annotation, is_argument=False, is_class=True 

778 ), 

779 *self._types_namespace, 

780 ) 

781 tp = get_origin(extras_annotation) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

782 if tp not in DICT_TYPES: 782 ↛ 783line 782 didn't jump to line 783 because the condition on line 782 was never true1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

783 raise PydanticSchemaGenerationError( 

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

785 ) 

786 extra_keys_type, extra_items_type = self._get_args_resolving_forward_refs( 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

787 extras_annotation, 

788 required=True, 

789 ) 

790 if extra_keys_type is not str: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

791 extras_keys_schema = self.generate_schema(extra_keys_type) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

792 if not typing_objects.is_any(extra_items_type): 792 ↛ 794line 792 didn't jump to line 794 because the condition on line 792 was always true1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

793 extras_schema = self.generate_schema(extra_items_type) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

794 if extras_keys_schema is not None or extras_schema is not None: 794 ↛ 769line 794 didn't jump to line 769 because the condition on line 794 was always true1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

795 break 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

796 

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

798 

799 if cls.__pydantic_root_model__: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

800 root_field = self._common_field_schema('root', fields['root'], decorators) 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

801 inner_schema = root_field['schema'] 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

802 inner_schema = apply_model_validators(inner_schema, model_validators, 'inner') 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

803 model_schema = core_schema.model_schema( 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

804 cls, 

805 inner_schema, 

806 generic_origin=generic_origin, 

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

808 root_model=True, 

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

810 config=core_config, 

811 ref=model_ref, 

812 ) 

813 else: 

814 fields_schema: core_schema.CoreSchema = core_schema.model_fields_schema( 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

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

816 computed_fields=[ 

817 self._computed_field_schema(d, decorators.field_serializers) 

818 for d in computed_fields.values() 

819 ], 

820 extras_schema=extras_schema, 

821 extras_keys_schema=extras_keys_schema, 

822 model_name=cls.__name__, 

823 ) 

824 inner_schema = apply_validators(fields_schema, decorators.root_validators.values()) 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

825 inner_schema = apply_model_validators(inner_schema, model_validators, 'inner') 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

826 

827 model_schema = core_schema.model_schema( 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

828 cls, 

829 inner_schema, 

830 generic_origin=generic_origin, 

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

832 root_model=False, 

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

834 config=core_config, 

835 ref=model_ref, 

836 ) 

837 

838 schema = self._apply_model_serializers(model_schema, decorators.model_serializers.values()) 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

839 schema = apply_model_validators(schema, model_validators, 'outer') 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

840 return self.defs.create_definition_reference_schema(schema) 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

841 

842 def _resolve_self_type(self, obj: Any) -> Any: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

843 obj = self.model_type_stack.get() 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

844 if obj is None: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

846 return obj 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

847 

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

849 BaseModel_ = import_cached_base_model() 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

850 

851 get_schema = getattr(obj, '__get_pydantic_core_schema__', None) 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

852 is_base_model_get_schema = ( 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

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

854 ) 

855 

856 if ( 1abkcfgOdh

857 get_schema is not None 

858 # BaseModel.__get_pydantic_core_schema__ is defined for backwards compatibility, 

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

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

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

862 # don't call the method: 

863 and not is_base_model_get_schema 

864 ): 

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

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

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

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

869 # not referenceable: 

870 with self.defs.get_schema_or_ref(obj) as (_, maybe_schema): 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

871 if maybe_schema is not None: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

872 return maybe_schema 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

873 

874 if obj is source: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

875 ref_mode = 'unpack' 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

876 else: 

877 ref_mode = 'to-def' 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

878 schema = get_schema( 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

880 ) 

881 if schema['type'] == 'definitions': 881 ↛ 882line 881 didn't jump to line 882 because the condition on line 881 was never true1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

882 schema = self.defs.unpack_definitions(schema) 

883 

884 ref = get_ref(schema) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

885 if ref: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

886 return self.defs.create_definition_reference_schema(schema) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

887 

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

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

890 return schema 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

891 

892 if get_schema is None and (validators := getattr(obj, '__get_validators__', None)) is not None: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

893 from pydantic.v1 import BaseModel as BaseModelV1 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

894 

895 if issubclass(obj, BaseModelV1): 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

896 warn( 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

898 UserWarning, 

899 ) 

900 else: 

901 warn( 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

903 PydanticDeprecatedSince20, 

904 ) 

905 return core_schema.chain_schema([core_schema.with_info_plain_validator_function(v) for v in validators()]) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

906 

907 def _resolve_forward_ref(self, obj: Any) -> Any: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

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

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

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

911 # `Validator(SomeImportedTypeAliasWithAForwardReference)` 

912 # or the equivalent for BaseModel 

913 # class Model(BaseModel): 

914 # x: SomeImportedTypeAliasWithAForwardReference 

915 try: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

916 obj = _typing_extra.eval_type_backport(obj, *self._types_namespace) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

917 except NameError as e: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

918 raise PydanticUndefinedAnnotation.from_name_error(e) from e 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

919 

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

921 if isinstance(obj, ForwardRef): 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

923 

924 if self._typevars_map: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

925 obj = replace_types(obj, self._typevars_map) 1abejkcfglmdhin

926 

927 return obj 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

928 

929 @overload 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

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

931 

932 @overload 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

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

934 

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

936 args = get_args(obj) 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

937 if args: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

938 if isinstance(obj, GenericAlias): 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

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

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

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

942 elif required: # pragma: no cover 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

944 return args 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

945 

946 def _get_first_arg_or_any(self, obj: Any) -> Any: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

947 args = self._get_args_resolving_forward_refs(obj) 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

948 if not args: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

949 return Any 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

950 return args[0] 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

951 

952 def _get_first_two_args_or_any(self, obj: Any) -> tuple[Any, Any]: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

953 args = self._get_args_resolving_forward_refs(obj) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

954 if not args: 954 ↛ 955line 954 didn't jump to line 955 because the condition on line 954 was never true1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

955 return (Any, Any) 

956 if len(args) < 2: 956 ↛ 957line 956 didn't jump to line 957 because the condition on line 956 was never true1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

957 origin = get_origin(obj) 

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

959 return args[0], args[1] 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

960 

961 def _generate_schema_inner(self, obj: Any) -> core_schema.CoreSchema: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

962 if typing_objects.is_self(obj): 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

963 obj = self._resolve_self_type(obj) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

964 

965 if typing_objects.is_annotated(get_origin(obj)): 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

966 return self._annotated_schema(obj) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

967 

968 if isinstance(obj, dict): 968 ↛ 970line 968 didn't jump to line 970 because the condition on line 968 was never true1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

969 # we assume this is already a valid schema 

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

971 

972 if isinstance(obj, str): 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

973 obj = ForwardRef(obj) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

974 

975 if isinstance(obj, ForwardRef): 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

976 return self.generate_schema(self._resolve_forward_ref(obj)) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

977 

978 BaseModel = import_cached_base_model() 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

979 

980 if lenient_issubclass(obj, BaseModel): 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

981 with self.model_type_stack.push(obj): 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

982 return self._model_schema(obj) 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

983 

984 if isinstance(obj, PydanticRecursiveRef): 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

985 return core_schema.definition_reference_schema(schema_ref=obj.type_ref) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

986 

987 return self.match_type(obj) 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

988 

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

990 """Main mapping of types to schemas. 

991 

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

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

994 

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

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

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

998 

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

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

1001 """ 

1002 if obj is str: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1003 return core_schema.str_schema() 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1004 elif obj is bytes: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1005 return core_schema.bytes_schema() 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1006 elif obj is int: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1007 return core_schema.int_schema() 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1008 elif obj is float: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1009 return core_schema.float_schema() 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1010 elif obj is bool: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1011 return core_schema.bool_schema() 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1012 elif obj is complex: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1013 return core_schema.complex_schema() 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1014 elif typing_objects.is_any(obj) or obj is object: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1015 return core_schema.any_schema() 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1016 elif obj is datetime.date: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1017 return core_schema.date_schema() 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1018 elif obj is datetime.datetime: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1019 return core_schema.datetime_schema() 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1020 elif obj is datetime.time: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1021 return core_schema.time_schema() 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1022 elif obj is datetime.timedelta: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1023 return core_schema.timedelta_schema() 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1024 elif obj is Decimal: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1025 return core_schema.decimal_schema() 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1026 elif obj is UUID: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1027 return core_schema.uuid_schema() 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1028 elif obj is Url: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1029 return core_schema.url_schema() 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1030 elif obj is Fraction: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1031 return self._fraction_schema() 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1032 elif obj is MultiHostUrl: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1033 return core_schema.multi_host_url_schema() 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1034 elif obj is None or obj is _typing_extra.NoneType: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1035 return core_schema.none_schema() 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1036 elif obj in IP_TYPES: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1037 return self._ip_schema(obj) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1038 elif obj in TUPLE_TYPES: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1039 return self._tuple_schema(obj) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1040 elif obj in LIST_TYPES: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1041 return self._list_schema(Any) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1042 elif obj in SET_TYPES: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1043 return self._set_schema(Any) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1044 elif obj in FROZEN_SET_TYPES: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1045 return self._frozenset_schema(Any) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1046 elif obj in SEQUENCE_TYPES: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1047 return self._sequence_schema(Any) 1aeouAdipvB

1048 elif obj in ITERABLE_TYPES: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1049 return self._iterable_schema(obj) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1050 elif obj in DICT_TYPES: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1051 return self._dict_schema(Any, Any) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1052 elif obj in PATH_TYPES: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1053 return self._path_schema(obj, Any) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1054 elif obj in DEQUE_TYPES: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1055 return self._deque_schema(Any) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1056 elif obj in MAPPING_TYPES: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1057 return self._mapping_schema(obj, Any, Any) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1058 elif obj in COUNTER_TYPES: 1058 ↛ 1059line 1058 didn't jump to line 1059 because the condition on line 1058 was never true1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

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

1060 elif typing_objects.is_typealiastype(obj): 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1061 return self._type_alias_type_schema(obj) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1062 elif obj is type: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1063 return self._type_schema() 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1064 elif _typing_extra.is_callable(obj): 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1065 return core_schema.callable_schema() 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1066 elif typing_objects.is_literal(get_origin(obj)): 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1067 return self._literal_schema(obj) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1068 elif is_typeddict(obj): 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1069 return self._typed_dict_schema(obj, None) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1070 elif _typing_extra.is_namedtuple(obj): 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1071 return self._namedtuple_schema(obj, None) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1072 elif typing_objects.is_newtype(obj): 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

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

1074 return self.generate_schema(obj.__supertype__) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1075 elif obj in PATTERN_TYPES: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1076 return self._pattern_schema(obj) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1077 elif _typing_extra.is_hashable(obj): 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1078 return self._hashable_schema() 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1079 elif isinstance(obj, typing.TypeVar): 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1080 return self._unsubstituted_typevar_schema(obj) 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1081 elif _typing_extra.is_finalvar(obj): 1081 ↛ 1082line 1081 didn't jump to line 1082 because the condition on line 1081 was never true1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1082 if obj is Final: 

1083 return core_schema.any_schema() 

1084 return self.generate_schema( 

1085 self._get_first_arg_or_any(obj), 

1086 ) 

1087 elif isinstance(obj, VALIDATE_CALL_SUPPORTED_TYPES): 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1088 return self._call_schema(obj) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1089 elif inspect.isclass(obj) and issubclass(obj, Enum): 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1090 return self._enum_schema(obj) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1091 elif obj is ZoneInfo: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1092 return self._zoneinfo_schema() 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1093 

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

1095 # the case of a dc type here 

1096 if dataclasses.is_dataclass(obj): 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

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

1098 

1099 origin = get_origin(obj) 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1100 if origin is not None: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1101 return self._match_generic_type(obj, origin) 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1102 

1103 if self._arbitrary_types: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1104 return self._arbitrary_type_schema(obj) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1105 return self._unknown_type_schema(obj) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1106 

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

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

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

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

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

1112 if dataclasses.is_dataclass(origin): 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

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

1114 if _typing_extra.is_namedtuple(origin): 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1115 return self._namedtuple_schema(obj, origin) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1116 

1117 schema = self._generate_schema_from_get_schema_method(origin, obj) 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1118 if schema is not None: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1119 return schema 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1120 

1121 if typing_objects.is_typealiastype(origin): 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1122 return self._type_alias_type_schema(obj) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1123 elif is_union_origin(origin): 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1124 return self._union_schema(obj) 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1125 elif origin in TUPLE_TYPES: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1126 return self._tuple_schema(obj) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1127 elif origin in LIST_TYPES: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1128 return self._list_schema(self._get_first_arg_or_any(obj)) 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1129 elif origin in SET_TYPES: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1130 return self._set_schema(self._get_first_arg_or_any(obj)) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1131 elif origin in FROZEN_SET_TYPES: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1132 return self._frozenset_schema(self._get_first_arg_or_any(obj)) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1133 elif origin in DICT_TYPES: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1134 return self._dict_schema(*self._get_first_two_args_or_any(obj)) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1135 elif origin in PATH_TYPES: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1136 return self._path_schema(origin, self._get_first_arg_or_any(obj)) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1137 elif origin in DEQUE_TYPES: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1138 return self._deque_schema(self._get_first_arg_or_any(obj)) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1139 elif origin in MAPPING_TYPES: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1140 return self._mapping_schema(origin, *self._get_first_two_args_or_any(obj)) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1141 elif origin in COUNTER_TYPES: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1142 return self._mapping_schema(origin, self._get_first_arg_or_any(obj), int) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1143 elif is_typeddict(origin): 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1144 return self._typed_dict_schema(obj, origin) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1145 elif origin in TYPE_TYPES: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1146 return self._subclass_schema(obj) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1147 elif origin in SEQUENCE_TYPES: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1148 return self._sequence_schema(self._get_first_arg_or_any(obj)) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1149 elif origin in ITERABLE_TYPES: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1150 return self._iterable_schema(obj) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1151 elif origin in PATTERN_TYPES: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1152 return self._pattern_schema(obj) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1153 

1154 if self._arbitrary_types: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1155 return self._arbitrary_type_schema(origin) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1156 return self._unknown_type_schema(obj) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1157 

1158 def _generate_td_field_schema( 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1159 self, 

1160 name: str, 

1161 field_info: FieldInfo, 

1162 decorators: DecoratorInfos, 

1163 *, 

1164 required: bool = True, 

1165 ) -> core_schema.TypedDictField: 

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

1167 common_field = self._common_field_schema(name, field_info, decorators) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1168 return core_schema.typed_dict_field( 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1169 common_field['schema'], 

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

1171 serialization_exclude=common_field['serialization_exclude'], 

1172 validation_alias=common_field['validation_alias'], 

1173 serialization_alias=common_field['serialization_alias'], 

1174 metadata=common_field['metadata'], 

1175 ) 

1176 

1177 def _generate_md_field_schema( 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1178 self, 

1179 name: str, 

1180 field_info: FieldInfo, 

1181 decorators: DecoratorInfos, 

1182 ) -> core_schema.ModelField: 

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

1184 common_field = self._common_field_schema(name, field_info, decorators) 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1185 return core_schema.model_field( 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1186 common_field['schema'], 

1187 serialization_exclude=common_field['serialization_exclude'], 

1188 validation_alias=common_field['validation_alias'], 

1189 serialization_alias=common_field['serialization_alias'], 

1190 frozen=common_field['frozen'], 

1191 metadata=common_field['metadata'], 

1192 ) 

1193 

1194 def _generate_dc_field_schema( 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1195 self, 

1196 name: str, 

1197 field_info: FieldInfo, 

1198 decorators: DecoratorInfos, 

1199 ) -> core_schema.DataclassField: 

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

1201 common_field = self._common_field_schema(name, field_info, decorators) 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1202 return core_schema.dataclass_field( 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1203 name, 

1204 common_field['schema'], 

1205 init=field_info.init, 

1206 init_only=field_info.init_var or None, 

1207 kw_only=None if field_info.kw_only else False, 

1208 serialization_exclude=common_field['serialization_exclude'], 

1209 validation_alias=common_field['validation_alias'], 

1210 serialization_alias=common_field['serialization_alias'], 

1211 frozen=common_field['frozen'], 

1212 metadata=common_field['metadata'], 

1213 ) 

1214 

1215 @staticmethod 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1216 def _apply_alias_generator_to_field_info( 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

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

1218 ) -> None: 

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

1220 

1221 Args: 

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

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

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

1225 """ 

1226 # Apply an alias_generator if 

1227 # 1. An alias is not specified 

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

1229 if ( 1abkcfgdh

1230 field_info.alias_priority is None 

1231 or field_info.alias_priority <= 1 

1232 or field_info.alias is None 

1233 or field_info.validation_alias is None 

1234 or field_info.serialization_alias is None 

1235 ): 

1236 alias, validation_alias, serialization_alias = None, None, None 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1237 

1238 if isinstance(alias_generator, AliasGenerator): 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1239 alias, validation_alias, serialization_alias = alias_generator.generate_aliases(field_name) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1240 elif isinstance(alias_generator, Callable): 1240 ↛ 1248line 1240 didn't jump to line 1248 because the condition on line 1240 was always true1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1241 alias = alias_generator(field_name) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1242 if not isinstance(alias, str): 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

1244 

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

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

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

1248 if field_info.alias_priority is None or field_info.alias_priority <= 1: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1249 field_info.alias_priority = 1 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1250 

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

1252 if field_info.alias_priority == 1: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1253 field_info.serialization_alias = _get_first_non_null(serialization_alias, alias) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1254 field_info.validation_alias = _get_first_non_null(validation_alias, alias) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1255 field_info.alias = alias 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1256 

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

1258 if field_info.alias is None: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1259 field_info.alias = alias 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1260 if field_info.serialization_alias is None: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1261 field_info.serialization_alias = _get_first_non_null(serialization_alias, alias) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1262 if field_info.validation_alias is None: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1263 field_info.validation_alias = _get_first_non_null(validation_alias, alias) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1264 

1265 @staticmethod 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1266 def _apply_alias_generator_to_computed_field_info( 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

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

1268 computed_field_info: ComputedFieldInfo, 

1269 computed_field_name: str, 

1270 ): 

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

1272 

1273 Args: 

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

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

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

1277 """ 

1278 # Apply an alias_generator if 

1279 # 1. An alias is not specified 

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

1281 

1282 if ( 1abkc

1283 computed_field_info.alias_priority is None 

1284 or computed_field_info.alias_priority <= 1 

1285 or computed_field_info.alias is None 

1286 ): 

1287 alias, validation_alias, serialization_alias = None, None, None 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1288 

1289 if isinstance(alias_generator, AliasGenerator): 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1290 alias, validation_alias, serialization_alias = alias_generator.generate_aliases(computed_field_name) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1291 elif isinstance(alias_generator, Callable): 1291 ↛ 1299line 1291 didn't jump to line 1299 because the condition on line 1291 was always true1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1292 alias = alias_generator(computed_field_name) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1293 if not isinstance(alias, str): 1293 ↛ 1294line 1293 didn't jump to line 1294 because the condition on line 1293 was never true1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

1295 

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

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

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

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

1300 computed_field_info.alias_priority = 1 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1301 

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

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

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

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

1306 computed_field_info.alias = _get_first_non_null(serialization_alias, alias) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1307 

1308 @staticmethod 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1309 def _apply_field_title_generator_to_field_info( 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

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

1311 ) -> None: 

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

1313 Args: 

1314 config_wrapper: The config of the model 

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

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

1317 """ 

1318 field_title_generator = field_info.field_title_generator or config_wrapper.field_title_generator 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1319 

1320 if field_title_generator is None: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1321 return 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1322 

1323 if field_info.title is None: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1324 title = field_title_generator(field_name, field_info) # type: ignore 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1325 if not isinstance(title, str): 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

1327 

1328 field_info.title = title 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1329 

1330 def _common_field_schema( # C901 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

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

1332 ) -> _CommonField: 

1333 source_type, annotations = field_info.annotation, field_info.metadata 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1334 

1335 def set_discriminator(schema: CoreSchema) -> CoreSchema: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1336 schema = self._apply_discriminator_to_union(schema, field_info.discriminator) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1337 return schema 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1338 

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

1340 validators_from_decorators = [] 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1341 for decorator in filter_field_decorator_info_by_field(decorators.field_validators.values(), name): 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1342 validators_from_decorators.append(_mode_to_validator[decorator.info.mode]._from_decorator(decorator)) 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1343 

1344 with self.field_name_stack.push(name): 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1345 if field_info.discriminator is not None: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1346 schema = self._apply_annotations( 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1347 source_type, annotations + validators_from_decorators, transform_inner_schema=set_discriminator 

1348 ) 

1349 else: 

1350 schema = self._apply_annotations( 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1351 source_type, 

1352 annotations + validators_from_decorators, 

1353 ) 

1354 

1355 # This V1 compatibility shim should eventually be removed 

1356 # push down any `each_item=True` validators 

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

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

1359 this_field_validators = filter_field_decorator_info_by_field(decorators.validators.values(), name) 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1360 if _validators_require_validate_default(this_field_validators): 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1361 field_info.validate_default = True 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1362 each_item_validators = [v for v in this_field_validators if v.info.each_item is True] 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1363 this_field_validators = [v for v in this_field_validators if v not in each_item_validators] 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1364 schema = apply_each_item_validators(schema, each_item_validators) 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1365 

1366 schema = apply_validators(schema, this_field_validators) 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1367 

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

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

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

1371 if not field_info.is_required(): 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1372 schema = wrap_default(field_info, schema) 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1373 

1374 schema = self._apply_field_serializers( 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

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

1376 ) 

1377 self._apply_field_title_generator_to_field_info(self._config_wrapper, field_info, name) 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1378 

1379 pydantic_js_updates, pydantic_js_extra = _extract_json_schema_info_from_field_info(field_info) 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1380 core_metadata: dict[str, Any] = {} 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1381 update_core_metadata( 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1382 core_metadata, pydantic_js_updates=pydantic_js_updates, pydantic_js_extra=pydantic_js_extra 

1383 ) 

1384 

1385 alias_generator = self._config_wrapper.alias_generator 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1386 if alias_generator is not None: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1387 self._apply_alias_generator_to_field_info(alias_generator, field_info, name) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1388 

1389 if isinstance(field_info.validation_alias, (AliasChoices, AliasPath)): 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1390 validation_alias = field_info.validation_alias.convert_to_aliases() 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1391 else: 

1392 validation_alias = field_info.validation_alias 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1393 

1394 return _common_field( 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1395 schema, 

1396 serialization_exclude=True if field_info.exclude else None, 

1397 validation_alias=validation_alias, 

1398 serialization_alias=field_info.serialization_alias, 

1399 frozen=field_info.frozen, 

1400 metadata=core_metadata, 

1401 ) 

1402 

1403 def _union_schema(self, union_type: Any) -> core_schema.CoreSchema: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1404 """Generate schema for a Union.""" 

1405 args = self._get_args_resolving_forward_refs(union_type, required=True) 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1406 choices: list[CoreSchema] = [] 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1407 nullable = False 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1408 for arg in args: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1409 if arg is None or arg is _typing_extra.NoneType: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1410 nullable = True 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1411 else: 

1412 choices.append(self.generate_schema(arg)) 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1413 

1414 if len(choices) == 1: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1415 s = choices[0] 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1416 else: 

1417 choices_with_tags: list[CoreSchema | tuple[CoreSchema, str]] = [] 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1418 for choice in choices: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

1420 if tag is not None: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1421 choices_with_tags.append((choice, tag)) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1422 else: 

1423 choices_with_tags.append(choice) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1424 s = core_schema.union_schema(choices_with_tags) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1425 

1426 if nullable: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1427 s = core_schema.nullable_schema(s) 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1428 return s 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1429 

1430 def _type_alias_type_schema(self, obj: TypeAliasType) -> CoreSchema: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1431 with self.defs.get_schema_or_ref(obj) as (ref, maybe_schema): 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1432 if maybe_schema is not None: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1433 return maybe_schema 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1434 

1435 origin: TypeAliasType = get_origin(obj) or obj 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1436 typevars_map = get_standard_typevars_map(obj) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1437 

1438 with self._ns_resolver.push(origin): 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1439 try: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1440 annotation = _typing_extra.eval_type(origin.__value__, *self._types_namespace) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1441 except NameError as e: 

1442 raise PydanticUndefinedAnnotation.from_name_error(e) from e 

1443 annotation = replace_types(annotation, typevars_map) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1444 schema = self.generate_schema(annotation) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1445 assert schema['type'] != 'definitions' 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1446 schema['ref'] = ref # type: ignore 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1447 return self.defs.create_definition_reference_schema(schema) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1448 

1449 def _literal_schema(self, literal_type: Any) -> CoreSchema: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1450 """Generate schema for a Literal.""" 

1451 expected = list(get_literal_values(literal_type, type_check=False, unpack_type_aliases='eager')) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

1453 schema = core_schema.literal_schema(expected) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1454 

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

1456 schema = core_schema.no_info_after_validator_function( 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

1458 ) 

1459 

1460 return schema 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1461 

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

1463 """Generate a core schema for a `TypedDict` class. 

1464 

1465 To be able to build a `DecoratorInfos` instance for the `TypedDict` class (which will include 

1466 validators, serializers, etc.), we need to have access to the original bases of the class 

1467 (see https://docs.python.org/3/library/types.html#types.get_original_bases). 

1468 However, the `__orig_bases__` attribute was only added in 3.12 (https://github.com/python/cpython/pull/103698). 

1469 

1470 For this reason, we require Python 3.12 (or using the `typing_extensions` backport). 

1471 """ 

1472 FieldInfo = import_cached_field_info() 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1473 

1474 with ( 1abejoqkcfglmrsdhinpt

1475 self.model_type_stack.push(typed_dict_cls), 

1476 self.defs.get_schema_or_ref(typed_dict_cls) as ( 

1477 typed_dict_ref, 

1478 maybe_schema, 

1479 ), 

1480 ): 

1481 if maybe_schema is not None: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1482 return maybe_schema 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1483 

1484 typevars_map = get_standard_typevars_map(typed_dict_cls) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1485 if origin is not None: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1486 typed_dict_cls = origin 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1487 

1488 if not _SUPPORTS_TYPEDDICT and type(typed_dict_cls).__module__ == 'typing': 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1489 raise PydanticUserError( 1abejoqkcfglmrsdhinpt

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

1491 code='typed-dict-version', 

1492 ) 

1493 

1494 try: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

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

1497 config: ConfigDict | None = get_attribute_from_bases(typed_dict_cls, '__pydantic_config__') 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1498 except AttributeError: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1499 config = None 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1500 

1501 with self._config_wrapper_stack.push(config): 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1502 core_config = self._config_wrapper.core_config(title=typed_dict_cls.__name__) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1503 

1504 required_keys: frozenset[str] = typed_dict_cls.__required_keys__ 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1505 

1506 fields: dict[str, core_schema.TypedDictField] = {} 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1507 

1508 decorators = DecoratorInfos.build(typed_dict_cls) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1509 

1510 if self._config_wrapper.use_attribute_docstrings: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1511 field_docstrings = extract_docstrings_from_cls(typed_dict_cls, use_inspect=True) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1512 else: 

1513 field_docstrings = None 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1514 

1515 try: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1516 annotations = _typing_extra.get_cls_type_hints(typed_dict_cls, ns_resolver=self._ns_resolver) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1517 except NameError as e: 

1518 raise PydanticUndefinedAnnotation.from_name_error(e) from e 

1519 

1520 readonly_fields: list[str] = [] 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1521 

1522 for field_name, annotation in annotations.items(): 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1523 field_info = FieldInfo.from_annotation(annotation, _source=AnnotationSource.TYPED_DICT) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1524 field_info.annotation = replace_types(field_info.annotation, typevars_map) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1525 

1526 required = ( 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1527 field_name in required_keys or 'required' in field_info._qualifiers 

1528 ) and 'not_required' not in field_info._qualifiers 

1529 if 'read_only' in field_info._qualifiers: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1530 readonly_fields.append(field_name) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1531 

1532 if ( 1abkcfgdh

1533 field_docstrings is not None 

1534 and field_info.description is None 

1535 and field_name in field_docstrings 

1536 ): 

1537 field_info.description = field_docstrings[field_name] 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1538 self._apply_field_title_generator_to_field_info(self._config_wrapper, field_info, field_name) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1539 fields[field_name] = self._generate_td_field_schema( 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1540 field_name, field_info, decorators, required=required 

1541 ) 

1542 

1543 if readonly_fields: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1544 fields_repr = ', '.join(repr(f) for f in readonly_fields) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1545 plural = len(readonly_fields) >= 2 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1546 warnings.warn( 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1547 f'Item{"s" if plural else ""} {fields_repr} on TypedDict class {typed_dict_cls.__name__!r} ' 

1548 f'{"are" if plural else "is"} using the `ReadOnly` qualifier. Pydantic will not protect items ' 

1549 'from any mutation on dictionary instances.', 

1550 UserWarning, 

1551 ) 

1552 

1553 td_schema = core_schema.typed_dict_schema( 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1554 fields, 

1555 cls=typed_dict_cls, 

1556 computed_fields=[ 

1557 self._computed_field_schema(d, decorators.field_serializers) 

1558 for d in decorators.computed_fields.values() 

1559 ], 

1560 ref=typed_dict_ref, 

1561 config=core_config, 

1562 ) 

1563 

1564 schema = self._apply_model_serializers(td_schema, decorators.model_serializers.values()) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1565 schema = apply_model_validators(schema, decorators.model_validators.values(), 'all') 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1566 return self.defs.create_definition_reference_schema(schema) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1567 

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

1569 """Generate schema for a NamedTuple.""" 

1570 with ( 1abejoqkcfglmrsdhinpt

1571 self.model_type_stack.push(namedtuple_cls), 

1572 self.defs.get_schema_or_ref(namedtuple_cls) as ( 

1573 namedtuple_ref, 

1574 maybe_schema, 

1575 ), 

1576 ): 

1577 if maybe_schema is not None: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1578 return maybe_schema 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1579 typevars_map = get_standard_typevars_map(namedtuple_cls) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1580 if origin is not None: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1581 namedtuple_cls = origin 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1582 

1583 try: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1584 annotations = _typing_extra.get_cls_type_hints(namedtuple_cls, ns_resolver=self._ns_resolver) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1585 except NameError as e: 

1586 raise PydanticUndefinedAnnotation.from_name_error(e) from e 

1587 if not annotations: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

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

1590 

1591 if typevars_map: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1592 annotations = { 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1593 field_name: replace_types(annotation, typevars_map) 

1594 for field_name, annotation in annotations.items() 

1595 } 

1596 

1597 arguments_schema = core_schema.arguments_schema( 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1598 [ 

1599 self._generate_parameter_schema( 

1600 field_name, 

1601 annotation, 

1602 source=AnnotationSource.NAMED_TUPLE, 

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

1604 ) 

1605 for field_name, annotation in annotations.items() 

1606 ], 

1607 metadata={'pydantic_js_prefer_positional_arguments': True}, 

1608 ) 

1609 schema = core_schema.call_schema(arguments_schema, namedtuple_cls, ref=namedtuple_ref) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1610 return self.defs.create_definition_reference_schema(schema) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1611 

1612 def _generate_parameter_schema( 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1613 self, 

1614 name: str, 

1615 annotation: type[Any], 

1616 source: AnnotationSource, 

1617 default: Any = Parameter.empty, 

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

1619 ) -> core_schema.ArgumentsParameter: 

1620 """Generate the definition of a field in a namedtuple or a parameter in a function signature. 

1621 

1622 This definition is meant to be used for the `'arguments'` core schema, which will be replaced 

1623 in V3 by the `'arguments-v3`'. 

1624 """ 

1625 FieldInfo = import_cached_field_info() 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1626 

1627 if default is Parameter.empty: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1628 field = FieldInfo.from_annotation(annotation, _source=source) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1629 else: 

1630 field = FieldInfo.from_annotated_attribute(annotation, default, _source=source) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

1632 with self.field_name_stack.push(name): 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1633 schema = self._apply_annotations(field.annotation, [field]) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1634 

1635 if not field.is_required(): 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1636 schema = wrap_default(field, schema) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1637 

1638 parameter_schema = core_schema.arguments_parameter(name, schema) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1639 if mode is not None: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1640 parameter_schema['mode'] = mode 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1641 if field.alias is not None: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1642 parameter_schema['alias'] = field.alias 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1643 else: 

1644 alias_generator = self._config_wrapper.alias_generator 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

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

1647 elif callable(alias_generator): 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1648 parameter_schema['alias'] = alias_generator(name) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1649 return parameter_schema 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1650 

1651 def _generate_parameter_v3_schema( 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1652 self, 

1653 name: str, 

1654 annotation: Any, 

1655 source: AnnotationSource, 

1656 mode: Literal[ 

1657 'positional_only', 

1658 'positional_or_keyword', 

1659 'keyword_only', 

1660 'var_args', 

1661 'var_kwargs_uniform', 

1662 'var_kwargs_unpacked_typed_dict', 

1663 ], 

1664 default: Any = Parameter.empty, 

1665 ) -> core_schema.ArgumentsV3Parameter: 

1666 """Generate the definition of a parameter in a function signature. 

1667 

1668 This definition is meant to be used for the `'arguments-v3'` core schema, which will replace 

1669 the `'arguments`' schema in V3. 

1670 """ 

1671 FieldInfo = import_cached_field_info() 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1672 

1673 if default is Parameter.empty: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1674 field = FieldInfo.from_annotation(annotation, _source=source) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1675 else: 

1676 field = FieldInfo.from_annotated_attribute(annotation, default, _source=source) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1677 

1678 with self.field_name_stack.push(name): 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1679 schema = self._apply_annotations(field.annotation, [field]) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1680 

1681 if not field.is_required(): 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1682 schema = wrap_default(field, schema) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1683 

1684 parameter_schema = core_schema.arguments_v3_parameter( 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1685 name=name, 

1686 schema=schema, 

1687 mode=mode, 

1688 ) 

1689 if field.alias is not None: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1690 parameter_schema['alias'] = field.alias 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1691 else: 

1692 alias_generator = self._config_wrapper.alias_generator 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1693 if isinstance(alias_generator, AliasGenerator) and alias_generator.alias is not None: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1694 parameter_schema['alias'] = alias_generator.alias(name) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1695 elif callable(alias_generator): 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1696 parameter_schema['alias'] = alias_generator(name) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1697 

1698 return parameter_schema 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1699 

1700 def _tuple_schema(self, tuple_type: Any) -> core_schema.CoreSchema: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

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

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

1703 typevars_map = get_standard_typevars_map(tuple_type) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1704 params = self._get_args_resolving_forward_refs(tuple_type) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1705 

1706 if typevars_map and params: 1706 ↛ 1707line 1706 didn't jump to line 1707 because the condition on line 1706 was never true1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

1708 

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

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

1711 if not params: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1712 if tuple_type in TUPLE_TYPES: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1713 return core_schema.tuple_schema([core_schema.any_schema()], variadic_item_index=0) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1714 else: 

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

1716 return core_schema.tuple_schema([]) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1717 elif params[-1] is Ellipsis: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1718 if len(params) == 2: 1718 ↛ 1722line 1718 didn't jump to line 1722 because the condition on line 1718 was always true1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

1720 else: 

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

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

1723 elif len(params) == 1 and params[0] == (): 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

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

1726 return core_schema.tuple_schema([]) 1abejkcfglmdhin

1727 else: 

1728 return core_schema.tuple_schema([self.generate_schema(param) for param in params]) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1729 

1730 def _type_schema(self) -> core_schema.CoreSchema: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1731 return core_schema.custom_error_schema( 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1732 core_schema.is_instance_schema(type), 

1733 custom_error_type='is_type', 

1734 custom_error_message='Input should be a type', 

1735 ) 

1736 

1737 def _zoneinfo_schema(self) -> core_schema.CoreSchema: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

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

1739 from ._validators import validate_str_is_valid_iana_tz 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1740 

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

1742 return core_schema.no_info_plain_validator_function( 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1743 validate_str_is_valid_iana_tz, 

1744 serialization=core_schema.to_string_ser_schema(), 

1745 metadata=metadata, 

1746 ) 

1747 

1748 def _union_is_subclass_schema(self, union_type: Any) -> core_schema.CoreSchema: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

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

1750 args = self._get_args_resolving_forward_refs(union_type, required=True) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1751 return core_schema.union_schema([self.generate_schema(type[args]) for args in args]) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1752 

1753 def _subclass_schema(self, type_: Any) -> core_schema.CoreSchema: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

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

1755 type_param = self._get_first_arg_or_any(type_) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1756 

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

1758 type_param = _typing_extra.annotated_type(type_param) or type_param 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1759 

1760 if typing_objects.is_any(type_param): 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1761 return self._type_schema() 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1762 elif typing_objects.is_typealiastype(type_param): 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1763 return self.generate_schema(type[type_param.__value__]) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1764 elif typing_objects.is_typevar(type_param): 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1765 if type_param.__bound__: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1766 if is_union_origin(get_origin(type_param.__bound__)): 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1767 return self._union_is_subclass_schema(type_param.__bound__) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1768 return core_schema.is_subclass_schema(type_param.__bound__) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1769 elif type_param.__constraints__: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

1771 else: 

1772 return self._type_schema() 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1773 elif is_union_origin(get_origin(type_param)): 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1774 return self._union_is_subclass_schema(type_param) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1775 else: 

1776 if typing_objects.is_self(type_param): 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1777 type_param = self._resolve_self_type(type_param) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1778 if _typing_extra.is_generic_alias(type_param): 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1779 raise PydanticUserError( 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

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

1782 code=None, 

1783 ) 

1784 if not inspect.isclass(type_param): 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

1786 # so we handle it manually here 

1787 if type_param is None: 1787 ↛ 1789line 1787 didn't jump to line 1789 because the condition on line 1787 was always true1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1788 return core_schema.is_subclass_schema(_typing_extra.NoneType) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

1790 return core_schema.is_subclass_schema(type_param) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1791 

1792 def _sequence_schema(self, items_type: Any) -> core_schema.CoreSchema: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

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

1794 from ._serializers import serialize_sequence_via_list 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1795 

1796 item_type_schema = self.generate_schema(items_type) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1797 list_schema = core_schema.list_schema(item_type_schema) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1798 

1799 json_schema = smart_deepcopy(list_schema) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1800 python_schema = core_schema.is_instance_schema(typing.Sequence, cls_repr='Sequence') 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1801 if not typing_objects.is_any(items_type): 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1802 from ._validators import sequence_validator 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1803 

1804 python_schema = core_schema.chain_schema( 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

1806 ) 

1807 

1808 serialization = core_schema.wrap_serializer_function_ser_schema( 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1809 serialize_sequence_via_list, schema=item_type_schema, info_arg=True 

1810 ) 

1811 return core_schema.json_or_python_schema( 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1812 json_schema=json_schema, python_schema=python_schema, serialization=serialization 

1813 ) 

1814 

1815 def _iterable_schema(self, type_: Any) -> core_schema.GeneratorSchema: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

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

1817 item_type = self._get_first_arg_or_any(type_) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1818 

1819 return core_schema.generator_schema(self.generate_schema(item_type)) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1820 

1821 def _pattern_schema(self, pattern_type: Any) -> core_schema.CoreSchema: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1822 from . import _validators 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1823 

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

1825 ser = core_schema.plain_serializer_function_ser_schema( 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

1827 ) 

1828 if pattern_type is typing.Pattern or pattern_type is re.Pattern: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1829 # bare type 

1830 return core_schema.no_info_plain_validator_function( 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

1832 ) 

1833 

1834 param = self._get_args_resolving_forward_refs( 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1835 pattern_type, 

1836 required=True, 

1837 )[0] 

1838 if param is str: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1839 return core_schema.no_info_plain_validator_function( 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

1841 ) 

1842 elif param is bytes: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1843 return core_schema.no_info_plain_validator_function( 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

1845 ) 

1846 else: 

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

1848 

1849 def _hashable_schema(self) -> core_schema.CoreSchema: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1850 return core_schema.custom_error_schema( 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1851 schema=core_schema.json_or_python_schema( 

1852 json_schema=core_schema.chain_schema( 

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

1854 ), 

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

1856 ), 

1857 custom_error_type='is_hashable', 

1858 custom_error_message='Input should be hashable', 

1859 ) 

1860 

1861 def _dataclass_schema( 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

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

1863 ) -> core_schema.CoreSchema: 

1864 """Generate schema for a dataclass.""" 

1865 with ( 1abejoqkcfglmrsOJKLMNdhinpt

1866 self.model_type_stack.push(dataclass), 

1867 self.defs.get_schema_or_ref(dataclass) as ( 

1868 dataclass_ref, 

1869 maybe_schema, 

1870 ), 

1871 ): 

1872 if maybe_schema is not None: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1873 return maybe_schema 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1874 

1875 schema = dataclass.__dict__.get('__pydantic_core_schema__') 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1876 if schema is not None and not isinstance(schema, MockCoreSchema): 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1877 if schema['type'] == 'definitions': 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1878 schema = self.defs.unpack_definitions(schema) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1879 ref = get_ref(schema) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1880 if ref: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1881 return self.defs.create_definition_reference_schema(schema) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1882 else: 

1883 return schema 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1884 

1885 typevars_map = get_standard_typevars_map(dataclass) 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1886 if origin is not None: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1887 dataclass = origin 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1888 

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

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

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

1892 config = getattr(dataclass, '__pydantic_config__', None) 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1893 

1894 from ..dataclasses import is_pydantic_dataclass 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1895 

1896 with self._ns_resolver.push(dataclass), self._config_wrapper_stack.push(config): 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1897 if is_pydantic_dataclass(dataclass): 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

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

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

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

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

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

1903 if typevars_map: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1904 for field in fields.values(): 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1905 field.apply_typevars_map(typevars_map, *self._types_namespace) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1906 else: 

1907 fields = collect_dataclass_fields( 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1908 dataclass, 

1909 typevars_map=typevars_map, 

1910 config_wrapper=self._config_wrapper, 

1911 ) 

1912 

1913 if self._config_wrapper.extra == 'allow': 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

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

1915 for field_name, field in fields.items(): 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1916 if field.init is False: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1917 raise PydanticUserError( 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

1919 f'This combination is not allowed.', 

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

1921 ) 

1922 

1923 decorators = dataclass.__dict__.get('__pydantic_decorators__') or DecoratorInfos.build(dataclass) 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

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

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

1926 args = sorted( 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

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

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

1929 ) 

1930 has_post_init = hasattr(dataclass, '__post_init__') 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1931 has_slots = hasattr(dataclass, '__slots__') 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1932 

1933 args_schema = core_schema.dataclass_args_schema( 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1934 dataclass.__name__, 

1935 args, 

1936 computed_fields=[ 

1937 self._computed_field_schema(d, decorators.field_serializers) 

1938 for d in decorators.computed_fields.values() 

1939 ], 

1940 collect_init_only=has_post_init, 

1941 ) 

1942 

1943 inner_schema = apply_validators(args_schema, decorators.root_validators.values()) 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1944 

1945 model_validators = decorators.model_validators.values() 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1946 inner_schema = apply_model_validators(inner_schema, model_validators, 'inner') 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1947 

1948 core_config = self._config_wrapper.core_config(title=dataclass.__name__) 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1949 

1950 dc_schema = core_schema.dataclass_schema( 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1951 dataclass, 

1952 inner_schema, 

1953 generic_origin=origin, 

1954 post_init=has_post_init, 

1955 ref=dataclass_ref, 

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

1957 slots=has_slots, 

1958 config=core_config, 

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

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

1961 frozen=self._config_wrapper_stack.tail.frozen, 

1962 ) 

1963 schema = self._apply_model_serializers(dc_schema, decorators.model_serializers.values()) 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1964 schema = apply_model_validators(schema, model_validators, 'outer') 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1965 return self.defs.create_definition_reference_schema(schema) 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1966 

1967 def _call_schema(self, function: ValidateCallSupportedTypes) -> core_schema.CallSchema: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1968 """Generate schema for a Callable. 

1969 

1970 TODO support functional validators once we support them in Config 

1971 """ 

1972 arguments_schema = self._arguments_schema(function) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1973 

1974 return_schema: core_schema.CoreSchema | None = None 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1975 config_wrapper = self._config_wrapper 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1976 if config_wrapper.validate_return: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1977 sig = signature(function) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1978 return_hint = sig.return_annotation 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1979 if return_hint is not sig.empty: 1979 ↛ 1986line 1979 didn't jump to line 1986 because the condition on line 1979 was always true1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1980 globalns, localns = self._types_namespace 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1981 type_hints = _typing_extra.get_function_type_hints( 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1982 function, globalns=globalns, localns=localns, include_keys={'return'} 

1983 ) 

1984 return_schema = self.generate_schema(type_hints['return']) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1985 

1986 return core_schema.call_schema( 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1987 arguments_schema, 

1988 function, 

1989 return_schema=return_schema, 

1990 ) 

1991 

1992 def _arguments_schema( 1abejoquwACDfglmrsxyEFGOJKLMNPdhinptvzBHI

1993 self, function: ValidateCallSupportedTypes, parameters_callback: ParametersCallback | None = None 

1994 ) -> core_schema.ArgumentsSchema: 

1995 """Generate schema for a Signature.""" 

1996 mode_lookup: dict[_ParameterKind, Literal['positional_only', 'positional_or_keyword', 'keyword_only']] = { 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1997 Parameter.POSITIONAL_ONLY: 'positional_only', 

1998 Parameter.POSITIONAL_OR_KEYWORD: 'positional_or_keyword', 

1999 Parameter.KEYWORD_ONLY: 'keyword_only', 

2000 } 

2001 

2002 sig = signature(function) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2003 globalns, localns = self._types_namespace 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2004 type_hints = _typing_extra.get_function_type_hints(function, globalns=globalns, localns=localns) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2005 

2006 arguments_list: list[core_schema.ArgumentsParameter] = [] 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2007 var_args_schema: core_schema.CoreSchema | None = None 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2008 var_kwargs_schema: core_schema.CoreSchema | None = None 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2009 var_kwargs_mode: core_schema.VarKwargsMode | None = None 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2010 

2011 for i, (name, p) in enumerate(sig.parameters.items()): 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2012 if p.annotation is sig.empty: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2013 annotation = typing.cast(Any, Any) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2014 else: 

2015 annotation = type_hints[name] 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2016 

2017 if parameters_callback is not None: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2018 result = parameters_callback(i, name, annotation) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2019 if result == 'skip': 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2020 continue 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2021 

2022 parameter_mode = mode_lookup.get(p.kind) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2023 if parameter_mode is not None: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2024 arg_schema = self._generate_parameter_schema( 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2025 name, annotation, AnnotationSource.FUNCTION, p.default, parameter_mode 

2026 ) 

2027 arguments_list.append(arg_schema) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2028 elif p.kind == Parameter.VAR_POSITIONAL: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2029 var_args_schema = self.generate_schema(annotation) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2030 else: 

2031 assert p.kind == Parameter.VAR_KEYWORD, p.kind 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2032 

2033 unpack_type = _typing_extra.unpack_type(annotation) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2034 if unpack_type is not None: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2035 origin = get_origin(unpack_type) or unpack_type 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2036 if not is_typeddict(origin): 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2037 raise PydanticUserError( 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2038 f'Expected a `TypedDict` class inside `Unpack[...]`, got {unpack_type!r}', 

2039 code='unpack-typed-dict', 

2040 ) 

2041 non_pos_only_param_names = { 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

2043 } 

2044 overlapping_params = non_pos_only_param_names.intersection(origin.__annotations__) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2045 if overlapping_params: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2046 raise PydanticUserError( 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2047 f'Typed dictionary {origin.__name__!r} overlaps with parameter' 

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

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

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

2051 ) 

2052 

2053 var_kwargs_mode = 'unpacked-typed-dict' 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2054 var_kwargs_schema = self._typed_dict_schema(unpack_type, get_origin(unpack_type)) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2055 else: 

2056 var_kwargs_mode = 'uniform' 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2057 var_kwargs_schema = self.generate_schema(annotation) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2058 

2059 return core_schema.arguments_schema( 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2060 arguments_list, 

2061 var_args_schema=var_args_schema, 

2062 var_kwargs_mode=var_kwargs_mode, 

2063 var_kwargs_schema=var_kwargs_schema, 

2064 validate_by_name=self._config_wrapper.validate_by_name, 

2065 ) 

2066 

2067 def _arguments_v3_schema( 1abejoquwACDfglmrsxyEFGOJKLMNPdhinptvzBHI

2068 self, function: ValidateCallSupportedTypes, parameters_callback: ParametersCallback | None = None 

2069 ) -> core_schema.ArgumentsV3Schema: 

2070 mode_lookup: dict[ 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2071 _ParameterKind, Literal['positional_only', 'positional_or_keyword', 'var_args', 'keyword_only'] 

2072 ] = { 

2073 Parameter.POSITIONAL_ONLY: 'positional_only', 

2074 Parameter.POSITIONAL_OR_KEYWORD: 'positional_or_keyword', 

2075 Parameter.VAR_POSITIONAL: 'var_args', 

2076 Parameter.KEYWORD_ONLY: 'keyword_only', 

2077 } 

2078 

2079 sig = signature(function) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2080 globalns, localns = self._types_namespace 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2081 type_hints = _typing_extra.get_function_type_hints(function, globalns=globalns, localns=localns) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2082 

2083 parameters_list: list[core_schema.ArgumentsV3Parameter] = [] 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2084 

2085 for i, (name, p) in enumerate(sig.parameters.items()): 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2086 if parameters_callback is not None: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2087 result = parameters_callback(i, name, p.annotation) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2088 if result == 'skip': 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2089 continue 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2090 

2091 if p.annotation is Parameter.empty: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2092 annotation = typing.cast(Any, Any) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2093 else: 

2094 annotation = type_hints[name] 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2095 

2096 parameter_mode = mode_lookup.get(p.kind) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2097 if parameter_mode is None: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2098 assert p.kind == Parameter.VAR_KEYWORD, p.kind 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2099 

2100 unpack_type = _typing_extra.unpack_type(annotation) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2101 if unpack_type is not None: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2102 origin = get_origin(unpack_type) or unpack_type 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2103 if not is_typeddict(origin): 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2104 raise PydanticUserError( 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2105 f'Expected a `TypedDict` class inside `Unpack[...]`, got {unpack_type!r}', 

2106 code='unpack-typed-dict', 

2107 ) 

2108 non_pos_only_param_names = { 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

2110 } 

2111 overlapping_params = non_pos_only_param_names.intersection(origin.__annotations__) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2112 if overlapping_params: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2113 raise PydanticUserError( 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2114 f'Typed dictionary {origin.__name__!r} overlaps with parameter' 

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

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

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

2118 ) 

2119 parameter_mode = 'var_kwargs_unpacked_typed_dict' 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2120 annotation = unpack_type 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2121 else: 

2122 parameter_mode = 'var_kwargs_uniform' 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2123 

2124 parameters_list.append( 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2125 self._generate_parameter_v3_schema( 

2126 name, annotation, AnnotationSource.FUNCTION, parameter_mode, default=p.default 

2127 ) 

2128 ) 

2129 

2130 return core_schema.arguments_v3_schema( 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2131 parameters_list, 

2132 validate_by_name=self._config_wrapper.validate_by_name, 

2133 ) 

2134 

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

2136 try: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2137 has_default = typevar.has_default() 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2138 except AttributeError: 1abejoquwkcfglmrsxyOJKLMNdhinptvz

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

2140 pass 1abejoquwkcfglmrsxyOJKLMNdhinptvz

2141 else: 

2142 if has_default: 1abejoquwACDkcfglmrsxyEFGPdhinptvzBHI

2143 return self.generate_schema(typevar.__default__) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2144 

2145 if constraints := typevar.__constraints__: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2146 return self._union_schema(typing.Union[constraints]) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2147 

2148 if bound := typevar.__bound__: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2149 schema = self.generate_schema(bound) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2150 schema['serialization'] = core_schema.wrap_serializer_function_ser_schema( 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2151 lambda x, h: h(x), 

2152 schema=core_schema.any_schema(), 

2153 ) 

2154 return schema 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2155 

2156 return core_schema.any_schema() 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2157 

2158 def _computed_field_schema( 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2159 self, 

2160 d: Decorator[ComputedFieldInfo], 

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

2162 ) -> core_schema.ComputedField: 

2163 if d.info.return_type is not PydanticUndefined: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2164 return_type = d.info.return_type 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2165 else: 

2166 try: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

2168 # Instead, let `get_callable_return_type` infer the globals to use, but still pass 

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

2170 return_type = _decorators.get_callable_return_type(d.func, localns=self._types_namespace.locals) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2171 except NameError as e: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2172 raise PydanticUndefinedAnnotation.from_name_error(e) from e 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2173 if return_type is PydanticUndefined: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2174 raise PydanticUserError( 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

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

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

2178 ) 

2179 

2180 return_type = replace_types(return_type, self._typevars_map) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

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

2183 d.info = dataclasses.replace(d.info, return_type=return_type) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2184 return_type_schema = self.generate_schema(return_type) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2185 # Apply serializers to computed field if there exist 

2186 return_type_schema = self._apply_field_serializers( 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2187 return_type_schema, 

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

2189 ) 

2190 

2191 alias_generator = self._config_wrapper.alias_generator 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2192 if alias_generator is not None: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2193 self._apply_alias_generator_to_computed_field_info( 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

2195 ) 

2196 self._apply_field_title_generator_to_field_info(self._config_wrapper, d.info, d.cls_var_name) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2197 

2198 pydantic_js_updates, pydantic_js_extra = _extract_json_schema_info_from_field_info(d.info) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2199 core_metadata: dict[str, Any] = {} 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2200 update_core_metadata( 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2201 core_metadata, 

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

2203 pydantic_js_extra=pydantic_js_extra, 

2204 ) 

2205 return core_schema.computed_field( 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

2207 ) 

2208 

2209 def _annotated_schema(self, annotated_type: Any) -> core_schema.CoreSchema: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

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

2211 FieldInfo = import_cached_field_info() 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2212 source_type, *annotations = self._get_args_resolving_forward_refs( 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2213 annotated_type, 

2214 required=True, 

2215 ) 

2216 schema = self._apply_annotations(source_type, annotations) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

2218 # even if there are function validators involved 

2219 for annotation in annotations: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2220 if isinstance(annotation, FieldInfo): 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2221 schema = wrap_default(annotation, schema) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2222 return schema 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2223 

2224 def _apply_annotations( 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2225 self, 

2226 source_type: Any, 

2227 annotations: list[Any], 

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

2229 ) -> CoreSchema: 

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

2231 

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

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

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

2235 """ 

2236 annotations = list(_known_annotated_metadata.expand_grouped_metadata(annotations)) 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2237 

2238 pydantic_js_annotation_functions: list[GetJsonSchemaFunction] = [] 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2239 

2240 def inner_handler(obj: Any) -> CoreSchema: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2241 schema = self._generate_schema_from_get_schema_method(obj, source_type) 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2242 

2243 if schema is None: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2244 schema = self._generate_schema_inner(obj) 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2245 

2246 metadata_js_function = _extract_get_pydantic_json_schema(obj) 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2247 if metadata_js_function is not None: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2248 metadata_schema = resolve_original_schema(schema, self.defs) 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2249 if metadata_schema is not None: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2250 self._add_js_function(metadata_schema, metadata_js_function) 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2251 return transform_inner_schema(schema) 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2252 

2253 get_inner_schema = CallbackGetCoreSchemaHandler(inner_handler, self) 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2254 

2255 for annotation in annotations: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2256 if annotation is None: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2257 continue 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2258 get_inner_schema = self._get_wrapped_inner_schema( 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2259 get_inner_schema, annotation, pydantic_js_annotation_functions 

2260 ) 

2261 

2262 schema = get_inner_schema(source_type) 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2263 if pydantic_js_annotation_functions: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2264 core_metadata = schema.setdefault('metadata', {}) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2265 update_core_metadata(core_metadata, pydantic_js_annotation_functions=pydantic_js_annotation_functions) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2266 return _add_custom_serialization_from_json_encoders(self._config_wrapper.json_encoders, source_type, schema) 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2267 

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

2269 FieldInfo = import_cached_field_info() 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2270 

2271 if isinstance(metadata, FieldInfo): 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2272 for field_metadata in metadata.metadata: 2272 ↛ 2273line 2272 didn't jump to line 2273 because the loop on line 2272 never started1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2273 schema = self._apply_single_annotation(schema, field_metadata) 

2274 

2275 if metadata.discriminator is not None: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2276 schema = self._apply_discriminator_to_union(schema, metadata.discriminator) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2277 return schema 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2278 

2279 if schema['type'] == 'nullable': 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

2281 inner = schema.get('schema', core_schema.any_schema()) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2282 inner = self._apply_single_annotation(inner, metadata) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2283 if inner: 2283 ↛ 2285line 2283 didn't jump to line 2285 because the condition on line 2283 was always true1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2284 schema['schema'] = inner 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2285 return schema 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2286 

2287 original_schema = schema 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2288 ref = schema.get('ref') 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2289 if ref is not None: 2289 ↛ 2290line 2289 didn't jump to line 2290 because the condition on line 2289 was never true1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2290 schema = schema.copy() 

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

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

2293 return existing 

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

2295 elif schema['type'] == 'definition-ref': 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2296 ref = schema['schema_ref'] 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

2298 schema = referenced_schema.copy() 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2299 new_ref = ref + f'_{repr(metadata)}' 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2300 if (existing := self.defs.get_schema_from_ref(new_ref)) is not None: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2301 return existing 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2302 schema['ref'] = new_ref # pyright: ignore[reportGeneralTypeIssues] 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2303 

2304 maybe_updated_schema = _known_annotated_metadata.apply_known_metadata(metadata, schema) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2305 

2306 if maybe_updated_schema is not None: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2307 return maybe_updated_schema 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2308 return original_schema 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2309 

2310 def _apply_single_annotation_json_schema( 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

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

2312 ) -> core_schema.CoreSchema: 

2313 FieldInfo = import_cached_field_info() 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2314 

2315 if isinstance(metadata, FieldInfo): 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2316 for field_metadata in metadata.metadata: 2316 ↛ 2317line 2316 didn't jump to line 2317 because the loop on line 2316 never started1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2317 schema = self._apply_single_annotation_json_schema(schema, field_metadata) 

2318 

2319 pydantic_js_updates, pydantic_js_extra = _extract_json_schema_info_from_field_info(metadata) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2320 core_metadata = schema.setdefault('metadata', {}) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2321 update_core_metadata( 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2322 core_metadata, pydantic_js_updates=pydantic_js_updates, pydantic_js_extra=pydantic_js_extra 

2323 ) 

2324 return schema 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2325 

2326 def _get_wrapped_inner_schema( 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2327 self, 

2328 get_inner_schema: GetCoreSchemaHandler, 

2329 annotation: Any, 

2330 pydantic_js_annotation_functions: list[GetJsonSchemaFunction], 

2331 ) -> CallbackGetCoreSchemaHandler: 

2332 annotation_get_schema: GetCoreSchemaFunction | None = getattr(annotation, '__get_pydantic_core_schema__', None) 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2333 

2334 def new_handler(source: Any) -> core_schema.CoreSchema: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2335 if annotation_get_schema is not None: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2336 schema = annotation_get_schema(source, get_inner_schema) 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2337 else: 

2338 schema = get_inner_schema(source) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2339 schema = self._apply_single_annotation(schema, annotation) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2340 schema = self._apply_single_annotation_json_schema(schema, annotation) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2341 

2342 metadata_js_function = _extract_get_pydantic_json_schema(annotation) 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2343 if metadata_js_function is not None: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2344 pydantic_js_annotation_functions.append(metadata_js_function) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2345 return schema 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2346 

2347 return CallbackGetCoreSchemaHandler(new_handler, self) 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2348 

2349 def _apply_field_serializers( 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2350 self, 

2351 schema: core_schema.CoreSchema, 

2352 serializers: list[Decorator[FieldSerializerDecoratorInfo]], 

2353 ) -> core_schema.CoreSchema: 

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

2355 if serializers: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2356 schema = copy(schema) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2357 if schema['type'] == 'definitions': 2357 ↛ 2358line 2357 didn't jump to line 2358 because the condition on line 2357 was never true1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2358 inner_schema = schema['schema'] 

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

2360 return schema 

2361 elif 'ref' in schema: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2362 schema = self.defs.create_definition_reference_schema(schema) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2363 

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

2365 serializer = serializers[-1] 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2366 is_field_serializer, info_arg = inspect_field_serializer(serializer.func, serializer.info.mode) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2367 

2368 if serializer.info.return_type is not PydanticUndefined: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2369 return_type = serializer.info.return_type 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2370 else: 

2371 try: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

2373 # Instead, let `get_callable_return_type` infer the globals to use, but still pass 

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

2375 return_type = _decorators.get_callable_return_type( 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2376 serializer.func, localns=self._types_namespace.locals 

2377 ) 

2378 except NameError as e: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2379 raise PydanticUndefinedAnnotation.from_name_error(e) from e 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2380 

2381 if return_type is PydanticUndefined: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2382 return_schema = None 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2383 else: 

2384 return_schema = self.generate_schema(return_type) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2385 

2386 if serializer.info.mode == 'wrap': 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2387 schema['serialization'] = core_schema.wrap_serializer_function_ser_schema( 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2388 serializer.func, 

2389 is_field_serializer=is_field_serializer, 

2390 info_arg=info_arg, 

2391 return_schema=return_schema, 

2392 when_used=serializer.info.when_used, 

2393 ) 

2394 else: 

2395 assert serializer.info.mode == 'plain' 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2396 schema['serialization'] = core_schema.plain_serializer_function_ser_schema( 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2397 serializer.func, 

2398 is_field_serializer=is_field_serializer, 

2399 info_arg=info_arg, 

2400 return_schema=return_schema, 

2401 when_used=serializer.info.when_used, 

2402 ) 

2403 return schema 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2404 

2405 def _apply_model_serializers( 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

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

2407 ) -> core_schema.CoreSchema: 

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

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

2410 if serializers: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2411 serializer = list(serializers)[-1] 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2412 info_arg = inspect_model_serializer(serializer.func, serializer.info.mode) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2413 

2414 if serializer.info.return_type is not PydanticUndefined: 2414 ↛ 2415line 2414 didn't jump to line 2415 because the condition on line 2414 was never true1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2415 return_type = serializer.info.return_type 

2416 else: 

2417 try: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

2419 # Instead, let `get_callable_return_type` infer the globals to use, but still pass 

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

2421 return_type = _decorators.get_callable_return_type( 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2422 serializer.func, localns=self._types_namespace.locals 

2423 ) 

2424 except NameError as e: 

2425 raise PydanticUndefinedAnnotation.from_name_error(e) from e 

2426 

2427 if return_type is PydanticUndefined: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2428 return_schema = None 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2429 else: 

2430 return_schema = self.generate_schema(return_type) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2431 

2432 if serializer.info.mode == 'wrap': 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2433 ser_schema: core_schema.SerSchema = core_schema.wrap_serializer_function_ser_schema( 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2434 serializer.func, 

2435 info_arg=info_arg, 

2436 return_schema=return_schema, 

2437 when_used=serializer.info.when_used, 

2438 ) 

2439 else: 

2440 # plain 

2441 ser_schema = core_schema.plain_serializer_function_ser_schema( 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2442 serializer.func, 

2443 info_arg=info_arg, 

2444 return_schema=return_schema, 

2445 when_used=serializer.info.when_used, 

2446 ) 

2447 schema['serialization'] = ser_schema 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2448 if ref: 2448 ↛ 2450line 2448 didn't jump to line 2450 because the condition on line 2448 was always true1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2449 schema['ref'] = ref # type: ignore 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2450 return schema 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2451 

2452 

2453_VALIDATOR_F_MATCH: Mapping[ 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

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

2455 Callable[[Callable[..., Any], core_schema.CoreSchema], core_schema.CoreSchema], 

2456] = { 

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

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

2459 ('plain', 'no-info'): lambda f, _: core_schema.no_info_plain_validator_function(f), 

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

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

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

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

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

2465} 

2466 

2467 

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

2469# be removed once we drop support for those. 

2470def apply_validators( 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2471 schema: core_schema.CoreSchema, 

2472 validators: Iterable[Decorator[RootValidatorDecoratorInfo]] 

2473 | Iterable[Decorator[ValidatorDecoratorInfo]] 

2474 | Iterable[Decorator[FieldValidatorDecoratorInfo]], 

2475) -> core_schema.CoreSchema: 

2476 """Apply validators to a schema. 

2477 

2478 Args: 

2479 schema: The schema to apply validators on. 

2480 validators: An iterable of validators. 

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

2482 

2483 Returns: 

2484 The updated schema. 

2485 """ 

2486 for validator in validators: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2487 info_arg = inspect_validator(validator.func, validator.info.mode) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2488 val_type = 'with-info' if info_arg else 'no-info' 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2489 

2490 schema = _VALIDATOR_F_MATCH[(validator.info.mode, val_type)](validator.func, schema) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2491 return schema 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2492 

2493 

2494def _validators_require_validate_default(validators: Iterable[Decorator[ValidatorDecoratorInfo]]) -> bool: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

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

2496 

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

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

2499 

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

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

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

2503 """ 

2504 for validator in validators: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2505 if validator.info.always: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2506 return True 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2507 return False 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2508 

2509 

2510def apply_model_validators( 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2511 schema: core_schema.CoreSchema, 

2512 validators: Iterable[Decorator[ModelValidatorDecoratorInfo]], 

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

2514) -> core_schema.CoreSchema: 

2515 """Apply model validators to a schema. 

2516 

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

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

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

2520 

2521 Args: 

2522 schema: The schema to apply validators on. 

2523 validators: An iterable of validators. 

2524 mode: The validator mode. 

2525 

2526 Returns: 

2527 The updated schema. 

2528 """ 

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

2530 for validator in validators: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2531 if mode == 'inner' and validator.info.mode != 'before': 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2532 continue 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2533 if mode == 'outer' and validator.info.mode == 'before': 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2534 continue 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2535 info_arg = inspect_validator(validator.func, validator.info.mode) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2536 if validator.info.mode == 'wrap': 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2537 if info_arg: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2538 schema = core_schema.with_info_wrap_validator_function(function=validator.func, schema=schema) 1uwACDxyEFGvzBHI

2539 else: 

2540 schema = core_schema.no_info_wrap_validator_function(function=validator.func, schema=schema) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2541 elif validator.info.mode == 'before': 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2542 if info_arg: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2543 schema = core_schema.with_info_before_validator_function(function=validator.func, schema=schema) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2544 else: 

2545 schema = core_schema.no_info_before_validator_function(function=validator.func, schema=schema) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2546 else: 

2547 assert validator.info.mode == 'after' 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2548 if info_arg: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2549 schema = core_schema.with_info_after_validator_function(function=validator.func, schema=schema) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2550 else: 

2551 schema = core_schema.no_info_after_validator_function(function=validator.func, schema=schema) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2552 if ref: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2553 schema['ref'] = ref # type: ignore 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2554 return schema 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2555 

2556 

2557def wrap_default(field_info: FieldInfo, schema: core_schema.CoreSchema) -> core_schema.CoreSchema: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

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

2559 

2560 Args: 

2561 field_info: The field info object. 

2562 schema: The schema to apply default on. 

2563 

2564 Returns: 

2565 Updated schema by default value or `default_factory`. 

2566 """ 

2567 if field_info.default_factory: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2568 return core_schema.with_default_schema( 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2569 schema, 

2570 default_factory=field_info.default_factory, 

2571 default_factory_takes_data=takes_validated_data_argument(field_info.default_factory), 

2572 validate_default=field_info.validate_default, 

2573 ) 

2574 elif field_info.default is not PydanticUndefined: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2575 return core_schema.with_default_schema( 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2576 schema, default=field_info.default, validate_default=field_info.validate_default 

2577 ) 

2578 else: 

2579 return schema 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2580 

2581 

2582def _extract_get_pydantic_json_schema(tp: Any) -> GetJsonSchemaFunction | None: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

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

2584 js_modify_function = getattr(tp, '__get_pydantic_json_schema__', None) 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2585 

2586 if hasattr(tp, '__modify_schema__'): 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2587 BaseModel = import_cached_base_model() 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2588 

2589 has_custom_v2_modify_js_func = ( 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2590 js_modify_function is not None 

2591 and BaseModel.__get_pydantic_json_schema__.__func__ # type: ignore 

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

2593 ) 

2594 

2595 if not has_custom_v2_modify_js_func: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2596 cls_name = getattr(tp, '__name__', None) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2597 raise PydanticUserError( 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

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

2600 code='custom-json-schema', 

2601 ) 

2602 

2603 if (origin := get_origin(tp)) is not None: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

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

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

2606 return _extract_get_pydantic_json_schema(origin) 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2607 

2608 if js_modify_function is None: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2609 return None 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2610 

2611 return js_modify_function 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2612 

2613 

2614class _CommonField(TypedDict): 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2615 schema: core_schema.CoreSchema 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2616 validation_alias: str | list[str | int] | list[list[str | int]] | None 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2617 serialization_alias: str | None 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2618 serialization_exclude: bool | None 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2619 frozen: bool | None 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2620 metadata: dict[str, Any] 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2621 

2622 

2623def _common_field( 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2624 schema: core_schema.CoreSchema, 

2625 *, 

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

2627 serialization_alias: str | None = None, 

2628 serialization_exclude: bool | None = None, 

2629 frozen: bool | None = None, 

2630 metadata: Any = None, 

2631) -> _CommonField: 

2632 return { 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2633 'schema': schema, 

2634 'validation_alias': validation_alias, 

2635 'serialization_alias': serialization_alias, 

2636 'serialization_exclude': serialization_exclude, 

2637 'frozen': frozen, 

2638 'metadata': metadata, 

2639 } 

2640 

2641 

2642def resolve_original_schema(schema: CoreSchema, definitions: _Definitions) -> CoreSchema | None: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2643 if schema['type'] == 'definition-ref': 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2644 return definitions.get_schema_from_ref(schema['schema_ref']) 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2645 elif schema['type'] == 'definitions': 2645 ↛ 2646line 2645 didn't jump to line 2646 because the condition on line 2645 was never true1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2646 return schema['schema'] 

2647 else: 

2648 return schema 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2649 

2650 

2651def _inlining_behavior( 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2652 def_ref: core_schema.DefinitionReferenceSchema, 

2653) -> Literal['inline', 'keep', 'preserve_metadata']: 

2654 """Determine the inlining behavior of the `'definition-ref'` schema. 

2655 

2656 - If no `'serialization'` schema and no metadata is attached, the schema can safely be inlined. 

2657 - If it has metadata but only related to the deferred discriminator application, it can be inlined 

2658 provided that such metadata is kept. 

2659 - Otherwise, the schema should not be inlined. Doing so would remove the `'serialization'` schema or metadata. 

2660 """ 

2661 if 'serialization' in def_ref: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2662 return 'keep' 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2663 metadata = def_ref.get('metadata') 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2664 if not metadata: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2665 return 'inline' 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2666 if len(metadata) == 1 and 'pydantic_internal_union_discriminator' in metadata: 2666 ↛ 2667line 2666 didn't jump to line 2667 because the condition on line 2666 was never true1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2667 return 'preserve_metadata' 

2668 return 'keep' 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2669 

2670 

2671class _Definitions: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

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

2673 

2674 _recursively_seen: set[str] 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2675 """A set of recursively seen references. 1ejoquwACDclmrsxyEFGJKLMNPinptvzBHI

2676 

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

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

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

2680 entering the context manager again will yield a `'definition-ref'` schema that should 

2681 short-circuit the normal generation process, as the reference was already in this set. 

2682 """ 

2683 

2684 _definitions: dict[str, core_schema.CoreSchema] 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2685 """A mapping of references to their corresponding schema. 1ejoquwACDclmrsxyEFGJKLMNPinptvzBHI

2686 

2687 When a schema for a referenceable type is generated, it is stored in this mapping. If the 

2688 same type is encountered again, the reference is yielded by the `get_schema_or_ref` context 

2689 manager. 

2690 """ 

2691 

2692 def __init__(self) -> None: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2693 self._recursively_seen = set() 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2694 self._definitions = {} 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2695 

2696 @contextmanager 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2697 def get_schema_or_ref(self, tp: Any, /) -> Generator[tuple[str, core_schema.DefinitionReferenceSchema | None]]: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2698 """Get a definition for `tp` if one exists. 

2699 

2700 If a definition exists, a tuple of `(ref_string, CoreSchema)` is returned. 

2701 If no definition exists yet, a tuple of `(ref_string, None)` is returned. 

2702 

2703 Note that the returned `CoreSchema` will always be a `DefinitionReferenceSchema`, 

2704 not the actual definition itself. 

2705 

2706 This should be called for any type that can be identified by reference. 

2707 This includes any recursive types. 

2708 

2709 At present the following types can be named/recursive: 

2710 

2711 - Pydantic model 

2712 - Pydantic and stdlib dataclasses 

2713 - Typed dictionaries 

2714 - Named tuples 

2715 - `TypeAliasType` instances 

2716 - Enums 

2717 """ 

2718 ref = get_type_ref(tp) 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2719 # return the reference if we're either (1) in a cycle or (2) it the reference was already encountered: 

2720 if ref in self._recursively_seen or ref in self._definitions: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2721 yield (ref, core_schema.definition_reference_schema(ref)) 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2722 else: 

2723 self._recursively_seen.add(ref) 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2724 try: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2725 yield (ref, None) 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2726 finally: 

2727 self._recursively_seen.discard(ref) 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2728 

2729 def get_schema_from_ref(self, ref: str) -> CoreSchema | None: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2730 """Resolve the schema from the given reference.""" 

2731 return self._definitions.get(ref) 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2732 

2733 def create_definition_reference_schema(self, schema: CoreSchema) -> core_schema.DefinitionReferenceSchema: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2734 """Store the schema as a definition and return a `'definition-reference'` schema pointing to it. 

2735 

2736 The schema must have a reference attached to it. 

2737 """ 

2738 ref = schema['ref'] # pyright: ignore 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2739 self._definitions[ref] = schema 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2740 return core_schema.definition_reference_schema(ref) 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2741 

2742 def unpack_definitions(self, schema: core_schema.DefinitionsSchema) -> CoreSchema: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2743 """Store the definitions of the `'definitions'` core schema and return the inner core schema.""" 

2744 for def_schema in schema['definitions']: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2745 self._definitions[def_schema['ref']] = def_schema # pyright: ignore 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2746 return schema['schema'] 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2747 

2748 def finalize_schema(self, schema: CoreSchema) -> CoreSchema: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2749 """Finalize the core schema. 

2750 

2751 This traverses the core schema and referenced definitions, replaces `'definition-ref'` schemas 

2752 by the referenced definition if possible, and applies deferred discriminators. 

2753 """ 

2754 definitions = self._definitions 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2755 try: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2756 gather_result = gather_schemas_for_cleaning( 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2757 schema, 

2758 definitions=definitions, 

2759 ) 

2760 except MissingDefinitionError as e: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2761 raise InvalidSchemaError from e 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2762 

2763 remaining_defs: dict[str, CoreSchema] = {} 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2764 

2765 # Note: this logic doesn't play well when core schemas with deferred discriminator metadata 

2766 # and references are encountered. See the `test_deferred_discriminated_union_and_references()` test. 

2767 for ref, inlinable_def_ref in gather_result['collected_references'].items(): 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2768 if inlinable_def_ref is not None and (inlining_behavior := _inlining_behavior(inlinable_def_ref)) != 'keep': 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2769 if inlining_behavior == 'inline': 2769 ↛ 2776line 2769 didn't jump to line 2776 because the condition on line 2769 was always true1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2770 # `ref` was encountered, and only once: 

2771 # - `inlinable_def_ref` is a `'definition-ref'` schema and is guaranteed to be 

2772 # the only one. Transform it into the definition it points to. 

2773 # - Do not store the definition in the `remaining_defs`. 

2774 inlinable_def_ref.clear() # pyright: ignore[reportAttributeAccessIssue] 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2775 inlinable_def_ref.update(self._resolve_definition(ref, definitions)) # pyright: ignore 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2776 elif inlining_behavior == 'preserve_metadata': 

2777 # `ref` was encountered, and only once, but contains discriminator metadata. 

2778 # We will do the same thing as if `inlining_behavior` was `'inline'`, but make 

2779 # sure to keep the metadata for the deferred discriminator application logic below. 

2780 meta = inlinable_def_ref.pop('metadata') 

2781 inlinable_def_ref.clear() # pyright: ignore[reportAttributeAccessIssue] 

2782 inlinable_def_ref.update(self._resolve_definition(ref, definitions)) # pyright: ignore 

2783 inlinable_def_ref['metadata'] = meta 

2784 else: 

2785 # `ref` was encountered, at least two times (or only once, but with metadata or a serialization schema): 

2786 # - Do not inline the `'definition-ref'` schemas (they are not provided in the gather result anyway). 

2787 # - Store the the definition in the `remaining_defs` 

2788 remaining_defs[ref] = self._resolve_definition(ref, definitions) 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2789 

2790 for cs in gather_result['deferred_discriminator_schemas']: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2791 discriminator: str | None = cs['metadata'].pop('pydantic_internal_union_discriminator', None) # pyright: ignore[reportTypedDictNotRequiredAccess] 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2792 if discriminator is None: 2792 ↛ 2796line 2792 didn't jump to line 2796 because the condition on line 2792 was never true1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2793 # This can happen in rare scenarios, when a deferred schema is present multiple times in the 

2794 # gather result (e.g. when using the `Sequence` type -- see `test_sequence_discriminated_union()`). 

2795 # In this case, a previous loop iteration applied the discriminator and so we can just skip it here. 

2796 continue 

2797 applied = _discriminated_union.apply_discriminator(cs.copy(), discriminator, remaining_defs) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2798 # Mutate the schema directly to have the discriminator applied 

2799 cs.clear() # pyright: ignore[reportAttributeAccessIssue] 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2800 cs.update(applied) # pyright: ignore 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2801 

2802 if remaining_defs: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2803 schema = core_schema.definitions_schema(schema=schema, definitions=[*remaining_defs.values()]) 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2804 return schema 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2805 

2806 def _resolve_definition(self, ref: str, definitions: dict[str, CoreSchema]) -> CoreSchema: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2807 definition = definitions[ref] 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2808 if definition['type'] != 'definition-ref': 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2809 return definition 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2810 

2811 # Some `'definition-ref'` schemas might act as "intermediate" references (e.g. when using 

2812 # a PEP 695 type alias (which is referenceable) that references another PEP 695 type alias): 

2813 visited: set[str] = set() 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2814 while definition['type'] == 'definition-ref' and _inlining_behavior(definition) == 'inline': 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2815 schema_ref = definition['schema_ref'] 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2816 if schema_ref in visited: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2817 raise PydanticUserError( 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2818 f'{ref} contains a circular reference to itself.', code='circular-reference-schema' 

2819 ) 

2820 visited.add(schema_ref) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2821 definition = definitions[schema_ref] 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2822 return {**definition, 'ref': ref} # pyright: ignore[reportReturnType] 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2823 

2824 

2825class _FieldNameStack: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2826 __slots__ = ('_stack',) 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2827 

2828 def __init__(self) -> None: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2829 self._stack: list[str] = [] 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2830 

2831 @contextmanager 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2832 def push(self, field_name: str) -> Iterator[None]: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2833 self._stack.append(field_name) 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2834 yield 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2835 self._stack.pop() 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2836 

2837 def get(self) -> str | None: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2838 if self._stack: 

2839 return self._stack[-1] 

2840 else: 

2841 return None 

2842 

2843 

2844class _ModelTypeStack: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2845 __slots__ = ('_stack',) 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2846 

2847 def __init__(self) -> None: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2848 self._stack: list[type] = [] 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2849 

2850 @contextmanager 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2851 def push(self, type_obj: type) -> Iterator[None]: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2852 self._stack.append(type_obj) 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2853 yield 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2854 self._stack.pop() 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2855 

2856 def get(self) -> type | None: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2857 if self._stack: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2858 return self._stack[-1] 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2859 else: 

2860 return None 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI