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

1349 statements  

« prev     ^ index     » next       coverage.py v7.8.0, created at 2025-04-17 15:12 +0000

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

2 

3from __future__ import annotations as _annotations 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

4 

5import collections.abc 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

6import dataclasses 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

7import datetime 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

8import inspect 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

9import os 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

10import pathlib 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

11import re 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

12import sys 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

13import typing 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

14import warnings 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

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

16from contextlib import contextmanager 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

17from copy import copy 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

18from decimal import Decimal 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

19from enum import Enum 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

20from fractions import Fraction 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

21from functools import partial 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

22from inspect import Parameter, _ParameterKind, signature 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

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

24from itertools import chain 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

25from operator import attrgetter 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

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

27from typing import ( 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

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

40from warnings import warn 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

41from zoneinfo import ZoneInfo 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

42 

43import typing_extensions 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

44from pydantic_core import ( 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

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

55from typing_inspection import typing_objects 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

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

57 

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

59from ..annotated_handlers import GetCoreSchemaHandler, GetJsonSchemaHandler 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

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

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

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

63from ..json_schema import JsonSchemaValue 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

64from ..version import version_short 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

65from ..warnings import PydanticDeprecatedSince20 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

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

67from ._config import ConfigWrapper, ConfigWrapperStack 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

68from ._core_metadata import CoreMetadata, update_core_metadata 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

69from ._core_utils import ( 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

70 get_ref, 

71 get_type_ref, 

72 is_list_like_schema_with_items_schema, 

73 validate_core_schema, 

74) 

75from ._decorators import ( 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

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

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

91from ._forward_ref import PydanticRecursiveRef 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

92from ._generics import get_standard_typevars_map, replace_types 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

93from ._import_utils import import_cached_base_model, import_cached_field_info 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

94from ._mock_val_ser import MockCoreSchema 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

95from ._namespace_utils import NamespacesTuple, NsResolver 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

96from ._schema_gather import MissingDefinitionError, gather_schemas_for_cleaning 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

97from ._schema_generation_shared import CallbackGetCoreSchemaHandler 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

98from ._utils import lenient_issubclass, smart_deepcopy 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

99 

100if TYPE_CHECKING: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

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) 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

108 

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

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

111AnyFieldDecorator = Union[ 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

112 Decorator[ValidatorDecoratorInfo], 

113 Decorator[FieldValidatorDecoratorInfo], 

114 Decorator[FieldSerializerDecoratorInfo], 

115] 

116 

117ModifyCoreSchemaWrapHandler: TypeAlias = GetCoreSchemaHandler 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

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

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

120 

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

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

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

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

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

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

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

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

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

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

131PATH_TYPES: list[type] = [ 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

132 os.PathLike, 

133 pathlib.Path, 

134 pathlib.PurePath, 

135 pathlib.PosixPath, 

136 pathlib.PurePosixPath, 

137 pathlib.PureWindowsPath, 

138] 

139MAPPING_TYPES = [ 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

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] 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

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

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[ 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

155 LambdaType, 

156 FunctionType, 

157 MethodType, 

158 partial, 

159] 

160 

161VALIDATE_CALL_SUPPORTED_TYPES = get_args(ValidateCallSupportedTypes) 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

162 

163_mode_to_validator: dict[ 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

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( 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

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

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

183 

184 

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

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) 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

198 for dec in decorators: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

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

200 continue 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

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

202 continue 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

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

204 if field not in fields: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

205 raise PydanticUserError( 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

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( 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

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)] 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

216 

217 

218def apply_each_item_validators( 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

219 schema: core_schema.CoreSchema, 

220 each_item_validators: list[Decorator[ValidatorDecoratorInfo]], 

221 field_name: str | None, 

222) -> core_schema.CoreSchema: 

223 # This V1 compatibility shim should eventually be removed 

224 

225 # fail early if each_item_validators is empty 

226 if not each_item_validators: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

227 return schema 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

228 

229 # push down any `each_item=True` validators 

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

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

232 if schema['type'] == 'nullable': 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

233 schema['schema'] = apply_each_item_validators(schema['schema'], each_item_validators, field_name) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

234 return schema 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

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

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

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

238 schema['items_schema'][variadic_item_index], 

239 each_item_validators, 

240 field_name, 

241 ) 

242 elif is_list_like_schema_with_items_schema(schema): 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

243 inner_schema = schema.get('items_schema', core_schema.any_schema()) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

244 schema['items_schema'] = apply_validators(inner_schema, each_item_validators, field_name) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

245 elif schema['type'] == 'dict': 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

246 inner_schema = schema.get('values_schema', core_schema.any_schema()) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

247 schema['values_schema'] = apply_validators(inner_schema, each_item_validators, field_name) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

248 else: 

249 raise TypeError( 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

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

251 ) 

252 return schema 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

253 

254 

255def _extract_json_schema_info_from_field_info( 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

256 info: FieldInfo | ComputedFieldInfo, 

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

258 json_schema_updates = { 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

259 'title': info.title, 

260 'description': info.description, 

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

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

263 } 

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

265 return (json_schema_updates or None, info.json_schema_extra) 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

266 

267 

268JsonEncoders = dict[type[Any], JsonEncoder] 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

269 

270 

271def _add_custom_serialization_from_json_encoders( 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

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

273) -> CoreSchema: 

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

275 

276 Args: 

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

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

279 schema: The schema to add the encoder to. 

280 """ 

281 if not json_encoders: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

282 return schema 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

283 if 'serialization' in schema: 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

284 return schema 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

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

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

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

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

289 encoder = json_encoders.get(base) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

290 if encoder is None: 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

291 continue 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

292 

293 warnings.warn( 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

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

295 PydanticDeprecatedSince20, 

296 ) 

297 

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

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

300 return schema 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

301 

302 return schema 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

303 

304 

305def _get_first_non_null(a: Any, b: Any) -> Any: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

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

307 

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

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

310 """ 

311 return a if a is not None else b 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

312 

313 

314class InvalidSchemaError(Exception): 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

315 """The core schema is invalid.""" 

316 

317 

318class GenerateSchema: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

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

320 

321 __slots__ = ( 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

322 '_config_wrapper_stack', 

323 '_ns_resolver', 

324 '_typevars_map', 

325 'field_name_stack', 

326 'model_type_stack', 

327 'defs', 

328 ) 

329 

330 def __init__( 1abdjoquwxCDghlmrsyzEFGOJKLMNPcifnptvABHI

331 self, 

332 config_wrapper: ConfigWrapper, 

333 ns_resolver: NsResolver | None = None, 

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

335 ) -> None: 

336 # we need a stack for recursing into nested models 

337 self._config_wrapper_stack = ConfigWrapperStack(config_wrapper) 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

338 self._ns_resolver = ns_resolver or NsResolver() 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

339 self._typevars_map = typevars_map 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

340 self.field_name_stack = _FieldNameStack() 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

341 self.model_type_stack = _ModelTypeStack() 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

342 self.defs = _Definitions() 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

343 

344 def __init_subclass__(cls) -> None: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

345 super().__init_subclass__() 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

346 warnings.warn( 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

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

348 UserWarning, 

349 stacklevel=2, 

350 ) 

351 

352 @property 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

353 def _config_wrapper(self) -> ConfigWrapper: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

354 return self._config_wrapper_stack.tail 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

355 

356 @property 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

357 def _types_namespace(self) -> NamespacesTuple: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

358 return self._ns_resolver.types_namespace 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

359 

360 @property 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

361 def _arbitrary_types(self) -> bool: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

362 return self._config_wrapper.arbitrary_types_allowed 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

363 

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

365 # unstable / private APIs 

366 def _list_schema(self, items_type: Any) -> CoreSchema: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

367 return core_schema.list_schema(self.generate_schema(items_type)) 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

368 

369 def _dict_schema(self, keys_type: Any, values_type: Any) -> CoreSchema: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

370 return core_schema.dict_schema(self.generate_schema(keys_type), self.generate_schema(values_type)) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

371 

372 def _set_schema(self, items_type: Any) -> CoreSchema: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

373 return core_schema.set_schema(self.generate_schema(items_type)) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

374 

375 def _frozenset_schema(self, items_type: Any) -> CoreSchema: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

376 return core_schema.frozenset_schema(self.generate_schema(items_type)) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

377 

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

379 cases: list[Any] = list(enum_type.__members__.values()) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

380 

381 enum_ref = get_type_ref(enum_type) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

382 description = None if not enum_type.__doc__ else inspect.cleandoc(enum_type.__doc__) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

383 if ( 1abke

384 description == 'An enumeration.' 

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

386 description = None 1abdjkeghlmcifn

387 js_updates = {'title': enum_type.__name__, 'description': description} 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

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

389 

390 sub_type: Literal['str', 'int', 'float'] | None = None 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

391 if issubclass(enum_type, int): 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

392 sub_type = 'int' 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

393 value_ser_type: core_schema.SerSchema = core_schema.simple_ser_schema('int') 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

394 elif issubclass(enum_type, str): 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

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

396 sub_type = 'str' 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

397 value_ser_type = core_schema.simple_ser_schema('str') 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

398 elif issubclass(enum_type, float): 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

399 sub_type = 'float' 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

400 value_ser_type = core_schema.simple_ser_schema('float') 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

401 else: 

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

403 value_ser_type = core_schema.plain_serializer_function_ser_schema(lambda x: x) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

404 

405 if cases: 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

406 

407 def get_json_schema(schema: CoreSchema, handler: GetJsonSchemaHandler) -> JsonSchemaValue: 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

408 json_schema = handler(schema) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

409 original_schema = handler.resolve_ref_schema(json_schema) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

410 original_schema.update(js_updates) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

411 return json_schema 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

412 

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

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

415 enum_schema = core_schema.enum_schema( 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

416 enum_type, 

417 cases, 

418 sub_type=sub_type, 

419 missing=None if default_missing else enum_type._missing_, 

420 ref=enum_ref, 

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

422 ) 

423 

424 if self._config_wrapper.use_enum_values: 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

425 enum_schema = core_schema.no_info_after_validator_function( 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

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

427 ) 

428 

429 return enum_schema 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

430 

431 else: 

432 

433 def get_json_schema_no_cases(_, handler: GetJsonSchemaHandler) -> JsonSchemaValue: 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

434 json_schema = handler(core_schema.enum_schema(enum_type, cases, sub_type=sub_type, ref=enum_ref)) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

435 original_schema = handler.resolve_ref_schema(json_schema) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

436 original_schema.update(js_updates) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

437 return json_schema 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

438 

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

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

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

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

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

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

445 return core_schema.is_instance_schema( 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

446 enum_type, 

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

448 ) 

449 

450 def _ip_schema(self, tp: Any) -> CoreSchema: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

451 from ._validators import IP_VALIDATOR_LOOKUP, IpType 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

452 

453 ip_type_json_schema_format: dict[type[IpType], str] = { 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

454 IPv4Address: 'ipv4', 

455 IPv4Network: 'ipv4network', 

456 IPv4Interface: 'ipv4interface', 

457 IPv6Address: 'ipv6', 

458 IPv6Network: 'ipv6network', 

459 IPv6Interface: 'ipv6interface', 

460 } 

461 

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

463 if not isinstance(ip, (tp, str)): 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

464 raise PydanticSerializationUnexpectedValue( 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

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

466 ) 

467 if info.mode == 'python': 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

468 return ip 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

469 return str(ip) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

470 

471 return core_schema.lax_or_strict_schema( 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

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

473 strict_schema=core_schema.json_or_python_schema( 

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

475 python_schema=core_schema.is_instance_schema(tp), 

476 ), 

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

478 metadata={ 

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

480 }, 

481 ) 

482 

483 def _path_schema(self, tp: Any, path_type: Any) -> CoreSchema: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

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

485 raise PydanticUserError( 

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

487 ) 

488 

489 path_constructor = pathlib.PurePath if tp is os.PathLike else tp 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

490 strict_inner_schema = ( 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

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

492 ) 

493 lax_inner_schema = core_schema.bytes_schema() if (path_type is bytes) else core_schema.str_schema() 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

494 

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

496 try: 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

497 if path_type is bytes: 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

498 if isinstance(input_value, bytes): 498 ↛ 504line 498 didn't jump to line 504 because the condition on line 498 was always true1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

499 try: 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

500 input_value = input_value.decode() 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

501 except UnicodeDecodeError as e: 

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

503 else: 

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

505 elif not isinstance(input_value, str): 505 ↛ 506line 505 didn't jump to line 506 because the condition on line 505 was never true1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

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

507 

508 return path_constructor(input_value) # type: ignore 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

509 except TypeError as e: 

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

511 

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

513 if not isinstance(path, (tp, str)): 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

514 raise PydanticSerializationUnexpectedValue( 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

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

516 ) 

517 if info.mode == 'python': 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

518 return path 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

519 return str(path) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

520 

521 instance_schema = core_schema.json_or_python_schema( 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

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

523 python_schema=core_schema.is_instance_schema(tp), 

524 ) 

525 

526 schema = core_schema.lax_or_strict_schema( 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

527 lax_schema=core_schema.union_schema( 

528 [ 

529 instance_schema, 

530 core_schema.no_info_after_validator_function(path_validator, strict_inner_schema), 

531 ], 

532 custom_error_type='path_type', 

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

534 ), 

535 strict_schema=instance_schema, 

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

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

538 ) 

539 return schema 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

540 

541 def _deque_schema(self, items_type: Any) -> CoreSchema: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

542 from ._serializers import serialize_sequence_via_list 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

543 from ._validators import deque_validator 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

544 

545 item_type_schema = self.generate_schema(items_type) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

546 

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

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

549 list_schema = core_schema.list_schema(item_type_schema, strict=False) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

550 

551 check_instance = core_schema.json_or_python_schema( 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

552 json_schema=list_schema, 

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

554 ) 

555 

556 lax_schema = core_schema.no_info_wrap_validator_function(deque_validator, list_schema) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

557 

558 return core_schema.lax_or_strict_schema( 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

559 lax_schema=lax_schema, 

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

561 serialization=core_schema.wrap_serializer_function_ser_schema( 

562 serialize_sequence_via_list, schema=item_type_schema, info_arg=True 

563 ), 

564 ) 

565 

566 def _mapping_schema(self, tp: Any, keys_type: Any, values_type: Any) -> CoreSchema: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

567 from ._validators import MAPPING_ORIGIN_MAP, defaultdict_validator, get_defaultdict_default_default_factory 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

568 

569 mapped_origin = MAPPING_ORIGIN_MAP[tp] 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

570 keys_schema = self.generate_schema(keys_type) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

571 values_schema = self.generate_schema(values_type) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

572 dict_schema = core_schema.dict_schema(keys_schema, values_schema, strict=False) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

573 

574 if mapped_origin is dict: 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

575 schema = dict_schema 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

576 else: 

577 check_instance = core_schema.json_or_python_schema( 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

578 json_schema=dict_schema, 

579 python_schema=core_schema.is_instance_schema(mapped_origin), 

580 ) 

581 

582 if tp is collections.defaultdict: 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

583 default_default_factory = get_defaultdict_default_default_factory(values_type) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

584 coerce_instance_wrap = partial( 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

585 core_schema.no_info_wrap_validator_function, 

586 partial(defaultdict_validator, default_default_factory=default_default_factory), 

587 ) 

588 else: 

589 coerce_instance_wrap = partial(core_schema.no_info_after_validator_function, mapped_origin) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

590 

591 lax_schema = coerce_instance_wrap(dict_schema) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

592 strict_schema = core_schema.chain_schema([check_instance, lax_schema]) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

593 

594 schema = core_schema.lax_or_strict_schema( 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

595 lax_schema=lax_schema, 

596 strict_schema=strict_schema, 

597 serialization=core_schema.wrap_serializer_function_ser_schema( 

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

599 ), 

600 ) 

601 

602 return schema 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

603 

604 def _fraction_schema(self) -> CoreSchema: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

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

606 from ._validators import fraction_validator 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

607 

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

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

610 return core_schema.lax_or_strict_schema( 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

611 lax_schema=core_schema.no_info_plain_validator_function(fraction_validator), 

612 strict_schema=core_schema.json_or_python_schema( 

613 json_schema=core_schema.no_info_plain_validator_function(fraction_validator), 

614 python_schema=core_schema.is_instance_schema(Fraction), 

615 ), 

616 # use str serialization to guarantee round trip behavior 

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

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

619 ) 

620 

621 def _arbitrary_type_schema(self, tp: Any) -> CoreSchema: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

622 if not isinstance(tp, type): 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

623 warn( 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

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

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

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

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

628 UserWarning, 

629 ) 

630 return core_schema.any_schema() 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

631 return core_schema.is_instance_schema(tp) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

632 

633 def _unknown_type_schema(self, obj: Any) -> CoreSchema: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

634 raise PydanticSchemaGenerationError( 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

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

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

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

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

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

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

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

642 ) 

643 

644 def _apply_discriminator_to_union( 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

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

646 ) -> CoreSchema: 

647 if discriminator is None: 647 ↛ 648line 647 didn't jump to line 648 because the condition on line 647 was never true1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

648 return schema 

649 try: 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

650 return _discriminated_union.apply_discriminator( 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

651 schema, 

652 discriminator, 

653 self.defs._definitions, 

654 ) 

655 except _discriminated_union.MissingDefinitionForUnionRef: 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

656 # defer until defs are resolved 

657 _discriminated_union.set_discriminator_in_metadata( 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

658 schema, 

659 discriminator, 

660 ) 

661 return schema 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

662 

663 def clean_schema(self, schema: CoreSchema) -> CoreSchema: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

664 schema = self.defs.finalize_schema(schema) 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

665 schema = validate_core_schema(schema) 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

666 return schema 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

667 

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

669 metadata = metadata_schema.get('metadata', {}) 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

670 pydantic_js_functions = metadata.setdefault('pydantic_js_functions', []) 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

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

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

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

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

675 if js_function not in pydantic_js_functions: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

676 pydantic_js_functions.append(js_function) 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

677 metadata_schema['metadata'] = metadata 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

678 

679 def generate_schema( 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

680 self, 

681 obj: Any, 

682 ) -> core_schema.CoreSchema: 

683 """Generate core schema. 

684 

685 Args: 

686 obj: The object to generate core schema for. 

687 

688 Returns: 

689 The generated core schema. 

690 

691 Raises: 

692 PydanticUndefinedAnnotation: 

693 If it is not possible to evaluate forward reference. 

694 PydanticSchemaGenerationError: 

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

696 TypeError: 

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

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

699 PydanticUserError: 

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

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

702 """ 

703 schema = self._generate_schema_from_get_schema_method(obj, obj) 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

704 

705 if schema is None: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

706 schema = self._generate_schema_inner(obj) 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

707 

708 metadata_js_function = _extract_get_pydantic_json_schema(obj) 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

709 if metadata_js_function is not None: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

710 metadata_schema = resolve_original_schema(schema, self.defs) 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

711 if metadata_schema: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

712 self._add_js_function(metadata_schema, metadata_js_function) 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

713 

714 schema = _add_custom_serialization_from_json_encoders(self._config_wrapper.json_encoders, obj, schema) 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

715 

716 return schema 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

717 

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

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

720 BaseModel_ = import_cached_base_model() 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

721 

722 with self.defs.get_schema_or_ref(cls) as (model_ref, maybe_schema): 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

723 if maybe_schema is not None: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

724 return maybe_schema 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

725 

726 schema = cls.__dict__.get('__pydantic_core_schema__') 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

727 if schema is not None and not isinstance(schema, MockCoreSchema): 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

728 if schema['type'] == 'definitions': 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

729 schema = self.defs.unpack_definitions(schema) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

730 ref = get_ref(schema) 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

731 if ref: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

732 return self.defs.create_definition_reference_schema(schema) 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

733 else: 

734 return schema 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

735 

736 config_wrapper = ConfigWrapper(cls.model_config, check=False) 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

737 

738 with self._config_wrapper_stack.push(config_wrapper), self._ns_resolver.push(cls): 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

739 core_config = self._config_wrapper.core_config(title=cls.__name__) 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

740 

741 if cls.__pydantic_fields_complete__ or cls is BaseModel_: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

742 fields = getattr(cls, '__pydantic_fields__', {}) 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

743 else: 

744 try: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

745 fields = rebuild_model_fields( 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

746 cls, 

747 ns_resolver=self._ns_resolver, 

748 typevars_map=self._typevars_map or {}, 

749 ) 

750 except NameError as e: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

751 raise PydanticUndefinedAnnotation.from_name_error(e) from e 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

752 

753 decorators = cls.__pydantic_decorators__ 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

754 computed_fields = decorators.computed_fields 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

755 check_decorator_fields_exist( 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

756 chain( 

757 decorators.field_validators.values(), 

758 decorators.field_serializers.values(), 

759 decorators.validators.values(), 

760 ), 

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

762 ) 

763 

764 model_validators = decorators.model_validators.values() 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

765 

766 extras_schema = None 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

767 extras_keys_schema = None 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

768 if core_config.get('extra_fields_behavior') == 'allow': 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

769 assert cls.__mro__[0] is cls 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

770 assert cls.__mro__[-1] is object 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

771 for candidate_cls in cls.__mro__[:-1]: 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

772 extras_annotation = getattr(candidate_cls, '__annotations__', {}).get( 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

773 '__pydantic_extra__', None 

774 ) 

775 if extras_annotation is not None: 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

776 if isinstance(extras_annotation, str): 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

777 extras_annotation = _typing_extra.eval_type_backport( 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

778 _typing_extra._make_forward_ref( 

779 extras_annotation, is_argument=False, is_class=True 

780 ), 

781 *self._types_namespace, 

782 ) 

783 tp = get_origin(extras_annotation) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

784 if tp not in DICT_TYPES: 784 ↛ 785line 784 didn't jump to line 785 because the condition on line 784 was never true1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

785 raise PydanticSchemaGenerationError( 

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

787 ) 

788 extra_keys_type, extra_items_type = self._get_args_resolving_forward_refs( 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

789 extras_annotation, 

790 required=True, 

791 ) 

792 if extra_keys_type is not str: 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

793 extras_keys_schema = self.generate_schema(extra_keys_type) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

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

795 extras_schema = self.generate_schema(extra_items_type) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

796 if extras_keys_schema is not None or extras_schema is not None: 796 ↛ 771line 796 didn't jump to line 771 because the condition on line 796 was always true1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

797 break 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

798 

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

800 

801 if cls.__pydantic_root_model__: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

802 root_field = self._common_field_schema('root', fields['root'], decorators) 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

803 inner_schema = root_field['schema'] 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

804 inner_schema = apply_model_validators(inner_schema, model_validators, 'inner') 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

805 model_schema = core_schema.model_schema( 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

806 cls, 

807 inner_schema, 

808 generic_origin=generic_origin, 

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

810 root_model=True, 

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

812 config=core_config, 

813 ref=model_ref, 

814 ) 

815 else: 

816 fields_schema: core_schema.CoreSchema = core_schema.model_fields_schema( 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

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

818 computed_fields=[ 

819 self._computed_field_schema(d, decorators.field_serializers) 

820 for d in computed_fields.values() 

821 ], 

822 extras_schema=extras_schema, 

823 extras_keys_schema=extras_keys_schema, 

824 model_name=cls.__name__, 

825 ) 

826 inner_schema = apply_validators(fields_schema, decorators.root_validators.values(), None) 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

827 inner_schema = apply_model_validators(inner_schema, model_validators, 'inner') 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

828 

829 model_schema = core_schema.model_schema( 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

830 cls, 

831 inner_schema, 

832 generic_origin=generic_origin, 

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

834 root_model=False, 

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

836 config=core_config, 

837 ref=model_ref, 

838 ) 

839 

840 schema = self._apply_model_serializers(model_schema, decorators.model_serializers.values()) 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

841 schema = apply_model_validators(schema, model_validators, 'outer') 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

842 return self.defs.create_definition_reference_schema(schema) 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

843 

844 def _resolve_self_type(self, obj: Any) -> Any: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

845 obj = self.model_type_stack.get() 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

846 if obj is None: 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

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

848 return obj 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

849 

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

851 BaseModel_ = import_cached_base_model() 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

852 

853 get_schema = getattr(obj, '__get_pydantic_core_schema__', None) 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

854 is_base_model_get_schema = ( 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

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

856 ) 

857 

858 if ( 1abkeghOci

859 get_schema is not None 

860 # BaseModel.__get_pydantic_core_schema__ is defined for backwards compatibility, 

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

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

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

864 # don't call the method: 

865 and not is_base_model_get_schema 

866 ): 

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

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

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

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

871 # not referenceable: 

872 with self.defs.get_schema_or_ref(obj) as (_, maybe_schema): 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

873 if maybe_schema is not None: 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

874 return maybe_schema 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

875 

876 if obj is source: 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

877 ref_mode = 'unpack' 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

878 else: 

879 ref_mode = 'to-def' 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

880 schema = get_schema( 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

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

882 ) 

883 if schema['type'] == 'definitions': 883 ↛ 884line 883 didn't jump to line 884 because the condition on line 883 was never true1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

884 schema = self.defs.unpack_definitions(schema) 

885 

886 ref = get_ref(schema) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

887 if ref: 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

888 return self.defs.create_definition_reference_schema(schema) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

889 

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

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

892 return schema 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

893 

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

895 from pydantic.v1 import BaseModel as BaseModelV1 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

896 

897 if issubclass(obj, BaseModelV1): 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

898 warn( 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

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

900 UserWarning, 

901 ) 

902 else: 

903 warn( 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

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

905 PydanticDeprecatedSince20, 

906 ) 

907 return core_schema.chain_schema([core_schema.with_info_plain_validator_function(v) for v in validators()]) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

908 

909 def _resolve_forward_ref(self, obj: Any) -> Any: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

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

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

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

913 # `Validator(SomeImportedTypeAliasWithAForwardReference)` 

914 # or the equivalent for BaseModel 

915 # class Model(BaseModel): 

916 # x: SomeImportedTypeAliasWithAForwardReference 

917 try: 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

918 obj = _typing_extra.eval_type_backport(obj, *self._types_namespace) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

919 except NameError as e: 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

920 raise PydanticUndefinedAnnotation.from_name_error(e) from e 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

921 

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

923 if isinstance(obj, ForwardRef): 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

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

925 

926 if self._typevars_map: 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

927 obj = replace_types(obj, self._typevars_map) 1abdjkeghlmcifn

928 

929 return obj 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

930 

931 @overload 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

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

933 

934 @overload 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

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

936 

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

938 args = get_args(obj) 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

939 if args: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

940 if isinstance(obj, GenericAlias): 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

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

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

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

944 elif required: # pragma: no cover 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

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

946 return args 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

947 

948 def _get_first_arg_or_any(self, obj: Any) -> Any: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

949 args = self._get_args_resolving_forward_refs(obj) 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

950 if not args: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

951 return Any 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

952 return args[0] 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

953 

954 def _get_first_two_args_or_any(self, obj: Any) -> tuple[Any, Any]: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

955 args = self._get_args_resolving_forward_refs(obj) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

956 if not args: 956 ↛ 957line 956 didn't jump to line 957 because the condition on line 956 was never true1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

957 return (Any, Any) 

958 if len(args) < 2: 958 ↛ 959line 958 didn't jump to line 959 because the condition on line 958 was never true1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

959 origin = get_origin(obj) 

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

961 return args[0], args[1] 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

962 

963 def _generate_schema_inner(self, obj: Any) -> core_schema.CoreSchema: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

964 if typing_objects.is_self(obj): 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

965 obj = self._resolve_self_type(obj) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

966 

967 if typing_objects.is_annotated(get_origin(obj)): 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

968 return self._annotated_schema(obj) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

969 

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

971 # we assume this is already a valid schema 

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

973 

974 if isinstance(obj, str): 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

975 obj = ForwardRef(obj) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

976 

977 if isinstance(obj, ForwardRef): 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

978 return self.generate_schema(self._resolve_forward_ref(obj)) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

979 

980 BaseModel = import_cached_base_model() 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

981 

982 if lenient_issubclass(obj, BaseModel): 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

983 with self.model_type_stack.push(obj): 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

984 return self._model_schema(obj) 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

985 

986 if isinstance(obj, PydanticRecursiveRef): 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

987 return core_schema.definition_reference_schema(schema_ref=obj.type_ref) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

988 

989 return self.match_type(obj) 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

990 

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

992 """Main mapping of types to schemas. 

993 

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

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

996 

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

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

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

1000 

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

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

1003 """ 

1004 if obj is str: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1005 return core_schema.str_schema() 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1006 elif obj is bytes: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1007 return core_schema.bytes_schema() 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1008 elif obj is int: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1009 return core_schema.int_schema() 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1010 elif obj is float: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1011 return core_schema.float_schema() 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1012 elif obj is bool: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1013 return core_schema.bool_schema() 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1014 elif obj is complex: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1015 return core_schema.complex_schema() 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1016 elif typing_objects.is_any(obj) or obj is object: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1017 return core_schema.any_schema() 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1018 elif obj is datetime.date: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1019 return core_schema.date_schema() 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1020 elif obj is datetime.datetime: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1021 return core_schema.datetime_schema() 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1022 elif obj is datetime.time: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1023 return core_schema.time_schema() 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1024 elif obj is datetime.timedelta: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1025 return core_schema.timedelta_schema() 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1026 elif obj is Decimal: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1027 return core_schema.decimal_schema() 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1028 elif obj is UUID: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1029 return core_schema.uuid_schema() 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1030 elif obj is Url: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1031 return core_schema.url_schema() 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1032 elif obj is Fraction: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1033 return self._fraction_schema() 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1034 elif obj is MultiHostUrl: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1035 return core_schema.multi_host_url_schema() 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1036 elif obj is None or obj is _typing_extra.NoneType: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1037 return core_schema.none_schema() 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1038 elif obj in IP_TYPES: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1039 return self._ip_schema(obj) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1040 elif obj in TUPLE_TYPES: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1041 return self._tuple_schema(obj) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1042 elif obj in LIST_TYPES: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1043 return self._list_schema(Any) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1044 elif obj in SET_TYPES: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1045 return self._set_schema(Any) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1046 elif obj in FROZEN_SET_TYPES: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1047 return self._frozenset_schema(Any) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1048 elif obj in SEQUENCE_TYPES: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1049 return self._sequence_schema(Any) 1adouxcfpvB

1050 elif obj in ITERABLE_TYPES: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1051 return self._iterable_schema(obj) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1052 elif obj in DICT_TYPES: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1053 return self._dict_schema(Any, Any) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1054 elif obj in PATH_TYPES: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1055 return self._path_schema(obj, Any) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1056 elif obj in DEQUE_TYPES: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1057 return self._deque_schema(Any) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1058 elif obj in MAPPING_TYPES: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1059 return self._mapping_schema(obj, Any, Any) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1060 elif obj in COUNTER_TYPES: 1060 ↛ 1061line 1060 didn't jump to line 1061 because the condition on line 1060 was never true1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

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

1062 elif typing_objects.is_typealiastype(obj): 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1063 return self._type_alias_type_schema(obj) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1064 elif obj is type: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1065 return self._type_schema() 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1066 elif _typing_extra.is_callable(obj): 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1067 return core_schema.callable_schema() 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1068 elif typing_objects.is_literal(get_origin(obj)): 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1069 return self._literal_schema(obj) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1070 elif is_typeddict(obj): 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1071 return self._typed_dict_schema(obj, None) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1072 elif _typing_extra.is_namedtuple(obj): 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1073 return self._namedtuple_schema(obj, None) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1074 elif typing_objects.is_newtype(obj): 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

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

1076 return self.generate_schema(obj.__supertype__) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1077 elif obj in PATTERN_TYPES: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1078 return self._pattern_schema(obj) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1079 elif _typing_extra.is_hashable(obj): 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1080 return self._hashable_schema() 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1081 elif isinstance(obj, typing.TypeVar): 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1082 return self._unsubstituted_typevar_schema(obj) 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1083 elif _typing_extra.is_finalvar(obj): 1083 ↛ 1084line 1083 didn't jump to line 1084 because the condition on line 1083 was never true1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1084 if obj is Final: 

1085 return core_schema.any_schema() 

1086 return self.generate_schema( 

1087 self._get_first_arg_or_any(obj), 

1088 ) 

1089 elif isinstance(obj, VALIDATE_CALL_SUPPORTED_TYPES): 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1090 return self._call_schema(obj) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1091 elif inspect.isclass(obj) and issubclass(obj, Enum): 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1092 return self._enum_schema(obj) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1093 elif obj is ZoneInfo: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1094 return self._zoneinfo_schema() 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1095 

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

1097 # the case of a dc type here 

1098 if dataclasses.is_dataclass(obj): 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

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

1100 

1101 origin = get_origin(obj) 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1102 if origin is not None: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1103 return self._match_generic_type(obj, origin) 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1104 

1105 if self._arbitrary_types: 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1106 return self._arbitrary_type_schema(obj) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1107 return self._unknown_type_schema(obj) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1108 

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

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

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

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

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

1114 if dataclasses.is_dataclass(origin): 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

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

1116 if _typing_extra.is_namedtuple(origin): 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1117 return self._namedtuple_schema(obj, origin) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1118 

1119 schema = self._generate_schema_from_get_schema_method(origin, obj) 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1120 if schema is not None: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1121 return schema 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1122 

1123 if typing_objects.is_typealiastype(origin): 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1124 return self._type_alias_type_schema(obj) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1125 elif is_union_origin(origin): 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1126 return self._union_schema(obj) 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1127 elif origin in TUPLE_TYPES: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1128 return self._tuple_schema(obj) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1129 elif origin in LIST_TYPES: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1130 return self._list_schema(self._get_first_arg_or_any(obj)) 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1131 elif origin in SET_TYPES: 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1132 return self._set_schema(self._get_first_arg_or_any(obj)) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1133 elif origin in FROZEN_SET_TYPES: 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1134 return self._frozenset_schema(self._get_first_arg_or_any(obj)) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1135 elif origin in DICT_TYPES: 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1136 return self._dict_schema(*self._get_first_two_args_or_any(obj)) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1137 elif origin in PATH_TYPES: 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1138 return self._path_schema(origin, self._get_first_arg_or_any(obj)) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1139 elif origin in DEQUE_TYPES: 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1140 return self._deque_schema(self._get_first_arg_or_any(obj)) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1141 elif origin in MAPPING_TYPES: 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1142 return self._mapping_schema(origin, *self._get_first_two_args_or_any(obj)) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1143 elif origin in COUNTER_TYPES: 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1144 return self._mapping_schema(origin, self._get_first_arg_or_any(obj), int) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1145 elif is_typeddict(origin): 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1146 return self._typed_dict_schema(obj, origin) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1147 elif origin in TYPE_TYPES: 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1148 return self._subclass_schema(obj) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1149 elif origin in SEQUENCE_TYPES: 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1150 return self._sequence_schema(self._get_first_arg_or_any(obj)) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1151 elif origin in ITERABLE_TYPES: 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1152 return self._iterable_schema(obj) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1153 elif origin in PATTERN_TYPES: 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1154 return self._pattern_schema(obj) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1155 

1156 if self._arbitrary_types: 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1157 return self._arbitrary_type_schema(origin) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1158 return self._unknown_type_schema(obj) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1159 

1160 def _generate_td_field_schema( 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1161 self, 

1162 name: str, 

1163 field_info: FieldInfo, 

1164 decorators: DecoratorInfos, 

1165 *, 

1166 required: bool = True, 

1167 ) -> core_schema.TypedDictField: 

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

1169 common_field = self._common_field_schema(name, field_info, decorators) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1170 return core_schema.typed_dict_field( 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1171 common_field['schema'], 

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

1173 serialization_exclude=common_field['serialization_exclude'], 

1174 validation_alias=common_field['validation_alias'], 

1175 serialization_alias=common_field['serialization_alias'], 

1176 metadata=common_field['metadata'], 

1177 ) 

1178 

1179 def _generate_md_field_schema( 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1180 self, 

1181 name: str, 

1182 field_info: FieldInfo, 

1183 decorators: DecoratorInfos, 

1184 ) -> core_schema.ModelField: 

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

1186 common_field = self._common_field_schema(name, field_info, decorators) 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1187 return core_schema.model_field( 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1188 common_field['schema'], 

1189 serialization_exclude=common_field['serialization_exclude'], 

1190 validation_alias=common_field['validation_alias'], 

1191 serialization_alias=common_field['serialization_alias'], 

1192 frozen=common_field['frozen'], 

1193 metadata=common_field['metadata'], 

1194 ) 

1195 

1196 def _generate_dc_field_schema( 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1197 self, 

1198 name: str, 

1199 field_info: FieldInfo, 

1200 decorators: DecoratorInfos, 

1201 ) -> core_schema.DataclassField: 

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

1203 common_field = self._common_field_schema(name, field_info, decorators) 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1204 return core_schema.dataclass_field( 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1205 name, 

1206 common_field['schema'], 

1207 init=field_info.init, 

1208 init_only=field_info.init_var or None, 

1209 kw_only=None if field_info.kw_only else False, 

1210 serialization_exclude=common_field['serialization_exclude'], 

1211 validation_alias=common_field['validation_alias'], 

1212 serialization_alias=common_field['serialization_alias'], 

1213 frozen=common_field['frozen'], 

1214 metadata=common_field['metadata'], 

1215 ) 

1216 

1217 @staticmethod 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1218 def _apply_alias_generator_to_field_info( 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

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

1220 ) -> None: 

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

1222 

1223 Args: 

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

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

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

1227 """ 

1228 # Apply an alias_generator if 

1229 # 1. An alias is not specified 

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

1231 if ( 1abkeghci

1232 field_info.alias_priority is None 

1233 or field_info.alias_priority <= 1 

1234 or field_info.alias is None 

1235 or field_info.validation_alias is None 

1236 or field_info.serialization_alias is None 

1237 ): 

1238 alias, validation_alias, serialization_alias = None, None, None 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1239 

1240 if isinstance(alias_generator, AliasGenerator): 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1241 alias, validation_alias, serialization_alias = alias_generator.generate_aliases(field_name) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1242 elif isinstance(alias_generator, Callable): 1242 ↛ 1250line 1242 didn't jump to line 1250 because the condition on line 1242 was always true1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1243 alias = alias_generator(field_name) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1244 if not isinstance(alias, str): 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

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

1246 

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

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

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

1250 if field_info.alias_priority is None or field_info.alias_priority <= 1: 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1251 field_info.alias_priority = 1 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1252 

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

1254 if field_info.alias_priority == 1: 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1255 field_info.serialization_alias = _get_first_non_null(serialization_alias, alias) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1256 field_info.validation_alias = _get_first_non_null(validation_alias, alias) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1257 field_info.alias = alias 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1258 

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

1260 if field_info.alias is None: 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1261 field_info.alias = alias 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1262 if field_info.serialization_alias is None: 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1263 field_info.serialization_alias = _get_first_non_null(serialization_alias, alias) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1264 if field_info.validation_alias is None: 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1265 field_info.validation_alias = _get_first_non_null(validation_alias, alias) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1266 

1267 @staticmethod 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1268 def _apply_alias_generator_to_computed_field_info( 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

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

1270 computed_field_info: ComputedFieldInfo, 

1271 computed_field_name: str, 

1272 ): 

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

1274 

1275 Args: 

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

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

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

1279 """ 

1280 # Apply an alias_generator if 

1281 # 1. An alias is not specified 

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

1283 

1284 if ( 1abke

1285 computed_field_info.alias_priority is None 

1286 or computed_field_info.alias_priority <= 1 

1287 or computed_field_info.alias is None 

1288 ): 

1289 alias, validation_alias, serialization_alias = None, None, None 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1290 

1291 if isinstance(alias_generator, AliasGenerator): 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1292 alias, validation_alias, serialization_alias = alias_generator.generate_aliases(computed_field_name) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1293 elif isinstance(alias_generator, Callable): 1293 ↛ 1301line 1293 didn't jump to line 1301 because the condition on line 1293 was always true1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1294 alias = alias_generator(computed_field_name) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1295 if not isinstance(alias, str): 1295 ↛ 1296line 1295 didn't jump to line 1296 because the condition on line 1295 was never true1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

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

1297 

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

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

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

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

1302 computed_field_info.alias_priority = 1 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1303 

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

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

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

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

1308 computed_field_info.alias = _get_first_non_null(serialization_alias, alias) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1309 

1310 @staticmethod 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1311 def _apply_field_title_generator_to_field_info( 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

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

1313 ) -> None: 

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

1315 Args: 

1316 config_wrapper: The config of the model 

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

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

1319 """ 

1320 field_title_generator = field_info.field_title_generator or config_wrapper.field_title_generator 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1321 

1322 if field_title_generator is None: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1323 return 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1324 

1325 if field_info.title is None: 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1326 title = field_title_generator(field_name, field_info) # type: ignore 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1327 if not isinstance(title, str): 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

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

1329 

1330 field_info.title = title 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1331 

1332 def _common_field_schema( # C901 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

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

1334 ) -> _CommonField: 

1335 source_type, annotations = field_info.annotation, field_info.metadata 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1336 

1337 def set_discriminator(schema: CoreSchema) -> CoreSchema: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1338 schema = self._apply_discriminator_to_union(schema, field_info.discriminator) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1339 return schema 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1340 

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

1342 validators_from_decorators = [] 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1343 for decorator in filter_field_decorator_info_by_field(decorators.field_validators.values(), name): 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1344 validators_from_decorators.append(_mode_to_validator[decorator.info.mode]._from_decorator(decorator)) 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1345 

1346 with self.field_name_stack.push(name): 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1347 if field_info.discriminator is not None: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1348 schema = self._apply_annotations( 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1349 source_type, annotations + validators_from_decorators, transform_inner_schema=set_discriminator 

1350 ) 

1351 else: 

1352 schema = self._apply_annotations( 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1353 source_type, 

1354 annotations + validators_from_decorators, 

1355 ) 

1356 

1357 # This V1 compatibility shim should eventually be removed 

1358 # push down any `each_item=True` validators 

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

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

1361 this_field_validators = filter_field_decorator_info_by_field(decorators.validators.values(), name) 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1362 if _validators_require_validate_default(this_field_validators): 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1363 field_info.validate_default = True 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1364 each_item_validators = [v for v in this_field_validators if v.info.each_item is True] 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1365 this_field_validators = [v for v in this_field_validators if v not in each_item_validators] 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1366 schema = apply_each_item_validators(schema, each_item_validators, name) 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1367 

1368 schema = apply_validators(schema, this_field_validators, name) 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1369 

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

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

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

1373 if not field_info.is_required(): 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1374 schema = wrap_default(field_info, schema) 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1375 

1376 schema = self._apply_field_serializers( 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

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

1378 ) 

1379 self._apply_field_title_generator_to_field_info(self._config_wrapper, field_info, name) 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1380 

1381 pydantic_js_updates, pydantic_js_extra = _extract_json_schema_info_from_field_info(field_info) 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1382 core_metadata: dict[str, Any] = {} 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1383 update_core_metadata( 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1384 core_metadata, pydantic_js_updates=pydantic_js_updates, pydantic_js_extra=pydantic_js_extra 

1385 ) 

1386 

1387 alias_generator = self._config_wrapper.alias_generator 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1388 if alias_generator is not None: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1389 self._apply_alias_generator_to_field_info(alias_generator, field_info, name) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1390 

1391 if isinstance(field_info.validation_alias, (AliasChoices, AliasPath)): 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1392 validation_alias = field_info.validation_alias.convert_to_aliases() 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1393 else: 

1394 validation_alias = field_info.validation_alias 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1395 

1396 return _common_field( 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1397 schema, 

1398 serialization_exclude=True if field_info.exclude else None, 

1399 validation_alias=validation_alias, 

1400 serialization_alias=field_info.serialization_alias, 

1401 frozen=field_info.frozen, 

1402 metadata=core_metadata, 

1403 ) 

1404 

1405 def _union_schema(self, union_type: Any) -> core_schema.CoreSchema: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1406 """Generate schema for a Union.""" 

1407 args = self._get_args_resolving_forward_refs(union_type, required=True) 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1408 choices: list[CoreSchema] = [] 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1409 nullable = False 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1410 for arg in args: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1411 if arg is None or arg is _typing_extra.NoneType: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1412 nullable = True 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1413 else: 

1414 choices.append(self.generate_schema(arg)) 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1415 

1416 if len(choices) == 1: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1417 s = choices[0] 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1418 else: 

1419 choices_with_tags: list[CoreSchema | tuple[CoreSchema, str]] = [] 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1420 for choice in choices: 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

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

1422 if tag is not None: 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1423 choices_with_tags.append((choice, tag)) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1424 else: 

1425 choices_with_tags.append(choice) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1426 s = core_schema.union_schema(choices_with_tags) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1427 

1428 if nullable: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1429 s = core_schema.nullable_schema(s) 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1430 return s 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1431 

1432 def _type_alias_type_schema(self, obj: TypeAliasType) -> CoreSchema: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1433 with self.defs.get_schema_or_ref(obj) as (ref, maybe_schema): 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1434 if maybe_schema is not None: 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1435 return maybe_schema 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1436 

1437 origin: TypeAliasType = get_origin(obj) or obj 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1438 typevars_map = get_standard_typevars_map(obj) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1439 

1440 with self._ns_resolver.push(origin): 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1441 try: 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1442 annotation = _typing_extra.eval_type(origin.__value__, *self._types_namespace) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1443 except NameError as e: 

1444 raise PydanticUndefinedAnnotation.from_name_error(e) from e 

1445 annotation = replace_types(annotation, typevars_map) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1446 schema = self.generate_schema(annotation) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1447 assert schema['type'] != 'definitions' 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1448 schema['ref'] = ref # type: ignore 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1449 return self.defs.create_definition_reference_schema(schema) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1450 

1451 def _literal_schema(self, literal_type: Any) -> CoreSchema: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1452 """Generate schema for a Literal.""" 

1453 expected = list(get_literal_values(literal_type, type_check=False, unpack_type_aliases='eager')) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

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

1455 schema = core_schema.literal_schema(expected) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1456 

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

1458 schema = core_schema.no_info_after_validator_function( 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

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

1460 ) 

1461 

1462 return schema 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1463 

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

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

1466 

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

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

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

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

1471 

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

1473 """ 

1474 FieldInfo = import_cached_field_info() 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1475 

1476 with ( 1abdjoqkeghlmrscifnpt

1477 self.model_type_stack.push(typed_dict_cls), 

1478 self.defs.get_schema_or_ref(typed_dict_cls) as ( 

1479 typed_dict_ref, 

1480 maybe_schema, 

1481 ), 

1482 ): 

1483 if maybe_schema is not None: 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1484 return maybe_schema 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1485 

1486 typevars_map = get_standard_typevars_map(typed_dict_cls) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1487 if origin is not None: 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1488 typed_dict_cls = origin 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1489 

1490 if not _SUPPORTS_TYPEDDICT and type(typed_dict_cls).__module__ == 'typing': 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1491 raise PydanticUserError( 1abdjoqkeghlmrscifnpt

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

1493 code='typed-dict-version', 

1494 ) 

1495 

1496 try: 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

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

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

1499 config: ConfigDict | None = get_attribute_from_bases(typed_dict_cls, '__pydantic_config__') 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1500 except AttributeError: 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1501 config = None 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1502 

1503 with self._config_wrapper_stack.push(config): 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1504 core_config = self._config_wrapper.core_config(title=typed_dict_cls.__name__) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1505 

1506 required_keys: frozenset[str] = typed_dict_cls.__required_keys__ 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1507 

1508 fields: dict[str, core_schema.TypedDictField] = {} 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1509 

1510 decorators = DecoratorInfos.build(typed_dict_cls) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1511 

1512 if self._config_wrapper.use_attribute_docstrings: 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1513 field_docstrings = extract_docstrings_from_cls(typed_dict_cls, use_inspect=True) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1514 else: 

1515 field_docstrings = None 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1516 

1517 try: 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1518 annotations = _typing_extra.get_cls_type_hints(typed_dict_cls, ns_resolver=self._ns_resolver) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1519 except NameError as e: 

1520 raise PydanticUndefinedAnnotation.from_name_error(e) from e 

1521 

1522 readonly_fields: list[str] = [] 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1523 

1524 for field_name, annotation in annotations.items(): 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1525 field_info = FieldInfo.from_annotation(annotation, _source=AnnotationSource.TYPED_DICT) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1526 field_info.annotation = replace_types(field_info.annotation, typevars_map) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1527 

1528 required = ( 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

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

1530 ) and 'not_required' not in field_info._qualifiers 

1531 if 'read_only' in field_info._qualifiers: 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1532 readonly_fields.append(field_name) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1533 

1534 if ( 1abkeghci

1535 field_docstrings is not None 

1536 and field_info.description is None 

1537 and field_name in field_docstrings 

1538 ): 

1539 field_info.description = field_docstrings[field_name] 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1540 self._apply_field_title_generator_to_field_info(self._config_wrapper, field_info, field_name) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1541 fields[field_name] = self._generate_td_field_schema( 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1542 field_name, field_info, decorators, required=required 

1543 ) 

1544 

1545 if readonly_fields: 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1546 fields_repr = ', '.join(repr(f) for f in readonly_fields) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1547 plural = len(readonly_fields) >= 2 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1548 warnings.warn( 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

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

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

1551 'from any mutation on dictionary instances.', 

1552 UserWarning, 

1553 ) 

1554 

1555 td_schema = core_schema.typed_dict_schema( 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1556 fields, 

1557 cls=typed_dict_cls, 

1558 computed_fields=[ 

1559 self._computed_field_schema(d, decorators.field_serializers) 

1560 for d in decorators.computed_fields.values() 

1561 ], 

1562 ref=typed_dict_ref, 

1563 config=core_config, 

1564 ) 

1565 

1566 schema = self._apply_model_serializers(td_schema, decorators.model_serializers.values()) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1567 schema = apply_model_validators(schema, decorators.model_validators.values(), 'all') 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1568 return self.defs.create_definition_reference_schema(schema) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1569 

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

1571 """Generate schema for a NamedTuple.""" 

1572 with ( 1abdjoqkeghlmrscifnpt

1573 self.model_type_stack.push(namedtuple_cls), 

1574 self.defs.get_schema_or_ref(namedtuple_cls) as ( 

1575 namedtuple_ref, 

1576 maybe_schema, 

1577 ), 

1578 ): 

1579 if maybe_schema is not None: 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1580 return maybe_schema 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1581 typevars_map = get_standard_typevars_map(namedtuple_cls) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1582 if origin is not None: 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1583 namedtuple_cls = origin 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1584 

1585 try: 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1586 annotations = _typing_extra.get_cls_type_hints(namedtuple_cls, ns_resolver=self._ns_resolver) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1587 except NameError as e: 

1588 raise PydanticUndefinedAnnotation.from_name_error(e) from e 

1589 if not annotations: 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

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

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

1592 

1593 if typevars_map: 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1594 annotations = { 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1595 field_name: replace_types(annotation, typevars_map) 

1596 for field_name, annotation in annotations.items() 

1597 } 

1598 

1599 arguments_schema = core_schema.arguments_schema( 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1600 [ 

1601 self._generate_parameter_schema( 

1602 field_name, 

1603 annotation, 

1604 source=AnnotationSource.NAMED_TUPLE, 

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

1606 ) 

1607 for field_name, annotation in annotations.items() 

1608 ], 

1609 metadata={'pydantic_js_prefer_positional_arguments': True}, 

1610 ) 

1611 schema = core_schema.call_schema(arguments_schema, namedtuple_cls, ref=namedtuple_ref) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1612 return self.defs.create_definition_reference_schema(schema) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1613 

1614 def _generate_parameter_schema( 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1615 self, 

1616 name: str, 

1617 annotation: type[Any], 

1618 source: AnnotationSource, 

1619 default: Any = Parameter.empty, 

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

1621 ) -> core_schema.ArgumentsParameter: 

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

1623 

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

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

1626 """ 

1627 FieldInfo = import_cached_field_info() 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1628 

1629 if default is Parameter.empty: 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1630 field = FieldInfo.from_annotation(annotation, _source=source) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1631 else: 

1632 field = FieldInfo.from_annotated_attribute(annotation, default, _source=source) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

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

1634 with self.field_name_stack.push(name): 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1635 schema = self._apply_annotations(field.annotation, [field]) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1636 

1637 if not field.is_required(): 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1638 schema = wrap_default(field, schema) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1639 

1640 parameter_schema = core_schema.arguments_parameter(name, schema) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1641 if mode is not None: 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1642 parameter_schema['mode'] = mode 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1643 if field.alias is not None: 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1644 parameter_schema['alias'] = field.alias 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1645 else: 

1646 alias_generator = self._config_wrapper.alias_generator 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

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

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

1649 elif callable(alias_generator): 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1650 parameter_schema['alias'] = alias_generator(name) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1651 return parameter_schema 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1652 

1653 def _generate_parameter_v3_schema( 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1654 self, 

1655 name: str, 

1656 annotation: Any, 

1657 source: AnnotationSource, 

1658 mode: Literal[ 

1659 'positional_only', 

1660 'positional_or_keyword', 

1661 'keyword_only', 

1662 'var_args', 

1663 'var_kwargs_uniform', 

1664 'var_kwargs_unpacked_typed_dict', 

1665 ], 

1666 default: Any = Parameter.empty, 

1667 ) -> core_schema.ArgumentsV3Parameter: 

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

1669 

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

1671 the `'arguments`' schema in V3. 

1672 """ 

1673 FieldInfo = import_cached_field_info() 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1674 

1675 if default is Parameter.empty: 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1676 field = FieldInfo.from_annotation(annotation, _source=source) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1677 else: 

1678 field = FieldInfo.from_annotated_attribute(annotation, default, _source=source) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1679 

1680 with self.field_name_stack.push(name): 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1681 schema = self._apply_annotations(field.annotation, [field]) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1682 

1683 if not field.is_required(): 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1684 schema = wrap_default(field, schema) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1685 

1686 parameter_schema = core_schema.arguments_v3_parameter( 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1687 name=name, 

1688 schema=schema, 

1689 mode=mode, 

1690 ) 

1691 if field.alias is not None: 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1692 parameter_schema['alias'] = field.alias 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1693 else: 

1694 alias_generator = self._config_wrapper.alias_generator 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1695 if isinstance(alias_generator, AliasGenerator) and alias_generator.alias is not None: 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

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

1697 elif callable(alias_generator): 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1698 parameter_schema['alias'] = alias_generator(name) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1699 

1700 return parameter_schema 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1701 

1702 def _tuple_schema(self, tuple_type: Any) -> core_schema.CoreSchema: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

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

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

1705 typevars_map = get_standard_typevars_map(tuple_type) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1706 params = self._get_args_resolving_forward_refs(tuple_type) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1707 

1708 if typevars_map and params: 1708 ↛ 1709line 1708 didn't jump to line 1709 because the condition on line 1708 was never true1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

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

1710 

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

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

1713 if not params: 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1714 if tuple_type in TUPLE_TYPES: 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1715 return core_schema.tuple_schema([core_schema.any_schema()], variadic_item_index=0) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1716 else: 

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

1718 return core_schema.tuple_schema([]) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1719 elif params[-1] is Ellipsis: 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1720 if len(params) == 2: 1720 ↛ 1724line 1720 didn't jump to line 1724 because the condition on line 1720 was always true1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

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

1722 else: 

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

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

1725 elif len(params) == 1 and params[0] == (): 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

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

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

1728 return core_schema.tuple_schema([]) 1abdjkeghlmcifn

1729 else: 

1730 return core_schema.tuple_schema([self.generate_schema(param) for param in params]) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1731 

1732 def _type_schema(self) -> core_schema.CoreSchema: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1733 return core_schema.custom_error_schema( 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1734 core_schema.is_instance_schema(type), 

1735 custom_error_type='is_type', 

1736 custom_error_message='Input should be a type', 

1737 ) 

1738 

1739 def _zoneinfo_schema(self) -> core_schema.CoreSchema: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

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

1741 from ._validators import validate_str_is_valid_iana_tz 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1742 

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

1744 return core_schema.no_info_plain_validator_function( 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1745 validate_str_is_valid_iana_tz, 

1746 serialization=core_schema.to_string_ser_schema(), 

1747 metadata=metadata, 

1748 ) 

1749 

1750 def _union_is_subclass_schema(self, union_type: Any) -> core_schema.CoreSchema: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

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

1752 args = self._get_args_resolving_forward_refs(union_type, required=True) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1753 return core_schema.union_schema([self.generate_schema(type[args]) for args in args]) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1754 

1755 def _subclass_schema(self, type_: Any) -> core_schema.CoreSchema: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

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

1757 type_param = self._get_first_arg_or_any(type_) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1758 

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

1760 type_param = _typing_extra.annotated_type(type_param) or type_param 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1761 

1762 if typing_objects.is_any(type_param): 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1763 return self._type_schema() 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1764 elif typing_objects.is_typealiastype(type_param): 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1765 return self.generate_schema(type[type_param.__value__]) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1766 elif typing_objects.is_typevar(type_param): 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1767 if type_param.__bound__: 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1768 if is_union_origin(get_origin(type_param.__bound__)): 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1769 return self._union_is_subclass_schema(type_param.__bound__) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1770 return core_schema.is_subclass_schema(type_param.__bound__) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1771 elif type_param.__constraints__: 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

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

1773 else: 

1774 return self._type_schema() 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1775 elif is_union_origin(get_origin(type_param)): 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1776 return self._union_is_subclass_schema(type_param) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1777 else: 

1778 if typing_objects.is_self(type_param): 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1779 type_param = self._resolve_self_type(type_param) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1780 if _typing_extra.is_generic_alias(type_param): 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1781 raise PydanticUserError( 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

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

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

1784 code=None, 

1785 ) 

1786 if not inspect.isclass(type_param): 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

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

1788 # so we handle it manually here 

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

1790 return core_schema.is_subclass_schema(_typing_extra.NoneType) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

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

1792 return core_schema.is_subclass_schema(type_param) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1793 

1794 def _sequence_schema(self, items_type: Any) -> core_schema.CoreSchema: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

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

1796 from ._serializers import serialize_sequence_via_list 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1797 

1798 item_type_schema = self.generate_schema(items_type) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1799 list_schema = core_schema.list_schema(item_type_schema) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1800 

1801 json_schema = smart_deepcopy(list_schema) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1802 python_schema = core_schema.is_instance_schema(typing.Sequence, cls_repr='Sequence') 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1803 if not typing_objects.is_any(items_type): 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1804 from ._validators import sequence_validator 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1805 

1806 python_schema = core_schema.chain_schema( 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

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

1808 ) 

1809 

1810 serialization = core_schema.wrap_serializer_function_ser_schema( 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1811 serialize_sequence_via_list, schema=item_type_schema, info_arg=True 

1812 ) 

1813 return core_schema.json_or_python_schema( 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1814 json_schema=json_schema, python_schema=python_schema, serialization=serialization 

1815 ) 

1816 

1817 def _iterable_schema(self, type_: Any) -> core_schema.GeneratorSchema: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

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

1819 item_type = self._get_first_arg_or_any(type_) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1820 

1821 return core_schema.generator_schema(self.generate_schema(item_type)) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1822 

1823 def _pattern_schema(self, pattern_type: Any) -> core_schema.CoreSchema: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1824 from . import _validators 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1825 

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

1827 ser = core_schema.plain_serializer_function_ser_schema( 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

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

1829 ) 

1830 if pattern_type is typing.Pattern or pattern_type is re.Pattern: 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1831 # bare type 

1832 return core_schema.no_info_plain_validator_function( 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

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

1834 ) 

1835 

1836 param = self._get_args_resolving_forward_refs( 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1837 pattern_type, 

1838 required=True, 

1839 )[0] 

1840 if param is str: 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1841 return core_schema.no_info_plain_validator_function( 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

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

1843 ) 

1844 elif param is bytes: 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1845 return core_schema.no_info_plain_validator_function( 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

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

1847 ) 

1848 else: 

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

1850 

1851 def _hashable_schema(self) -> core_schema.CoreSchema: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1852 return core_schema.custom_error_schema( 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1853 schema=core_schema.json_or_python_schema( 

1854 json_schema=core_schema.chain_schema( 

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

1856 ), 

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

1858 ), 

1859 custom_error_type='is_hashable', 

1860 custom_error_message='Input should be hashable', 

1861 ) 

1862 

1863 def _dataclass_schema( 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

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

1865 ) -> core_schema.CoreSchema: 

1866 """Generate schema for a dataclass.""" 

1867 with ( 1abdjoqkeghlmrsOJKLMNcifnpt

1868 self.model_type_stack.push(dataclass), 

1869 self.defs.get_schema_or_ref(dataclass) as ( 

1870 dataclass_ref, 

1871 maybe_schema, 

1872 ), 

1873 ): 

1874 if maybe_schema is not None: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1875 return maybe_schema 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1876 

1877 schema = dataclass.__dict__.get('__pydantic_core_schema__') 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1878 if schema is not None and not isinstance(schema, MockCoreSchema): 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1879 if schema['type'] == 'definitions': 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1880 schema = self.defs.unpack_definitions(schema) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1881 ref = get_ref(schema) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1882 if ref: 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1883 return self.defs.create_definition_reference_schema(schema) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1884 else: 

1885 return schema 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1886 

1887 typevars_map = get_standard_typevars_map(dataclass) 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1888 if origin is not None: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1889 dataclass = origin 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1890 

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

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

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

1894 config = getattr(dataclass, '__pydantic_config__', None) 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1895 

1896 from ..dataclasses import is_pydantic_dataclass 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1897 

1898 with self._ns_resolver.push(dataclass), self._config_wrapper_stack.push(config): 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1899 if is_pydantic_dataclass(dataclass): 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

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

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

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

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

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

1905 if typevars_map: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1906 for field in fields.values(): 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1907 field.apply_typevars_map(typevars_map, *self._types_namespace) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1908 else: 

1909 fields = collect_dataclass_fields( 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1910 dataclass, 

1911 typevars_map=typevars_map, 

1912 config_wrapper=self._config_wrapper, 

1913 ) 

1914 

1915 if self._config_wrapper.extra == 'allow': 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

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

1917 for field_name, field in fields.items(): 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1918 if field.init is False: 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1919 raise PydanticUserError( 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

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

1921 f'This combination is not allowed.', 

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

1923 ) 

1924 

1925 decorators = dataclass.__dict__.get('__pydantic_decorators__') or DecoratorInfos.build(dataclass) 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

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

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

1928 args = sorted( 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

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

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

1931 ) 

1932 has_post_init = hasattr(dataclass, '__post_init__') 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1933 has_slots = hasattr(dataclass, '__slots__') 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1934 

1935 args_schema = core_schema.dataclass_args_schema( 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1936 dataclass.__name__, 

1937 args, 

1938 computed_fields=[ 

1939 self._computed_field_schema(d, decorators.field_serializers) 

1940 for d in decorators.computed_fields.values() 

1941 ], 

1942 collect_init_only=has_post_init, 

1943 ) 

1944 

1945 inner_schema = apply_validators(args_schema, decorators.root_validators.values(), None) 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1946 

1947 model_validators = decorators.model_validators.values() 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1948 inner_schema = apply_model_validators(inner_schema, model_validators, 'inner') 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1949 

1950 core_config = self._config_wrapper.core_config(title=dataclass.__name__) 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1951 

1952 dc_schema = core_schema.dataclass_schema( 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1953 dataclass, 

1954 inner_schema, 

1955 generic_origin=origin, 

1956 post_init=has_post_init, 

1957 ref=dataclass_ref, 

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

1959 slots=has_slots, 

1960 config=core_config, 

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

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

1963 frozen=self._config_wrapper_stack.tail.frozen, 

1964 ) 

1965 schema = self._apply_model_serializers(dc_schema, decorators.model_serializers.values()) 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1966 schema = apply_model_validators(schema, model_validators, 'outer') 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1967 return self.defs.create_definition_reference_schema(schema) 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1968 

1969 def _call_schema(self, function: ValidateCallSupportedTypes) -> core_schema.CallSchema: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

1970 """Generate schema for a Callable. 

1971 

1972 TODO support functional validators once we support them in Config 

1973 """ 

1974 arguments_schema = self._arguments_schema(function) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1975 

1976 return_schema: core_schema.CoreSchema | None = None 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1977 config_wrapper = self._config_wrapper 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1978 if config_wrapper.validate_return: 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1979 sig = signature(function) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1980 return_hint = sig.return_annotation 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1981 if return_hint is not sig.empty: 1981 ↛ 1988line 1981 didn't jump to line 1988 because the condition on line 1981 was always true1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1982 globalns, localns = self._types_namespace 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1983 type_hints = _typing_extra.get_function_type_hints( 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

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

1985 ) 

1986 return_schema = self.generate_schema(type_hints['return']) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1987 

1988 return core_schema.call_schema( 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1989 arguments_schema, 

1990 function, 

1991 return_schema=return_schema, 

1992 ) 

1993 

1994 def _arguments_schema( 1abdjoquwxCDghlmrsyzEFGOJKLMNPcifnptvABHI

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

1996 ) -> core_schema.ArgumentsSchema: 

1997 """Generate schema for a Signature.""" 

1998 mode_lookup: dict[_ParameterKind, Literal['positional_only', 'positional_or_keyword', 'keyword_only']] = { 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

1999 Parameter.POSITIONAL_ONLY: 'positional_only', 

2000 Parameter.POSITIONAL_OR_KEYWORD: 'positional_or_keyword', 

2001 Parameter.KEYWORD_ONLY: 'keyword_only', 

2002 } 

2003 

2004 sig = signature(function) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2005 globalns, localns = self._types_namespace 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2006 type_hints = _typing_extra.get_function_type_hints(function, globalns=globalns, localns=localns) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2007 

2008 arguments_list: list[core_schema.ArgumentsParameter] = [] 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2009 var_args_schema: core_schema.CoreSchema | None = None 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2010 var_kwargs_schema: core_schema.CoreSchema | None = None 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2011 var_kwargs_mode: core_schema.VarKwargsMode | None = None 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2012 

2013 for i, (name, p) in enumerate(sig.parameters.items()): 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2014 if p.annotation is sig.empty: 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2015 annotation = typing.cast(Any, Any) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2016 else: 

2017 annotation = type_hints[name] 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2018 

2019 if parameters_callback is not None: 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2020 result = parameters_callback(i, name, annotation) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2021 if result == 'skip': 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2022 continue 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2023 

2024 parameter_mode = mode_lookup.get(p.kind) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2025 if parameter_mode is not None: 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2026 arg_schema = self._generate_parameter_schema( 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

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

2028 ) 

2029 arguments_list.append(arg_schema) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2030 elif p.kind == Parameter.VAR_POSITIONAL: 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2031 var_args_schema = self.generate_schema(annotation) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2032 else: 

2033 assert p.kind == Parameter.VAR_KEYWORD, p.kind 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2034 

2035 unpack_type = _typing_extra.unpack_type(annotation) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2036 if unpack_type is not None: 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2037 origin = get_origin(unpack_type) or unpack_type 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2038 if not is_typeddict(origin): 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2039 raise PydanticUserError( 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

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

2041 code='unpack-typed-dict', 

2042 ) 

2043 non_pos_only_param_names = { 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

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

2045 } 

2046 overlapping_params = non_pos_only_param_names.intersection(origin.__annotations__) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2047 if overlapping_params: 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2048 raise PydanticUserError( 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

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

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

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

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

2053 ) 

2054 

2055 var_kwargs_mode = 'unpacked-typed-dict' 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2056 var_kwargs_schema = self._typed_dict_schema(unpack_type, get_origin(unpack_type)) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2057 else: 

2058 var_kwargs_mode = 'uniform' 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2059 var_kwargs_schema = self.generate_schema(annotation) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2060 

2061 return core_schema.arguments_schema( 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2062 arguments_list, 

2063 var_args_schema=var_args_schema, 

2064 var_kwargs_mode=var_kwargs_mode, 

2065 var_kwargs_schema=var_kwargs_schema, 

2066 validate_by_name=self._config_wrapper.validate_by_name, 

2067 ) 

2068 

2069 def _arguments_v3_schema( 1abdjoquwxCDghlmrsyzEFGOJKLMNPcifnptvABHI

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

2071 ) -> core_schema.ArgumentsV3Schema: 

2072 mode_lookup: dict[ 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

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

2074 ] = { 

2075 Parameter.POSITIONAL_ONLY: 'positional_only', 

2076 Parameter.POSITIONAL_OR_KEYWORD: 'positional_or_keyword', 

2077 Parameter.VAR_POSITIONAL: 'var_args', 

2078 Parameter.KEYWORD_ONLY: 'keyword_only', 

2079 } 

2080 

2081 sig = signature(function) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2082 globalns, localns = self._types_namespace 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2083 type_hints = _typing_extra.get_function_type_hints(function, globalns=globalns, localns=localns) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2084 

2085 parameters_list: list[core_schema.ArgumentsV3Parameter] = [] 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2086 

2087 for i, (name, p) in enumerate(sig.parameters.items()): 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2088 if parameters_callback is not None: 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2089 result = parameters_callback(i, name, p.annotation) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2090 if result == 'skip': 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2091 continue 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2092 

2093 if p.annotation is Parameter.empty: 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2094 annotation = typing.cast(Any, Any) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2095 else: 

2096 annotation = type_hints[name] 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2097 

2098 parameter_mode = mode_lookup.get(p.kind) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2099 if parameter_mode is None: 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2100 assert p.kind == Parameter.VAR_KEYWORD, p.kind 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2101 

2102 unpack_type = _typing_extra.unpack_type(annotation) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2103 if unpack_type is not None: 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2104 origin = get_origin(unpack_type) or unpack_type 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2105 if not is_typeddict(origin): 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2106 raise PydanticUserError( 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

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

2108 code='unpack-typed-dict', 

2109 ) 

2110 non_pos_only_param_names = { 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

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

2112 } 

2113 overlapping_params = non_pos_only_param_names.intersection(origin.__annotations__) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2114 if overlapping_params: 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2115 raise PydanticUserError( 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

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

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

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

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

2120 ) 

2121 parameter_mode = 'var_kwargs_unpacked_typed_dict' 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2122 annotation = unpack_type 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2123 else: 

2124 parameter_mode = 'var_kwargs_uniform' 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2125 

2126 parameters_list.append( 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2127 self._generate_parameter_v3_schema( 

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

2129 ) 

2130 ) 

2131 

2132 return core_schema.arguments_v3_schema( 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2133 parameters_list, 

2134 validate_by_name=self._config_wrapper.validate_by_name, 

2135 ) 

2136 

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

2138 try: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

2139 has_default = typevar.has_default() 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

2140 except AttributeError: 1abdjoquwkeghlmrsyzOJKLMNcifnptvA

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

2142 pass 1abdjoquwkeghlmrsyzOJKLMNcifnptvA

2143 else: 

2144 if has_default: 1abdjoquwxCDkeghlmrsyzEFGPcifnptvABHI

2145 return self.generate_schema(typevar.__default__) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2146 

2147 if constraints := typevar.__constraints__: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

2148 return self._union_schema(typing.Union[constraints]) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2149 

2150 if bound := typevar.__bound__: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

2151 schema = self.generate_schema(bound) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2152 schema['serialization'] = core_schema.wrap_serializer_function_ser_schema( 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2153 lambda x, h: h(x), 

2154 schema=core_schema.any_schema(), 

2155 ) 

2156 return schema 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2157 

2158 return core_schema.any_schema() 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

2159 

2160 def _computed_field_schema( 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

2161 self, 

2162 d: Decorator[ComputedFieldInfo], 

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

2164 ) -> core_schema.ComputedField: 

2165 if d.info.return_type is not PydanticUndefined: 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2166 return_type = d.info.return_type 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2167 else: 

2168 try: 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

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

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

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

2172 return_type = _decorators.get_callable_return_type(d.func, localns=self._types_namespace.locals) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2173 except NameError as e: 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2174 raise PydanticUndefinedAnnotation.from_name_error(e) from e 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2175 if return_type is PydanticUndefined: 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2176 raise PydanticUserError( 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

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

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

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

2180 ) 

2181 

2182 return_type = replace_types(return_type, self._typevars_map) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

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

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

2185 d.info = dataclasses.replace(d.info, return_type=return_type) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2186 return_type_schema = self.generate_schema(return_type) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2187 # Apply serializers to computed field if there exist 

2188 return_type_schema = self._apply_field_serializers( 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2189 return_type_schema, 

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

2191 ) 

2192 

2193 alias_generator = self._config_wrapper.alias_generator 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2194 if alias_generator is not None: 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2195 self._apply_alias_generator_to_computed_field_info( 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

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

2197 ) 

2198 self._apply_field_title_generator_to_field_info(self._config_wrapper, d.info, d.cls_var_name) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2199 

2200 pydantic_js_updates, pydantic_js_extra = _extract_json_schema_info_from_field_info(d.info) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2201 core_metadata: dict[str, Any] = {} 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2202 update_core_metadata( 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2203 core_metadata, 

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

2205 pydantic_js_extra=pydantic_js_extra, 

2206 ) 

2207 return core_schema.computed_field( 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

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

2209 ) 

2210 

2211 def _annotated_schema(self, annotated_type: Any) -> core_schema.CoreSchema: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

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

2213 FieldInfo = import_cached_field_info() 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2214 source_type, *annotations = self._get_args_resolving_forward_refs( 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2215 annotated_type, 

2216 required=True, 

2217 ) 

2218 schema = self._apply_annotations(source_type, annotations) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

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

2220 # even if there are function validators involved 

2221 for annotation in annotations: 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2222 if isinstance(annotation, FieldInfo): 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2223 schema = wrap_default(annotation, schema) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2224 return schema 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2225 

2226 def _apply_annotations( 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

2227 self, 

2228 source_type: Any, 

2229 annotations: list[Any], 

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

2231 ) -> CoreSchema: 

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

2233 

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

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

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

2237 """ 

2238 annotations = list(_known_annotated_metadata.expand_grouped_metadata(annotations)) 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

2239 

2240 pydantic_js_annotation_functions: list[GetJsonSchemaFunction] = [] 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

2241 

2242 def inner_handler(obj: Any) -> CoreSchema: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

2243 schema = self._generate_schema_from_get_schema_method(obj, source_type) 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

2244 

2245 if schema is None: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

2246 schema = self._generate_schema_inner(obj) 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

2247 

2248 metadata_js_function = _extract_get_pydantic_json_schema(obj) 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

2249 if metadata_js_function is not None: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

2250 metadata_schema = resolve_original_schema(schema, self.defs) 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

2251 if metadata_schema is not None: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

2252 self._add_js_function(metadata_schema, metadata_js_function) 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

2253 return transform_inner_schema(schema) 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

2254 

2255 get_inner_schema = CallbackGetCoreSchemaHandler(inner_handler, self) 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

2256 

2257 for annotation in annotations: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

2258 if annotation is None: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

2259 continue 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2260 get_inner_schema = self._get_wrapped_inner_schema( 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

2261 get_inner_schema, annotation, pydantic_js_annotation_functions 

2262 ) 

2263 

2264 schema = get_inner_schema(source_type) 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

2265 if pydantic_js_annotation_functions: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

2266 core_metadata = schema.setdefault('metadata', {}) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2267 update_core_metadata(core_metadata, pydantic_js_annotation_functions=pydantic_js_annotation_functions) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2268 return _add_custom_serialization_from_json_encoders(self._config_wrapper.json_encoders, source_type, schema) 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

2269 

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

2271 FieldInfo = import_cached_field_info() 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2272 

2273 if isinstance(metadata, FieldInfo): 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2274 for field_metadata in metadata.metadata: 2274 ↛ 2275line 2274 didn't jump to line 2275 because the loop on line 2274 never started1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2275 schema = self._apply_single_annotation(schema, field_metadata) 

2276 

2277 if metadata.discriminator is not None: 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2278 schema = self._apply_discriminator_to_union(schema, metadata.discriminator) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2279 return schema 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2280 

2281 if schema['type'] == 'nullable': 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

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

2283 inner = schema.get('schema', core_schema.any_schema()) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2284 inner = self._apply_single_annotation(inner, metadata) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

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

2286 schema['schema'] = inner 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2287 return schema 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2288 

2289 original_schema = schema 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2290 ref = schema.get('ref') 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2291 if ref is not None: 2291 ↛ 2292line 2291 didn't jump to line 2292 because the condition on line 2291 was never true1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2292 schema = schema.copy() 

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

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

2295 return existing 

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

2297 elif schema['type'] == 'definition-ref': 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2298 ref = schema['schema_ref'] 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

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

2300 schema = referenced_schema.copy() 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2301 new_ref = ref + f'_{repr(metadata)}' 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2302 if (existing := self.defs.get_schema_from_ref(new_ref)) is not None: 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2303 return existing 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2304 schema['ref'] = new_ref # pyright: ignore[reportGeneralTypeIssues] 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2305 

2306 maybe_updated_schema = _known_annotated_metadata.apply_known_metadata(metadata, schema) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2307 

2308 if maybe_updated_schema is not None: 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2309 return maybe_updated_schema 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2310 return original_schema 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2311 

2312 def _apply_single_annotation_json_schema( 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

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

2314 ) -> core_schema.CoreSchema: 

2315 FieldInfo = import_cached_field_info() 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2316 

2317 if isinstance(metadata, FieldInfo): 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2318 for field_metadata in metadata.metadata: 2318 ↛ 2319line 2318 didn't jump to line 2319 because the loop on line 2318 never started1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2319 schema = self._apply_single_annotation_json_schema(schema, field_metadata) 

2320 

2321 pydantic_js_updates, pydantic_js_extra = _extract_json_schema_info_from_field_info(metadata) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2322 core_metadata = schema.setdefault('metadata', {}) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2323 update_core_metadata( 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2324 core_metadata, pydantic_js_updates=pydantic_js_updates, pydantic_js_extra=pydantic_js_extra 

2325 ) 

2326 return schema 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2327 

2328 def _get_wrapped_inner_schema( 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

2329 self, 

2330 get_inner_schema: GetCoreSchemaHandler, 

2331 annotation: Any, 

2332 pydantic_js_annotation_functions: list[GetJsonSchemaFunction], 

2333 ) -> CallbackGetCoreSchemaHandler: 

2334 annotation_get_schema: GetCoreSchemaFunction | None = getattr(annotation, '__get_pydantic_core_schema__', None) 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

2335 

2336 def new_handler(source: Any) -> core_schema.CoreSchema: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

2337 if annotation_get_schema is not None: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

2338 schema = annotation_get_schema(source, get_inner_schema) 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

2339 else: 

2340 schema = get_inner_schema(source) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2341 schema = self._apply_single_annotation(schema, annotation) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2342 schema = self._apply_single_annotation_json_schema(schema, annotation) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2343 

2344 metadata_js_function = _extract_get_pydantic_json_schema(annotation) 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

2345 if metadata_js_function is not None: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

2346 pydantic_js_annotation_functions.append(metadata_js_function) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2347 return schema 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

2348 

2349 return CallbackGetCoreSchemaHandler(new_handler, self) 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

2350 

2351 def _apply_field_serializers( 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

2352 self, 

2353 schema: core_schema.CoreSchema, 

2354 serializers: list[Decorator[FieldSerializerDecoratorInfo]], 

2355 ) -> core_schema.CoreSchema: 

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

2357 if serializers: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

2358 schema = copy(schema) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2359 if schema['type'] == 'definitions': 2359 ↛ 2360line 2359 didn't jump to line 2360 because the condition on line 2359 was never true1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2360 inner_schema = schema['schema'] 

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

2362 return schema 

2363 elif 'ref' in schema: 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2364 schema = self.defs.create_definition_reference_schema(schema) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2365 

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

2367 serializer = serializers[-1] 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2368 is_field_serializer, info_arg = inspect_field_serializer(serializer.func, serializer.info.mode) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2369 

2370 if serializer.info.return_type is not PydanticUndefined: 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2371 return_type = serializer.info.return_type 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2372 else: 

2373 try: 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

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

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

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

2377 return_type = _decorators.get_callable_return_type( 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

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

2379 ) 

2380 except NameError as e: 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2381 raise PydanticUndefinedAnnotation.from_name_error(e) from e 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2382 

2383 if return_type is PydanticUndefined: 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2384 return_schema = None 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2385 else: 

2386 return_schema = self.generate_schema(return_type) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2387 

2388 if serializer.info.mode == 'wrap': 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2389 schema['serialization'] = core_schema.wrap_serializer_function_ser_schema( 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2390 serializer.func, 

2391 is_field_serializer=is_field_serializer, 

2392 info_arg=info_arg, 

2393 return_schema=return_schema, 

2394 when_used=serializer.info.when_used, 

2395 ) 

2396 else: 

2397 assert serializer.info.mode == 'plain' 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2398 schema['serialization'] = core_schema.plain_serializer_function_ser_schema( 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2399 serializer.func, 

2400 is_field_serializer=is_field_serializer, 

2401 info_arg=info_arg, 

2402 return_schema=return_schema, 

2403 when_used=serializer.info.when_used, 

2404 ) 

2405 return schema 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

2406 

2407 def _apply_model_serializers( 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

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

2409 ) -> core_schema.CoreSchema: 

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

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

2412 if serializers: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

2413 serializer = list(serializers)[-1] 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2414 info_arg = inspect_model_serializer(serializer.func, serializer.info.mode) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2415 

2416 if serializer.info.return_type is not PydanticUndefined: 2416 ↛ 2417line 2416 didn't jump to line 2417 because the condition on line 2416 was never true1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2417 return_type = serializer.info.return_type 

2418 else: 

2419 try: 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

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

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

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

2423 return_type = _decorators.get_callable_return_type( 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

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

2425 ) 

2426 except NameError as e: 

2427 raise PydanticUndefinedAnnotation.from_name_error(e) from e 

2428 

2429 if return_type is PydanticUndefined: 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2430 return_schema = None 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2431 else: 

2432 return_schema = self.generate_schema(return_type) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2433 

2434 if serializer.info.mode == 'wrap': 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2435 ser_schema: core_schema.SerSchema = core_schema.wrap_serializer_function_ser_schema( 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2436 serializer.func, 

2437 info_arg=info_arg, 

2438 return_schema=return_schema, 

2439 when_used=serializer.info.when_used, 

2440 ) 

2441 else: 

2442 # plain 

2443 ser_schema = core_schema.plain_serializer_function_ser_schema( 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2444 serializer.func, 

2445 info_arg=info_arg, 

2446 return_schema=return_schema, 

2447 when_used=serializer.info.when_used, 

2448 ) 

2449 schema['serialization'] = ser_schema 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

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

2451 schema['ref'] = ref # type: ignore 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

2452 return schema 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

2453 

2454 

2455_VALIDATOR_F_MATCH: Mapping[ 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

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

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

2458] = { 

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

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

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

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

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

2464 f, schema, field_name=field_name 

2465 ), 

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

2467 f, schema, field_name=field_name 

2468 ), 

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

2470 f, field_name=field_name 

2471 ), 

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

2473 f, schema, field_name=field_name 

2474 ), 

2475} 

2476 

2477 

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

2479# be removed once we drop support for those. 

2480def apply_validators( 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

2481 schema: core_schema.CoreSchema, 

2482 validators: Iterable[Decorator[RootValidatorDecoratorInfo]] 

2483 | Iterable[Decorator[ValidatorDecoratorInfo]] 

2484 | Iterable[Decorator[FieldValidatorDecoratorInfo]], 

2485 field_name: str | None, 

2486) -> core_schema.CoreSchema: 

2487 """Apply validators to a schema. 

2488 

2489 Args: 

2490 schema: The schema to apply validators on. 

2491 validators: An iterable of validators. 

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

2493 

2494 Returns: 

2495 The updated schema. 

2496 """ 

2497 for validator in validators: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

2498 info_arg = inspect_validator(validator.func, validator.info.mode) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2499 val_type = 'with-info' if info_arg else 'no-info' 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2500 

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

2502 return schema 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

2503 

2504 

2505def _validators_require_validate_default(validators: Iterable[Decorator[ValidatorDecoratorInfo]]) -> bool: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

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

2507 

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

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

2510 

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

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

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

2514 """ 

2515 for validator in validators: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

2516 if validator.info.always: 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2517 return True 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2518 return False 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

2519 

2520 

2521def apply_model_validators( 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

2522 schema: core_schema.CoreSchema, 

2523 validators: Iterable[Decorator[ModelValidatorDecoratorInfo]], 

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

2525) -> core_schema.CoreSchema: 

2526 """Apply model validators to a schema. 

2527 

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

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

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

2531 

2532 Args: 

2533 schema: The schema to apply validators on. 

2534 validators: An iterable of validators. 

2535 mode: The validator mode. 

2536 

2537 Returns: 

2538 The updated schema. 

2539 """ 

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

2541 for validator in validators: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

2542 if mode == 'inner' and validator.info.mode != 'before': 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2543 continue 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2544 if mode == 'outer' and validator.info.mode == 'before': 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2545 continue 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2546 info_arg = inspect_validator(validator.func, validator.info.mode) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2547 if validator.info.mode == 'wrap': 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2548 if info_arg: 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2549 schema = core_schema.with_info_wrap_validator_function(function=validator.func, schema=schema) 1uwxCDyzEFGvABHI

2550 else: 

2551 schema = core_schema.no_info_wrap_validator_function(function=validator.func, schema=schema) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2552 elif validator.info.mode == 'before': 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2553 if info_arg: 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2554 schema = core_schema.with_info_before_validator_function(function=validator.func, schema=schema) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2555 else: 

2556 schema = core_schema.no_info_before_validator_function(function=validator.func, schema=schema) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2557 else: 

2558 assert validator.info.mode == 'after' 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2559 if info_arg: 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2560 schema = core_schema.with_info_after_validator_function(function=validator.func, schema=schema) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2561 else: 

2562 schema = core_schema.no_info_after_validator_function(function=validator.func, schema=schema) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2563 if ref: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

2564 schema['ref'] = ref # type: ignore 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

2565 return schema 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

2566 

2567 

2568def wrap_default(field_info: FieldInfo, schema: core_schema.CoreSchema) -> core_schema.CoreSchema: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

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

2570 

2571 Args: 

2572 field_info: The field info object. 

2573 schema: The schema to apply default on. 

2574 

2575 Returns: 

2576 Updated schema by default value or `default_factory`. 

2577 """ 

2578 if field_info.default_factory: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

2579 return core_schema.with_default_schema( 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

2580 schema, 

2581 default_factory=field_info.default_factory, 

2582 default_factory_takes_data=takes_validated_data_argument(field_info.default_factory), 

2583 validate_default=field_info.validate_default, 

2584 ) 

2585 elif field_info.default is not PydanticUndefined: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

2586 return core_schema.with_default_schema( 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

2587 schema, default=field_info.default, validate_default=field_info.validate_default 

2588 ) 

2589 else: 

2590 return schema 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2591 

2592 

2593def _extract_get_pydantic_json_schema(tp: Any) -> GetJsonSchemaFunction | None: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

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

2595 js_modify_function = getattr(tp, '__get_pydantic_json_schema__', None) 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

2596 

2597 if hasattr(tp, '__modify_schema__'): 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

2598 BaseModel = import_cached_base_model() 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2599 

2600 has_custom_v2_modify_js_func = ( 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2601 js_modify_function is not None 

2602 and BaseModel.__get_pydantic_json_schema__.__func__ # type: ignore 

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

2604 ) 

2605 

2606 if not has_custom_v2_modify_js_func: 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2607 cls_name = getattr(tp, '__name__', None) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2608 raise PydanticUserError( 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

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

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

2611 code='custom-json-schema', 

2612 ) 

2613 

2614 if (origin := get_origin(tp)) is not None: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

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

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

2617 return _extract_get_pydantic_json_schema(origin) 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

2618 

2619 if js_modify_function is None: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

2620 return None 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

2621 

2622 return js_modify_function 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

2623 

2624 

2625class _CommonField(TypedDict): 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

2626 schema: core_schema.CoreSchema 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

2627 validation_alias: str | list[str | int] | list[list[str | int]] | None 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

2628 serialization_alias: str | None 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

2629 serialization_exclude: bool | None 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

2630 frozen: bool | None 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

2631 metadata: dict[str, Any] 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

2632 

2633 

2634def _common_field( 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

2635 schema: core_schema.CoreSchema, 

2636 *, 

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

2638 serialization_alias: str | None = None, 

2639 serialization_exclude: bool | None = None, 

2640 frozen: bool | None = None, 

2641 metadata: Any = None, 

2642) -> _CommonField: 

2643 return { 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

2644 'schema': schema, 

2645 'validation_alias': validation_alias, 

2646 'serialization_alias': serialization_alias, 

2647 'serialization_exclude': serialization_exclude, 

2648 'frozen': frozen, 

2649 'metadata': metadata, 

2650 } 

2651 

2652 

2653def resolve_original_schema(schema: CoreSchema, definitions: _Definitions) -> CoreSchema | None: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

2654 if schema['type'] == 'definition-ref': 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

2655 return definitions.get_schema_from_ref(schema['schema_ref']) 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

2656 elif schema['type'] == 'definitions': 2656 ↛ 2657line 2656 didn't jump to line 2657 because the condition on line 2656 was never true1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2657 return schema['schema'] 

2658 else: 

2659 return schema 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2660 

2661 

2662def _inlining_behavior( 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

2663 def_ref: core_schema.DefinitionReferenceSchema, 

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

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

2666 

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

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

2669 provided that such metadata is kept. 

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

2671 """ 

2672 if 'serialization' in def_ref: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

2673 return 'keep' 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2674 metadata = def_ref.get('metadata') 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

2675 if not metadata: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

2676 return 'inline' 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

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

2678 return 'preserve_metadata' 

2679 return 'keep' 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2680 

2681 

2682class _Definitions: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

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

2684 

2685 _recursively_seen: set[str] 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

2686 """A set of recursively seen references. 1djoquwxCDelmrsyzEFGJKLMNPfnptvABHI

2687 

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

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

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

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

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

2693 """ 

2694 

2695 _definitions: dict[str, core_schema.CoreSchema] 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

2696 """A mapping of references to their corresponding schema. 1djoquwxCDelmrsyzEFGJKLMNPfnptvABHI

2697 

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

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

2700 manager. 

2701 """ 

2702 

2703 def __init__(self) -> None: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

2704 self._recursively_seen = set() 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

2705 self._definitions = {} 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

2706 

2707 @contextmanager 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

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

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

2710 

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

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

2713 

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

2715 not the actual definition itself. 

2716 

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

2718 This includes any recursive types. 

2719 

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

2721 

2722 - Pydantic model 

2723 - Pydantic and stdlib dataclasses 

2724 - Typed dictionaries 

2725 - Named tuples 

2726 - `TypeAliasType` instances 

2727 - Enums 

2728 """ 

2729 ref = get_type_ref(tp) 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

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

2731 if ref in self._recursively_seen or ref in self._definitions: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

2732 yield (ref, core_schema.definition_reference_schema(ref)) 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

2733 else: 

2734 self._recursively_seen.add(ref) 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

2735 try: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

2736 yield (ref, None) 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

2737 finally: 

2738 self._recursively_seen.discard(ref) 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

2739 

2740 def get_schema_from_ref(self, ref: str) -> CoreSchema | None: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

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

2742 return self._definitions.get(ref) 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

2743 

2744 def create_definition_reference_schema(self, schema: CoreSchema) -> core_schema.DefinitionReferenceSchema: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

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

2746 

2747 The schema must have a reference attached to it. 

2748 """ 

2749 ref = schema['ref'] # pyright: ignore 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

2750 self._definitions[ref] = schema 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

2751 return core_schema.definition_reference_schema(ref) 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

2752 

2753 def unpack_definitions(self, schema: core_schema.DefinitionsSchema) -> CoreSchema: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

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

2755 for def_schema in schema['definitions']: 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2756 self._definitions[def_schema['ref']] = def_schema # pyright: ignore 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2757 return schema['schema'] 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2758 

2759 def finalize_schema(self, schema: CoreSchema) -> CoreSchema: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

2760 """Finalize the core schema. 

2761 

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

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

2764 """ 

2765 definitions = self._definitions 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

2766 try: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

2767 gather_result = gather_schemas_for_cleaning( 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

2768 schema, 

2769 definitions=definitions, 

2770 ) 

2771 except MissingDefinitionError as e: 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2772 raise InvalidSchemaError from e 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2773 

2774 remaining_defs: dict[str, CoreSchema] = {} 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

2775 

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

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

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

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

2780 if inlining_behavior == 'inline': 2780 ↛ 2787line 2780 didn't jump to line 2787 because the condition on line 2780 was always true1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

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

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

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

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

2785 inlinable_def_ref.clear() # pyright: ignore[reportAttributeAccessIssue] 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

2786 inlinable_def_ref.update(self._resolve_definition(ref, definitions)) # pyright: ignore 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

2787 elif inlining_behavior == 'preserve_metadata': 

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

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

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

2791 meta = inlinable_def_ref.pop('metadata') 

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

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

2794 inlinable_def_ref['metadata'] = meta 

2795 else: 

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

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

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

2799 remaining_defs[ref] = self._resolve_definition(ref, definitions) 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

2800 

2801 for cs in gather_result['deferred_discriminator_schemas']: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

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

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

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

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

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

2807 continue 

2808 applied = _discriminated_union.apply_discriminator(cs.copy(), discriminator, remaining_defs) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2809 # Mutate the schema directly to have the discriminator applied 

2810 cs.clear() # pyright: ignore[reportAttributeAccessIssue] 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2811 cs.update(applied) # pyright: ignore 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2812 

2813 if remaining_defs: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

2814 schema = core_schema.definitions_schema(schema=schema, definitions=[*remaining_defs.values()]) 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

2815 return schema 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

2816 

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

2818 definition = definitions[ref] 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

2819 if definition['type'] != 'definition-ref': 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

2820 return definition 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

2821 

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

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

2824 visited: set[str] = set() 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

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

2826 schema_ref = definition['schema_ref'] 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2827 if schema_ref in visited: 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2828 raise PydanticUserError( 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

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

2830 ) 

2831 visited.add(schema_ref) 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2832 definition = definitions[schema_ref] 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

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

2834 

2835 

2836class _FieldNameStack: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

2837 __slots__ = ('_stack',) 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

2838 

2839 def __init__(self) -> None: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

2840 self._stack: list[str] = [] 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

2841 

2842 @contextmanager 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

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

2844 self._stack.append(field_name) 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

2845 yield 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

2846 self._stack.pop() 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

2847 

2848 def get(self) -> str | None: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

2849 if self._stack: 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2850 return self._stack[-1] 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2851 else: 

2852 return None 1adouxcfpvB

2853 

2854 

2855class _ModelTypeStack: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

2856 __slots__ = ('_stack',) 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

2857 

2858 def __init__(self) -> None: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

2859 self._stack: list[type] = [] 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

2860 

2861 @contextmanager 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

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

2863 self._stack.append(type_obj) 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

2864 yield 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

2865 self._stack.pop() 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

2866 

2867 def get(self) -> type | None: 1abdjoquwxCDkeghlmrsyzEFGOJKLMNPcifnptvABHI

2868 if self._stack: 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2869 return self._stack[-1] 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI

2870 else: 

2871 return None 1abdjoquwxCDkeghlmrsyzEFGcifnptvABHI