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

1289 statements  

« prev     ^ index     » next       coverage.py v7.8.0, created at 2025-04-18 09:13 +0000

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

2 

3from __future__ import annotations as _annotations 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

4 

5import collections.abc 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

6import dataclasses 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

7import datetime 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

8import inspect 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

9import os 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

10import pathlib 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

11import re 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

12import sys 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

13import typing 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

14import warnings 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

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

16from contextlib import contextmanager 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

17from copy import copy 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

18from decimal import Decimal 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

19from enum import Enum 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

20from fractions import Fraction 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

21from functools import partial 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

22from inspect import Parameter, _ParameterKind, signature 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

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

24from itertools import chain 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

25from operator import attrgetter 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

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

27from typing import ( 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

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

40from warnings import warn 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

41from zoneinfo import ZoneInfo 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

42 

43import typing_extensions 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

44from pydantic_core import ( 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

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

55from typing_inspection import typing_objects 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

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

57 

58from ..aliases import AliasChoices, AliasPath 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

59from ..annotated_handlers import GetCoreSchemaHandler, GetJsonSchemaHandler 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

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

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

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

63from ..json_schema import JsonSchemaValue 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

64from ..version import version_short 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

65from ..warnings import PydanticDeprecatedSince20 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

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

67from ._config import ConfigWrapper, ConfigWrapperStack 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

68from ._core_metadata import CoreMetadata, update_core_metadata 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

69from ._core_utils import ( 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

70 get_ref, 

71 get_type_ref, 

72 is_list_like_schema_with_items_schema, 

73 validate_core_schema, 

74) 

75from ._decorators import ( 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

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

90from ._fields import ( 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

91 collect_dataclass_fields, 

92 rebuild_model_fields, 

93 takes_validated_data_argument, 

94 update_field_from_config, 

95) 

96from ._forward_ref import PydanticRecursiveRef 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

97from ._generics import get_standard_typevars_map, replace_types 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

98from ._import_utils import import_cached_base_model, import_cached_field_info 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

99from ._mock_val_ser import MockCoreSchema 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

100from ._namespace_utils import NamespacesTuple, NsResolver 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

101from ._schema_gather import MissingDefinitionError, gather_schemas_for_cleaning 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

102from ._schema_generation_shared import CallbackGetCoreSchemaHandler 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

103from ._utils import lenient_issubclass, smart_deepcopy 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

104 

105if TYPE_CHECKING: 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

106 from ..fields import ComputedFieldInfo, FieldInfo 

107 from ..main import BaseModel 

108 from ..types import Discriminator 

109 from ._dataclasses import StandardDataclass 

110 from ._schema_generation_shared import GetJsonSchemaFunction 

111 

112_SUPPORTS_TYPEDDICT = sys.version_info >= (3, 12) 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

113 

114FieldDecoratorInfo = Union[ValidatorDecoratorInfo, FieldValidatorDecoratorInfo, FieldSerializerDecoratorInfo] 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

115FieldDecoratorInfoType = TypeVar('FieldDecoratorInfoType', bound=FieldDecoratorInfo) 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

116AnyFieldDecorator = Union[ 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

117 Decorator[ValidatorDecoratorInfo], 

118 Decorator[FieldValidatorDecoratorInfo], 

119 Decorator[FieldSerializerDecoratorInfo], 

120] 

121 

122ModifyCoreSchemaWrapHandler: TypeAlias = GetCoreSchemaHandler 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

123GetCoreSchemaFunction: TypeAlias = Callable[[Any, ModifyCoreSchemaWrapHandler], core_schema.CoreSchema] 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

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

125 

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

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

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

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

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

131IP_TYPES: list[type] = [IPv4Address, IPv4Interface, IPv4Network, IPv6Address, IPv6Interface, IPv6Network] 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

132SEQUENCE_TYPES: list[type] = [typing.Sequence, collections.abc.Sequence] 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

133ITERABLE_TYPES: list[type] = [typing.Iterable, collections.abc.Iterable, typing.Generator, collections.abc.Generator] 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

134TYPE_TYPES: list[type] = [typing.Type, type] # noqa: UP006 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

135PATTERN_TYPES: list[type] = [typing.Pattern, re.Pattern] 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

136PATH_TYPES: list[type] = [ 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

137 os.PathLike, 

138 pathlib.Path, 

139 pathlib.PurePath, 

140 pathlib.PosixPath, 

141 pathlib.PurePosixPath, 

142 pathlib.PureWindowsPath, 

143] 

144MAPPING_TYPES = [ 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

145 typing.Mapping, 

146 typing.MutableMapping, 

147 collections.abc.Mapping, 

148 collections.abc.MutableMapping, 

149 collections.OrderedDict, 

150 typing_extensions.OrderedDict, 

151 typing.DefaultDict, # noqa: UP006 

152 collections.defaultdict, 

153] 

154COUNTER_TYPES = [collections.Counter, typing.Counter] 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

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

156 

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

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

159ValidateCallSupportedTypes = Union[ 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

160 LambdaType, 

161 FunctionType, 

162 MethodType, 

163 partial, 

164] 

165 

166VALIDATE_CALL_SUPPORTED_TYPES = get_args(ValidateCallSupportedTypes) 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

167 

168_mode_to_validator: dict[ 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

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

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

171 

172 

173def check_validator_fields_against_field_name( 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

174 info: FieldDecoratorInfo, 

175 field: str, 

176) -> bool: 

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

178 

179 Args: 

180 info: The field info. 

181 field: The field name to check. 

182 

183 Returns: 

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

185 """ 

186 fields = info.fields 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

187 return '*' in fields or field in fields 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

188 

189 

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

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

192 

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

194 

195 Args: 

196 decorators: An iterable of decorators. 

197 fields: An iterable of fields name. 

198 

199 Raises: 

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

201 """ 

202 fields = set(fields) 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

203 for dec in decorators: 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

204 if '*' in dec.info.fields: 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

205 continue 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

206 if dec.info.check_fields is False: 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

207 continue 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

208 for field in dec.info.fields: 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

209 if field not in fields: 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

210 raise PydanticUserError( 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

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

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

213 code='decorator-missing-field', 

214 ) 

215 

216 

217def filter_field_decorator_info_by_field( 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

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

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

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

221 

222 

223def apply_each_item_validators( 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

224 schema: core_schema.CoreSchema, 

225 each_item_validators: list[Decorator[ValidatorDecoratorInfo]], 

226 field_name: str | None, 

227) -> core_schema.CoreSchema: 

228 # This V1 compatibility shim should eventually be removed 

229 

230 # fail early if each_item_validators is empty 

231 if not each_item_validators: 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

232 return schema 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

233 

234 # push down any `each_item=True` validators 

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

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

237 if schema['type'] == 'nullable': 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

238 schema['schema'] = apply_each_item_validators(schema['schema'], each_item_validators, field_name) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

239 return schema 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

240 elif schema['type'] == 'tuple': 240 ↛ 241line 240 didn't jump to line 241 because the condition on line 240 was never true1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

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

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

243 schema['items_schema'][variadic_item_index], 

244 each_item_validators, 

245 field_name, 

246 ) 

247 elif is_list_like_schema_with_items_schema(schema): 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

248 inner_schema = schema.get('items_schema', core_schema.any_schema()) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

249 schema['items_schema'] = apply_validators(inner_schema, each_item_validators, field_name) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

250 elif schema['type'] == 'dict': 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

251 inner_schema = schema.get('values_schema', core_schema.any_schema()) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

252 schema['values_schema'] = apply_validators(inner_schema, each_item_validators, field_name) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

253 else: 

254 raise TypeError( 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

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

256 ) 

257 return schema 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

258 

259 

260def _extract_json_schema_info_from_field_info( 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

261 info: FieldInfo | ComputedFieldInfo, 

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

263 json_schema_updates = { 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

264 'title': info.title, 

265 'description': info.description, 

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

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

268 } 

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

270 return (json_schema_updates or None, info.json_schema_extra) 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

271 

272 

273JsonEncoders = dict[type[Any], JsonEncoder] 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

274 

275 

276def _add_custom_serialization_from_json_encoders( 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

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

278) -> CoreSchema: 

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

280 

281 Args: 

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

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

284 schema: The schema to add the encoder to. 

285 """ 

286 if not json_encoders: 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

287 return schema 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

288 if 'serialization' in schema: 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

289 return schema 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

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

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

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

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

294 encoder = json_encoders.get(base) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

295 if encoder is None: 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

296 continue 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

297 

298 warnings.warn( 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

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

300 PydanticDeprecatedSince20, 

301 ) 

302 

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

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

305 return schema 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

306 

307 return schema 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

308 

309 

310class InvalidSchemaError(Exception): 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

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

312 

313 

314class GenerateSchema: 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

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

316 

317 __slots__ = ( 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

318 '_config_wrapper_stack', 

319 '_ns_resolver', 

320 '_typevars_map', 

321 'field_name_stack', 

322 'model_type_stack', 

323 'defs', 

324 ) 

325 

326 def __init__( 1aebfnquwxCDhijkrsyzEFGOJKLMNPcldmotvABHI

327 self, 

328 config_wrapper: ConfigWrapper, 

329 ns_resolver: NsResolver | None = None, 

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

331 ) -> None: 

332 # we need a stack for recursing into nested models 

333 self._config_wrapper_stack = ConfigWrapperStack(config_wrapper) 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

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

335 self._typevars_map = typevars_map 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

336 self.field_name_stack = _FieldNameStack() 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

337 self.model_type_stack = _ModelTypeStack() 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

338 self.defs = _Definitions() 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

339 

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

341 super().__init_subclass__() 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

342 warnings.warn( 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

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

344 UserWarning, 

345 stacklevel=2, 

346 ) 

347 

348 @property 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

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

350 return self._config_wrapper_stack.tail 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

351 

352 @property 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

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

354 return self._ns_resolver.types_namespace 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

355 

356 @property 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

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

358 return self._config_wrapper.arbitrary_types_allowed 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

359 

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

361 # unstable / private APIs 

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

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

364 

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

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

367 

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

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

370 

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

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

373 

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

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

376 

377 enum_ref = get_type_ref(enum_type) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

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

379 if ( 1aepg

380 description == 'An enumeration.' 

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

382 description = None 1aebfpghijkcldm

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

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

385 

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

387 if issubclass(enum_type, int): 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

388 sub_type = 'int' 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

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

390 elif issubclass(enum_type, str): 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

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

392 sub_type = 'str' 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

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

394 elif issubclass(enum_type, float): 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

395 sub_type = 'float' 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

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

397 else: 

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

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

400 

401 if cases: 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

402 

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

404 json_schema = handler(schema) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

405 original_schema = handler.resolve_ref_schema(json_schema) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

406 original_schema.update(js_updates) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

407 return json_schema 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

408 

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

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

411 enum_schema = core_schema.enum_schema( 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

412 enum_type, 

413 cases, 

414 sub_type=sub_type, 

415 missing=None if default_missing else enum_type._missing_, 

416 ref=enum_ref, 

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

418 ) 

419 

420 if self._config_wrapper.use_enum_values: 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

421 enum_schema = core_schema.no_info_after_validator_function( 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

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

423 ) 

424 

425 return enum_schema 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

426 

427 else: 

428 

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

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

431 original_schema = handler.resolve_ref_schema(json_schema) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

432 original_schema.update(js_updates) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

433 return json_schema 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

434 

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

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

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

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

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

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

441 return core_schema.is_instance_schema( 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

442 enum_type, 

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

444 ) 

445 

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

447 from ._validators import IP_VALIDATOR_LOOKUP, IpType 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

448 

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

450 IPv4Address: 'ipv4', 

451 IPv4Network: 'ipv4network', 

452 IPv4Interface: 'ipv4interface', 

453 IPv6Address: 'ipv6', 

454 IPv6Network: 'ipv6network', 

455 IPv6Interface: 'ipv6interface', 

456 } 

457 

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

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

460 raise PydanticSerializationUnexpectedValue( 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

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

462 ) 

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

464 return ip 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

465 return str(ip) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

466 

467 return core_schema.lax_or_strict_schema( 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

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

469 strict_schema=core_schema.json_or_python_schema( 

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

471 python_schema=core_schema.is_instance_schema(tp), 

472 ), 

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

474 metadata={ 

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

476 }, 

477 ) 

478 

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

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

481 raise PydanticUserError( 

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

483 ) 

484 

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

486 strict_inner_schema = ( 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

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

488 ) 

489 lax_inner_schema = core_schema.bytes_schema() if (path_type is bytes) else core_schema.str_schema() 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

490 

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

492 try: 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

493 if path_type is bytes: 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

494 if isinstance(input_value, bytes): 494 ↛ 500line 494 didn't jump to line 500 because the condition on line 494 was always true1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

495 try: 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

496 input_value = input_value.decode() 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

497 except UnicodeDecodeError as e: 

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

499 else: 

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

501 elif not isinstance(input_value, str): 501 ↛ 502line 501 didn't jump to line 502 because the condition on line 501 was never true1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

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

503 

504 return path_constructor(input_value) # type: ignore 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

505 except TypeError as e: 

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

507 

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

509 if not isinstance(path, (tp, str)): 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

510 raise PydanticSerializationUnexpectedValue( 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

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

512 ) 

513 if info.mode == 'python': 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

514 return path 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

515 return str(path) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

516 

517 instance_schema = core_schema.json_or_python_schema( 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

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

519 python_schema=core_schema.is_instance_schema(tp), 

520 ) 

521 

522 schema = core_schema.lax_or_strict_schema( 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

523 lax_schema=core_schema.union_schema( 

524 [ 

525 instance_schema, 

526 core_schema.no_info_after_validator_function(path_validator, strict_inner_schema), 

527 ], 

528 custom_error_type='path_type', 

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

530 ), 

531 strict_schema=instance_schema, 

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

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

534 ) 

535 return schema 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

536 

537 def _deque_schema(self, items_type: Any) -> CoreSchema: 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

538 from ._serializers import serialize_sequence_via_list 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

539 from ._validators import deque_validator 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

540 

541 item_type_schema = self.generate_schema(items_type) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

542 

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

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

545 list_schema = core_schema.list_schema(item_type_schema, strict=False) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

546 

547 check_instance = core_schema.json_or_python_schema( 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

548 json_schema=list_schema, 

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

550 ) 

551 

552 lax_schema = core_schema.no_info_wrap_validator_function(deque_validator, list_schema) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

553 

554 return core_schema.lax_or_strict_schema( 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

555 lax_schema=lax_schema, 

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

557 serialization=core_schema.wrap_serializer_function_ser_schema( 

558 serialize_sequence_via_list, schema=item_type_schema, info_arg=True 

559 ), 

560 ) 

561 

562 def _mapping_schema(self, tp: Any, keys_type: Any, values_type: Any) -> CoreSchema: 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

563 from ._validators import MAPPING_ORIGIN_MAP, defaultdict_validator, get_defaultdict_default_default_factory 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

564 

565 mapped_origin = MAPPING_ORIGIN_MAP[tp] 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

566 keys_schema = self.generate_schema(keys_type) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

567 values_schema = self.generate_schema(values_type) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

568 dict_schema = core_schema.dict_schema(keys_schema, values_schema, strict=False) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

569 

570 if mapped_origin is dict: 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

571 schema = dict_schema 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

572 else: 

573 check_instance = core_schema.json_or_python_schema( 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

574 json_schema=dict_schema, 

575 python_schema=core_schema.is_instance_schema(mapped_origin), 

576 ) 

577 

578 if tp is collections.defaultdict: 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

579 default_default_factory = get_defaultdict_default_default_factory(values_type) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

580 coerce_instance_wrap = partial( 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

581 core_schema.no_info_wrap_validator_function, 

582 partial(defaultdict_validator, default_default_factory=default_default_factory), 

583 ) 

584 else: 

585 coerce_instance_wrap = partial(core_schema.no_info_after_validator_function, mapped_origin) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

586 

587 lax_schema = coerce_instance_wrap(dict_schema) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

588 strict_schema = core_schema.chain_schema([check_instance, lax_schema]) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

589 

590 schema = core_schema.lax_or_strict_schema( 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

591 lax_schema=lax_schema, 

592 strict_schema=strict_schema, 

593 serialization=core_schema.wrap_serializer_function_ser_schema( 

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

595 ), 

596 ) 

597 

598 return schema 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

599 

600 def _fraction_schema(self) -> CoreSchema: 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

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

602 from ._validators import fraction_validator 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

603 

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

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

606 return core_schema.lax_or_strict_schema( 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

607 lax_schema=core_schema.no_info_plain_validator_function(fraction_validator), 

608 strict_schema=core_schema.json_or_python_schema( 

609 json_schema=core_schema.no_info_plain_validator_function(fraction_validator), 

610 python_schema=core_schema.is_instance_schema(Fraction), 

611 ), 

612 # use str serialization to guarantee round trip behavior 

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

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

615 ) 

616 

617 def _arbitrary_type_schema(self, tp: Any) -> CoreSchema: 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

618 if not isinstance(tp, type): 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

619 warn( 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

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

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

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

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

624 UserWarning, 

625 ) 

626 return core_schema.any_schema() 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

627 return core_schema.is_instance_schema(tp) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

628 

629 def _unknown_type_schema(self, obj: Any) -> CoreSchema: 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

630 raise PydanticSchemaGenerationError( 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

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

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

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

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

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

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

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

638 ) 

639 

640 def _apply_discriminator_to_union( 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

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

642 ) -> CoreSchema: 

643 if discriminator is None: 643 ↛ 644line 643 didn't jump to line 644 because the condition on line 643 was never true1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

644 return schema 

645 try: 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

646 return _discriminated_union.apply_discriminator( 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

647 schema, 

648 discriminator, 

649 self.defs._definitions, 

650 ) 

651 except _discriminated_union.MissingDefinitionForUnionRef: 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

652 # defer until defs are resolved 

653 _discriminated_union.set_discriminator_in_metadata( 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

654 schema, 

655 discriminator, 

656 ) 

657 return schema 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

658 

659 def clean_schema(self, schema: CoreSchema) -> CoreSchema: 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

660 schema = self.defs.finalize_schema(schema) 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

661 schema = validate_core_schema(schema) 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

662 return schema 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

663 

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

665 metadata = metadata_schema.get('metadata', {}) 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

666 pydantic_js_functions = metadata.setdefault('pydantic_js_functions', []) 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

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

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

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

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

671 if js_function not in pydantic_js_functions: 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

672 pydantic_js_functions.append(js_function) 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

673 metadata_schema['metadata'] = metadata 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

674 

675 def generate_schema( 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

676 self, 

677 obj: Any, 

678 ) -> core_schema.CoreSchema: 

679 """Generate core schema. 

680 

681 Args: 

682 obj: The object to generate core schema for. 

683 

684 Returns: 

685 The generated core schema. 

686 

687 Raises: 

688 PydanticUndefinedAnnotation: 

689 If it is not possible to evaluate forward reference. 

690 PydanticSchemaGenerationError: 

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

692 TypeError: 

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

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

695 PydanticUserError: 

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

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

698 """ 

699 schema = self._generate_schema_from_get_schema_method(obj, obj) 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

700 

701 if schema is None: 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

702 schema = self._generate_schema_inner(obj) 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

703 

704 metadata_js_function = _extract_get_pydantic_json_schema(obj) 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

705 if metadata_js_function is not None: 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

706 metadata_schema = resolve_original_schema(schema, self.defs) 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

707 if metadata_schema: 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

708 self._add_js_function(metadata_schema, metadata_js_function) 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

709 

710 schema = _add_custom_serialization_from_json_encoders(self._config_wrapper.json_encoders, obj, schema) 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

711 

712 return schema 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

713 

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

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

716 BaseModel_ = import_cached_base_model() 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

717 

718 with self.defs.get_schema_or_ref(cls) as (model_ref, maybe_schema): 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

719 if maybe_schema is not None: 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

720 return maybe_schema 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

721 

722 schema = cls.__dict__.get('__pydantic_core_schema__') 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

723 if schema is not None and not isinstance(schema, MockCoreSchema): 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

724 if schema['type'] == 'definitions': 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

725 schema = self.defs.unpack_definitions(schema) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

726 ref = get_ref(schema) 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

727 if ref: 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

728 return self.defs.create_definition_reference_schema(schema) 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

729 else: 

730 return schema 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

731 

732 config_wrapper = ConfigWrapper(cls.model_config, check=False) 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

733 

734 with self._config_wrapper_stack.push(config_wrapper), self._ns_resolver.push(cls): 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

735 core_config = self._config_wrapper.core_config(title=cls.__name__) 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

736 

737 if cls.__pydantic_fields_complete__ or cls is BaseModel_: 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

738 fields = getattr(cls, '__pydantic_fields__', {}) 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

739 else: 

740 try: 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

741 fields = rebuild_model_fields( 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

742 cls, 

743 config_wrapper=self._config_wrapper, 

744 ns_resolver=self._ns_resolver, 

745 typevars_map=self._typevars_map or {}, 

746 ) 

747 except NameError as e: 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

748 raise PydanticUndefinedAnnotation.from_name_error(e) from e 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

749 

750 decorators = cls.__pydantic_decorators__ 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

751 computed_fields = decorators.computed_fields 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

752 check_decorator_fields_exist( 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

753 chain( 

754 decorators.field_validators.values(), 

755 decorators.field_serializers.values(), 

756 decorators.validators.values(), 

757 ), 

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

759 ) 

760 

761 model_validators = decorators.model_validators.values() 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

762 

763 extras_schema = None 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

764 extras_keys_schema = None 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

765 if core_config.get('extra_fields_behavior') == 'allow': 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

766 assert cls.__mro__[0] is cls 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

767 assert cls.__mro__[-1] is object 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

768 for candidate_cls in cls.__mro__[:-1]: 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

769 extras_annotation = getattr(candidate_cls, '__annotations__', {}).get( 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

770 '__pydantic_extra__', None 

771 ) 

772 if extras_annotation is not None: 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

773 if isinstance(extras_annotation, str): 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

774 extras_annotation = _typing_extra.eval_type_backport( 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

775 _typing_extra._make_forward_ref( 

776 extras_annotation, is_argument=False, is_class=True 

777 ), 

778 *self._types_namespace, 

779 ) 

780 tp = get_origin(extras_annotation) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

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

782 raise PydanticSchemaGenerationError( 

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

784 ) 

785 extra_keys_type, extra_items_type = self._get_args_resolving_forward_refs( 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

786 extras_annotation, 

787 required=True, 

788 ) 

789 if extra_keys_type is not str: 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

790 extras_keys_schema = self.generate_schema(extra_keys_type) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

791 if not typing_objects.is_any(extra_items_type): 791 ↛ 793line 791 didn't jump to line 793 because the condition on line 791 was always true1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

792 extras_schema = self.generate_schema(extra_items_type) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

793 if extras_keys_schema is not None or extras_schema is not None: 793 ↛ 768line 793 didn't jump to line 768 because the condition on line 793 was always true1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

794 break 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

795 

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

797 

798 if cls.__pydantic_root_model__: 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

799 root_field = self._common_field_schema('root', fields['root'], decorators) 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

800 inner_schema = root_field['schema'] 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

801 inner_schema = apply_model_validators(inner_schema, model_validators, 'inner') 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

802 model_schema = core_schema.model_schema( 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

803 cls, 

804 inner_schema, 

805 generic_origin=generic_origin, 

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

807 root_model=True, 

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

809 config=core_config, 

810 ref=model_ref, 

811 ) 

812 else: 

813 fields_schema: core_schema.CoreSchema = core_schema.model_fields_schema( 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

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

815 computed_fields=[ 

816 self._computed_field_schema(d, decorators.field_serializers) 

817 for d in computed_fields.values() 

818 ], 

819 extras_schema=extras_schema, 

820 extras_keys_schema=extras_keys_schema, 

821 model_name=cls.__name__, 

822 ) 

823 inner_schema = apply_validators(fields_schema, decorators.root_validators.values(), None) 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

824 inner_schema = apply_model_validators(inner_schema, model_validators, 'inner') 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

825 

826 model_schema = core_schema.model_schema( 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

827 cls, 

828 inner_schema, 

829 generic_origin=generic_origin, 

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

831 root_model=False, 

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

833 config=core_config, 

834 ref=model_ref, 

835 ) 

836 

837 schema = self._apply_model_serializers(model_schema, decorators.model_serializers.values()) 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

838 schema = apply_model_validators(schema, model_validators, 'outer') 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

839 return self.defs.create_definition_reference_schema(schema) 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

840 

841 def _resolve_self_type(self, obj: Any) -> Any: 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

842 obj = self.model_type_stack.get() 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

843 if obj is None: 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

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

845 return obj 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

846 

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

848 BaseModel_ = import_cached_base_model() 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

849 

850 get_schema = getattr(obj, '__get_pydantic_core_schema__', None) 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

851 is_base_model_get_schema = ( 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

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

853 ) 

854 

855 if ( 1aepghiOcl

856 get_schema is not None 

857 # BaseModel.__get_pydantic_core_schema__ is defined for backwards compatibility, 

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

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

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

861 # don't call the method: 

862 and not is_base_model_get_schema 

863 ): 

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

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

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

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

868 # not referenceable: 

869 with self.defs.get_schema_or_ref(obj) as (_, maybe_schema): 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

870 if maybe_schema is not None: 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

871 return maybe_schema 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

872 

873 if obj is source: 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

874 ref_mode = 'unpack' 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

875 else: 

876 ref_mode = 'to-def' 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

877 schema = get_schema( 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

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

879 ) 

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

881 schema = self.defs.unpack_definitions(schema) 

882 

883 ref = get_ref(schema) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

884 if ref: 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

885 return self.defs.create_definition_reference_schema(schema) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

886 

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

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

889 return schema 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

890 

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

892 from pydantic.v1 import BaseModel as BaseModelV1 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

893 

894 if issubclass(obj, BaseModelV1): 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

895 warn( 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

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

897 UserWarning, 

898 ) 

899 else: 

900 warn( 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

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

902 PydanticDeprecatedSince20, 

903 ) 

904 return core_schema.chain_schema([core_schema.with_info_plain_validator_function(v) for v in validators()]) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

905 

906 def _resolve_forward_ref(self, obj: Any) -> Any: 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

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

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

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

910 # `Validator(SomeImportedTypeAliasWithAForwardReference)` 

911 # or the equivalent for BaseModel 

912 # class Model(BaseModel): 

913 # x: SomeImportedTypeAliasWithAForwardReference 

914 try: 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

915 obj = _typing_extra.eval_type_backport(obj, *self._types_namespace) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

916 except NameError as e: 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

917 raise PydanticUndefinedAnnotation.from_name_error(e) from e 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

918 

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

920 if isinstance(obj, ForwardRef): 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

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

922 

923 if self._typevars_map: 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

924 obj = replace_types(obj, self._typevars_map) 1aebfpghijkcldm

925 

926 return obj 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

927 

928 @overload 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

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

930 

931 @overload 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

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

933 

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

935 args = get_args(obj) 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

936 if args: 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

937 if isinstance(obj, GenericAlias): 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

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

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

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

941 elif required: # pragma: no cover 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

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

943 return args 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

944 

945 def _get_first_arg_or_any(self, obj: Any) -> Any: 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

946 args = self._get_args_resolving_forward_refs(obj) 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

947 if not args: 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

948 return Any 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

949 return args[0] 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

950 

951 def _get_first_two_args_or_any(self, obj: Any) -> tuple[Any, Any]: 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

952 args = self._get_args_resolving_forward_refs(obj) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

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

954 return (Any, Any) 

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

956 origin = get_origin(obj) 

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

958 return args[0], args[1] 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

959 

960 def _generate_schema_inner(self, obj: Any) -> core_schema.CoreSchema: 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

961 if typing_objects.is_self(obj): 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

962 obj = self._resolve_self_type(obj) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

963 

964 if typing_objects.is_annotated(get_origin(obj)): 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

965 return self._annotated_schema(obj) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

966 

967 if isinstance(obj, dict): 967 ↛ 969line 967 didn't jump to line 969 because the condition on line 967 was never true1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

968 # we assume this is already a valid schema 

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

970 

971 if isinstance(obj, str): 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

972 obj = ForwardRef(obj) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

973 

974 if isinstance(obj, ForwardRef): 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

975 return self.generate_schema(self._resolve_forward_ref(obj)) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

976 

977 BaseModel = import_cached_base_model() 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

978 

979 if lenient_issubclass(obj, BaseModel): 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

980 with self.model_type_stack.push(obj): 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

981 return self._model_schema(obj) 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

982 

983 if isinstance(obj, PydanticRecursiveRef): 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

984 return core_schema.definition_reference_schema(schema_ref=obj.type_ref) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

985 

986 return self.match_type(obj) 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

987 

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

989 """Main mapping of types to schemas. 

990 

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

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

993 

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

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

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

997 

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

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

1000 """ 

1001 if obj is str: 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

1002 return core_schema.str_schema() 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

1003 elif obj is bytes: 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

1004 return core_schema.bytes_schema() 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1005 elif obj is int: 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

1006 return core_schema.int_schema() 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

1007 elif obj is float: 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

1008 return core_schema.float_schema() 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

1009 elif obj is bool: 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

1010 return core_schema.bool_schema() 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1011 elif obj is complex: 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

1012 return core_schema.complex_schema() 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1013 elif typing_objects.is_any(obj) or obj is object: 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

1014 return core_schema.any_schema() 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1015 elif obj is datetime.date: 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

1016 return core_schema.date_schema() 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1017 elif obj is datetime.datetime: 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

1018 return core_schema.datetime_schema() 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1019 elif obj is datetime.time: 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

1020 return core_schema.time_schema() 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1021 elif obj is datetime.timedelta: 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

1022 return core_schema.timedelta_schema() 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1023 elif obj is Decimal: 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

1024 return core_schema.decimal_schema() 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1025 elif obj is UUID: 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

1026 return core_schema.uuid_schema() 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1027 elif obj is Url: 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

1028 return core_schema.url_schema() 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1029 elif obj is Fraction: 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

1030 return self._fraction_schema() 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1031 elif obj is MultiHostUrl: 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

1032 return core_schema.multi_host_url_schema() 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1033 elif obj is None or obj is _typing_extra.NoneType: 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

1034 return core_schema.none_schema() 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1035 elif obj in IP_TYPES: 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

1036 return self._ip_schema(obj) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1037 elif obj in TUPLE_TYPES: 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

1038 return self._tuple_schema(obj) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1039 elif obj in LIST_TYPES: 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

1040 return self._list_schema(Any) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1041 elif obj in SET_TYPES: 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

1042 return self._set_schema(Any) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1043 elif obj in FROZEN_SET_TYPES: 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

1044 return self._frozenset_schema(Any) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1045 elif obj in SEQUENCE_TYPES: 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

1046 return self._sequence_schema(Any) 1abnuxcdovB

1047 elif obj in ITERABLE_TYPES: 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

1048 return self._iterable_schema(obj) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1049 elif obj in DICT_TYPES: 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

1050 return self._dict_schema(Any, Any) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1051 elif obj in PATH_TYPES: 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

1052 return self._path_schema(obj, Any) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1053 elif obj in DEQUE_TYPES: 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

1054 return self._deque_schema(Any) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1055 elif obj in MAPPING_TYPES: 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

1056 return self._mapping_schema(obj, Any, Any) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

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

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

1059 elif typing_objects.is_typealiastype(obj): 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

1060 return self._type_alias_type_schema(obj) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1061 elif obj is type: 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

1062 return self._type_schema() 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1063 elif _typing_extra.is_callable(obj): 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

1064 return core_schema.callable_schema() 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1065 elif typing_objects.is_literal(get_origin(obj)): 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

1066 return self._literal_schema(obj) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1067 elif is_typeddict(obj): 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

1068 return self._typed_dict_schema(obj, None) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1069 elif _typing_extra.is_namedtuple(obj): 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

1070 return self._namedtuple_schema(obj, None) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1071 elif typing_objects.is_newtype(obj): 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

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

1073 return self.generate_schema(obj.__supertype__) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1074 elif obj in PATTERN_TYPES: 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

1075 return self._pattern_schema(obj) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1076 elif _typing_extra.is_hashable(obj): 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

1077 return self._hashable_schema() 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1078 elif isinstance(obj, typing.TypeVar): 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

1079 return self._unsubstituted_typevar_schema(obj) 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

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

1081 if obj is Final: 

1082 return core_schema.any_schema() 

1083 return self.generate_schema( 

1084 self._get_first_arg_or_any(obj), 

1085 ) 

1086 elif isinstance(obj, VALIDATE_CALL_SUPPORTED_TYPES): 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

1087 return self._call_schema(obj) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1088 elif inspect.isclass(obj) and issubclass(obj, Enum): 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

1089 return self._enum_schema(obj) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1090 elif obj is ZoneInfo: 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

1091 return self._zoneinfo_schema() 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1092 

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

1094 # the case of a dc type here 

1095 if dataclasses.is_dataclass(obj): 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

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

1097 

1098 origin = get_origin(obj) 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

1099 if origin is not None: 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

1100 return self._match_generic_type(obj, origin) 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

1101 

1102 if self._arbitrary_types: 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1103 return self._arbitrary_type_schema(obj) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1104 return self._unknown_type_schema(obj) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1105 

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

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

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

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

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

1111 if dataclasses.is_dataclass(origin): 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

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

1113 if _typing_extra.is_namedtuple(origin): 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

1114 return self._namedtuple_schema(obj, origin) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1115 

1116 schema = self._generate_schema_from_get_schema_method(origin, obj) 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

1117 if schema is not None: 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

1118 return schema 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1119 

1120 if typing_objects.is_typealiastype(origin): 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

1121 return self._type_alias_type_schema(obj) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1122 elif is_union_origin(origin): 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

1123 return self._union_schema(obj) 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

1124 elif origin in TUPLE_TYPES: 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

1125 return self._tuple_schema(obj) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1126 elif origin in LIST_TYPES: 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

1127 return self._list_schema(self._get_first_arg_or_any(obj)) 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

1128 elif origin in SET_TYPES: 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1129 return self._set_schema(self._get_first_arg_or_any(obj)) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1130 elif origin in FROZEN_SET_TYPES: 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1131 return self._frozenset_schema(self._get_first_arg_or_any(obj)) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1132 elif origin in DICT_TYPES: 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1133 return self._dict_schema(*self._get_first_two_args_or_any(obj)) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1134 elif origin in PATH_TYPES: 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1135 return self._path_schema(origin, self._get_first_arg_or_any(obj)) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1136 elif origin in DEQUE_TYPES: 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1137 return self._deque_schema(self._get_first_arg_or_any(obj)) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1138 elif origin in MAPPING_TYPES: 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1139 return self._mapping_schema(origin, *self._get_first_two_args_or_any(obj)) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1140 elif origin in COUNTER_TYPES: 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1141 return self._mapping_schema(origin, self._get_first_arg_or_any(obj), int) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1142 elif is_typeddict(origin): 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1143 return self._typed_dict_schema(obj, origin) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1144 elif origin in TYPE_TYPES: 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1145 return self._subclass_schema(obj) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1146 elif origin in SEQUENCE_TYPES: 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1147 return self._sequence_schema(self._get_first_arg_or_any(obj)) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1148 elif origin in ITERABLE_TYPES: 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1149 return self._iterable_schema(obj) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1150 elif origin in PATTERN_TYPES: 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1151 return self._pattern_schema(obj) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1152 

1153 if self._arbitrary_types: 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1154 return self._arbitrary_type_schema(origin) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1155 return self._unknown_type_schema(obj) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1156 

1157 def _generate_td_field_schema( 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

1158 self, 

1159 name: str, 

1160 field_info: FieldInfo, 

1161 decorators: DecoratorInfos, 

1162 *, 

1163 required: bool = True, 

1164 ) -> core_schema.TypedDictField: 

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

1166 common_field = self._common_field_schema(name, field_info, decorators) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1167 return core_schema.typed_dict_field( 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1168 common_field['schema'], 

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

1170 serialization_exclude=common_field['serialization_exclude'], 

1171 validation_alias=common_field['validation_alias'], 

1172 serialization_alias=common_field['serialization_alias'], 

1173 metadata=common_field['metadata'], 

1174 ) 

1175 

1176 def _generate_md_field_schema( 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

1177 self, 

1178 name: str, 

1179 field_info: FieldInfo, 

1180 decorators: DecoratorInfos, 

1181 ) -> core_schema.ModelField: 

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

1183 common_field = self._common_field_schema(name, field_info, decorators) 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

1184 return core_schema.model_field( 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

1185 common_field['schema'], 

1186 serialization_exclude=common_field['serialization_exclude'], 

1187 validation_alias=common_field['validation_alias'], 

1188 serialization_alias=common_field['serialization_alias'], 

1189 frozen=common_field['frozen'], 

1190 metadata=common_field['metadata'], 

1191 ) 

1192 

1193 def _generate_dc_field_schema( 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

1194 self, 

1195 name: str, 

1196 field_info: FieldInfo, 

1197 decorators: DecoratorInfos, 

1198 ) -> core_schema.DataclassField: 

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

1200 common_field = self._common_field_schema(name, field_info, decorators) 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

1201 return core_schema.dataclass_field( 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

1202 name, 

1203 common_field['schema'], 

1204 init=field_info.init, 

1205 init_only=field_info.init_var or None, 

1206 kw_only=None if field_info.kw_only else False, 

1207 serialization_exclude=common_field['serialization_exclude'], 

1208 validation_alias=common_field['validation_alias'], 

1209 serialization_alias=common_field['serialization_alias'], 

1210 frozen=common_field['frozen'], 

1211 metadata=common_field['metadata'], 

1212 ) 

1213 

1214 def _common_field_schema( # C901 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

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

1216 ) -> _CommonField: 

1217 source_type, annotations = field_info.annotation, field_info.metadata 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

1218 

1219 def set_discriminator(schema: CoreSchema) -> CoreSchema: 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

1220 schema = self._apply_discriminator_to_union(schema, field_info.discriminator) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1221 return schema 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1222 

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

1224 validators_from_decorators = [] 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

1225 for decorator in filter_field_decorator_info_by_field(decorators.field_validators.values(), name): 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

1226 validators_from_decorators.append(_mode_to_validator[decorator.info.mode]._from_decorator(decorator)) 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

1227 

1228 with self.field_name_stack.push(name): 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

1229 if field_info.discriminator is not None: 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

1230 schema = self._apply_annotations( 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1231 source_type, annotations + validators_from_decorators, transform_inner_schema=set_discriminator 

1232 ) 

1233 else: 

1234 schema = self._apply_annotations( 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

1235 source_type, 

1236 annotations + validators_from_decorators, 

1237 ) 

1238 

1239 # This V1 compatibility shim should eventually be removed 

1240 # push down any `each_item=True` validators 

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

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

1243 this_field_validators = filter_field_decorator_info_by_field(decorators.validators.values(), name) 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

1244 if _validators_require_validate_default(this_field_validators): 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

1245 field_info.validate_default = True 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1246 each_item_validators = [v for v in this_field_validators if v.info.each_item is True] 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

1247 this_field_validators = [v for v in this_field_validators if v not in each_item_validators] 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

1248 schema = apply_each_item_validators(schema, each_item_validators, name) 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

1249 

1250 schema = apply_validators(schema, this_field_validators, name) 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

1251 

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

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

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

1255 if not field_info.is_required(): 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

1256 schema = wrap_default(field_info, schema) 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

1257 

1258 schema = self._apply_field_serializers( 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

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

1260 ) 

1261 

1262 pydantic_js_updates, pydantic_js_extra = _extract_json_schema_info_from_field_info(field_info) 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

1263 core_metadata: dict[str, Any] = {} 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

1264 update_core_metadata( 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

1265 core_metadata, pydantic_js_updates=pydantic_js_updates, pydantic_js_extra=pydantic_js_extra 

1266 ) 

1267 

1268 if isinstance(field_info.validation_alias, (AliasChoices, AliasPath)): 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

1269 validation_alias = field_info.validation_alias.convert_to_aliases() 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1270 else: 

1271 validation_alias = field_info.validation_alias 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

1272 

1273 return _common_field( 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

1274 schema, 

1275 serialization_exclude=True if field_info.exclude else None, 

1276 validation_alias=validation_alias, 

1277 serialization_alias=field_info.serialization_alias, 

1278 frozen=field_info.frozen, 

1279 metadata=core_metadata, 

1280 ) 

1281 

1282 def _union_schema(self, union_type: Any) -> core_schema.CoreSchema: 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

1283 """Generate schema for a Union.""" 

1284 args = self._get_args_resolving_forward_refs(union_type, required=True) 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

1285 choices: list[CoreSchema] = [] 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

1286 nullable = False 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

1287 for arg in args: 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

1288 if arg is None or arg is _typing_extra.NoneType: 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

1289 nullable = True 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

1290 else: 

1291 choices.append(self.generate_schema(arg)) 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

1292 

1293 if len(choices) == 1: 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

1294 s = choices[0] 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

1295 else: 

1296 choices_with_tags: list[CoreSchema | tuple[CoreSchema, str]] = [] 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1297 for choice in choices: 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

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

1299 if tag is not None: 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1300 choices_with_tags.append((choice, tag)) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1301 else: 

1302 choices_with_tags.append(choice) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1303 s = core_schema.union_schema(choices_with_tags) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1304 

1305 if nullable: 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

1306 s = core_schema.nullable_schema(s) 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

1307 return s 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

1308 

1309 def _type_alias_type_schema(self, obj: TypeAliasType) -> CoreSchema: 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

1310 with self.defs.get_schema_or_ref(obj) as (ref, maybe_schema): 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1311 if maybe_schema is not None: 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1312 return maybe_schema 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1313 

1314 origin: TypeAliasType = get_origin(obj) or obj 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1315 typevars_map = get_standard_typevars_map(obj) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1316 

1317 with self._ns_resolver.push(origin): 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1318 try: 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1319 annotation = _typing_extra.eval_type(origin.__value__, *self._types_namespace) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1320 except NameError as e: 

1321 raise PydanticUndefinedAnnotation.from_name_error(e) from e 

1322 annotation = replace_types(annotation, typevars_map) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1323 schema = self.generate_schema(annotation) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1324 assert schema['type'] != 'definitions' 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1325 schema['ref'] = ref # type: ignore 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1326 return self.defs.create_definition_reference_schema(schema) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1327 

1328 def _literal_schema(self, literal_type: Any) -> CoreSchema: 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

1329 """Generate schema for a Literal.""" 

1330 expected = list(get_literal_values(literal_type, type_check=False, unpack_type_aliases='eager')) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

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

1332 schema = core_schema.literal_schema(expected) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1333 

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

1335 schema = core_schema.no_info_after_validator_function( 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

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

1337 ) 

1338 

1339 return schema 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1340 

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

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

1343 

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

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

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

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

1348 

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

1350 """ 

1351 FieldInfo = import_cached_field_info() 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1352 

1353 with ( 1aebfnqpghijkrscldmot

1354 self.model_type_stack.push(typed_dict_cls), 

1355 self.defs.get_schema_or_ref(typed_dict_cls) as ( 

1356 typed_dict_ref, 

1357 maybe_schema, 

1358 ), 

1359 ): 

1360 if maybe_schema is not None: 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1361 return maybe_schema 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1362 

1363 typevars_map = get_standard_typevars_map(typed_dict_cls) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1364 if origin is not None: 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1365 typed_dict_cls = origin 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1366 

1367 if not _SUPPORTS_TYPEDDICT and type(typed_dict_cls).__module__ == 'typing': 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1368 raise PydanticUserError( 1aebfnqpghijkrscldmot

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

1370 code='typed-dict-version', 

1371 ) 

1372 

1373 try: 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

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

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

1376 config: ConfigDict | None = get_attribute_from_bases(typed_dict_cls, '__pydantic_config__') 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1377 except AttributeError: 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1378 config = None 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1379 

1380 with self._config_wrapper_stack.push(config): 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1381 core_config = self._config_wrapper.core_config(title=typed_dict_cls.__name__) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1382 

1383 required_keys: frozenset[str] = typed_dict_cls.__required_keys__ 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1384 

1385 fields: dict[str, core_schema.TypedDictField] = {} 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1386 

1387 decorators = DecoratorInfos.build(typed_dict_cls) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1388 decorators.update_from_config(self._config_wrapper) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1389 

1390 if self._config_wrapper.use_attribute_docstrings: 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1391 field_docstrings = extract_docstrings_from_cls(typed_dict_cls, use_inspect=True) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1392 else: 

1393 field_docstrings = None 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1394 

1395 try: 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1396 annotations = _typing_extra.get_cls_type_hints(typed_dict_cls, ns_resolver=self._ns_resolver) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1397 except NameError as e: 

1398 raise PydanticUndefinedAnnotation.from_name_error(e) from e 

1399 

1400 readonly_fields: list[str] = [] 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1401 

1402 for field_name, annotation in annotations.items(): 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1403 field_info = FieldInfo.from_annotation(annotation, _source=AnnotationSource.TYPED_DICT) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1404 field_info.annotation = replace_types(field_info.annotation, typevars_map) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1405 

1406 required = ( 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

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

1408 ) and 'not_required' not in field_info._qualifiers 

1409 if 'read_only' in field_info._qualifiers: 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1410 readonly_fields.append(field_name) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1411 

1412 if ( 1aepghicl

1413 field_docstrings is not None 

1414 and field_info.description is None 

1415 and field_name in field_docstrings 

1416 ): 

1417 field_info.description = field_docstrings[field_name] 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1418 update_field_from_config(self._config_wrapper, field_name, field_info) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1419 

1420 fields[field_name] = self._generate_td_field_schema( 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1421 field_name, field_info, decorators, required=required 

1422 ) 

1423 

1424 if readonly_fields: 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1425 fields_repr = ', '.join(repr(f) for f in readonly_fields) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1426 plural = len(readonly_fields) >= 2 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1427 warnings.warn( 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

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

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

1430 'from any mutation on dictionary instances.', 

1431 UserWarning, 

1432 ) 

1433 

1434 td_schema = core_schema.typed_dict_schema( 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1435 fields, 

1436 cls=typed_dict_cls, 

1437 computed_fields=[ 

1438 self._computed_field_schema(d, decorators.field_serializers) 

1439 for d in decorators.computed_fields.values() 

1440 ], 

1441 ref=typed_dict_ref, 

1442 config=core_config, 

1443 ) 

1444 

1445 schema = self._apply_model_serializers(td_schema, decorators.model_serializers.values()) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1446 schema = apply_model_validators(schema, decorators.model_validators.values(), 'all') 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

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

1448 

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

1450 """Generate schema for a NamedTuple.""" 

1451 with ( 1aebfnqpghijkrscldmot

1452 self.model_type_stack.push(namedtuple_cls), 

1453 self.defs.get_schema_or_ref(namedtuple_cls) as ( 

1454 namedtuple_ref, 

1455 maybe_schema, 

1456 ), 

1457 ): 

1458 if maybe_schema is not None: 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1459 return maybe_schema 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1460 typevars_map = get_standard_typevars_map(namedtuple_cls) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1461 if origin is not None: 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1462 namedtuple_cls = origin 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1463 

1464 try: 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1465 annotations = _typing_extra.get_cls_type_hints(namedtuple_cls, ns_resolver=self._ns_resolver) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1466 except NameError as e: 

1467 raise PydanticUndefinedAnnotation.from_name_error(e) from e 

1468 if not annotations: 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

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

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

1471 

1472 if typevars_map: 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1473 annotations = { 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1474 field_name: replace_types(annotation, typevars_map) 

1475 for field_name, annotation in annotations.items() 

1476 } 

1477 

1478 arguments_schema = core_schema.arguments_schema( 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1479 [ 

1480 self._generate_parameter_schema( 

1481 field_name, 

1482 annotation, 

1483 source=AnnotationSource.NAMED_TUPLE, 

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

1485 ) 

1486 for field_name, annotation in annotations.items() 

1487 ], 

1488 metadata={'pydantic_js_prefer_positional_arguments': True}, 

1489 ) 

1490 schema = core_schema.call_schema(arguments_schema, namedtuple_cls, ref=namedtuple_ref) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1491 return self.defs.create_definition_reference_schema(schema) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1492 

1493 def _generate_parameter_schema( 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

1494 self, 

1495 name: str, 

1496 annotation: type[Any], 

1497 source: AnnotationSource, 

1498 default: Any = Parameter.empty, 

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

1500 ) -> core_schema.ArgumentsParameter: 

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

1502 

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

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

1505 """ 

1506 FieldInfo = import_cached_field_info() 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1507 

1508 if default is Parameter.empty: 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1509 field = FieldInfo.from_annotation(annotation, _source=source) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1510 else: 

1511 field = FieldInfo.from_annotated_attribute(annotation, default, _source=source) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1512 

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

1514 update_field_from_config(self._config_wrapper, name, field) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1515 

1516 with self.field_name_stack.push(name): 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1517 schema = self._apply_annotations(field.annotation, [field]) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1518 

1519 if not field.is_required(): 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1520 schema = wrap_default(field, schema) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1521 

1522 parameter_schema = core_schema.arguments_parameter(name, schema) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1523 if mode is not None: 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1524 parameter_schema['mode'] = mode 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1525 if field.alias is not None: 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1526 parameter_schema['alias'] = field.alias 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1527 

1528 return parameter_schema 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1529 

1530 def _generate_parameter_v3_schema( 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

1531 self, 

1532 name: str, 

1533 annotation: Any, 

1534 source: AnnotationSource, 

1535 mode: Literal[ 

1536 'positional_only', 

1537 'positional_or_keyword', 

1538 'keyword_only', 

1539 'var_args', 

1540 'var_kwargs_uniform', 

1541 'var_kwargs_unpacked_typed_dict', 

1542 ], 

1543 default: Any = Parameter.empty, 

1544 ) -> core_schema.ArgumentsV3Parameter: 

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

1546 

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

1548 the `'arguments`' schema in V3. 

1549 """ 

1550 FieldInfo = import_cached_field_info() 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1551 

1552 if default is Parameter.empty: 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1553 field = FieldInfo.from_annotation(annotation, _source=source) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1554 else: 

1555 field = FieldInfo.from_annotated_attribute(annotation, default, _source=source) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1556 update_field_from_config(self._config_wrapper, name, field) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1557 

1558 with self.field_name_stack.push(name): 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1559 schema = self._apply_annotations(field.annotation, [field]) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1560 

1561 if not field.is_required(): 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1562 schema = wrap_default(field, schema) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1563 

1564 parameter_schema = core_schema.arguments_v3_parameter( 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1565 name=name, 

1566 schema=schema, 

1567 mode=mode, 

1568 ) 

1569 if field.alias is not None: 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1570 parameter_schema['alias'] = field.alias 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1571 

1572 return parameter_schema 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1573 

1574 def _tuple_schema(self, tuple_type: Any) -> core_schema.CoreSchema: 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

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

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

1577 typevars_map = get_standard_typevars_map(tuple_type) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1578 params = self._get_args_resolving_forward_refs(tuple_type) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1579 

1580 if typevars_map and params: 1580 ↛ 1581line 1580 didn't jump to line 1581 because the condition on line 1580 was never true1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

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

1582 

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

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

1585 if not params: 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1586 if tuple_type in TUPLE_TYPES: 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1587 return core_schema.tuple_schema([core_schema.any_schema()], variadic_item_index=0) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1588 else: 

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

1590 return core_schema.tuple_schema([]) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1591 elif params[-1] is Ellipsis: 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1592 if len(params) == 2: 1592 ↛ 1596line 1592 didn't jump to line 1596 because the condition on line 1592 was always true1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

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

1594 else: 

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

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

1597 elif len(params) == 1 and params[0] == (): 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

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

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

1600 return core_schema.tuple_schema([]) 1aebfpghijkcldm

1601 else: 

1602 return core_schema.tuple_schema([self.generate_schema(param) for param in params]) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1603 

1604 def _type_schema(self) -> core_schema.CoreSchema: 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

1605 return core_schema.custom_error_schema( 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1606 core_schema.is_instance_schema(type), 

1607 custom_error_type='is_type', 

1608 custom_error_message='Input should be a type', 

1609 ) 

1610 

1611 def _zoneinfo_schema(self) -> core_schema.CoreSchema: 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

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

1613 from ._validators import validate_str_is_valid_iana_tz 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1614 

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

1616 return core_schema.no_info_plain_validator_function( 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1617 validate_str_is_valid_iana_tz, 

1618 serialization=core_schema.to_string_ser_schema(), 

1619 metadata=metadata, 

1620 ) 

1621 

1622 def _union_is_subclass_schema(self, union_type: Any) -> core_schema.CoreSchema: 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

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

1624 args = self._get_args_resolving_forward_refs(union_type, required=True) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1625 return core_schema.union_schema([self.generate_schema(type[args]) for args in args]) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1626 

1627 def _subclass_schema(self, type_: Any) -> core_schema.CoreSchema: 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

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

1629 type_param = self._get_first_arg_or_any(type_) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1630 

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

1632 type_param = _typing_extra.annotated_type(type_param) or type_param 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1633 

1634 if typing_objects.is_any(type_param): 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1635 return self._type_schema() 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1636 elif typing_objects.is_typealiastype(type_param): 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1637 return self.generate_schema(type[type_param.__value__]) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1638 elif typing_objects.is_typevar(type_param): 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1639 if type_param.__bound__: 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1640 if is_union_origin(get_origin(type_param.__bound__)): 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1641 return self._union_is_subclass_schema(type_param.__bound__) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1642 return core_schema.is_subclass_schema(type_param.__bound__) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1643 elif type_param.__constraints__: 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

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

1645 else: 

1646 return self._type_schema() 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1647 elif is_union_origin(get_origin(type_param)): 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1648 return self._union_is_subclass_schema(type_param) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1649 else: 

1650 if typing_objects.is_self(type_param): 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1651 type_param = self._resolve_self_type(type_param) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1652 if _typing_extra.is_generic_alias(type_param): 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1653 raise PydanticUserError( 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

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

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

1656 code=None, 

1657 ) 

1658 if not inspect.isclass(type_param): 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

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

1660 # so we handle it manually here 

1661 if type_param is None: 1661 ↛ 1663line 1661 didn't jump to line 1663 because the condition on line 1661 was always true1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1662 return core_schema.is_subclass_schema(_typing_extra.NoneType) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

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

1664 return core_schema.is_subclass_schema(type_param) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1665 

1666 def _sequence_schema(self, items_type: Any) -> core_schema.CoreSchema: 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

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

1668 from ._serializers import serialize_sequence_via_list 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1669 

1670 item_type_schema = self.generate_schema(items_type) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1671 list_schema = core_schema.list_schema(item_type_schema) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1672 

1673 json_schema = smart_deepcopy(list_schema) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1674 python_schema = core_schema.is_instance_schema(typing.Sequence, cls_repr='Sequence') 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1675 if not typing_objects.is_any(items_type): 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1676 from ._validators import sequence_validator 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1677 

1678 python_schema = core_schema.chain_schema( 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

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

1680 ) 

1681 

1682 serialization = core_schema.wrap_serializer_function_ser_schema( 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1683 serialize_sequence_via_list, schema=item_type_schema, info_arg=True 

1684 ) 

1685 return core_schema.json_or_python_schema( 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1686 json_schema=json_schema, python_schema=python_schema, serialization=serialization 

1687 ) 

1688 

1689 def _iterable_schema(self, type_: Any) -> core_schema.GeneratorSchema: 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

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

1691 item_type = self._get_first_arg_or_any(type_) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1692 

1693 return core_schema.generator_schema(self.generate_schema(item_type)) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1694 

1695 def _pattern_schema(self, pattern_type: Any) -> core_schema.CoreSchema: 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

1696 from . import _validators 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1697 

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

1699 ser = core_schema.plain_serializer_function_ser_schema( 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

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

1701 ) 

1702 if pattern_type is typing.Pattern or pattern_type is re.Pattern: 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1703 # bare type 

1704 return core_schema.no_info_plain_validator_function( 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

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

1706 ) 

1707 

1708 param = self._get_args_resolving_forward_refs( 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1709 pattern_type, 

1710 required=True, 

1711 )[0] 

1712 if param is str: 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1713 return core_schema.no_info_plain_validator_function( 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

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

1715 ) 

1716 elif param is bytes: 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1717 return core_schema.no_info_plain_validator_function( 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

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

1719 ) 

1720 else: 

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

1722 

1723 def _hashable_schema(self) -> core_schema.CoreSchema: 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

1724 return core_schema.custom_error_schema( 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1725 schema=core_schema.json_or_python_schema( 

1726 json_schema=core_schema.chain_schema( 

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

1728 ), 

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

1730 ), 

1731 custom_error_type='is_hashable', 

1732 custom_error_message='Input should be hashable', 

1733 ) 

1734 

1735 def _dataclass_schema( 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

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

1737 ) -> core_schema.CoreSchema: 

1738 """Generate schema for a dataclass.""" 

1739 with ( 1aebfnqpghijkrsOJKLMNcldmot

1740 self.model_type_stack.push(dataclass), 

1741 self.defs.get_schema_or_ref(dataclass) as ( 

1742 dataclass_ref, 

1743 maybe_schema, 

1744 ), 

1745 ): 

1746 if maybe_schema is not None: 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

1747 return maybe_schema 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1748 

1749 schema = dataclass.__dict__.get('__pydantic_core_schema__') 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

1750 if schema is not None and not isinstance(schema, MockCoreSchema): 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

1751 if schema['type'] == 'definitions': 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1752 schema = self.defs.unpack_definitions(schema) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1753 ref = get_ref(schema) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1754 if ref: 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1755 return self.defs.create_definition_reference_schema(schema) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1756 else: 

1757 return schema 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1758 

1759 typevars_map = get_standard_typevars_map(dataclass) 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

1760 if origin is not None: 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

1761 dataclass = origin 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1762 

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

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

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

1766 config = getattr(dataclass, '__pydantic_config__', None) 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

1767 

1768 from ..dataclasses import is_pydantic_dataclass 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

1769 

1770 with self._ns_resolver.push(dataclass), self._config_wrapper_stack.push(config): 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

1771 if is_pydantic_dataclass(dataclass): 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

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

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

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

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

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

1777 if typevars_map: 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

1778 for field in fields.values(): 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1779 field.apply_typevars_map(typevars_map, *self._types_namespace) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1780 else: 

1781 fields = collect_dataclass_fields( 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1782 dataclass, 

1783 typevars_map=typevars_map, 

1784 config_wrapper=self._config_wrapper, 

1785 ) 

1786 

1787 if self._config_wrapper.extra == 'allow': 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

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

1789 for field_name, field in fields.items(): 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1790 if field.init is False: 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1791 raise PydanticUserError( 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

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

1793 f'This combination is not allowed.', 

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

1795 ) 

1796 

1797 decorators = dataclass.__dict__.get('__pydantic_decorators__') 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

1798 if decorators is None: 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

1799 decorators = DecoratorInfos.build(dataclass) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1800 decorators.update_from_config(self._config_wrapper) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

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

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

1803 args = sorted( 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

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

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

1806 ) 

1807 has_post_init = hasattr(dataclass, '__post_init__') 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

1808 has_slots = hasattr(dataclass, '__slots__') 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

1809 

1810 args_schema = core_schema.dataclass_args_schema( 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

1811 dataclass.__name__, 

1812 args, 

1813 computed_fields=[ 

1814 self._computed_field_schema(d, decorators.field_serializers) 

1815 for d in decorators.computed_fields.values() 

1816 ], 

1817 collect_init_only=has_post_init, 

1818 ) 

1819 

1820 inner_schema = apply_validators(args_schema, decorators.root_validators.values(), None) 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

1821 

1822 model_validators = decorators.model_validators.values() 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

1823 inner_schema = apply_model_validators(inner_schema, model_validators, 'inner') 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

1824 

1825 core_config = self._config_wrapper.core_config(title=dataclass.__name__) 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

1826 

1827 dc_schema = core_schema.dataclass_schema( 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

1828 dataclass, 

1829 inner_schema, 

1830 generic_origin=origin, 

1831 post_init=has_post_init, 

1832 ref=dataclass_ref, 

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

1834 slots=has_slots, 

1835 config=core_config, 

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

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

1838 frozen=self._config_wrapper_stack.tail.frozen, 

1839 ) 

1840 schema = self._apply_model_serializers(dc_schema, decorators.model_serializers.values()) 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

1841 schema = apply_model_validators(schema, model_validators, 'outer') 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

1842 return self.defs.create_definition_reference_schema(schema) 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

1843 

1844 def _call_schema(self, function: ValidateCallSupportedTypes) -> core_schema.CallSchema: 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

1845 """Generate schema for a Callable. 

1846 

1847 TODO support functional validators once we support them in Config 

1848 """ 

1849 arguments_schema = self._arguments_schema(function) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1850 

1851 return_schema: core_schema.CoreSchema | None = None 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1852 config_wrapper = self._config_wrapper 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1853 if config_wrapper.validate_return: 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1854 sig = signature(function) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1855 return_hint = sig.return_annotation 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1856 if return_hint is not sig.empty: 1856 ↛ 1863line 1856 didn't jump to line 1863 because the condition on line 1856 was always true1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1857 globalns, localns = self._types_namespace 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1858 type_hints = _typing_extra.get_function_type_hints( 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

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

1860 ) 

1861 return_schema = self.generate_schema(type_hints['return']) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1862 

1863 return core_schema.call_schema( 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1864 arguments_schema, 

1865 function, 

1866 return_schema=return_schema, 

1867 ) 

1868 

1869 def _arguments_schema( 1aebfnquwxCDhijkrsyzEFGOJKLMNPcldmotvABHI

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

1871 ) -> core_schema.ArgumentsSchema: 

1872 """Generate schema for a Signature.""" 

1873 mode_lookup: dict[_ParameterKind, Literal['positional_only', 'positional_or_keyword', 'keyword_only']] = { 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1874 Parameter.POSITIONAL_ONLY: 'positional_only', 

1875 Parameter.POSITIONAL_OR_KEYWORD: 'positional_or_keyword', 

1876 Parameter.KEYWORD_ONLY: 'keyword_only', 

1877 } 

1878 

1879 sig = signature(function) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1880 globalns, localns = self._types_namespace 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1881 type_hints = _typing_extra.get_function_type_hints(function, globalns=globalns, localns=localns) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1882 

1883 arguments_list: list[core_schema.ArgumentsParameter] = [] 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1884 var_args_schema: core_schema.CoreSchema | None = None 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1885 var_kwargs_schema: core_schema.CoreSchema | None = None 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1886 var_kwargs_mode: core_schema.VarKwargsMode | None = None 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1887 

1888 for i, (name, p) in enumerate(sig.parameters.items()): 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1889 if p.annotation is sig.empty: 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1890 annotation = typing.cast(Any, Any) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1891 else: 

1892 annotation = type_hints[name] 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1893 

1894 if parameters_callback is not None: 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1895 result = parameters_callback(i, name, annotation) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1896 if result == 'skip': 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1897 continue 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1898 

1899 parameter_mode = mode_lookup.get(p.kind) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1900 if parameter_mode is not None: 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1901 arg_schema = self._generate_parameter_schema( 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

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

1903 ) 

1904 arguments_list.append(arg_schema) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1905 elif p.kind == Parameter.VAR_POSITIONAL: 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1906 var_args_schema = self.generate_schema(annotation) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1907 else: 

1908 assert p.kind == Parameter.VAR_KEYWORD, p.kind 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1909 

1910 unpack_type = _typing_extra.unpack_type(annotation) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1911 if unpack_type is not None: 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1912 origin = get_origin(unpack_type) or unpack_type 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1913 if not is_typeddict(origin): 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1914 raise PydanticUserError( 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

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

1916 code='unpack-typed-dict', 

1917 ) 

1918 non_pos_only_param_names = { 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

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

1920 } 

1921 overlapping_params = non_pos_only_param_names.intersection(origin.__annotations__) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1922 if overlapping_params: 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1923 raise PydanticUserError( 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

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

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

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

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

1928 ) 

1929 

1930 var_kwargs_mode = 'unpacked-typed-dict' 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1931 var_kwargs_schema = self._typed_dict_schema(unpack_type, get_origin(unpack_type)) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1932 else: 

1933 var_kwargs_mode = 'uniform' 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1934 var_kwargs_schema = self.generate_schema(annotation) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1935 

1936 return core_schema.arguments_schema( 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1937 arguments_list, 

1938 var_args_schema=var_args_schema, 

1939 var_kwargs_mode=var_kwargs_mode, 

1940 var_kwargs_schema=var_kwargs_schema, 

1941 validate_by_name=self._config_wrapper.validate_by_name, 

1942 ) 

1943 

1944 def _arguments_v3_schema( 1aebfnquwxCDhijkrsyzEFGOJKLMNPcldmotvABHI

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

1946 ) -> core_schema.ArgumentsV3Schema: 

1947 mode_lookup: dict[ 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

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

1949 ] = { 

1950 Parameter.POSITIONAL_ONLY: 'positional_only', 

1951 Parameter.POSITIONAL_OR_KEYWORD: 'positional_or_keyword', 

1952 Parameter.VAR_POSITIONAL: 'var_args', 

1953 Parameter.KEYWORD_ONLY: 'keyword_only', 

1954 } 

1955 

1956 sig = signature(function) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1957 globalns, localns = self._types_namespace 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1958 type_hints = _typing_extra.get_function_type_hints(function, globalns=globalns, localns=localns) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1959 

1960 parameters_list: list[core_schema.ArgumentsV3Parameter] = [] 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1961 

1962 for i, (name, p) in enumerate(sig.parameters.items()): 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1963 if parameters_callback is not None: 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1964 result = parameters_callback(i, name, p.annotation) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1965 if result == 'skip': 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1966 continue 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1967 

1968 if p.annotation is Parameter.empty: 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1969 annotation = typing.cast(Any, Any) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1970 else: 

1971 annotation = type_hints[name] 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1972 

1973 parameter_mode = mode_lookup.get(p.kind) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1974 if parameter_mode is None: 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1975 assert p.kind == Parameter.VAR_KEYWORD, p.kind 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1976 

1977 unpack_type = _typing_extra.unpack_type(annotation) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1978 if unpack_type is not None: 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1979 origin = get_origin(unpack_type) or unpack_type 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1980 if not is_typeddict(origin): 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1981 raise PydanticUserError( 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

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

1983 code='unpack-typed-dict', 

1984 ) 

1985 non_pos_only_param_names = { 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

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

1987 } 

1988 overlapping_params = non_pos_only_param_names.intersection(origin.__annotations__) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1989 if overlapping_params: 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1990 raise PydanticUserError( 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

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

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

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

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

1995 ) 

1996 parameter_mode = 'var_kwargs_unpacked_typed_dict' 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1997 annotation = unpack_type 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

1998 else: 

1999 parameter_mode = 'var_kwargs_uniform' 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

2000 

2001 parameters_list.append( 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

2002 self._generate_parameter_v3_schema( 

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

2004 ) 

2005 ) 

2006 

2007 return core_schema.arguments_v3_schema( 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

2008 parameters_list, 

2009 validate_by_name=self._config_wrapper.validate_by_name, 

2010 ) 

2011 

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

2013 try: 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

2014 has_default = typevar.has_default() 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

2015 except AttributeError: 1aebfnquwpghijkrsyzOJKLMNcldmotvA

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

2017 pass 1aebfnquwpghijkrsyzOJKLMNcldmotvA

2018 else: 

2019 if has_default: 1aebfnquwxCDpghijkrsyzEFGPcldmotvABHI

2020 return self.generate_schema(typevar.__default__) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

2021 

2022 if constraints := typevar.__constraints__: 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

2023 return self._union_schema(typing.Union[constraints]) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

2024 

2025 if bound := typevar.__bound__: 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

2026 schema = self.generate_schema(bound) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

2027 schema['serialization'] = core_schema.wrap_serializer_function_ser_schema( 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

2028 lambda x, h: h(x), 

2029 schema=core_schema.any_schema(), 

2030 ) 

2031 return schema 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

2032 

2033 return core_schema.any_schema() 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

2034 

2035 def _computed_field_schema( 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

2036 self, 

2037 d: Decorator[ComputedFieldInfo], 

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

2039 ) -> core_schema.ComputedField: 

2040 if d.info.return_type is not PydanticUndefined: 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

2041 return_type = d.info.return_type 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

2042 else: 

2043 try: 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

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

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

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

2047 return_type = _decorators.get_callable_return_type(d.func, localns=self._types_namespace.locals) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

2048 except NameError as e: 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

2049 raise PydanticUndefinedAnnotation.from_name_error(e) from e 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

2050 if return_type is PydanticUndefined: 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

2051 raise PydanticUserError( 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

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

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

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

2055 ) 

2056 

2057 return_type = replace_types(return_type, self._typevars_map) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

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

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

2060 d.info = dataclasses.replace(d.info, return_type=return_type) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

2061 return_type_schema = self.generate_schema(return_type) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

2062 # Apply serializers to computed field if there exist 

2063 return_type_schema = self._apply_field_serializers( 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

2064 return_type_schema, 

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

2066 ) 

2067 

2068 pydantic_js_updates, pydantic_js_extra = _extract_json_schema_info_from_field_info(d.info) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

2069 core_metadata: dict[str, Any] = {} 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

2070 update_core_metadata( 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

2071 core_metadata, 

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

2073 pydantic_js_extra=pydantic_js_extra, 

2074 ) 

2075 return core_schema.computed_field( 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

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

2077 ) 

2078 

2079 def _annotated_schema(self, annotated_type: Any) -> core_schema.CoreSchema: 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

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

2081 FieldInfo = import_cached_field_info() 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

2082 source_type, *annotations = self._get_args_resolving_forward_refs( 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

2083 annotated_type, 

2084 required=True, 

2085 ) 

2086 schema = self._apply_annotations(source_type, annotations) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

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

2088 # even if there are function validators involved 

2089 for annotation in annotations: 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

2090 if isinstance(annotation, FieldInfo): 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

2091 schema = wrap_default(annotation, schema) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

2092 return schema 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

2093 

2094 def _apply_annotations( 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

2095 self, 

2096 source_type: Any, 

2097 annotations: list[Any], 

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

2099 ) -> CoreSchema: 

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

2101 

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

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

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

2105 """ 

2106 annotations = list(_known_annotated_metadata.expand_grouped_metadata(annotations)) 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

2107 

2108 pydantic_js_annotation_functions: list[GetJsonSchemaFunction] = [] 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

2109 

2110 def inner_handler(obj: Any) -> CoreSchema: 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

2111 schema = self._generate_schema_from_get_schema_method(obj, source_type) 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

2112 

2113 if schema is None: 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

2114 schema = self._generate_schema_inner(obj) 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

2115 

2116 metadata_js_function = _extract_get_pydantic_json_schema(obj) 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

2117 if metadata_js_function is not None: 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

2118 metadata_schema = resolve_original_schema(schema, self.defs) 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

2119 if metadata_schema is not None: 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

2120 self._add_js_function(metadata_schema, metadata_js_function) 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

2121 return transform_inner_schema(schema) 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

2122 

2123 get_inner_schema = CallbackGetCoreSchemaHandler(inner_handler, self) 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

2124 

2125 for annotation in annotations: 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

2126 if annotation is None: 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

2127 continue 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

2128 get_inner_schema = self._get_wrapped_inner_schema( 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

2129 get_inner_schema, annotation, pydantic_js_annotation_functions 

2130 ) 

2131 

2132 schema = get_inner_schema(source_type) 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

2133 if pydantic_js_annotation_functions: 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

2134 core_metadata = schema.setdefault('metadata', {}) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

2135 update_core_metadata(core_metadata, pydantic_js_annotation_functions=pydantic_js_annotation_functions) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

2136 return _add_custom_serialization_from_json_encoders(self._config_wrapper.json_encoders, source_type, schema) 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

2137 

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

2139 FieldInfo = import_cached_field_info() 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

2140 

2141 if isinstance(metadata, FieldInfo): 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

2142 for field_metadata in metadata.metadata: 2142 ↛ 2143line 2142 didn't jump to line 2143 because the loop on line 2142 never started1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

2143 schema = self._apply_single_annotation(schema, field_metadata) 

2144 

2145 if metadata.discriminator is not None: 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

2146 schema = self._apply_discriminator_to_union(schema, metadata.discriminator) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

2147 return schema 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

2148 

2149 if schema['type'] == 'nullable': 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

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

2151 inner = schema.get('schema', core_schema.any_schema()) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

2152 inner = self._apply_single_annotation(inner, metadata) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

2153 if inner: 2153 ↛ 2155line 2153 didn't jump to line 2155 because the condition on line 2153 was always true1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

2154 schema['schema'] = inner 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

2155 return schema 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

2156 

2157 original_schema = schema 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

2158 ref = schema.get('ref') 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

2159 if ref is not None: 2159 ↛ 2160line 2159 didn't jump to line 2160 because the condition on line 2159 was never true1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

2160 schema = schema.copy() 

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

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

2163 return existing 

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

2165 elif schema['type'] == 'definition-ref': 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

2166 ref = schema['schema_ref'] 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

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

2168 schema = referenced_schema.copy() 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

2169 new_ref = ref + f'_{repr(metadata)}' 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

2170 if (existing := self.defs.get_schema_from_ref(new_ref)) is not None: 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

2171 return existing 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

2172 schema['ref'] = new_ref # pyright: ignore[reportGeneralTypeIssues] 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

2173 

2174 maybe_updated_schema = _known_annotated_metadata.apply_known_metadata(metadata, schema) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

2175 

2176 if maybe_updated_schema is not None: 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

2177 return maybe_updated_schema 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

2178 return original_schema 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

2179 

2180 def _apply_single_annotation_json_schema( 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

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

2182 ) -> core_schema.CoreSchema: 

2183 FieldInfo = import_cached_field_info() 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

2184 

2185 if isinstance(metadata, FieldInfo): 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

2186 for field_metadata in metadata.metadata: 2186 ↛ 2187line 2186 didn't jump to line 2187 because the loop on line 2186 never started1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

2187 schema = self._apply_single_annotation_json_schema(schema, field_metadata) 

2188 

2189 pydantic_js_updates, pydantic_js_extra = _extract_json_schema_info_from_field_info(metadata) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

2190 core_metadata = schema.setdefault('metadata', {}) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

2191 update_core_metadata( 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

2192 core_metadata, pydantic_js_updates=pydantic_js_updates, pydantic_js_extra=pydantic_js_extra 

2193 ) 

2194 return schema 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

2195 

2196 def _get_wrapped_inner_schema( 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

2197 self, 

2198 get_inner_schema: GetCoreSchemaHandler, 

2199 annotation: Any, 

2200 pydantic_js_annotation_functions: list[GetJsonSchemaFunction], 

2201 ) -> CallbackGetCoreSchemaHandler: 

2202 annotation_get_schema: GetCoreSchemaFunction | None = getattr(annotation, '__get_pydantic_core_schema__', None) 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

2203 

2204 def new_handler(source: Any) -> core_schema.CoreSchema: 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

2205 if annotation_get_schema is not None: 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

2206 schema = annotation_get_schema(source, get_inner_schema) 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

2207 else: 

2208 schema = get_inner_schema(source) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

2209 schema = self._apply_single_annotation(schema, annotation) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

2210 schema = self._apply_single_annotation_json_schema(schema, annotation) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

2211 

2212 metadata_js_function = _extract_get_pydantic_json_schema(annotation) 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

2213 if metadata_js_function is not None: 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

2214 pydantic_js_annotation_functions.append(metadata_js_function) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

2215 return schema 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

2216 

2217 return CallbackGetCoreSchemaHandler(new_handler, self) 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

2218 

2219 def _apply_field_serializers( 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

2220 self, 

2221 schema: core_schema.CoreSchema, 

2222 serializers: list[Decorator[FieldSerializerDecoratorInfo]], 

2223 ) -> core_schema.CoreSchema: 

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

2225 if serializers: 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

2226 schema = copy(schema) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

2227 if schema['type'] == 'definitions': 2227 ↛ 2228line 2227 didn't jump to line 2228 because the condition on line 2227 was never true1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

2228 inner_schema = schema['schema'] 

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

2230 return schema 

2231 elif 'ref' in schema: 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

2232 schema = self.defs.create_definition_reference_schema(schema) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

2233 

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

2235 serializer = serializers[-1] 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

2236 is_field_serializer, info_arg = inspect_field_serializer(serializer.func, serializer.info.mode) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

2237 

2238 if serializer.info.return_type is not PydanticUndefined: 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

2239 return_type = serializer.info.return_type 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

2240 else: 

2241 try: 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

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

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

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

2245 return_type = _decorators.get_callable_return_type( 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

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

2247 ) 

2248 except NameError as e: 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

2249 raise PydanticUndefinedAnnotation.from_name_error(e) from e 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

2250 

2251 if return_type is PydanticUndefined: 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

2252 return_schema = None 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

2253 else: 

2254 return_schema = self.generate_schema(return_type) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

2255 

2256 if serializer.info.mode == 'wrap': 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

2257 schema['serialization'] = core_schema.wrap_serializer_function_ser_schema( 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

2258 serializer.func, 

2259 is_field_serializer=is_field_serializer, 

2260 info_arg=info_arg, 

2261 return_schema=return_schema, 

2262 when_used=serializer.info.when_used, 

2263 ) 

2264 else: 

2265 assert serializer.info.mode == 'plain' 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

2266 schema['serialization'] = core_schema.plain_serializer_function_ser_schema( 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

2267 serializer.func, 

2268 is_field_serializer=is_field_serializer, 

2269 info_arg=info_arg, 

2270 return_schema=return_schema, 

2271 when_used=serializer.info.when_used, 

2272 ) 

2273 return schema 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

2274 

2275 def _apply_model_serializers( 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

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

2277 ) -> core_schema.CoreSchema: 

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

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

2280 if serializers: 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

2281 serializer = list(serializers)[-1] 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

2282 info_arg = inspect_model_serializer(serializer.func, serializer.info.mode) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

2283 

2284 if serializer.info.return_type is not PydanticUndefined: 2284 ↛ 2285line 2284 didn't jump to line 2285 because the condition on line 2284 was never true1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

2285 return_type = serializer.info.return_type 

2286 else: 

2287 try: 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

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

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

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

2291 return_type = _decorators.get_callable_return_type( 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

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

2293 ) 

2294 except NameError as e: 

2295 raise PydanticUndefinedAnnotation.from_name_error(e) from e 

2296 

2297 if return_type is PydanticUndefined: 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

2298 return_schema = None 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

2299 else: 

2300 return_schema = self.generate_schema(return_type) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

2301 

2302 if serializer.info.mode == 'wrap': 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

2303 ser_schema: core_schema.SerSchema = core_schema.wrap_serializer_function_ser_schema( 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

2304 serializer.func, 

2305 info_arg=info_arg, 

2306 return_schema=return_schema, 

2307 when_used=serializer.info.when_used, 

2308 ) 

2309 else: 

2310 # plain 

2311 ser_schema = core_schema.plain_serializer_function_ser_schema( 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

2312 serializer.func, 

2313 info_arg=info_arg, 

2314 return_schema=return_schema, 

2315 when_used=serializer.info.when_used, 

2316 ) 

2317 schema['serialization'] = ser_schema 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

2318 if ref: 2318 ↛ 2320line 2318 didn't jump to line 2320 because the condition on line 2318 was always true1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

2319 schema['ref'] = ref # type: ignore 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

2320 return schema 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

2321 

2322 

2323_VALIDATOR_F_MATCH: Mapping[ 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

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

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

2326] = { 

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

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

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

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

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

2332 f, schema, field_name=field_name 

2333 ), 

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

2335 f, schema, field_name=field_name 

2336 ), 

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

2338 f, field_name=field_name 

2339 ), 

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

2341 f, schema, field_name=field_name 

2342 ), 

2343} 

2344 

2345 

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

2347# be removed once we drop support for those. 

2348def apply_validators( 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

2349 schema: core_schema.CoreSchema, 

2350 validators: Iterable[Decorator[RootValidatorDecoratorInfo]] 

2351 | Iterable[Decorator[ValidatorDecoratorInfo]] 

2352 | Iterable[Decorator[FieldValidatorDecoratorInfo]], 

2353 field_name: str | None, 

2354) -> core_schema.CoreSchema: 

2355 """Apply validators to a schema. 

2356 

2357 Args: 

2358 schema: The schema to apply validators on. 

2359 validators: An iterable of validators. 

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

2361 

2362 Returns: 

2363 The updated schema. 

2364 """ 

2365 for validator in validators: 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

2366 info_arg = inspect_validator(validator.func, validator.info.mode) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

2367 val_type = 'with-info' if info_arg else 'no-info' 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

2368 

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

2370 return schema 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

2371 

2372 

2373def _validators_require_validate_default(validators: Iterable[Decorator[ValidatorDecoratorInfo]]) -> bool: 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

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

2375 

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

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

2378 

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

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

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

2382 """ 

2383 for validator in validators: 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

2384 if validator.info.always: 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

2385 return True 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

2386 return False 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

2387 

2388 

2389def apply_model_validators( 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

2390 schema: core_schema.CoreSchema, 

2391 validators: Iterable[Decorator[ModelValidatorDecoratorInfo]], 

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

2393) -> core_schema.CoreSchema: 

2394 """Apply model validators to a schema. 

2395 

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

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

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

2399 

2400 Args: 

2401 schema: The schema to apply validators on. 

2402 validators: An iterable of validators. 

2403 mode: The validator mode. 

2404 

2405 Returns: 

2406 The updated schema. 

2407 """ 

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

2409 for validator in validators: 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

2410 if mode == 'inner' and validator.info.mode != 'before': 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

2411 continue 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

2412 if mode == 'outer' and validator.info.mode == 'before': 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

2413 continue 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

2414 info_arg = inspect_validator(validator.func, validator.info.mode) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

2415 if validator.info.mode == 'wrap': 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

2416 if info_arg: 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

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

2418 else: 

2419 schema = core_schema.no_info_wrap_validator_function(function=validator.func, schema=schema) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

2420 elif validator.info.mode == 'before': 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

2421 if info_arg: 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

2422 schema = core_schema.with_info_before_validator_function(function=validator.func, schema=schema) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

2423 else: 

2424 schema = core_schema.no_info_before_validator_function(function=validator.func, schema=schema) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

2425 else: 

2426 assert validator.info.mode == 'after' 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

2427 if info_arg: 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

2428 schema = core_schema.with_info_after_validator_function(function=validator.func, schema=schema) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

2429 else: 

2430 schema = core_schema.no_info_after_validator_function(function=validator.func, schema=schema) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

2431 if ref: 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

2432 schema['ref'] = ref # type: ignore 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

2433 return schema 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

2434 

2435 

2436def wrap_default(field_info: FieldInfo, schema: core_schema.CoreSchema) -> core_schema.CoreSchema: 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

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

2438 

2439 Args: 

2440 field_info: The field info object. 

2441 schema: The schema to apply default on. 

2442 

2443 Returns: 

2444 Updated schema by default value or `default_factory`. 

2445 """ 

2446 if field_info.default_factory: 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

2447 return core_schema.with_default_schema( 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

2448 schema, 

2449 default_factory=field_info.default_factory, 

2450 default_factory_takes_data=takes_validated_data_argument(field_info.default_factory), 

2451 validate_default=field_info.validate_default, 

2452 ) 

2453 elif field_info.default is not PydanticUndefined: 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

2454 return core_schema.with_default_schema( 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

2455 schema, default=field_info.default, validate_default=field_info.validate_default 

2456 ) 

2457 else: 

2458 return schema 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

2459 

2460 

2461def _extract_get_pydantic_json_schema(tp: Any) -> GetJsonSchemaFunction | None: 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

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

2463 js_modify_function = getattr(tp, '__get_pydantic_json_schema__', None) 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

2464 

2465 if hasattr(tp, '__modify_schema__'): 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

2466 BaseModel = import_cached_base_model() 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

2467 

2468 has_custom_v2_modify_js_func = ( 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

2469 js_modify_function is not None 

2470 and BaseModel.__get_pydantic_json_schema__.__func__ # type: ignore 

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

2472 ) 

2473 

2474 if not has_custom_v2_modify_js_func: 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

2475 cls_name = getattr(tp, '__name__', None) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

2476 raise PydanticUserError( 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

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

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

2479 code='custom-json-schema', 

2480 ) 

2481 

2482 if (origin := get_origin(tp)) is not None: 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

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

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

2485 return _extract_get_pydantic_json_schema(origin) 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

2486 

2487 if js_modify_function is None: 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

2488 return None 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

2489 

2490 return js_modify_function 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

2491 

2492 

2493class _CommonField(TypedDict): 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

2494 schema: core_schema.CoreSchema 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

2495 validation_alias: str | list[str | int] | list[list[str | int]] | None 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

2496 serialization_alias: str | None 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

2497 serialization_exclude: bool | None 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

2498 frozen: bool | None 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

2499 metadata: dict[str, Any] 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

2500 

2501 

2502def _common_field( 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

2503 schema: core_schema.CoreSchema, 

2504 *, 

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

2506 serialization_alias: str | None = None, 

2507 serialization_exclude: bool | None = None, 

2508 frozen: bool | None = None, 

2509 metadata: Any = None, 

2510) -> _CommonField: 

2511 return { 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

2512 'schema': schema, 

2513 'validation_alias': validation_alias, 

2514 'serialization_alias': serialization_alias, 

2515 'serialization_exclude': serialization_exclude, 

2516 'frozen': frozen, 

2517 'metadata': metadata, 

2518 } 

2519 

2520 

2521def resolve_original_schema(schema: CoreSchema, definitions: _Definitions) -> CoreSchema | None: 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

2522 if schema['type'] == 'definition-ref': 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

2523 return definitions.get_schema_from_ref(schema['schema_ref']) 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

2524 elif schema['type'] == 'definitions': 2524 ↛ 2525line 2524 didn't jump to line 2525 because the condition on line 2524 was never true1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

2525 return schema['schema'] 

2526 else: 

2527 return schema 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

2528 

2529 

2530def _inlining_behavior( 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

2531 def_ref: core_schema.DefinitionReferenceSchema, 

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

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

2534 

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

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

2537 provided that such metadata is kept. 

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

2539 """ 

2540 if 'serialization' in def_ref: 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

2541 return 'keep' 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

2542 metadata = def_ref.get('metadata') 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

2543 if not metadata: 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

2544 return 'inline' 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

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

2546 return 'preserve_metadata' 

2547 return 'keep' 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

2548 

2549 

2550class _Definitions: 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

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

2552 

2553 _recursively_seen: set[str] 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

2554 """A set of recursively seen references. 1bfnquwxCDgjkrsyzEFGJKLMNPdmotvABHI

2555 

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

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

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

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

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

2561 """ 

2562 

2563 _definitions: dict[str, core_schema.CoreSchema] 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

2564 """A mapping of references to their corresponding schema. 1bfnquwxCDgjkrsyzEFGJKLMNPdmotvABHI

2565 

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

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

2568 manager. 

2569 """ 

2570 

2571 def __init__(self) -> None: 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

2572 self._recursively_seen = set() 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

2573 self._definitions = {} 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

2574 

2575 @contextmanager 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

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

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

2578 

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

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

2581 

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

2583 not the actual definition itself. 

2584 

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

2586 This includes any recursive types. 

2587 

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

2589 

2590 - Pydantic model 

2591 - Pydantic and stdlib dataclasses 

2592 - Typed dictionaries 

2593 - Named tuples 

2594 - `TypeAliasType` instances 

2595 - Enums 

2596 """ 

2597 ref = get_type_ref(tp) 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

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

2599 if ref in self._recursively_seen or ref in self._definitions: 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

2600 yield (ref, core_schema.definition_reference_schema(ref)) 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

2601 else: 

2602 self._recursively_seen.add(ref) 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

2603 try: 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

2604 yield (ref, None) 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

2605 finally: 

2606 self._recursively_seen.discard(ref) 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

2607 

2608 def get_schema_from_ref(self, ref: str) -> CoreSchema | None: 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

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

2610 return self._definitions.get(ref) 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

2611 

2612 def create_definition_reference_schema(self, schema: CoreSchema) -> core_schema.DefinitionReferenceSchema: 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

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

2614 

2615 The schema must have a reference attached to it. 

2616 """ 

2617 ref = schema['ref'] # pyright: ignore 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

2618 self._definitions[ref] = schema 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

2619 return core_schema.definition_reference_schema(ref) 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

2620 

2621 def unpack_definitions(self, schema: core_schema.DefinitionsSchema) -> CoreSchema: 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

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

2623 for def_schema in schema['definitions']: 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

2624 self._definitions[def_schema['ref']] = def_schema # pyright: ignore 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

2625 return schema['schema'] 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

2626 

2627 def finalize_schema(self, schema: CoreSchema) -> CoreSchema: 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

2628 """Finalize the core schema. 

2629 

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

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

2632 """ 

2633 definitions = self._definitions 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

2634 try: 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

2635 gather_result = gather_schemas_for_cleaning( 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

2636 schema, 

2637 definitions=definitions, 

2638 ) 

2639 except MissingDefinitionError as e: 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

2640 raise InvalidSchemaError from e 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

2641 

2642 remaining_defs: dict[str, CoreSchema] = {} 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

2643 

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

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

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

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

2648 if inlining_behavior == 'inline': 2648 ↛ 2655line 2648 didn't jump to line 2655 because the condition on line 2648 was always true1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

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

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

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

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

2653 inlinable_def_ref.clear() # pyright: ignore[reportAttributeAccessIssue] 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

2654 inlinable_def_ref.update(self._resolve_definition(ref, definitions)) # pyright: ignore 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

2655 elif inlining_behavior == 'preserve_metadata': 

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

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

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

2659 meta = inlinable_def_ref.pop('metadata') 

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

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

2662 inlinable_def_ref['metadata'] = meta 

2663 else: 

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

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

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

2667 remaining_defs[ref] = self._resolve_definition(ref, definitions) 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

2668 

2669 for cs in gather_result['deferred_discriminator_schemas']: 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

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

2671 if discriminator is None: 2671 ↛ 2675line 2671 didn't jump to line 2675 because the condition on line 2671 was never true1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

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

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

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

2675 continue 

2676 applied = _discriminated_union.apply_discriminator(cs.copy(), discriminator, remaining_defs) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

2677 # Mutate the schema directly to have the discriminator applied 

2678 cs.clear() # pyright: ignore[reportAttributeAccessIssue] 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

2679 cs.update(applied) # pyright: ignore 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

2680 

2681 if remaining_defs: 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

2682 schema = core_schema.definitions_schema(schema=schema, definitions=[*remaining_defs.values()]) 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

2683 return schema 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

2684 

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

2686 definition = definitions[ref] 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

2687 if definition['type'] != 'definition-ref': 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

2688 return definition 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

2689 

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

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

2692 visited: set[str] = set() 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

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

2694 schema_ref = definition['schema_ref'] 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

2695 if schema_ref in visited: 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

2696 raise PydanticUserError( 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

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

2698 ) 

2699 visited.add(schema_ref) 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

2700 definition = definitions[schema_ref] 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

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

2702 

2703 

2704class _FieldNameStack: 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

2705 __slots__ = ('_stack',) 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

2706 

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

2708 self._stack: list[str] = [] 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

2709 

2710 @contextmanager 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

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

2712 self._stack.append(field_name) 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

2713 yield 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

2714 self._stack.pop() 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

2715 

2716 def get(self) -> str | None: 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

2717 if self._stack: 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

2718 return self._stack[-1] 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

2719 else: 

2720 return None 1abnuxcdovB

2721 

2722 

2723class _ModelTypeStack: 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

2724 __slots__ = ('_stack',) 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

2725 

2726 def __init__(self) -> None: 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

2727 self._stack: list[type] = [] 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

2728 

2729 @contextmanager 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

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

2731 self._stack.append(type_obj) 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

2732 yield 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

2733 self._stack.pop() 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

2734 

2735 def get(self) -> type | None: 1aebfnquwxCDpghijkrsyzEFGOJKLMNPcldmotvABHI

2736 if self._stack: 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

2737 return self._stack[-1] 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI

2738 else: 

2739 return None 1aebfnquwxCDpghijkrsyzEFGcldmotvABHI