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

1351 statements  

« prev     ^ index     » next       coverage.py v7.8.0, created at 2025-04-26 07:51 +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 if not hasattr(cls, '__pydantic_fields__'): 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

743 # This happens when we have a loop in the schema generation: 

744 # class Base[T](BaseModel): 

745 # t: T 

746 # 

747 # class Other(BaseModel): 

748 # b: 'Base[Other]' 

749 # When we build fields for `Other`, we evaluate the forward annotation. 

750 # At this point, `Other` doesn't have the model fields set. We create 

751 # `Base[Other]`; model fields are successfully built, and we try to generate 

752 # a schema for `t: Other`. As `Other.__pydantic_fields__` aren't set, we abort. 

753 raise PydanticUndefinedAnnotation( 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

754 name=cls.__name__, 

755 message=f'Class {cls.__name__!r} is not defined', 

756 ) 

757 try: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

758 fields = rebuild_model_fields( 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

759 cls, 

760 ns_resolver=self._ns_resolver, 

761 typevars_map=self._typevars_map or {}, 

762 ) 

763 except NameError as e: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

765 

766 decorators = cls.__pydantic_decorators__ 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

767 computed_fields = decorators.computed_fields 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

768 check_decorator_fields_exist( 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

769 chain( 

770 decorators.field_validators.values(), 

771 decorators.field_serializers.values(), 

772 decorators.validators.values(), 

773 ), 

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

775 ) 

776 

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

778 

779 extras_schema = None 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

780 extras_keys_schema = None 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

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

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

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

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

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

786 '__pydantic_extra__', None 

787 ) 

788 if extras_annotation is not None: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

789 if isinstance(extras_annotation, str): 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

790 extras_annotation = _typing_extra.eval_type_backport( 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

791 _typing_extra._make_forward_ref( 

792 extras_annotation, is_argument=False, is_class=True 

793 ), 

794 *self._types_namespace, 

795 ) 

796 tp = get_origin(extras_annotation) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

798 raise PydanticSchemaGenerationError( 

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

800 ) 

801 extra_keys_type, extra_items_type = self._get_args_resolving_forward_refs( 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

802 extras_annotation, 

803 required=True, 

804 ) 

805 if extra_keys_type is not str: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

806 extras_keys_schema = self.generate_schema(extra_keys_type) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

808 extras_schema = self.generate_schema(extra_items_type) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

810 break 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

811 

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

813 

814 if cls.__pydantic_root_model__: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

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

816 inner_schema = root_field['schema'] 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

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

818 model_schema = core_schema.model_schema( 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

819 cls, 

820 inner_schema, 

821 generic_origin=generic_origin, 

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

823 root_model=True, 

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

825 config=core_config, 

826 ref=model_ref, 

827 ) 

828 else: 

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

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

831 computed_fields=[ 

832 self._computed_field_schema(d, decorators.field_serializers) 

833 for d in computed_fields.values() 

834 ], 

835 extras_schema=extras_schema, 

836 extras_keys_schema=extras_keys_schema, 

837 model_name=cls.__name__, 

838 ) 

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

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

841 

842 model_schema = core_schema.model_schema( 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

843 cls, 

844 inner_schema, 

845 generic_origin=generic_origin, 

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

847 root_model=False, 

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

849 config=core_config, 

850 ref=model_ref, 

851 ) 

852 

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

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

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

856 

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

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

859 if obj is None: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

861 return obj 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

862 

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

864 BaseModel_ = import_cached_base_model() 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

865 

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

867 is_base_model_get_schema = ( 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

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

869 ) 

870 

871 if ( 1abkcfgOdh

872 get_schema is not None 

873 # BaseModel.__get_pydantic_core_schema__ is defined for backwards compatibility, 

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

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

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

877 # don't call the method: 

878 and not is_base_model_get_schema 

879 ): 

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

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

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

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

884 # not referenceable: 

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

886 if maybe_schema is not None: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

887 return maybe_schema 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

888 

889 if obj is source: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

890 ref_mode = 'unpack' 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

891 else: 

892 ref_mode = 'to-def' 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

893 schema = get_schema( 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

895 ) 

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

897 schema = self.defs.unpack_definitions(schema) 

898 

899 ref = get_ref(schema) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

900 if ref: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

902 

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

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

905 return schema 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

906 

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

908 from pydantic.v1 import BaseModel as BaseModelV1 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

909 

910 if issubclass(obj, BaseModelV1): 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

911 warn( 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

913 UserWarning, 

914 ) 

915 else: 

916 warn( 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

918 PydanticDeprecatedSince20, 

919 ) 

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

921 

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

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

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

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

926 # `Validator(SomeImportedTypeAliasWithAForwardReference)` 

927 # or the equivalent for BaseModel 

928 # class Model(BaseModel): 

929 # x: SomeImportedTypeAliasWithAForwardReference 

930 try: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

932 except NameError as e: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

934 

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

936 if isinstance(obj, ForwardRef): 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

938 

939 if self._typevars_map: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

941 

942 return obj 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

943 

944 @overload 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

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

946 

947 @overload 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

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

949 

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

951 args = get_args(obj) 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

952 if args: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

953 if isinstance(obj, GenericAlias): 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

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

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

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

957 elif required: # pragma: no cover 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

959 return args 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

960 

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

962 args = self._get_args_resolving_forward_refs(obj) 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

963 if not args: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

964 return Any 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

965 return args[0] 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

966 

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

968 args = self._get_args_resolving_forward_refs(obj) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

970 return (Any, Any) 

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

972 origin = get_origin(obj) 

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

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

975 

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

977 if typing_objects.is_self(obj): 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

978 obj = self._resolve_self_type(obj) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

979 

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

981 return self._annotated_schema(obj) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

982 

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

984 # we assume this is already a valid schema 

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

986 

987 if isinstance(obj, str): 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

988 obj = ForwardRef(obj) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

989 

990 if isinstance(obj, ForwardRef): 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

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

992 

993 BaseModel = import_cached_base_model() 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

994 

995 if lenient_issubclass(obj, BaseModel): 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

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

997 return self._model_schema(obj) 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

998 

999 if isinstance(obj, PydanticRecursiveRef): 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

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

1001 

1002 return self.match_type(obj) 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1003 

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

1005 """Main mapping of types to schemas. 

1006 

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

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

1009 

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

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

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

1013 

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

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

1016 """ 

1017 if obj is str: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1018 return core_schema.str_schema() 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1019 elif obj is bytes: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1020 return core_schema.bytes_schema() 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1021 elif obj is int: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1022 return core_schema.int_schema() 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1023 elif obj is float: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1024 return core_schema.float_schema() 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1025 elif obj is bool: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1026 return core_schema.bool_schema() 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1027 elif obj is complex: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1028 return core_schema.complex_schema() 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

1030 return core_schema.any_schema() 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1031 elif obj is datetime.date: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1032 return core_schema.date_schema() 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1033 elif obj is datetime.datetime: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1034 return core_schema.datetime_schema() 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1035 elif obj is datetime.time: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1036 return core_schema.time_schema() 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1037 elif obj is datetime.timedelta: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1038 return core_schema.timedelta_schema() 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1039 elif obj is Decimal: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1040 return core_schema.decimal_schema() 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1041 elif obj is UUID: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1042 return core_schema.uuid_schema() 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1043 elif obj is Url: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1044 return core_schema.url_schema() 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1045 elif obj is Fraction: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1046 return self._fraction_schema() 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1047 elif obj is MultiHostUrl: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1048 return core_schema.multi_host_url_schema() 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

1050 return core_schema.none_schema() 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1051 elif obj in IP_TYPES: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1052 return self._ip_schema(obj) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1053 elif obj in TUPLE_TYPES: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1054 return self._tuple_schema(obj) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1055 elif obj in LIST_TYPES: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1056 return self._list_schema(Any) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1057 elif obj in SET_TYPES: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1058 return self._set_schema(Any) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1059 elif obj in FROZEN_SET_TYPES: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1060 return self._frozenset_schema(Any) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1061 elif obj in SEQUENCE_TYPES: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1062 return self._sequence_schema(Any) 1aeouAdipvB

1063 elif obj in ITERABLE_TYPES: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1064 return self._iterable_schema(obj) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1065 elif obj in DICT_TYPES: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

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

1067 elif obj in PATH_TYPES: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

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

1069 elif obj in DEQUE_TYPES: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1070 return self._deque_schema(Any) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1071 elif obj in MAPPING_TYPES: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

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

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

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

1075 elif typing_objects.is_typealiastype(obj): 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1076 return self._type_alias_type_schema(obj) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1077 elif obj is type: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1078 return self._type_schema() 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1079 elif _typing_extra.is_callable(obj): 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1080 return core_schema.callable_schema() 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

1082 return self._literal_schema(obj) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1083 elif is_typeddict(obj): 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

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

1085 elif _typing_extra.is_namedtuple(obj): 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

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

1087 elif typing_objects.is_newtype(obj): 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

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

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

1090 elif obj in PATTERN_TYPES: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1091 return self._pattern_schema(obj) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1092 elif _typing_extra.is_hashable(obj): 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1093 return self._hashable_schema() 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

1095 return self._unsubstituted_typevar_schema(obj) 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

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

1097 if obj is Final: 

1098 return core_schema.any_schema() 

1099 return self.generate_schema( 

1100 self._get_first_arg_or_any(obj), 

1101 ) 

1102 elif isinstance(obj, VALIDATE_CALL_SUPPORTED_TYPES): 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1103 return self._call_schema(obj) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

1105 return self._enum_schema(obj) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1106 elif obj is ZoneInfo: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1107 return self._zoneinfo_schema() 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1108 

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

1110 # the case of a dc type here 

1111 if dataclasses.is_dataclass(obj): 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

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

1113 

1114 origin = get_origin(obj) 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1115 if origin is not None: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

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

1117 

1118 if self._arbitrary_types: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1119 return self._arbitrary_type_schema(obj) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1120 return self._unknown_type_schema(obj) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1121 

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

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

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

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

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

1127 if dataclasses.is_dataclass(origin): 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

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

1129 if _typing_extra.is_namedtuple(origin): 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

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

1131 

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

1133 if schema is not None: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1134 return schema 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1135 

1136 if typing_objects.is_typealiastype(origin): 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1137 return self._type_alias_type_schema(obj) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1138 elif is_union_origin(origin): 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1139 return self._union_schema(obj) 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1140 elif origin in TUPLE_TYPES: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1141 return self._tuple_schema(obj) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1142 elif origin in LIST_TYPES: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

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

1144 elif origin in SET_TYPES: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

1146 elif origin in FROZEN_SET_TYPES: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

1148 elif origin in DICT_TYPES: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

1150 elif origin in PATH_TYPES: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

1152 elif origin in DEQUE_TYPES: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

1154 elif origin in MAPPING_TYPES: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

1156 elif origin in COUNTER_TYPES: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

1158 elif is_typeddict(origin): 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

1160 elif origin in TYPE_TYPES: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1161 return self._subclass_schema(obj) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1162 elif origin in SEQUENCE_TYPES: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

1164 elif origin in ITERABLE_TYPES: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1165 return self._iterable_schema(obj) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1166 elif origin in PATTERN_TYPES: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1167 return self._pattern_schema(obj) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1168 

1169 if self._arbitrary_types: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1170 return self._arbitrary_type_schema(origin) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1171 return self._unknown_type_schema(obj) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1172 

1173 def _generate_td_field_schema( 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1174 self, 

1175 name: str, 

1176 field_info: FieldInfo, 

1177 decorators: DecoratorInfos, 

1178 *, 

1179 required: bool = True, 

1180 ) -> core_schema.TypedDictField: 

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

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

1183 return core_schema.typed_dict_field( 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1184 common_field['schema'], 

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

1186 serialization_exclude=common_field['serialization_exclude'], 

1187 validation_alias=common_field['validation_alias'], 

1188 serialization_alias=common_field['serialization_alias'], 

1189 metadata=common_field['metadata'], 

1190 ) 

1191 

1192 def _generate_md_field_schema( 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1193 self, 

1194 name: str, 

1195 field_info: FieldInfo, 

1196 decorators: DecoratorInfos, 

1197 ) -> core_schema.ModelField: 

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

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

1200 return core_schema.model_field( 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1201 common_field['schema'], 

1202 serialization_exclude=common_field['serialization_exclude'], 

1203 validation_alias=common_field['validation_alias'], 

1204 serialization_alias=common_field['serialization_alias'], 

1205 frozen=common_field['frozen'], 

1206 metadata=common_field['metadata'], 

1207 ) 

1208 

1209 def _generate_dc_field_schema( 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1210 self, 

1211 name: str, 

1212 field_info: FieldInfo, 

1213 decorators: DecoratorInfos, 

1214 ) -> core_schema.DataclassField: 

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

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

1217 return core_schema.dataclass_field( 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1218 name, 

1219 common_field['schema'], 

1220 init=field_info.init, 

1221 init_only=field_info.init_var or None, 

1222 kw_only=None if field_info.kw_only else False, 

1223 serialization_exclude=common_field['serialization_exclude'], 

1224 validation_alias=common_field['validation_alias'], 

1225 serialization_alias=common_field['serialization_alias'], 

1226 frozen=common_field['frozen'], 

1227 metadata=common_field['metadata'], 

1228 ) 

1229 

1230 @staticmethod 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1231 def _apply_alias_generator_to_field_info( 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

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

1233 ) -> None: 

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

1235 

1236 Args: 

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

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

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

1240 """ 

1241 # Apply an alias_generator if 

1242 # 1. An alias is not specified 

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

1244 if ( 1abkcfgdh

1245 field_info.alias_priority is None 

1246 or field_info.alias_priority <= 1 

1247 or field_info.alias is None 

1248 or field_info.validation_alias is None 

1249 or field_info.serialization_alias is None 

1250 ): 

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

1252 

1253 if isinstance(alias_generator, AliasGenerator): 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

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

1256 alias = alias_generator(field_name) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

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

1259 

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

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

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

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

1264 field_info.alias_priority = 1 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1265 

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

1267 if field_info.alias_priority == 1: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

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

1270 field_info.alias = alias 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1271 

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

1273 if field_info.alias is None: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1274 field_info.alias = alias 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1275 if field_info.serialization_alias is None: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

1277 if field_info.validation_alias is None: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

1279 

1280 @staticmethod 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1281 def _apply_alias_generator_to_computed_field_info( 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

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

1283 computed_field_info: ComputedFieldInfo, 

1284 computed_field_name: str, 

1285 ): 

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

1287 

1288 Args: 

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

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

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

1292 """ 

1293 # Apply an alias_generator if 

1294 # 1. An alias is not specified 

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

1296 

1297 if ( 1abkc

1298 computed_field_info.alias_priority is None 

1299 or computed_field_info.alias_priority <= 1 

1300 or computed_field_info.alias is None 

1301 ): 

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

1303 

1304 if isinstance(alias_generator, AliasGenerator): 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

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

1307 alias = alias_generator(computed_field_name) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

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

1310 

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

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

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

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

1315 computed_field_info.alias_priority = 1 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1316 

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

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

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

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

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

1322 

1323 @staticmethod 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1324 def _apply_field_title_generator_to_field_info( 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

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

1326 ) -> None: 

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

1328 Args: 

1329 config_wrapper: The config of the model 

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

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

1332 """ 

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

1334 

1335 if field_title_generator is None: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1336 return 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1337 

1338 if field_info.title is None: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

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

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

1342 

1343 field_info.title = title 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1344 

1345 def _common_field_schema( # C901 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

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

1347 ) -> _CommonField: 

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

1349 

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

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

1352 return schema 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1353 

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

1355 validators_from_decorators = [] 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

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

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

1358 

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

1360 if field_info.discriminator is not None: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1361 schema = self._apply_annotations( 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1362 source_type, annotations + validators_from_decorators, transform_inner_schema=set_discriminator 

1363 ) 

1364 else: 

1365 schema = self._apply_annotations( 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1366 source_type, 

1367 annotations + validators_from_decorators, 

1368 ) 

1369 

1370 # This V1 compatibility shim should eventually be removed 

1371 # push down any `each_item=True` validators 

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

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

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

1375 if _validators_require_validate_default(this_field_validators): 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1376 field_info.validate_default = True 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

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

1379 schema = apply_each_item_validators(schema, each_item_validators) 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1380 

1381 schema = apply_validators(schema, this_field_validators) 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1382 

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

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

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

1386 if not field_info.is_required(): 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1387 schema = wrap_default(field_info, schema) 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1388 

1389 schema = self._apply_field_serializers( 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

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

1391 ) 

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

1393 

1394 pydantic_js_updates, pydantic_js_extra = _extract_json_schema_info_from_field_info(field_info) 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

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

1396 update_core_metadata( 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1397 core_metadata, pydantic_js_updates=pydantic_js_updates, pydantic_js_extra=pydantic_js_extra 

1398 ) 

1399 

1400 alias_generator = self._config_wrapper.alias_generator 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1401 if alias_generator is not None: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

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

1403 

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

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

1406 else: 

1407 validation_alias = field_info.validation_alias 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1408 

1409 return _common_field( 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1410 schema, 

1411 serialization_exclude=True if field_info.exclude else None, 

1412 validation_alias=validation_alias, 

1413 serialization_alias=field_info.serialization_alias, 

1414 frozen=field_info.frozen, 

1415 metadata=core_metadata, 

1416 ) 

1417 

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

1419 """Generate schema for a Union.""" 

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

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

1422 nullable = False 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1423 for arg in args: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

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

1425 nullable = True 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1426 else: 

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

1428 

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

1430 s = choices[0] 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1431 else: 

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

1433 for choice in choices: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

1435 if tag is not None: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

1437 else: 

1438 choices_with_tags.append(choice) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1439 s = core_schema.union_schema(choices_with_tags) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1440 

1441 if nullable: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1442 s = core_schema.nullable_schema(s) 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1443 return s 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1444 

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

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

1447 if maybe_schema is not None: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1448 return maybe_schema 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1449 

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

1451 typevars_map = get_standard_typevars_map(obj) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1452 

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

1454 try: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

1456 except NameError as e: 

1457 raise PydanticUndefinedAnnotation.from_name_error(e) from e 

1458 annotation = replace_types(annotation, typevars_map) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1459 schema = self.generate_schema(annotation) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

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

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

1463 

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

1465 """Generate schema for a Literal.""" 

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

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

1468 schema = core_schema.literal_schema(expected) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1469 

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

1471 schema = core_schema.no_info_after_validator_function( 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

1473 ) 

1474 

1475 return schema 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1476 

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

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

1479 

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

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

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

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

1484 

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

1486 """ 

1487 FieldInfo = import_cached_field_info() 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1488 

1489 with ( 1abejoqkcfglmrsdhinpt

1490 self.model_type_stack.push(typed_dict_cls), 

1491 self.defs.get_schema_or_ref(typed_dict_cls) as ( 

1492 typed_dict_ref, 

1493 maybe_schema, 

1494 ), 

1495 ): 

1496 if maybe_schema is not None: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1497 return maybe_schema 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1498 

1499 typevars_map = get_standard_typevars_map(typed_dict_cls) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1500 if origin is not None: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1501 typed_dict_cls = origin 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1502 

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

1504 raise PydanticUserError( 1abejoqkcfglmrsdhinpt

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

1506 code='typed-dict-version', 

1507 ) 

1508 

1509 try: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

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

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

1513 except AttributeError: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1514 config = None 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1515 

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

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

1518 

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

1520 

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

1522 

1523 decorators = DecoratorInfos.build(typed_dict_cls) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1524 

1525 if self._config_wrapper.use_attribute_docstrings: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

1527 else: 

1528 field_docstrings = None 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1529 

1530 try: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

1532 except NameError as e: 

1533 raise PydanticUndefinedAnnotation.from_name_error(e) from e 

1534 

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

1536 

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

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

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

1540 

1541 required = ( 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

1543 ) and 'not_required' not in field_info._qualifiers 

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

1545 readonly_fields.append(field_name) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1546 

1547 if ( 1abkcfgdh

1548 field_docstrings is not None 

1549 and field_info.description is None 

1550 and field_name in field_docstrings 

1551 ): 

1552 field_info.description = field_docstrings[field_name] 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

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

1555 field_name, field_info, decorators, required=required 

1556 ) 

1557 

1558 if readonly_fields: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

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

1561 warnings.warn( 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

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

1564 'from any mutation on dictionary instances.', 

1565 UserWarning, 

1566 ) 

1567 

1568 td_schema = core_schema.typed_dict_schema( 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1569 fields, 

1570 cls=typed_dict_cls, 

1571 computed_fields=[ 

1572 self._computed_field_schema(d, decorators.field_serializers) 

1573 for d in decorators.computed_fields.values() 

1574 ], 

1575 ref=typed_dict_ref, 

1576 config=core_config, 

1577 ) 

1578 

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

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

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

1582 

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

1584 """Generate schema for a NamedTuple.""" 

1585 with ( 1abejoqkcfglmrsdhinpt

1586 self.model_type_stack.push(namedtuple_cls), 

1587 self.defs.get_schema_or_ref(namedtuple_cls) as ( 

1588 namedtuple_ref, 

1589 maybe_schema, 

1590 ), 

1591 ): 

1592 if maybe_schema is not None: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1593 return maybe_schema 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1594 typevars_map = get_standard_typevars_map(namedtuple_cls) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1595 if origin is not None: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1596 namedtuple_cls = origin 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1597 

1598 try: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

1600 except NameError as e: 

1601 raise PydanticUndefinedAnnotation.from_name_error(e) from e 

1602 if not annotations: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

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

1605 

1606 if typevars_map: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1607 annotations = { 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1608 field_name: replace_types(annotation, typevars_map) 

1609 for field_name, annotation in annotations.items() 

1610 } 

1611 

1612 arguments_schema = core_schema.arguments_schema( 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1613 [ 

1614 self._generate_parameter_schema( 

1615 field_name, 

1616 annotation, 

1617 source=AnnotationSource.NAMED_TUPLE, 

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

1619 ) 

1620 for field_name, annotation in annotations.items() 

1621 ], 

1622 metadata={'pydantic_js_prefer_positional_arguments': True}, 

1623 ) 

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

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

1626 

1627 def _generate_parameter_schema( 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1628 self, 

1629 name: str, 

1630 annotation: type[Any], 

1631 source: AnnotationSource, 

1632 default: Any = Parameter.empty, 

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

1634 ) -> core_schema.ArgumentsParameter: 

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

1636 

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

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

1639 """ 

1640 FieldInfo = import_cached_field_info() 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1641 

1642 if default is Parameter.empty: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

1644 else: 

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

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

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

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

1649 

1650 if not field.is_required(): 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1651 schema = wrap_default(field, schema) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1652 

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

1654 if mode is not None: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1655 parameter_schema['mode'] = mode 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1656 if field.alias is not None: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

1658 else: 

1659 alias_generator = self._config_wrapper.alias_generator 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

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

1662 elif callable(alias_generator): 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

1664 return parameter_schema 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1665 

1666 def _generate_parameter_v3_schema( 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1667 self, 

1668 name: str, 

1669 annotation: Any, 

1670 source: AnnotationSource, 

1671 mode: Literal[ 

1672 'positional_only', 

1673 'positional_or_keyword', 

1674 'keyword_only', 

1675 'var_args', 

1676 'var_kwargs_uniform', 

1677 'var_kwargs_unpacked_typed_dict', 

1678 ], 

1679 default: Any = Parameter.empty, 

1680 ) -> core_schema.ArgumentsV3Parameter: 

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

1682 

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

1684 the `'arguments`' schema in V3. 

1685 """ 

1686 FieldInfo = import_cached_field_info() 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1687 

1688 if default is Parameter.empty: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

1690 else: 

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

1692 

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

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

1695 

1696 if not field.is_required(): 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1697 schema = wrap_default(field, schema) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1698 

1699 parameter_schema = core_schema.arguments_v3_parameter( 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1700 name=name, 

1701 schema=schema, 

1702 mode=mode, 

1703 ) 

1704 if field.alias is not None: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

1706 else: 

1707 alias_generator = self._config_wrapper.alias_generator 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

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

1710 elif callable(alias_generator): 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

1712 

1713 return parameter_schema 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1714 

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

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

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

1718 typevars_map = get_standard_typevars_map(tuple_type) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1719 params = self._get_args_resolving_forward_refs(tuple_type) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1720 

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

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

1723 

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

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

1726 if not params: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1727 if tuple_type in TUPLE_TYPES: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

1729 else: 

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

1731 return core_schema.tuple_schema([]) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

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

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

1735 else: 

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

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

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

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

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

1741 return core_schema.tuple_schema([]) 1abejkcfglmdhin

1742 else: 

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

1744 

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

1746 return core_schema.custom_error_schema( 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1747 core_schema.is_instance_schema(type), 

1748 custom_error_type='is_type', 

1749 custom_error_message='Input should be a type', 

1750 ) 

1751 

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

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

1754 from ._validators import validate_str_is_valid_iana_tz 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1755 

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

1757 return core_schema.no_info_plain_validator_function( 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1758 validate_str_is_valid_iana_tz, 

1759 serialization=core_schema.to_string_ser_schema(), 

1760 metadata=metadata, 

1761 ) 

1762 

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

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

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

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

1767 

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

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

1770 type_param = self._get_first_arg_or_any(type_) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1771 

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

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

1774 

1775 if typing_objects.is_any(type_param): 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1776 return self._type_schema() 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1777 elif typing_objects.is_typealiastype(type_param): 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

1779 elif typing_objects.is_typevar(type_param): 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1780 if type_param.__bound__: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

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

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

1784 elif type_param.__constraints__: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

1786 else: 

1787 return self._type_schema() 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

1789 return self._union_is_subclass_schema(type_param) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1790 else: 

1791 if typing_objects.is_self(type_param): 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1792 type_param = self._resolve_self_type(type_param) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1793 if _typing_extra.is_generic_alias(type_param): 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1794 raise PydanticUserError( 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

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

1797 code=None, 

1798 ) 

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

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

1801 # so we handle it manually here 

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

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

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

1805 return core_schema.is_subclass_schema(type_param) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1806 

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

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

1809 from ._serializers import serialize_sequence_via_list 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1810 

1811 item_type_schema = self.generate_schema(items_type) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1812 list_schema = core_schema.list_schema(item_type_schema) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1813 

1814 json_schema = smart_deepcopy(list_schema) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

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

1817 from ._validators import sequence_validator 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1818 

1819 python_schema = core_schema.chain_schema( 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

1821 ) 

1822 

1823 serialization = core_schema.wrap_serializer_function_ser_schema( 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1824 serialize_sequence_via_list, schema=item_type_schema, info_arg=True 

1825 ) 

1826 return core_schema.json_or_python_schema( 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1827 json_schema=json_schema, python_schema=python_schema, serialization=serialization 

1828 ) 

1829 

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

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

1832 item_type = self._get_first_arg_or_any(type_) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1833 

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

1835 

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

1837 from . import _validators 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1838 

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

1840 ser = core_schema.plain_serializer_function_ser_schema( 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

1842 ) 

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

1844 # bare type 

1845 return core_schema.no_info_plain_validator_function( 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

1847 ) 

1848 

1849 param = self._get_args_resolving_forward_refs( 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1850 pattern_type, 

1851 required=True, 

1852 )[0] 

1853 if param is str: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1854 return core_schema.no_info_plain_validator_function( 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

1856 ) 

1857 elif param is bytes: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1858 return core_schema.no_info_plain_validator_function( 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

1860 ) 

1861 else: 

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

1863 

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

1865 return core_schema.custom_error_schema( 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1866 schema=core_schema.json_or_python_schema( 

1867 json_schema=core_schema.chain_schema( 

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

1869 ), 

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

1871 ), 

1872 custom_error_type='is_hashable', 

1873 custom_error_message='Input should be hashable', 

1874 ) 

1875 

1876 def _dataclass_schema( 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

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

1878 ) -> core_schema.CoreSchema: 

1879 """Generate schema for a dataclass.""" 

1880 with ( 1abejoqkcfglmrsOJKLMNdhinpt

1881 self.model_type_stack.push(dataclass), 

1882 self.defs.get_schema_or_ref(dataclass) as ( 

1883 dataclass_ref, 

1884 maybe_schema, 

1885 ), 

1886 ): 

1887 if maybe_schema is not None: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1888 return maybe_schema 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1889 

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

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

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

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

1894 ref = get_ref(schema) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1895 if ref: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

1897 else: 

1898 return schema 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1899 

1900 typevars_map = get_standard_typevars_map(dataclass) 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1901 if origin is not None: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1902 dataclass = origin 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1903 

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

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

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

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

1908 

1909 from ..dataclasses import is_pydantic_dataclass 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1910 

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

1912 if is_pydantic_dataclass(dataclass): 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

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

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

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

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

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

1918 if typevars_map: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

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

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

1921 else: 

1922 fields = collect_dataclass_fields( 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1923 dataclass, 

1924 typevars_map=typevars_map, 

1925 config_wrapper=self._config_wrapper, 

1926 ) 

1927 

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

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

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

1931 if field.init is False: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1932 raise PydanticUserError( 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

1934 f'This combination is not allowed.', 

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

1936 ) 

1937 

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

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

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

1941 args = sorted( 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

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

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

1944 ) 

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

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

1947 

1948 args_schema = core_schema.dataclass_args_schema( 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1949 dataclass.__name__, 

1950 args, 

1951 computed_fields=[ 

1952 self._computed_field_schema(d, decorators.field_serializers) 

1953 for d in decorators.computed_fields.values() 

1954 ], 

1955 collect_init_only=has_post_init, 

1956 ) 

1957 

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

1959 

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

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

1962 

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

1964 

1965 dc_schema = core_schema.dataclass_schema( 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

1966 dataclass, 

1967 inner_schema, 

1968 generic_origin=origin, 

1969 post_init=has_post_init, 

1970 ref=dataclass_ref, 

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

1972 slots=has_slots, 

1973 config=core_config, 

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

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

1976 frozen=self._config_wrapper_stack.tail.frozen, 

1977 ) 

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

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

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

1981 

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

1983 """Generate schema for a Callable. 

1984 

1985 TODO support functional validators once we support them in Config 

1986 """ 

1987 arguments_schema = self._arguments_schema(function) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1988 

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

1990 config_wrapper = self._config_wrapper 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1991 if config_wrapper.validate_return: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1992 sig = signature(function) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1993 return_hint = sig.return_annotation 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

1995 globalns, localns = self._types_namespace 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

1996 type_hints = _typing_extra.get_function_type_hints( 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

1998 ) 

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

2000 

2001 return core_schema.call_schema( 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2002 arguments_schema, 

2003 function, 

2004 return_schema=return_schema, 

2005 ) 

2006 

2007 def _arguments_schema( 1abejoquwACDfglmrsxyEFGOJKLMNPdhinptvzBHI

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

2009 ) -> core_schema.ArgumentsSchema: 

2010 """Generate schema for a Signature.""" 

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

2012 Parameter.POSITIONAL_ONLY: 'positional_only', 

2013 Parameter.POSITIONAL_OR_KEYWORD: 'positional_or_keyword', 

2014 Parameter.KEYWORD_ONLY: 'keyword_only', 

2015 } 

2016 

2017 sig = signature(function) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2018 globalns, localns = self._types_namespace 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

2020 

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

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

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

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

2025 

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

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

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

2029 else: 

2030 annotation = type_hints[name] 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2031 

2032 if parameters_callback is not None: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

2034 if result == 'skip': 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2035 continue 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2036 

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

2038 if parameter_mode is not None: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2039 arg_schema = self._generate_parameter_schema( 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

2041 ) 

2042 arguments_list.append(arg_schema) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

2044 var_args_schema = self.generate_schema(annotation) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2045 else: 

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

2047 

2048 unpack_type = _typing_extra.unpack_type(annotation) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2049 if unpack_type is not None: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2050 origin = get_origin(unpack_type) or unpack_type 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2051 if not is_typeddict(origin): 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2052 raise PydanticUserError( 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

2054 code='unpack-typed-dict', 

2055 ) 

2056 non_pos_only_param_names = { 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

2058 } 

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

2060 if overlapping_params: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2061 raise PydanticUserError( 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

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

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

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

2066 ) 

2067 

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

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

2070 else: 

2071 var_kwargs_mode = 'uniform' 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2072 var_kwargs_schema = self.generate_schema(annotation) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2073 

2074 return core_schema.arguments_schema( 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2075 arguments_list, 

2076 var_args_schema=var_args_schema, 

2077 var_kwargs_mode=var_kwargs_mode, 

2078 var_kwargs_schema=var_kwargs_schema, 

2079 validate_by_name=self._config_wrapper.validate_by_name, 

2080 ) 

2081 

2082 def _arguments_v3_schema( 1abejoquwACDfglmrsxyEFGOJKLMNPdhinptvzBHI

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

2084 ) -> core_schema.ArgumentsV3Schema: 

2085 mode_lookup: dict[ 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

2087 ] = { 

2088 Parameter.POSITIONAL_ONLY: 'positional_only', 

2089 Parameter.POSITIONAL_OR_KEYWORD: 'positional_or_keyword', 

2090 Parameter.VAR_POSITIONAL: 'var_args', 

2091 Parameter.KEYWORD_ONLY: 'keyword_only', 

2092 } 

2093 

2094 sig = signature(function) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2095 globalns, localns = self._types_namespace 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

2097 

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

2099 

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

2101 if parameters_callback is not None: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

2103 if result == 'skip': 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2104 continue 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2105 

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

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

2108 else: 

2109 annotation = type_hints[name] 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2110 

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

2112 if parameter_mode is None: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

2114 

2115 unpack_type = _typing_extra.unpack_type(annotation) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2116 if unpack_type is not None: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2117 origin = get_origin(unpack_type) or unpack_type 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2118 if not is_typeddict(origin): 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2119 raise PydanticUserError( 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

2121 code='unpack-typed-dict', 

2122 ) 

2123 non_pos_only_param_names = { 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

2125 } 

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

2127 if overlapping_params: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2128 raise PydanticUserError( 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

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

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

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

2133 ) 

2134 parameter_mode = 'var_kwargs_unpacked_typed_dict' 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2135 annotation = unpack_type 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2136 else: 

2137 parameter_mode = 'var_kwargs_uniform' 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2138 

2139 parameters_list.append( 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2140 self._generate_parameter_v3_schema( 

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

2142 ) 

2143 ) 

2144 

2145 return core_schema.arguments_v3_schema( 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2146 parameters_list, 

2147 validate_by_name=self._config_wrapper.validate_by_name, 

2148 ) 

2149 

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

2151 try: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2152 has_default = typevar.has_default() 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2153 except AttributeError: 1abejoquwkcfglmrsxyOJKLMNdhinptvz

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

2155 pass 1abejoquwkcfglmrsxyOJKLMNdhinptvz

2156 else: 

2157 if has_default: 1abejoquwACDkcfglmrsxyEFGPdhinptvzBHI

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

2159 

2160 if constraints := typevar.__constraints__: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

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

2162 

2163 if bound := typevar.__bound__: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2164 schema = self.generate_schema(bound) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

2166 lambda x, h: h(x), 

2167 schema=core_schema.any_schema(), 

2168 ) 

2169 return schema 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2170 

2171 return core_schema.any_schema() 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2172 

2173 def _computed_field_schema( 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2174 self, 

2175 d: Decorator[ComputedFieldInfo], 

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

2177 ) -> core_schema.ComputedField: 

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

2179 return_type = d.info.return_type 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2180 else: 

2181 try: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

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

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

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

2186 except NameError as e: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

2188 if return_type is PydanticUndefined: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2189 raise PydanticUserError( 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

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

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

2193 ) 

2194 

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

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

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

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

2199 return_type_schema = self.generate_schema(return_type) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2200 # Apply serializers to computed field if there exist 

2201 return_type_schema = self._apply_field_serializers( 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2202 return_type_schema, 

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

2204 ) 

2205 

2206 alias_generator = self._config_wrapper.alias_generator 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2207 if alias_generator is not None: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2208 self._apply_alias_generator_to_computed_field_info( 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

2210 ) 

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

2212 

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

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

2215 update_core_metadata( 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2216 core_metadata, 

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

2218 pydantic_js_extra=pydantic_js_extra, 

2219 ) 

2220 return core_schema.computed_field( 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

2222 ) 

2223 

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

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

2226 FieldInfo = import_cached_field_info() 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

2228 annotated_type, 

2229 required=True, 

2230 ) 

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

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

2233 # even if there are function validators involved 

2234 for annotation in annotations: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2235 if isinstance(annotation, FieldInfo): 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2236 schema = wrap_default(annotation, schema) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2237 return schema 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2238 

2239 def _apply_annotations( 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2240 self, 

2241 source_type: Any, 

2242 annotations: list[Any], 

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

2244 ) -> CoreSchema: 

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

2246 

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

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

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

2250 """ 

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

2252 

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

2254 

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

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

2257 

2258 if schema is None: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2259 schema = self._generate_schema_inner(obj) 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2260 

2261 metadata_js_function = _extract_get_pydantic_json_schema(obj) 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2262 if metadata_js_function is not None: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

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

2264 if metadata_schema is not None: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2265 self._add_js_function(metadata_schema, metadata_js_function) 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2266 return transform_inner_schema(schema) 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2267 

2268 get_inner_schema = CallbackGetCoreSchemaHandler(inner_handler, self) 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2269 

2270 for annotation in annotations: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2271 if annotation is None: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2272 continue 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2273 get_inner_schema = self._get_wrapped_inner_schema( 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2274 get_inner_schema, annotation, pydantic_js_annotation_functions 

2275 ) 

2276 

2277 schema = get_inner_schema(source_type) 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2278 if pydantic_js_annotation_functions: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

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

2280 update_core_metadata(core_metadata, pydantic_js_annotation_functions=pydantic_js_annotation_functions) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

2282 

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

2284 FieldInfo = import_cached_field_info() 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2285 

2286 if isinstance(metadata, FieldInfo): 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

2288 schema = self._apply_single_annotation(schema, field_metadata) 

2289 

2290 if metadata.discriminator is not None: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

2292 return schema 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2293 

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

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

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

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

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

2299 schema['schema'] = inner 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2300 return schema 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2301 

2302 original_schema = schema 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

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

2305 schema = schema.copy() 

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

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

2308 return existing 

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

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

2311 ref = schema['schema_ref'] 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

2313 schema = referenced_schema.copy() 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

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

2316 return existing 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

2318 

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

2320 

2321 if maybe_updated_schema is not None: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2322 return maybe_updated_schema 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2323 return original_schema 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2324 

2325 def _apply_single_annotation_json_schema( 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

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

2327 ) -> core_schema.CoreSchema: 

2328 FieldInfo = import_cached_field_info() 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2329 

2330 if isinstance(metadata, FieldInfo): 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

2332 schema = self._apply_single_annotation_json_schema(schema, field_metadata) 

2333 

2334 pydantic_js_updates, pydantic_js_extra = _extract_json_schema_info_from_field_info(metadata) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

2336 update_core_metadata( 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2337 core_metadata, pydantic_js_updates=pydantic_js_updates, pydantic_js_extra=pydantic_js_extra 

2338 ) 

2339 return schema 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2340 

2341 def _get_wrapped_inner_schema( 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2342 self, 

2343 get_inner_schema: GetCoreSchemaHandler, 

2344 annotation: Any, 

2345 pydantic_js_annotation_functions: list[GetJsonSchemaFunction], 

2346 ) -> CallbackGetCoreSchemaHandler: 

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

2348 

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

2350 if annotation_get_schema is not None: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2351 schema = annotation_get_schema(source, get_inner_schema) 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2352 else: 

2353 schema = get_inner_schema(source) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

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

2356 

2357 metadata_js_function = _extract_get_pydantic_json_schema(annotation) 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2358 if metadata_js_function is not None: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2359 pydantic_js_annotation_functions.append(metadata_js_function) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2360 return schema 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2361 

2362 return CallbackGetCoreSchemaHandler(new_handler, self) 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2363 

2364 def _apply_field_serializers( 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2365 self, 

2366 schema: core_schema.CoreSchema, 

2367 serializers: list[Decorator[FieldSerializerDecoratorInfo]], 

2368 ) -> core_schema.CoreSchema: 

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

2370 if serializers: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2371 schema = copy(schema) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

2373 inner_schema = schema['schema'] 

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

2375 return schema 

2376 elif 'ref' in schema: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

2378 

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

2380 serializer = serializers[-1] 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

2382 

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

2384 return_type = serializer.info.return_type 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2385 else: 

2386 try: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

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

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

2390 return_type = _decorators.get_callable_return_type( 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

2392 ) 

2393 except NameError as e: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

2395 

2396 if return_type is PydanticUndefined: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2397 return_schema = None 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2398 else: 

2399 return_schema = self.generate_schema(return_type) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2400 

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

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

2403 serializer.func, 

2404 is_field_serializer=is_field_serializer, 

2405 info_arg=info_arg, 

2406 return_schema=return_schema, 

2407 when_used=serializer.info.when_used, 

2408 ) 

2409 else: 

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

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

2412 serializer.func, 

2413 is_field_serializer=is_field_serializer, 

2414 info_arg=info_arg, 

2415 return_schema=return_schema, 

2416 when_used=serializer.info.when_used, 

2417 ) 

2418 return schema 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2419 

2420 def _apply_model_serializers( 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

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

2422 ) -> core_schema.CoreSchema: 

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

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

2425 if serializers: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

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

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

2428 

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

2430 return_type = serializer.info.return_type 

2431 else: 

2432 try: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

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

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

2436 return_type = _decorators.get_callable_return_type( 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

2438 ) 

2439 except NameError as e: 

2440 raise PydanticUndefinedAnnotation.from_name_error(e) from e 

2441 

2442 if return_type is PydanticUndefined: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2443 return_schema = None 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2444 else: 

2445 return_schema = self.generate_schema(return_type) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2446 

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

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

2449 serializer.func, 

2450 info_arg=info_arg, 

2451 return_schema=return_schema, 

2452 when_used=serializer.info.when_used, 

2453 ) 

2454 else: 

2455 # plain 

2456 ser_schema = core_schema.plain_serializer_function_ser_schema( 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2457 serializer.func, 

2458 info_arg=info_arg, 

2459 return_schema=return_schema, 

2460 when_used=serializer.info.when_used, 

2461 ) 

2462 schema['serialization'] = ser_schema 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

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

2465 return schema 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2466 

2467 

2468_VALIDATOR_F_MATCH: Mapping[ 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

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

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

2471] = { 

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

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

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

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

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

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

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

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

2480} 

2481 

2482 

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

2484# be removed once we drop support for those. 

2485def apply_validators( 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2486 schema: core_schema.CoreSchema, 

2487 validators: Iterable[Decorator[RootValidatorDecoratorInfo]] 

2488 | Iterable[Decorator[ValidatorDecoratorInfo]] 

2489 | Iterable[Decorator[FieldValidatorDecoratorInfo]], 

2490) -> core_schema.CoreSchema: 

2491 """Apply validators to a schema. 

2492 

2493 Args: 

2494 schema: The schema to apply validators on. 

2495 validators: An iterable of validators. 

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

2497 

2498 Returns: 

2499 The updated schema. 

2500 """ 

2501 for validator in validators: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

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

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

2504 

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

2506 return schema 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2507 

2508 

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

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

2511 

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

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

2514 

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

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

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

2518 """ 

2519 for validator in validators: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2520 if validator.info.always: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2521 return True 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2522 return False 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2523 

2524 

2525def apply_model_validators( 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2526 schema: core_schema.CoreSchema, 

2527 validators: Iterable[Decorator[ModelValidatorDecoratorInfo]], 

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

2529) -> core_schema.CoreSchema: 

2530 """Apply model validators to a schema. 

2531 

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

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

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

2535 

2536 Args: 

2537 schema: The schema to apply validators on. 

2538 validators: An iterable of validators. 

2539 mode: The validator mode. 

2540 

2541 Returns: 

2542 The updated schema. 

2543 """ 

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

2545 for validator in validators: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

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

2547 continue 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

2549 continue 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

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

2552 if info_arg: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

2554 else: 

2555 schema = core_schema.no_info_wrap_validator_function(function=validator.func, schema=schema) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2556 elif validator.info.mode == 'before': 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2557 if info_arg: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2558 schema = core_schema.with_info_before_validator_function(function=validator.func, schema=schema) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2559 else: 

2560 schema = core_schema.no_info_before_validator_function(function=validator.func, schema=schema) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2561 else: 

2562 assert validator.info.mode == 'after' 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2563 if info_arg: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2564 schema = core_schema.with_info_after_validator_function(function=validator.func, schema=schema) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2565 else: 

2566 schema = core_schema.no_info_after_validator_function(function=validator.func, schema=schema) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2567 if ref: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

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

2569 return schema 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2570 

2571 

2572def wrap_default(field_info: FieldInfo, schema: core_schema.CoreSchema) -> core_schema.CoreSchema: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

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

2574 

2575 Args: 

2576 field_info: The field info object. 

2577 schema: The schema to apply default on. 

2578 

2579 Returns: 

2580 Updated schema by default value or `default_factory`. 

2581 """ 

2582 if field_info.default_factory: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2583 return core_schema.with_default_schema( 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2584 schema, 

2585 default_factory=field_info.default_factory, 

2586 default_factory_takes_data=takes_validated_data_argument(field_info.default_factory), 

2587 validate_default=field_info.validate_default, 

2588 ) 

2589 elif field_info.default is not PydanticUndefined: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2590 return core_schema.with_default_schema( 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2591 schema, default=field_info.default, validate_default=field_info.validate_default 

2592 ) 

2593 else: 

2594 return schema 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2595 

2596 

2597def _extract_get_pydantic_json_schema(tp: Any) -> GetJsonSchemaFunction | None: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

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

2599 js_modify_function = getattr(tp, '__get_pydantic_json_schema__', None) 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2600 

2601 if hasattr(tp, '__modify_schema__'): 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2602 BaseModel = import_cached_base_model() 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2603 

2604 has_custom_v2_modify_js_func = ( 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2605 js_modify_function is not None 

2606 and BaseModel.__get_pydantic_json_schema__.__func__ # type: ignore 

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

2608 ) 

2609 

2610 if not has_custom_v2_modify_js_func: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2611 cls_name = getattr(tp, '__name__', None) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2612 raise PydanticUserError( 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

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

2615 code='custom-json-schema', 

2616 ) 

2617 

2618 if (origin := get_origin(tp)) is not None: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

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

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

2621 return _extract_get_pydantic_json_schema(origin) 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2622 

2623 if js_modify_function is None: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2624 return None 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2625 

2626 return js_modify_function 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2627 

2628 

2629class _CommonField(TypedDict): 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2630 schema: core_schema.CoreSchema 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2631 validation_alias: str | list[str | int] | list[list[str | int]] | None 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2632 serialization_alias: str | None 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2633 serialization_exclude: bool | None 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2634 frozen: bool | None 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2635 metadata: dict[str, Any] 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2636 

2637 

2638def _common_field( 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2639 schema: core_schema.CoreSchema, 

2640 *, 

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

2642 serialization_alias: str | None = None, 

2643 serialization_exclude: bool | None = None, 

2644 frozen: bool | None = None, 

2645 metadata: Any = None, 

2646) -> _CommonField: 

2647 return { 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2648 'schema': schema, 

2649 'validation_alias': validation_alias, 

2650 'serialization_alias': serialization_alias, 

2651 'serialization_exclude': serialization_exclude, 

2652 'frozen': frozen, 

2653 'metadata': metadata, 

2654 } 

2655 

2656 

2657def resolve_original_schema(schema: CoreSchema, definitions: _Definitions) -> CoreSchema | None: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2658 if schema['type'] == 'definition-ref': 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2659 return definitions.get_schema_from_ref(schema['schema_ref']) 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2660 elif schema['type'] == 'definitions': 2660 ↛ 2661line 2660 didn't jump to line 2661 because the condition on line 2660 was never true1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2661 return schema['schema'] 

2662 else: 

2663 return schema 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2664 

2665 

2666def _inlining_behavior( 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2667 def_ref: core_schema.DefinitionReferenceSchema, 

2668) -> Literal['inline', 'keep', 'preserve_metadata']: 

2669 """Determine the inlining behavior of the `'definition-ref'` schema. 

2670 

2671 - If no `'serialization'` schema and no metadata is attached, the schema can safely be inlined. 

2672 - If it has metadata but only related to the deferred discriminator application, it can be inlined 

2673 provided that such metadata is kept. 

2674 - Otherwise, the schema should not be inlined. Doing so would remove the `'serialization'` schema or metadata. 

2675 """ 

2676 if 'serialization' in def_ref: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2677 return 'keep' 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2678 metadata = def_ref.get('metadata') 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2679 if not metadata: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2680 return 'inline' 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2681 if len(metadata) == 1 and 'pydantic_internal_union_discriminator' in metadata: 2681 ↛ 2682line 2681 didn't jump to line 2682 because the condition on line 2681 was never true1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2682 return 'preserve_metadata' 

2683 return 'keep' 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2684 

2685 

2686class _Definitions: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

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

2688 

2689 _recursively_seen: set[str] 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2690 """A set of recursively seen references. 1ejoquwACDclmrsxyEFGJKLMNPinptvzBHI

2691 

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

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

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

2695 entering the context manager again will yield a `'definition-ref'` schema that should 

2696 short-circuit the normal generation process, as the reference was already in this set. 

2697 """ 

2698 

2699 _definitions: dict[str, core_schema.CoreSchema] 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2700 """A mapping of references to their corresponding schema. 1ejoquwACDclmrsxyEFGJKLMNPinptvzBHI

2701 

2702 When a schema for a referenceable type is generated, it is stored in this mapping. If the 

2703 same type is encountered again, the reference is yielded by the `get_schema_or_ref` context 

2704 manager. 

2705 """ 

2706 

2707 def __init__(self) -> None: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2708 self._recursively_seen = set() 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2709 self._definitions = {} 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2710 

2711 @contextmanager 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2712 def get_schema_or_ref(self, tp: Any, /) -> Generator[tuple[str, core_schema.DefinitionReferenceSchema | None]]: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2713 """Get a definition for `tp` if one exists. 

2714 

2715 If a definition exists, a tuple of `(ref_string, CoreSchema)` is returned. 

2716 If no definition exists yet, a tuple of `(ref_string, None)` is returned. 

2717 

2718 Note that the returned `CoreSchema` will always be a `DefinitionReferenceSchema`, 

2719 not the actual definition itself. 

2720 

2721 This should be called for any type that can be identified by reference. 

2722 This includes any recursive types. 

2723 

2724 At present the following types can be named/recursive: 

2725 

2726 - Pydantic model 

2727 - Pydantic and stdlib dataclasses 

2728 - Typed dictionaries 

2729 - Named tuples 

2730 - `TypeAliasType` instances 

2731 - Enums 

2732 """ 

2733 ref = get_type_ref(tp) 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2734 # return the reference if we're either (1) in a cycle or (2) it the reference was already encountered: 

2735 if ref in self._recursively_seen or ref in self._definitions: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2736 yield (ref, core_schema.definition_reference_schema(ref)) 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2737 else: 

2738 self._recursively_seen.add(ref) 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2739 try: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2740 yield (ref, None) 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2741 finally: 

2742 self._recursively_seen.discard(ref) 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2743 

2744 def get_schema_from_ref(self, ref: str) -> CoreSchema | None: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2745 """Resolve the schema from the given reference.""" 

2746 return self._definitions.get(ref) 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2747 

2748 def create_definition_reference_schema(self, schema: CoreSchema) -> core_schema.DefinitionReferenceSchema: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2749 """Store the schema as a definition and return a `'definition-reference'` schema pointing to it. 

2750 

2751 The schema must have a reference attached to it. 

2752 """ 

2753 ref = schema['ref'] # pyright: ignore 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2754 self._definitions[ref] = schema 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2755 return core_schema.definition_reference_schema(ref) 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2756 

2757 def unpack_definitions(self, schema: core_schema.DefinitionsSchema) -> CoreSchema: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2758 """Store the definitions of the `'definitions'` core schema and return the inner core schema.""" 

2759 for def_schema in schema['definitions']: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2760 self._definitions[def_schema['ref']] = def_schema # pyright: ignore 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2761 return schema['schema'] 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2762 

2763 def finalize_schema(self, schema: CoreSchema) -> CoreSchema: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2764 """Finalize the core schema. 

2765 

2766 This traverses the core schema and referenced definitions, replaces `'definition-ref'` schemas 

2767 by the referenced definition if possible, and applies deferred discriminators. 

2768 """ 

2769 definitions = self._definitions 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2770 try: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2771 gather_result = gather_schemas_for_cleaning( 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2772 schema, 

2773 definitions=definitions, 

2774 ) 

2775 except MissingDefinitionError as e: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2776 raise InvalidSchemaError from e 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2777 

2778 remaining_defs: dict[str, CoreSchema] = {} 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2779 

2780 # Note: this logic doesn't play well when core schemas with deferred discriminator metadata 

2781 # and references are encountered. See the `test_deferred_discriminated_union_and_references()` test. 

2782 for ref, inlinable_def_ref in gather_result['collected_references'].items(): 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2783 if inlinable_def_ref is not None and (inlining_behavior := _inlining_behavior(inlinable_def_ref)) != 'keep': 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2784 if inlining_behavior == 'inline': 2784 ↛ 2791line 2784 didn't jump to line 2791 because the condition on line 2784 was always true1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2785 # `ref` was encountered, and only once: 

2786 # - `inlinable_def_ref` is a `'definition-ref'` schema and is guaranteed to be 

2787 # the only one. Transform it into the definition it points to. 

2788 # - Do not store the definition in the `remaining_defs`. 

2789 inlinable_def_ref.clear() # pyright: ignore[reportAttributeAccessIssue] 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2790 inlinable_def_ref.update(self._resolve_definition(ref, definitions)) # pyright: ignore 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2791 elif inlining_behavior == 'preserve_metadata': 

2792 # `ref` was encountered, and only once, but contains discriminator metadata. 

2793 # We will do the same thing as if `inlining_behavior` was `'inline'`, but make 

2794 # sure to keep the metadata for the deferred discriminator application logic below. 

2795 meta = inlinable_def_ref.pop('metadata') 

2796 inlinable_def_ref.clear() # pyright: ignore[reportAttributeAccessIssue] 

2797 inlinable_def_ref.update(self._resolve_definition(ref, definitions)) # pyright: ignore 

2798 inlinable_def_ref['metadata'] = meta 

2799 else: 

2800 # `ref` was encountered, at least two times (or only once, but with metadata or a serialization schema): 

2801 # - Do not inline the `'definition-ref'` schemas (they are not provided in the gather result anyway). 

2802 # - Store the the definition in the `remaining_defs` 

2803 remaining_defs[ref] = self._resolve_definition(ref, definitions) 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2804 

2805 for cs in gather_result['deferred_discriminator_schemas']: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2806 discriminator: str | None = cs['metadata'].pop('pydantic_internal_union_discriminator', None) # pyright: ignore[reportTypedDictNotRequiredAccess] 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

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

2808 # This can happen in rare scenarios, when a deferred schema is present multiple times in the 

2809 # gather result (e.g. when using the `Sequence` type -- see `test_sequence_discriminated_union()`). 

2810 # In this case, a previous loop iteration applied the discriminator and so we can just skip it here. 

2811 continue 

2812 applied = _discriminated_union.apply_discriminator(cs.copy(), discriminator, remaining_defs) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2813 # Mutate the schema directly to have the discriminator applied 

2814 cs.clear() # pyright: ignore[reportAttributeAccessIssue] 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2815 cs.update(applied) # pyright: ignore 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2816 

2817 if remaining_defs: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2818 schema = core_schema.definitions_schema(schema=schema, definitions=[*remaining_defs.values()]) 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2819 return schema 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2820 

2821 def _resolve_definition(self, ref: str, definitions: dict[str, CoreSchema]) -> CoreSchema: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2822 definition = definitions[ref] 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2823 if definition['type'] != 'definition-ref': 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2824 return definition 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2825 

2826 # Some `'definition-ref'` schemas might act as "intermediate" references (e.g. when using 

2827 # a PEP 695 type alias (which is referenceable) that references another PEP 695 type alias): 

2828 visited: set[str] = set() 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2829 while definition['type'] == 'definition-ref' and _inlining_behavior(definition) == 'inline': 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2830 schema_ref = definition['schema_ref'] 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2831 if schema_ref in visited: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2832 raise PydanticUserError( 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2833 f'{ref} contains a circular reference to itself.', code='circular-reference-schema' 

2834 ) 

2835 visited.add(schema_ref) 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2836 definition = definitions[schema_ref] 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2837 return {**definition, 'ref': ref} # pyright: ignore[reportReturnType] 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2838 

2839 

2840class _FieldNameStack: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2841 __slots__ = ('_stack',) 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2842 

2843 def __init__(self) -> None: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2844 self._stack: list[str] = [] 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2845 

2846 @contextmanager 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2847 def push(self, field_name: str) -> Iterator[None]: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2848 self._stack.append(field_name) 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2849 yield 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2850 self._stack.pop() 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2851 

2852 def get(self) -> str | None: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2853 if self._stack: 

2854 return self._stack[-1] 

2855 else: 

2856 return None 

2857 

2858 

2859class _ModelTypeStack: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2860 __slots__ = ('_stack',) 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2861 

2862 def __init__(self) -> None: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2863 self._stack: list[type] = [] 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2864 

2865 @contextmanager 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2866 def push(self, type_obj: type) -> Iterator[None]: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2867 self._stack.append(type_obj) 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2868 yield 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2869 self._stack.pop() 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2870 

2871 def get(self) -> type | None: 1abejoquwACDkcfglmrsxyEFGOJKLMNPdhinptvzBHI

2872 if self._stack: 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2873 return self._stack[-1] 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI

2874 else: 

2875 return None 1abejoquwACDkcfglmrsxyEFGdhinptvzBHI