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

1120 statements  

« prev     ^ index     » next       coverage.py v7.5.3, created at 2024-06-21 17:00 +0000

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

2 

3from __future__ import annotations as _annotations 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

4 

5import collections.abc 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

6import dataclasses 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

7import inspect 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

8import re 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

9import sys 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

10import typing 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

11import warnings 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

12from contextlib import ExitStack, contextmanager 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

13from copy import copy, deepcopy 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

14from enum import Enum 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

15from functools import partial 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

16from inspect import Parameter, _ParameterKind, signature 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

17from itertools import chain 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

18from operator import attrgetter 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

19from types import FunctionType, LambdaType, MethodType 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

20from typing import ( 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

21 TYPE_CHECKING, 

22 Any, 

23 Callable, 

24 Dict, 

25 Final, 

26 ForwardRef, 

27 Iterable, 

28 Iterator, 

29 Mapping, 

30 Type, 

31 TypeVar, 

32 Union, 

33 cast, 

34 overload, 

35) 

36from warnings import warn 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

37 

38from pydantic_core import CoreSchema, PydanticUndefined, core_schema, to_jsonable_python 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

39from typing_extensions import Annotated, Literal, TypeAliasType, TypedDict, get_args, get_origin, is_typeddict 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

40 

41from ..aliases import AliasGenerator 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

42from ..annotated_handlers import GetCoreSchemaHandler, GetJsonSchemaHandler 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

43from ..config import ConfigDict, JsonDict, JsonEncoder 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

44from ..errors import PydanticSchemaGenerationError, PydanticUndefinedAnnotation, PydanticUserError 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

45from ..json_schema import JsonSchemaValue 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

46from ..version import version_short 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

47from ..warnings import PydanticDeprecatedSince20 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

48from . import _core_utils, _decorators, _discriminated_union, _known_annotated_metadata, _typing_extra 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

49from ._config import ConfigWrapper, ConfigWrapperStack 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

50from ._core_metadata import CoreMetadataHandler, build_metadata_dict 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

51from ._core_utils import ( 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

52 CoreSchemaOrField, 

53 collect_invalid_schemas, 

54 define_expected_missing_refs, 

55 get_ref, 

56 get_type_ref, 

57 is_function_with_inner_schema, 

58 is_list_like_schema_with_items_schema, 

59 simplify_schema_references, 

60 validate_core_schema, 

61) 

62from ._decorators import ( 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

63 Decorator, 

64 DecoratorInfos, 

65 FieldSerializerDecoratorInfo, 

66 FieldValidatorDecoratorInfo, 

67 ModelSerializerDecoratorInfo, 

68 ModelValidatorDecoratorInfo, 

69 RootValidatorDecoratorInfo, 

70 ValidatorDecoratorInfo, 

71 get_attribute_from_bases, 

72 inspect_field_serializer, 

73 inspect_model_serializer, 

74 inspect_validator, 

75) 

76from ._docs_extraction import extract_docstrings_from_cls 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

77from ._fields import collect_dataclass_fields, get_type_hints_infer_globalns 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

78from ._forward_ref import PydanticRecursiveRef 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

79from ._generics import get_standard_typevars_map, has_instance_in_type, recursively_defined_type_refs, replace_types 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

80from ._mock_val_ser import MockCoreSchema 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

81from ._schema_generation_shared import CallbackGetCoreSchemaHandler 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

82from ._typing_extra import is_finalvar, is_self_type 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

83from ._utils import lenient_issubclass 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

84 

85if TYPE_CHECKING: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

86 from ..fields import ComputedFieldInfo, FieldInfo 

87 from ..main import BaseModel 

88 from ..types import Discriminator 

89 from ..validators import FieldValidatorModes 

90 from ._dataclasses import StandardDataclass 

91 from ._schema_generation_shared import GetJsonSchemaFunction 

92 

93_SUPPORTS_TYPEDDICT = sys.version_info >= (3, 12) 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

94_AnnotatedType = type(Annotated[int, 123]) 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

95 

96FieldDecoratorInfo = Union[ValidatorDecoratorInfo, FieldValidatorDecoratorInfo, FieldSerializerDecoratorInfo] 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

97FieldDecoratorInfoType = TypeVar('FieldDecoratorInfoType', bound=FieldDecoratorInfo) 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

98AnyFieldDecorator = Union[ 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

99 Decorator[ValidatorDecoratorInfo], 

100 Decorator[FieldValidatorDecoratorInfo], 

101 Decorator[FieldSerializerDecoratorInfo], 

102] 

103 

104ModifyCoreSchemaWrapHandler = GetCoreSchemaHandler 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

105GetCoreSchemaFunction = Callable[[Any, ModifyCoreSchemaWrapHandler], core_schema.CoreSchema] 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

106 

107 

108TUPLE_TYPES: list[type] = [tuple, typing.Tuple] 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

109LIST_TYPES: list[type] = [list, typing.List, collections.abc.MutableSequence] 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

110SET_TYPES: list[type] = [set, typing.Set, collections.abc.MutableSet] 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

111FROZEN_SET_TYPES: list[type] = [frozenset, typing.FrozenSet, collections.abc.Set] 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

112DICT_TYPES: list[type] = [dict, typing.Dict, collections.abc.MutableMapping, collections.abc.Mapping] 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

113 

114 

115def check_validator_fields_against_field_name( 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

116 info: FieldDecoratorInfo, 

117 field: str, 

118) -> bool: 

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

120 

121 Args: 

122 info: The field info. 

123 field: The field name to check. 

124 

125 Returns: 

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

127 """ 

128 if '*' in info.fields: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

129 return True 1eiacnqryszkolmfgtuABCDhjbdpvwExF

130 for v_field_name in info.fields: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

131 if v_field_name == field: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

132 return True 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

133 return False 1eiacnqryszkolmfgtuABCDhjbdpvwExF

134 

135 

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

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

138 

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

140 

141 Args: 

142 decorators: An iterable of decorators. 

143 fields: An iterable of fields name. 

144 

145 Raises: 

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

147 """ 

148 fields = set(fields) 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

149 for dec in decorators: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

150 if '*' in dec.info.fields: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

151 continue 1eiacnqryszkolmfgtuABCDhjbdpvwExF

152 if dec.info.check_fields is False: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

153 continue 1eiacnqryszkolmfgtuABCDhjbdpvwExF

154 for field in dec.info.fields: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

155 if field not in fields: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

156 raise PydanticUserError( 1eiacnqryszkolmfgtuABCDhjbdpvwExF

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

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

159 code='decorator-missing-field', 

160 ) 

161 

162 

163def filter_field_decorator_info_by_field( 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

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

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

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

167 

168 

169def apply_each_item_validators( 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

170 schema: core_schema.CoreSchema, 

171 each_item_validators: list[Decorator[ValidatorDecoratorInfo]], 

172 field_name: str | None, 

173) -> core_schema.CoreSchema: 

174 # This V1 compatibility shim should eventually be removed 

175 

176 # push down any `each_item=True` validators 

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

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

179 if schema['type'] == 'nullable': 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

180 schema['schema'] = apply_each_item_validators(schema['schema'], each_item_validators, field_name) 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

181 return schema 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

182 elif schema['type'] == 'tuple': 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

183 if (variadic_item_index := schema.get('variadic_item_index')) is not None: 1eiacnqryszkolmfgtuABCDhjbdpvwExF

184 schema['items_schema'][variadic_item_index] = apply_validators( 1eiacnqryszkolmfgtuABCDhjbdpvwExF

185 schema['items_schema'][variadic_item_index], each_item_validators, field_name 

186 ) 

187 elif is_list_like_schema_with_items_schema(schema): 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

188 inner_schema = schema.get('items_schema', None) 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

189 if inner_schema is None: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

190 inner_schema = core_schema.any_schema() 1eiacnqryszkolmfgtuABCDhjbdpvwExF

191 schema['items_schema'] = apply_validators(inner_schema, each_item_validators, field_name) 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

192 elif schema['type'] == 'dict': 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

193 # push down any `each_item=True` validators onto dict _values_ 

194 # this is super arbitrary but it's the V1 behavior 

195 inner_schema = schema.get('values_schema', None) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

196 if inner_schema is None: 1eiacnqryszkolmfgtuABCDhjbdpvwExF

197 inner_schema = core_schema.any_schema() 1eiacnqryszkolmfgtuABCDhjbdpvwExF

198 schema['values_schema'] = apply_validators(inner_schema, each_item_validators, field_name) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

199 elif each_item_validators: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

200 raise TypeError( 1eiacnqryszkolmfgtuABCDhjbdpvwExF

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

202 ) 

203 return schema 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

204 

205 

206def modify_model_json_schema( 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

207 schema_or_field: CoreSchemaOrField, handler: GetJsonSchemaHandler, *, cls: Any 

208) -> JsonSchemaValue: 

209 """Add title and description for model-like classes' JSON schema. 

210 

211 Args: 

212 schema_or_field: The schema data to generate a JSON schema from. 

213 handler: The `GetCoreSchemaHandler` instance. 

214 cls: The model-like class. 

215 

216 Returns: 

217 JsonSchemaValue: The updated JSON schema. 

218 """ 

219 from ..main import BaseModel 1eiacnqryszkolmfgtuABCDhjbdpvwExF

220 from ..root_model import RootModel 1eiacnqryszkolmfgtuABCDhjbdpvwExF

221 

222 json_schema = handler(schema_or_field) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

223 original_schema = handler.resolve_ref_schema(json_schema) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

224 # Preserve the fact that definitions schemas should never have sibling keys: 

225 if '$ref' in original_schema: 1eiacnqryszkolmfgtuABCDhjbdpvwExF

226 ref = original_schema['$ref'] 1eiacnqryszkolmfgtuABCDhjbdpvwExF

227 original_schema.clear() 1eiacnqryszkolmfgtuABCDhjbdpvwExF

228 original_schema['allOf'] = [{'$ref': ref}] 1eiacnqryszkolmfgtuABCDhjbdpvwExF

229 if 'title' not in original_schema: 1eiacnqryszkolmfgtuABCDhjbdpvwExF

230 original_schema['title'] = cls.__name__ 1eiacnqryszkolmfgtuABCDhjbdpvwExF

231 # BaseModel; don't use cls.__doc__ as it will contain the verbose class signature by default 

232 docstring = None if cls is BaseModel else cls.__doc__ 1eiacnqryszkolmfgtuABCDhjbdpvwExF

233 if docstring and 'description' not in original_schema: 1eiacnqryszkolmfgtuABCDhjbdpvwExF

234 original_schema['description'] = inspect.cleandoc(docstring) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

235 elif issubclass(cls, RootModel) and cls.model_fields['root'].description: 1eiacnqryszkolmfgtuABCDhjbdpvwExF

236 original_schema['description'] = cls.model_fields['root'].description 1eiacnqryszkolmfgtuABCDhjbdpvwExF

237 return json_schema 1eiacnqryszkolmfgtuABCDhjbdpvwExF

238 

239 

240JsonEncoders = Dict[Type[Any], JsonEncoder] 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

241 

242 

243def _add_custom_serialization_from_json_encoders( 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

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

245) -> CoreSchema: 

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

247 

248 Args: 

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

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

251 schema: The schema to add the encoder to. 

252 """ 

253 if not json_encoders: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

254 return schema 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

255 if 'serialization' in schema: 1eiacnqryszkolmfgtuABCDhjbdpvwExF

256 return schema 1eiacnqryszkolmfgtuABCDhjbdpvwExF

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

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

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

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

261 encoder = json_encoders.get(base) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

262 if encoder is None: 1eiacnqryszkolmfgtuABCDhjbdpvwExF

263 continue 1eiacnqryszkolmfgtuABCDhjbdpvwExF

264 

265 warnings.warn( 1eiacnqryszkolmfgtuABCDhjbdpvwExF

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

267 PydanticDeprecatedSince20, 

268 ) 

269 

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

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

272 return schema 1eiacnqryszkolmfgtuABCDhjbdpvwExF

273 

274 return schema 1eiacnqryszkolmfgtuABCDhjbdpvwExF

275 

276 

277TypesNamespace = Union[Dict[str, Any], None] 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

278 

279 

280class TypesNamespaceStack: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

281 """A stack of types namespaces.""" 

282 

283 def __init__(self, types_namespace: TypesNamespace): 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

284 self._types_namespace_stack: list[TypesNamespace] = [types_namespace] 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

285 

286 @property 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

287 def tail(self) -> TypesNamespace: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

288 return self._types_namespace_stack[-1] 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

289 

290 @contextmanager 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

291 def push(self, for_type: type[Any]): 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

292 types_namespace = {**_typing_extra.get_cls_types_namespace(for_type), **(self.tail or {})} 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

293 self._types_namespace_stack.append(types_namespace) 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

294 try: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

295 yield 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

296 finally: 

297 self._types_namespace_stack.pop() 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

298 

299 

300def _get_first_non_null(a: Any, b: Any) -> Any: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

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

302 

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

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

305 """ 

306 return a if a is not None else b 1eiacnqryszkolmfgtuABCDhjbdpvwExF

307 

308 

309class GenerateSchema: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

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

311 

312 __slots__ = ( 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

313 '_config_wrapper_stack', 

314 '_types_namespace_stack', 

315 '_typevars_map', 

316 'field_name_stack', 

317 'model_type_stack', 

318 'defs', 

319 ) 

320 

321 def __init__( 1eiacnqryszlmfgtuABCDGHIJKLMNOhjbdpvwExF

322 self, 

323 config_wrapper: ConfigWrapper, 

324 types_namespace: dict[str, Any] | None, 

325 typevars_map: dict[Any, Any] | None = None, 

326 ) -> None: 

327 # we need a stack for recursing into child models 

328 self._config_wrapper_stack = ConfigWrapperStack(config_wrapper) 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

329 self._types_namespace_stack = TypesNamespaceStack(types_namespace) 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

330 self._typevars_map = typevars_map 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

331 self.field_name_stack = _FieldNameStack() 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

332 self.model_type_stack = _ModelTypeStack() 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

333 self.defs = _Definitions() 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

334 

335 @classmethod 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

336 def __from_parent( 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

337 cls, 

338 config_wrapper_stack: ConfigWrapperStack, 

339 types_namespace_stack: TypesNamespaceStack, 

340 model_type_stack: _ModelTypeStack, 

341 typevars_map: dict[Any, Any] | None, 

342 defs: _Definitions, 

343 ) -> GenerateSchema: 

344 obj = cls.__new__(cls) 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

345 obj._config_wrapper_stack = config_wrapper_stack 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

346 obj._types_namespace_stack = types_namespace_stack 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

347 obj.model_type_stack = model_type_stack 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

348 obj._typevars_map = typevars_map 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

349 obj.field_name_stack = _FieldNameStack() 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

350 obj.defs = defs 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

351 return obj 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

352 

353 @property 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

354 def _config_wrapper(self) -> ConfigWrapper: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

355 return self._config_wrapper_stack.tail 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

356 

357 @property 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

358 def _types_namespace(self) -> dict[str, Any] | None: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

359 return self._types_namespace_stack.tail 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

360 

361 @property 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

362 def _current_generate_schema(self) -> GenerateSchema: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

363 cls = self._config_wrapper.schema_generator or GenerateSchema 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

364 return cls.__from_parent( 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

365 self._config_wrapper_stack, 

366 self._types_namespace_stack, 

367 self.model_type_stack, 

368 self._typevars_map, 

369 self.defs, 

370 ) 

371 

372 @property 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

373 def _arbitrary_types(self) -> bool: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

374 return self._config_wrapper.arbitrary_types_allowed 1eiacnqryszkolmfgtuABCDhjbdpvwExF

375 

376 def str_schema(self) -> CoreSchema: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

377 """Generate a CoreSchema for `str`""" 

378 return core_schema.str_schema() 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

379 

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

381 # unstable / private APIs 

382 def _list_schema(self, tp: Any, items_type: Any) -> CoreSchema: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

383 return core_schema.list_schema(self.generate_schema(items_type)) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

384 

385 def _dict_schema(self, tp: Any, keys_type: Any, values_type: Any) -> CoreSchema: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

386 return core_schema.dict_schema(self.generate_schema(keys_type), self.generate_schema(values_type)) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

387 

388 def _set_schema(self, tp: Any, items_type: Any) -> CoreSchema: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

389 return core_schema.set_schema(self.generate_schema(items_type)) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

390 

391 def _frozenset_schema(self, tp: Any, items_type: Any) -> CoreSchema: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

392 return core_schema.frozenset_schema(self.generate_schema(items_type)) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

393 

394 def _arbitrary_type_schema(self, tp: Any) -> CoreSchema: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

395 if not isinstance(tp, type): 1eiacnqryszkolmfgtuABCDhjbdpvwExF

396 warn( 1eiacnqryszkolmfgtuABCDhjbdpvwExF

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

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

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

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

401 UserWarning, 

402 ) 

403 return core_schema.any_schema() 1eiacnqryszkolmfgtuABCDhjbdpvwExF

404 return core_schema.is_instance_schema(tp) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

405 

406 def _unknown_type_schema(self, obj: Any) -> CoreSchema: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

407 raise PydanticSchemaGenerationError( 1eiacnqryszkolmfgtuABCDhjbdpvwExF

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

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

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

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

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

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

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

415 ) 

416 

417 def _apply_discriminator_to_union( 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

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

419 ) -> CoreSchema: 

420 if discriminator is None: 420 ↛ 421line 420 didn't jump to line 421, because the condition on line 420 was never true1eiacnqryszkolmfgtuABCDhjbdpvwExF

421 return schema 

422 try: 1eiacnqryszkolmfgtuABCDhjbdpvwExF

423 return _discriminated_union.apply_discriminator( 1eiacnqryszkolmfgtuABCDhjbdpvwExF

424 schema, 

425 discriminator, 

426 ) 

427 except _discriminated_union.MissingDefinitionForUnionRef: 1eiacnqryszkolmfgtuABCDhjbdpvwExF

428 # defer until defs are resolved 

429 _discriminated_union.set_discriminator_in_metadata( 1eiacnqryszkolmfgtuABCDhjbdpvwExF

430 schema, 

431 discriminator, 

432 ) 

433 return schema 1eiacnqryszkolmfgtuABCDhjbdpvwExF

434 

435 class CollectedInvalid(Exception): 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

436 pass 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

437 

438 def clean_schema(self, schema: CoreSchema) -> CoreSchema: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

439 schema = self.collect_definitions(schema) 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

440 schema = simplify_schema_references(schema) 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

441 if collect_invalid_schemas(schema): 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

442 raise self.CollectedInvalid() 1eiacnqryszkolmfgtuABCDhjbdpvwExF

443 schema = _discriminated_union.apply_discriminators(schema) 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

444 schema = validate_core_schema(schema) 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

445 return schema 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

446 

447 def collect_definitions(self, schema: CoreSchema) -> CoreSchema: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

448 ref = cast('str | None', schema.get('ref', None)) 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

449 if ref: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

450 self.defs.definitions[ref] = schema 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

451 if 'ref' in schema: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

452 schema = core_schema.definition_reference_schema(schema['ref']) 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

453 return core_schema.definitions_schema( 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

454 schema, 

455 list(self.defs.definitions.values()), 

456 ) 

457 

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

459 metadata = CoreMetadataHandler(metadata_schema).metadata 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

460 pydantic_js_functions = metadata.setdefault('pydantic_js_functions', []) 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

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

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

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

464 # or something like that 

465 # but if it does it'll fail by inserting the duplicate 

466 if js_function not in pydantic_js_functions: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

467 pydantic_js_functions.append(js_function) 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

468 

469 def generate_schema( 1eiacnqryszlmfgtuABCDGHIJKLMNOhjbdpvwExF

470 self, 

471 obj: Any, 

472 from_dunder_get_core_schema: bool = True, 

473 ) -> core_schema.CoreSchema: 

474 """Generate core schema. 

475 

476 Args: 

477 obj: The object to generate core schema for. 

478 from_dunder_get_core_schema: Whether to generate schema from either the 

479 `__get_pydantic_core_schema__` function or `__pydantic_core_schema__` property. 

480 

481 Returns: 

482 The generated core schema. 

483 

484 Raises: 

485 PydanticUndefinedAnnotation: 

486 If it is not possible to evaluate forward reference. 

487 PydanticSchemaGenerationError: 

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

489 TypeError: 

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

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

492 PydanticUserError: 

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

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

495 """ 

496 schema: CoreSchema | None = None 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

497 

498 if from_dunder_get_core_schema: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

499 from_property = self._generate_schema_from_property(obj, obj) 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

500 if from_property is not None: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

501 schema = from_property 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

502 

503 if schema is None: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

504 schema = self._generate_schema_inner(obj) 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

505 

506 metadata_js_function = _extract_get_pydantic_json_schema(obj, schema) 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

507 if metadata_js_function is not None: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

508 metadata_schema = resolve_original_schema(schema, self.defs.definitions) 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

509 if metadata_schema: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

510 self._add_js_function(metadata_schema, metadata_js_function) 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

511 

512 schema = _add_custom_serialization_from_json_encoders(self._config_wrapper.json_encoders, obj, schema) 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

513 

514 return schema 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

515 

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

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

518 with self.defs.get_schema_or_ref(cls) as (model_ref, maybe_schema): 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

519 if maybe_schema is not None: 519 ↛ 520line 519 didn't jump to line 520, because the condition on line 519 was never true1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

520 return maybe_schema 

521 

522 fields = cls.model_fields 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

523 decorators = cls.__pydantic_decorators__ 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

524 computed_fields = decorators.computed_fields 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

525 check_decorator_fields_exist( 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

526 chain( 

527 decorators.field_validators.values(), 

528 decorators.field_serializers.values(), 

529 decorators.validators.values(), 

530 ), 

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

532 ) 

533 config_wrapper = ConfigWrapper(cls.model_config, check=False) 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

534 core_config = config_wrapper.core_config(cls) 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

535 metadata = build_metadata_dict(js_functions=[partial(modify_model_json_schema, cls=cls)]) 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

536 

537 model_validators = decorators.model_validators.values() 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

538 

539 extras_schema = None 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

540 if core_config.get('extra_fields_behavior') == 'allow': 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

541 assert cls.__mro__[0] is cls 1eiacnqryszkolmfgtuABCDhjbdpvwExF

542 assert cls.__mro__[-1] is object 1eiacnqryszkolmfgtuABCDhjbdpvwExF

543 for candidate_cls in cls.__mro__[:-1]: 1eiacnqryszkolmfgtuABCDhjbdpvwExF

544 extras_annotation = getattr(candidate_cls, '__annotations__', {}).get('__pydantic_extra__', None) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

545 if extras_annotation is not None: 1eiacnqryszkolmfgtuABCDhjbdpvwExF

546 if isinstance(extras_annotation, str): 1eiacnqryszkolmfgtuABCDhjbdpvwExF

547 extras_annotation = _typing_extra.eval_type_backport( 1eiacnqryszkolmfgtuABCDhjbdpvwExF

548 _typing_extra._make_forward_ref(extras_annotation, is_argument=False, is_class=True), 

549 self._types_namespace, 

550 ) 

551 tp = get_origin(extras_annotation) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

552 if tp not in (Dict, dict): 552 ↛ 553line 552 didn't jump to line 553, because the condition on line 552 was never true1eiacnqryszkolmfgtuABCDhjbdpvwExF

553 raise PydanticSchemaGenerationError( 

554 'The type annotation for `__pydantic_extra__` must be `Dict[str, ...]`' 

555 ) 

556 extra_items_type = self._get_args_resolving_forward_refs( 1eiacnqryszkolmfgtuABCDhjbdpvwExF

557 extras_annotation, 

558 required=True, 

559 )[1] 

560 if extra_items_type is not Any: 560 ↛ 543line 560 didn't jump to line 543, because the condition on line 560 was always true1eiacnqryszkolmfgtuABCDhjbdpvwExF

561 extras_schema = self.generate_schema(extra_items_type) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

562 break 1eiacnqryszkolmfgtuABCDhjbdpvwExF

563 

564 with self._config_wrapper_stack.push(config_wrapper), self._types_namespace_stack.push(cls): 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

565 self = self._current_generate_schema 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

566 if cls.__pydantic_root_model__: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

567 root_field = self._common_field_schema('root', fields['root'], decorators) 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

568 inner_schema = root_field['schema'] 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

569 inner_schema = apply_model_validators(inner_schema, model_validators, 'inner') 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

570 model_schema = core_schema.model_schema( 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

571 cls, 

572 inner_schema, 

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

574 root_model=True, 

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

576 config=core_config, 

577 ref=model_ref, 

578 metadata=metadata, 

579 ) 

580 else: 

581 fields_schema: core_schema.CoreSchema = core_schema.model_fields_schema( 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

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

583 computed_fields=[ 

584 self._computed_field_schema(d, decorators.field_serializers) 

585 for d in computed_fields.values() 

586 ], 

587 extras_schema=extras_schema, 

588 model_name=cls.__name__, 

589 ) 

590 inner_schema = apply_validators(fields_schema, decorators.root_validators.values(), None) 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

591 new_inner_schema = define_expected_missing_refs(inner_schema, recursively_defined_type_refs()) 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

592 if new_inner_schema is not None: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

593 inner_schema = new_inner_schema 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

594 inner_schema = apply_model_validators(inner_schema, model_validators, 'inner') 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

595 

596 model_schema = core_schema.model_schema( 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

597 cls, 

598 inner_schema, 

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

600 root_model=False, 

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

602 config=core_config, 

603 ref=model_ref, 

604 metadata=metadata, 

605 ) 

606 

607 schema = self._apply_model_serializers(model_schema, decorators.model_serializers.values()) 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

608 schema = apply_model_validators(schema, model_validators, 'outer') 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

609 self.defs.definitions[model_ref] = schema 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

610 return core_schema.definition_reference_schema(model_ref) 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

611 

612 def _unpack_refs_defs(self, schema: CoreSchema) -> CoreSchema: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

613 """Unpack all 'definitions' schemas into `GenerateSchema.defs.definitions` 

614 and return the inner schema. 

615 """ 

616 

617 def get_ref(s: CoreSchema) -> str: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

618 return s['ref'] # type: ignore 1eiacnqryszkolmfgtuABCDhjbdpvwExF

619 

620 if schema['type'] == 'definitions': 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

621 self.defs.definitions.update({get_ref(s): s for s in schema['definitions']}) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

622 schema = schema['schema'] 1eiacnqryszkolmfgtuABCDhjbdpvwExF

623 return schema 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

624 

625 def _generate_schema_from_property(self, obj: Any, source: Any) -> core_schema.CoreSchema | None: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

626 """Try to generate schema from either the `__get_pydantic_core_schema__` function or 

627 `__pydantic_core_schema__` property. 

628 

629 Note: `__get_pydantic_core_schema__` takes priority so it can 

630 decide whether to use a `__pydantic_core_schema__` attribute, or generate a fresh schema. 

631 """ 

632 # avoid calling `__get_pydantic_core_schema__` if we've already visited this object 

633 if is_self_type(obj): 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

634 obj = self.model_type_stack.get() 1eiacnqryszkolmfgtuABCDhjbdpvwExF

635 with self.defs.get_schema_or_ref(obj) as (_, maybe_schema): 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

636 if maybe_schema is not None: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

637 return maybe_schema 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

638 if obj is source: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

639 ref_mode = 'unpack' 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

640 else: 

641 ref_mode = 'to-def' 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

642 

643 schema: CoreSchema 

644 

645 if (get_schema := getattr(obj, '__get_pydantic_core_schema__', None)) is not None: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

646 if len(inspect.signature(get_schema).parameters) == 1: 646 ↛ 648line 646 didn't jump to line 648, because the condition on line 646 was never true1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

647 # (source) -> CoreSchema 

648 schema = get_schema(source) 

649 else: 

650 schema = get_schema( 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

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

652 ) 

653 # fmt: off 

654 elif ( 1eiackolmfgGHhjbd

655 (existing_schema := getattr(obj, '__pydantic_core_schema__', None)) is not None 

656 and not isinstance(existing_schema, MockCoreSchema) 

657 and existing_schema.get('cls', None) == obj 

658 ): 

659 schema = existing_schema 1eiacnqryszkolmfgtuABCDhjbdpvwExF

660 # fmt: on 

661 elif (validators := getattr(obj, '__get_validators__', None)) is not None: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

662 warn( 1eiacnqryszkolmfgtuABCDhjbdpvwExF

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

664 PydanticDeprecatedSince20, 

665 ) 

666 schema = core_schema.chain_schema([core_schema.with_info_plain_validator_function(v) for v in validators()]) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

667 else: 

668 # we have no existing schema information on the property, exit early so that we can go generate a schema 

669 return None 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

670 

671 schema = self._unpack_refs_defs(schema) 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

672 

673 if is_function_with_inner_schema(schema): 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

674 ref = schema['schema'].pop('ref', None) # pyright: ignore[reportCallIssue, reportArgumentType] 1eiacnqryszkolmfgtuABCDhjbdpvwExF

675 if ref: 1eiacnqryszkolmfgtuABCDhjbdpvwExF

676 schema['ref'] = ref 1eiacnqryszkolmfgtuABCDhjbdpvwExF

677 else: 

678 ref = get_ref(schema) 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

679 

680 if ref: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

681 self.defs.definitions[ref] = schema 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

682 return core_schema.definition_reference_schema(ref) 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

683 

684 return schema 1eiacnqryszkolmfgtuABCDhjbdpvwExF

685 

686 def _resolve_forward_ref(self, obj: Any) -> Any: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

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

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

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

690 # `Validator(SomeImportedTypeAliasWithAForwardReference)` 

691 # or the equivalent for BaseModel 

692 # class Model(BaseModel): 

693 # x: SomeImportedTypeAliasWithAForwardReference 

694 try: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

695 obj = _typing_extra.eval_type_backport(obj, globalns=self._types_namespace) 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

696 except NameError as e: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

697 raise PydanticUndefinedAnnotation.from_name_error(e) from e 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

698 

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

700 if isinstance(obj, ForwardRef): 1eiacnqryszkolmfgtuABCDhjbdpvwExF

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

702 

703 if self._typevars_map: 1eiacnqryszkolmfgtuABCDhjbdpvwExF

704 obj = replace_types(obj, self._typevars_map) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

705 

706 return obj 1eiacnqryszkolmfgtuABCDhjbdpvwExF

707 

708 @overload 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

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

710 

711 @overload 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

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

713 

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

715 args = get_args(obj) 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

716 if args: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

717 args = tuple([self._resolve_forward_ref(a) if isinstance(a, ForwardRef) else a for a in args]) 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

718 elif required: # pragma: no cover 1eiacnqryszkolmfgtuABCDhjbdpvwExF

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

720 return args 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

721 

722 def _get_first_arg_or_any(self, obj: Any) -> Any: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

723 args = self._get_args_resolving_forward_refs(obj) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

724 if not args: 1eiacnqryszkolmfgtuABCDhjbdpvwExF

725 return Any 1eiacnqryszkolmfgtuABCDhjbdpvwExF

726 return args[0] 1eiacnqryszkolmfgtuABCDhjbdpvwExF

727 

728 def _get_first_two_args_or_any(self, obj: Any) -> tuple[Any, Any]: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

729 args = self._get_args_resolving_forward_refs(obj) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

730 if not args: 730 ↛ 732line 730 didn't jump to line 732, because the condition on line 730 was always true1eiacnqryszkolmfgtuABCDhjbdpvwExF

731 return (Any, Any) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

732 if len(args) < 2: 

733 origin = get_origin(obj) 

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

735 return args[0], args[1] 

736 

737 def _generate_schema_inner(self, obj: Any) -> core_schema.CoreSchema: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

738 if isinstance(obj, _AnnotatedType): 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

739 return self._annotated_schema(obj) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

740 

741 if isinstance(obj, dict): 741 ↛ 743line 741 didn't jump to line 743, because the condition on line 741 was never true1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

742 # we assume this is already a valid schema 

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

744 

745 if isinstance(obj, str): 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

746 obj = ForwardRef(obj) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

747 

748 if isinstance(obj, ForwardRef): 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

749 return self.generate_schema(self._resolve_forward_ref(obj)) 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

750 

751 from ..main import BaseModel 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

752 

753 if lenient_issubclass(obj, BaseModel): 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

754 with self.model_type_stack.push(obj): 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

755 return self._model_schema(obj) 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

756 

757 if isinstance(obj, PydanticRecursiveRef): 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

758 return core_schema.definition_reference_schema(schema_ref=obj.type_ref) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

759 

760 return self.match_type(obj) 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

761 

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

763 """Main mapping of types to schemas. 

764 

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

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

767 

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

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

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

771 

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

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

774 """ 

775 if obj is str: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

776 return self.str_schema() 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

777 elif obj is bytes: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

778 return core_schema.bytes_schema() 1eiacnqryszkolmfgtuABCDhjbdpvwExF

779 elif obj is int: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

780 return core_schema.int_schema() 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

781 elif obj is float: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

782 return core_schema.float_schema() 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

783 elif obj is bool: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

784 return core_schema.bool_schema() 1eiacnqryszkolmfgtuABCDhjbdpvwExF

785 elif obj is Any or obj is object: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

786 return core_schema.any_schema() 1eiacnqryszkolmfgtuABCDhjbdpvwExF

787 elif obj is None or obj is _typing_extra.NoneType: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

788 return core_schema.none_schema() 1eiacnqryszkolmfgtuABCDhjbdpvwExF

789 elif obj in TUPLE_TYPES: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

790 return self._tuple_schema(obj) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

791 elif obj in LIST_TYPES: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

792 return self._list_schema(obj, self._get_first_arg_or_any(obj)) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

793 elif obj in SET_TYPES: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

794 return self._set_schema(obj, self._get_first_arg_or_any(obj)) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

795 elif obj in FROZEN_SET_TYPES: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

796 return self._frozenset_schema(obj, self._get_first_arg_or_any(obj)) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

797 elif obj in DICT_TYPES: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

798 return self._dict_schema(obj, *self._get_first_two_args_or_any(obj)) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

799 elif isinstance(obj, TypeAliasType): 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

800 return self._type_alias_type_schema(obj) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

801 elif obj == type: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

802 return self._type_schema() 1eiacnqryszkolmfgtuABCDhjbdpvwExF

803 elif _typing_extra.is_callable_type(obj): 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

804 return core_schema.callable_schema() 1eiacnqryszkolmfgtuABCDhjbdpvwExF

805 elif _typing_extra.is_literal_type(obj): 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

806 return self._literal_schema(obj) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

807 elif is_typeddict(obj): 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

808 return self._typed_dict_schema(obj, None) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

809 elif _typing_extra.is_namedtuple(obj): 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

810 return self._namedtuple_schema(obj, None) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

811 elif _typing_extra.is_new_type(obj): 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

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

813 return self.generate_schema(obj.__supertype__) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

814 elif obj == re.Pattern: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

815 return self._pattern_schema(obj) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

816 elif obj is collections.abc.Hashable or obj is typing.Hashable: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

817 return self._hashable_schema() 1eiacnqryszkolmfgtuABCDhjbdpvwExF

818 elif isinstance(obj, typing.TypeVar): 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

819 return self._unsubstituted_typevar_schema(obj) 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

820 elif is_finalvar(obj): 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

821 if obj is Final: 1eiacnqryszkolmfgtuABCDhjbdpvwExF

822 return core_schema.any_schema() 1eiacnqryszkolmfgtuABCDhjbdpvwExF

823 return self.generate_schema( 1eiacnqryszkolmfgtuABCDhjbdpvwExF

824 self._get_first_arg_or_any(obj), 

825 ) 

826 elif isinstance(obj, (FunctionType, LambdaType, MethodType, partial)): 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

827 return self._callable_schema(obj) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

828 elif inspect.isclass(obj) and issubclass(obj, Enum): 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

829 from ._std_types_schema import get_enum_core_schema 1eiacnqryszkolmfgtuABCDhjbdpvwExF

830 

831 return get_enum_core_schema(obj, self._config_wrapper.config_dict) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

832 

833 if _typing_extra.is_dataclass(obj): 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

834 return self._dataclass_schema(obj, None) 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

835 res = self._get_prepare_pydantic_annotations_for_known_type(obj, ()) 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

836 if res is not None: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

837 source_type, annotations = res 1eiacnqryszkolmfgtuABCDhjbdpvwExF

838 return self._apply_annotations(source_type, annotations) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

839 

840 origin = get_origin(obj) 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

841 if origin is not None: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

842 return self._match_generic_type(obj, origin) 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

843 

844 if self._arbitrary_types: 1eiacnqryszkolmfgtuABCDhjbdpvwExF

845 return self._arbitrary_type_schema(obj) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

846 return self._unknown_type_schema(obj) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

847 

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

849 if isinstance(origin, TypeAliasType): 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

850 return self._type_alias_type_schema(obj) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

851 

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

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

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

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

856 if _typing_extra.is_dataclass(origin): 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

857 return self._dataclass_schema(obj, origin) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

858 if _typing_extra.is_namedtuple(origin): 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

859 return self._namedtuple_schema(obj, origin) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

860 

861 from_property = self._generate_schema_from_property(origin, obj) 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

862 if from_property is not None: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

863 return from_property 1eiacnqryszkolmfgtuABCDhjbdpvwExF

864 

865 if _typing_extra.origin_is_union(origin): 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

866 return self._union_schema(obj) 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

867 elif origin in TUPLE_TYPES: 1eiacnqryszkolmfgtuABCDhjbdpvwExF

868 return self._tuple_schema(obj) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

869 elif origin in LIST_TYPES: 869 ↛ 870line 869 didn't jump to line 870, because the condition on line 869 was never true1eiacnqryszkolmfgtuABCDhjbdpvwExF

870 return self._list_schema(obj, self._get_first_arg_or_any(obj)) 

871 elif origin in SET_TYPES: 871 ↛ 872line 871 didn't jump to line 872, because the condition on line 871 was never true1eiacnqryszkolmfgtuABCDhjbdpvwExF

872 return self._set_schema(obj, self._get_first_arg_or_any(obj)) 

873 elif origin in FROZEN_SET_TYPES: 873 ↛ 874line 873 didn't jump to line 874, because the condition on line 873 was never true1eiacnqryszkolmfgtuABCDhjbdpvwExF

874 return self._frozenset_schema(obj, self._get_first_arg_or_any(obj)) 

875 elif origin in DICT_TYPES: 875 ↛ 876line 875 didn't jump to line 876, because the condition on line 875 was never true1eiacnqryszkolmfgtuABCDhjbdpvwExF

876 return self._dict_schema(obj, *self._get_first_two_args_or_any(obj)) 

877 elif is_typeddict(origin): 1eiacnqryszkolmfgtuABCDhjbdpvwExF

878 return self._typed_dict_schema(obj, origin) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

879 elif origin in (typing.Type, type): 1eiacnqryszkolmfgtuABCDhjbdpvwExF

880 return self._subclass_schema(obj) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

881 elif origin in {typing.Sequence, collections.abc.Sequence}: 1eiacnqryszkolmfgtuABCDhjbdpvwExF

882 return self._sequence_schema(obj) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

883 elif origin in {typing.Iterable, collections.abc.Iterable, typing.Generator, collections.abc.Generator}: 1eiacnqryszkolmfgtuABCDhjbdpvwExF

884 return self._iterable_schema(obj) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

885 elif origin in (re.Pattern, typing.Pattern): 1eiacnqryszkolmfgtuABCDhjbdpvwExF

886 return self._pattern_schema(obj) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

887 

888 if self._arbitrary_types: 1eiacnqryszkolmfgtuABCDhjbdpvwExF

889 return self._arbitrary_type_schema(origin) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

890 return self._unknown_type_schema(obj) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

891 

892 def _generate_td_field_schema( 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

893 self, 

894 name: str, 

895 field_info: FieldInfo, 

896 decorators: DecoratorInfos, 

897 *, 

898 required: bool = True, 

899 ) -> core_schema.TypedDictField: 

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

901 common_field = self._common_field_schema(name, field_info, decorators) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

902 return core_schema.typed_dict_field( 1eiacnqryszkolmfgtuABCDhjbdpvwExF

903 common_field['schema'], 

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

905 serialization_exclude=common_field['serialization_exclude'], 

906 validation_alias=common_field['validation_alias'], 

907 serialization_alias=common_field['serialization_alias'], 

908 metadata=common_field['metadata'], 

909 ) 

910 

911 def _generate_md_field_schema( 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

912 self, 

913 name: str, 

914 field_info: FieldInfo, 

915 decorators: DecoratorInfos, 

916 ) -> core_schema.ModelField: 

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

918 common_field = self._common_field_schema(name, field_info, decorators) 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

919 return core_schema.model_field( 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

920 common_field['schema'], 

921 serialization_exclude=common_field['serialization_exclude'], 

922 validation_alias=common_field['validation_alias'], 

923 serialization_alias=common_field['serialization_alias'], 

924 frozen=common_field['frozen'], 

925 metadata=common_field['metadata'], 

926 ) 

927 

928 def _generate_dc_field_schema( 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

929 self, 

930 name: str, 

931 field_info: FieldInfo, 

932 decorators: DecoratorInfos, 

933 ) -> core_schema.DataclassField: 

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

935 common_field = self._common_field_schema(name, field_info, decorators) 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

936 return core_schema.dataclass_field( 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

937 name, 

938 common_field['schema'], 

939 init=field_info.init, 

940 init_only=field_info.init_var or None, 

941 kw_only=None if field_info.kw_only else False, 

942 serialization_exclude=common_field['serialization_exclude'], 

943 validation_alias=common_field['validation_alias'], 

944 serialization_alias=common_field['serialization_alias'], 

945 frozen=common_field['frozen'], 

946 metadata=common_field['metadata'], 

947 ) 

948 

949 @staticmethod 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

950 def _apply_alias_generator_to_field_info( 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

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

952 ) -> None: 

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

954 

955 Args: 

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

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

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

959 """ 

960 # Apply an alias_generator if 

961 # 1. An alias is not specified 

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

963 if ( 1eiackolmfghjbd

964 field_info.alias_priority is None 

965 or field_info.alias_priority <= 1 

966 or field_info.alias is None 

967 or field_info.validation_alias is None 

968 or field_info.serialization_alias is None 

969 ): 

970 alias, validation_alias, serialization_alias = None, None, None 1eiacnqryszkolmfgtuABCDhjbdpvwExF

971 

972 if isinstance(alias_generator, AliasGenerator): 1eiacnqryszkolmfgtuABCDhjbdpvwExF

973 alias, validation_alias, serialization_alias = alias_generator.generate_aliases(field_name) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

974 elif isinstance(alias_generator, Callable): 974 ↛ 982line 974 didn't jump to line 982, because the condition on line 974 was always true1eiacnqryszkolmfgtuABCDhjbdpvwExF

975 alias = alias_generator(field_name) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

976 if not isinstance(alias, str): 1eiacnqryszkolmfgtuABCDhjbdpvwExF

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

978 

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

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

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

982 if field_info.alias_priority is None or field_info.alias_priority <= 1: 1eiacnqryszkolmfgtuABCDhjbdpvwExF

983 field_info.alias_priority = 1 1eiacnqryszkolmfgtuABCDhjbdpvwExF

984 

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

986 if field_info.alias_priority == 1: 1eiacnqryszkolmfgtuABCDhjbdpvwExF

987 field_info.serialization_alias = _get_first_non_null(serialization_alias, alias) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

988 field_info.validation_alias = _get_first_non_null(validation_alias, alias) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

989 field_info.alias = alias 1eiacnqryszkolmfgtuABCDhjbdpvwExF

990 

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

992 if field_info.alias is None: 1eiacnqryszkolmfgtuABCDhjbdpvwExF

993 field_info.alias = alias 1eiacnqryszkolmfgtuABCDhjbdpvwExF

994 if field_info.serialization_alias is None: 1eiacnqryszkolmfgtuABCDhjbdpvwExF

995 field_info.serialization_alias = _get_first_non_null(serialization_alias, alias) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

996 if field_info.validation_alias is None: 1eiacnqryszkolmfgtuABCDhjbdpvwExF

997 field_info.validation_alias = _get_first_non_null(validation_alias, alias) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

998 

999 @staticmethod 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1000 def _apply_alias_generator_to_computed_field_info( 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

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

1002 computed_field_info: ComputedFieldInfo, 

1003 computed_field_name: str, 

1004 ): 

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

1006 

1007 Args: 

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

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

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

1011 """ 

1012 # Apply an alias_generator if 

1013 # 1. An alias is not specified 

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

1015 

1016 if ( 1eiackohjbd

1017 computed_field_info.alias_priority is None 

1018 or computed_field_info.alias_priority <= 1 

1019 or computed_field_info.alias is None 

1020 ): 

1021 alias, validation_alias, serialization_alias = None, None, None 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1022 

1023 if isinstance(alias_generator, AliasGenerator): 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1024 alias, validation_alias, serialization_alias = alias_generator.generate_aliases(computed_field_name) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1025 elif isinstance(alias_generator, Callable): 1025 ↛ 1033line 1025 didn't jump to line 1033, because the condition on line 1025 was always true1eiacnqryszkolmfgtuABCDhjbdpvwExF

1026 alias = alias_generator(computed_field_name) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1027 if not isinstance(alias, str): 1027 ↛ 1028line 1027 didn't jump to line 1028, because the condition on line 1027 was never true1eiacnqryszkolmfgtuABCDhjbdpvwExF

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

1029 

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

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

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

1033 if computed_field_info.alias_priority is None or computed_field_info.alias_priority <= 1: 1033 ↛ 1039line 1033 didn't jump to line 1039, because the condition on line 1033 was always true1eiacnqryszkolmfgtuABCDhjbdpvwExF

1034 computed_field_info.alias_priority = 1 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1035 

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

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

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

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

1040 computed_field_info.alias = _get_first_non_null(serialization_alias, alias) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1041 

1042 def _common_field_schema( # C901 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

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

1044 ) -> _CommonField: 

1045 # Update FieldInfo annotation if appropriate: 

1046 from .. import AliasChoices, AliasPath 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1047 from ..fields import FieldInfo 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1048 

1049 if has_instance_in_type(field_info.annotation, (ForwardRef, str)): 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1050 types_namespace = self._types_namespace 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1051 if self._typevars_map: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1052 types_namespace = (types_namespace or {}).copy() 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1053 # Ensure that typevars get mapped to their concrete types: 

1054 types_namespace.update({k.__name__: v for k, v in self._typevars_map.items()}) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1055 

1056 evaluated = _typing_extra.eval_type_lenient(field_info.annotation, types_namespace) 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1057 if evaluated is not field_info.annotation and not has_instance_in_type(evaluated, PydanticRecursiveRef): 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1058 new_field_info = FieldInfo.from_annotation(evaluated) 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1059 field_info.annotation = new_field_info.annotation 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1060 

1061 # Handle any field info attributes that may have been obtained from now-resolved annotations 

1062 for k, v in new_field_info._attributes_set.items(): 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1063 # If an attribute is already set, it means it was set by assigning to a call to Field (or just a 

1064 # default value), and that should take the highest priority. So don't overwrite existing attributes. 

1065 # We skip over "attributes" that are present in the metadata_lookup dict because these won't 

1066 # actually end up as attributes of the `FieldInfo` instance. 

1067 if k not in field_info._attributes_set and k not in field_info.metadata_lookup: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1068 setattr(field_info, k, v) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1069 

1070 # Finally, ensure the field info also reflects all the `_attributes_set` that are actually metadata. 

1071 field_info.metadata = [*new_field_info.metadata, *field_info.metadata] 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1072 

1073 source_type, annotations = field_info.annotation, field_info.metadata 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1074 

1075 def set_discriminator(schema: CoreSchema) -> CoreSchema: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1076 schema = self._apply_discriminator_to_union(schema, field_info.discriminator) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1077 return schema 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1078 

1079 with self.field_name_stack.push(name): 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1080 if field_info.discriminator is not None: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1081 schema = self._apply_annotations(source_type, annotations, transform_inner_schema=set_discriminator) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1082 else: 

1083 schema = self._apply_annotations( 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1084 source_type, 

1085 annotations, 

1086 ) 

1087 

1088 # This V1 compatibility shim should eventually be removed 

1089 # push down any `each_item=True` validators 

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

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

1092 this_field_validators = filter_field_decorator_info_by_field(decorators.validators.values(), name) 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1093 if _validators_require_validate_default(this_field_validators): 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1094 field_info.validate_default = True 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1095 each_item_validators = [v for v in this_field_validators if v.info.each_item is True] 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1096 this_field_validators = [v for v in this_field_validators if v not in each_item_validators] 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1097 schema = apply_each_item_validators(schema, each_item_validators, name) 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1098 

1099 schema = apply_validators(schema, filter_field_decorator_info_by_field(this_field_validators, name), name) 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1100 schema = apply_validators( 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1101 schema, filter_field_decorator_info_by_field(decorators.field_validators.values(), name), name 

1102 ) 

1103 

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

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

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

1107 if not field_info.is_required(): 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1108 schema = wrap_default(field_info, schema) 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1109 

1110 schema = self._apply_field_serializers( 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

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

1112 ) 

1113 json_schema_updates = { 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1114 'title': field_info.title, 

1115 'description': field_info.description, 

1116 'deprecated': bool(field_info.deprecated) or field_info.deprecated == '' or None, 

1117 'examples': to_jsonable_python(field_info.examples), 

1118 } 

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

1120 

1121 json_schema_extra = field_info.json_schema_extra 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1122 

1123 metadata = build_metadata_dict( 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1124 js_annotation_functions=[get_json_schema_update_func(json_schema_updates, json_schema_extra)] 

1125 ) 

1126 

1127 alias_generator = self._config_wrapper.alias_generator 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1128 if alias_generator is not None: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1129 self._apply_alias_generator_to_field_info(alias_generator, field_info, name) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1130 

1131 if isinstance(field_info.validation_alias, (AliasChoices, AliasPath)): 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1132 validation_alias = field_info.validation_alias.convert_to_aliases() 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1133 else: 

1134 validation_alias = field_info.validation_alias 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1135 

1136 return _common_field( 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1137 schema, 

1138 serialization_exclude=True if field_info.exclude else None, 

1139 validation_alias=validation_alias, 

1140 serialization_alias=field_info.serialization_alias, 

1141 frozen=field_info.frozen, 

1142 metadata=metadata, 

1143 ) 

1144 

1145 def _union_schema(self, union_type: Any) -> core_schema.CoreSchema: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1146 """Generate schema for a Union.""" 

1147 args = self._get_args_resolving_forward_refs(union_type, required=True) 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1148 choices: list[CoreSchema] = [] 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1149 nullable = False 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1150 for arg in args: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1151 if arg is None or arg is _typing_extra.NoneType: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1152 nullable = True 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1153 else: 

1154 choices.append(self.generate_schema(arg)) 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1155 

1156 if len(choices) == 1: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1157 s = choices[0] 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1158 else: 

1159 choices_with_tags: list[CoreSchema | tuple[CoreSchema, str]] = [] 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1160 for choice in choices: 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1161 tag = choice.get('metadata', {}).get(_core_utils.TAGGED_UNION_TAG_KEY) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1162 if tag is not None: 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1163 choices_with_tags.append((choice, tag)) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1164 else: 

1165 choices_with_tags.append(choice) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1166 s = core_schema.union_schema(choices_with_tags) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1167 

1168 if nullable: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1169 s = core_schema.nullable_schema(s) 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1170 return s 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1171 

1172 def _type_alias_type_schema( 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1173 self, 

1174 obj: Any, # TypeAliasType 

1175 ) -> CoreSchema: 

1176 with self.defs.get_schema_or_ref(obj) as (ref, maybe_schema): 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1177 if maybe_schema is not None: 1177 ↛ 1178line 1177 didn't jump to line 1178, because the condition on line 1177 was never true1eiacnqryszkolmfgtuABCDhjbdpvwExF

1178 return maybe_schema 

1179 

1180 origin = get_origin(obj) or obj 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1181 

1182 annotation = origin.__value__ 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1183 typevars_map = get_standard_typevars_map(obj) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1184 

1185 with self._types_namespace_stack.push(origin): 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1186 annotation = _typing_extra.eval_type_lenient(annotation, self._types_namespace) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1187 annotation = replace_types(annotation, typevars_map) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1188 schema = self.generate_schema(annotation) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1189 assert schema['type'] != 'definitions' 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1190 schema['ref'] = ref # type: ignore 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1191 self.defs.definitions[ref] = schema 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1192 return core_schema.definition_reference_schema(ref) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1193 

1194 def _literal_schema(self, literal_type: Any) -> CoreSchema: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1195 """Generate schema for a Literal.""" 

1196 expected = _typing_extra.all_literal_values(literal_type) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

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

1198 return core_schema.literal_schema(expected) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1199 

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

1201 """Generate schema for a TypedDict. 

1202 

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

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

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

1206 __required_keys__ was added in Python 3.9 

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

1208 however it is buggy 

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

1210 

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

1212 

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

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

1215 """ 

1216 from ..fields import FieldInfo 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1217 

1218 with self.model_type_stack.push(typed_dict_cls), self.defs.get_schema_or_ref(typed_dict_cls) as ( 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1219 typed_dict_ref, 

1220 maybe_schema, 

1221 ): 

1222 if maybe_schema is not None: 1222 ↛ 1223line 1222 didn't jump to line 1223, because the condition on line 1222 was never true1eiacnqryszkolmfgtuABCDhjbdpvwExF

1223 return maybe_schema 

1224 

1225 typevars_map = get_standard_typevars_map(typed_dict_cls) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1226 if origin is not None: 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1227 typed_dict_cls = origin 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1228 

1229 if not _SUPPORTS_TYPEDDICT and type(typed_dict_cls).__module__ == 'typing': 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1230 raise PydanticUserError( 1eiacnqrykolmfgtuABhjbdpvwE

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

1232 code='typed-dict-version', 

1233 ) 

1234 

1235 try: 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1236 config: ConfigDict | None = get_attribute_from_bases(typed_dict_cls, '__pydantic_config__') 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1237 except AttributeError: 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1238 config = None 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1239 

1240 with self._config_wrapper_stack.push(config), self._types_namespace_stack.push(typed_dict_cls): 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1241 core_config = self._config_wrapper.core_config(typed_dict_cls) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1242 

1243 self = self._current_generate_schema 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1244 

1245 required_keys: frozenset[str] = typed_dict_cls.__required_keys__ 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1246 

1247 fields: dict[str, core_schema.TypedDictField] = {} 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1248 

1249 decorators = DecoratorInfos.build(typed_dict_cls) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1250 

1251 if self._config_wrapper.use_attribute_docstrings: 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1252 field_docstrings = extract_docstrings_from_cls(typed_dict_cls, use_inspect=True) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1253 else: 

1254 field_docstrings = None 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1255 

1256 for field_name, annotation in get_type_hints_infer_globalns( 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1257 typed_dict_cls, localns=self._types_namespace, include_extras=True 

1258 ).items(): 

1259 annotation = replace_types(annotation, typevars_map) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1260 required = field_name in required_keys 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1261 

1262 if get_origin(annotation) == _typing_extra.Required: 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1263 required = True 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1264 annotation = self._get_args_resolving_forward_refs( 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1265 annotation, 

1266 required=True, 

1267 )[0] 

1268 elif get_origin(annotation) == _typing_extra.NotRequired: 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1269 required = False 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1270 annotation = self._get_args_resolving_forward_refs( 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1271 annotation, 

1272 required=True, 

1273 )[0] 

1274 

1275 field_info = FieldInfo.from_annotation(annotation) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1276 if ( 1eiackolmfghjbd

1277 field_docstrings is not None 

1278 and field_info.description is None 

1279 and field_name in field_docstrings 

1280 ): 

1281 field_info.description = field_docstrings[field_name] 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1282 fields[field_name] = self._generate_td_field_schema( 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1283 field_name, field_info, decorators, required=required 

1284 ) 

1285 

1286 metadata = build_metadata_dict( 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1287 js_functions=[partial(modify_model_json_schema, cls=typed_dict_cls)], typed_dict_cls=typed_dict_cls 

1288 ) 

1289 

1290 td_schema = core_schema.typed_dict_schema( 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1291 fields, 

1292 computed_fields=[ 

1293 self._computed_field_schema(d, decorators.field_serializers) 

1294 for d in decorators.computed_fields.values() 

1295 ], 

1296 ref=typed_dict_ref, 

1297 metadata=metadata, 

1298 config=core_config, 

1299 ) 

1300 

1301 schema = self._apply_model_serializers(td_schema, decorators.model_serializers.values()) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1302 schema = apply_model_validators(schema, decorators.model_validators.values(), 'all') 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1303 self.defs.definitions[typed_dict_ref] = schema 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1304 return core_schema.definition_reference_schema(typed_dict_ref) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1305 

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

1307 """Generate schema for a NamedTuple.""" 

1308 with self.model_type_stack.push(namedtuple_cls), self.defs.get_schema_or_ref(namedtuple_cls) as ( 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1309 namedtuple_ref, 

1310 maybe_schema, 

1311 ): 

1312 if maybe_schema is not None: 1312 ↛ 1313line 1312 didn't jump to line 1313, because the condition on line 1312 was never true1eiacnqryszkolmfgtuABCDhjbdpvwExF

1313 return maybe_schema 

1314 typevars_map = get_standard_typevars_map(namedtuple_cls) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1315 if origin is not None: 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1316 namedtuple_cls = origin 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1317 

1318 annotations: dict[str, Any] = get_type_hints_infer_globalns( 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1319 namedtuple_cls, include_extras=True, localns=self._types_namespace 

1320 ) 

1321 if not annotations: 1eiacnqryszkolmfgtuABCDhjbdpvwExF

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

1323 annotations = {k: Any for k in namedtuple_cls._fields} 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1324 

1325 if typevars_map: 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1326 annotations = { 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1327 field_name: replace_types(annotation, typevars_map) 

1328 for field_name, annotation in annotations.items() 

1329 } 

1330 

1331 arguments_schema = core_schema.arguments_schema( 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1332 [ 

1333 self._generate_parameter_schema( 

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

1335 ) 

1336 for field_name, annotation in annotations.items() 

1337 ], 

1338 metadata=build_metadata_dict(js_prefer_positional_arguments=True), 

1339 ) 

1340 return core_schema.call_schema(arguments_schema, namedtuple_cls, ref=namedtuple_ref) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1341 

1342 def _generate_parameter_schema( 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1343 self, 

1344 name: str, 

1345 annotation: type[Any], 

1346 default: Any = Parameter.empty, 

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

1348 ) -> core_schema.ArgumentsParameter: 

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

1350 from ..fields import FieldInfo 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1351 

1352 if default is Parameter.empty: 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1353 field = FieldInfo.from_annotation(annotation) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1354 else: 

1355 field = FieldInfo.from_annotated_attribute(annotation, default) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

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

1357 source_type, annotations = field.annotation, field.metadata 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1358 with self.field_name_stack.push(name): 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1359 schema = self._apply_annotations(source_type, annotations) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1360 

1361 if not field.is_required(): 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1362 schema = wrap_default(field, schema) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1363 

1364 parameter_schema = core_schema.arguments_parameter(name, schema) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1365 if mode is not None: 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1366 parameter_schema['mode'] = mode 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1367 if field.alias is not None: 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1368 parameter_schema['alias'] = field.alias 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1369 else: 

1370 alias_generator = self._config_wrapper.alias_generator 1eiacnqryszkolmfgtuABCDhjbdpvwExF

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

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

1373 elif isinstance(alias_generator, Callable): 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1374 parameter_schema['alias'] = alias_generator(name) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1375 return parameter_schema 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1376 

1377 def _tuple_schema(self, tuple_type: Any) -> core_schema.CoreSchema: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

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

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

1380 typevars_map = get_standard_typevars_map(tuple_type) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1381 params = self._get_args_resolving_forward_refs(tuple_type) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1382 

1383 if typevars_map and params: 1383 ↛ 1384line 1383 didn't jump to line 1384, because the condition on line 1383 was never true1eiacnqryszkolmfgtuABCDhjbdpvwExF

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

1385 

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

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

1388 if not params: 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1389 if tuple_type in TUPLE_TYPES: 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1390 return core_schema.tuple_schema([core_schema.any_schema()], variadic_item_index=0) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1391 else: 

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

1393 return core_schema.tuple_schema([]) 1acnqryszkofgtuABCDbdpvwExF

1394 elif params[-1] is Ellipsis: 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1395 if len(params) == 2: 1395 ↛ 1399line 1395 didn't jump to line 1399, because the condition on line 1395 was always true1eiacnqryszkolmfgtuABCDhjbdpvwExF

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

1397 else: 

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

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

1400 elif len(params) == 1 and params[0] == (): 1eiacnqryszkolmfgtuABCDhjbdpvwExF

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

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

1403 return core_schema.tuple_schema([]) 1eiacnqkolmfgtuhjbdpv

1404 else: 

1405 return core_schema.tuple_schema([self.generate_schema(param) for param in params]) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1406 

1407 def _type_schema(self) -> core_schema.CoreSchema: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1408 return core_schema.custom_error_schema( 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1409 core_schema.is_instance_schema(type), 

1410 custom_error_type='is_type', 

1411 custom_error_message='Input should be a type', 

1412 ) 

1413 

1414 def _union_is_subclass_schema(self, union_type: Any) -> core_schema.CoreSchema: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1415 """Generate schema for `Type[Union[X, ...]]`.""" 

1416 args = self._get_args_resolving_forward_refs(union_type, required=True) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1417 return core_schema.union_schema([self.generate_schema(typing.Type[args]) for args in args]) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1418 

1419 def _subclass_schema(self, type_: Any) -> core_schema.CoreSchema: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1420 """Generate schema for a Type, e.g. `Type[int]`.""" 

1421 type_param = self._get_first_arg_or_any(type_) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1422 if type_param == Any: 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1423 return self._type_schema() 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1424 elif isinstance(type_param, typing.TypeVar): 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1425 if type_param.__bound__: 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1426 if _typing_extra.origin_is_union(get_origin(type_param.__bound__)): 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1427 return self._union_is_subclass_schema(type_param.__bound__) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1428 return core_schema.is_subclass_schema(type_param.__bound__) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1429 elif type_param.__constraints__: 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1430 return core_schema.union_schema( 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1431 [self.generate_schema(typing.Type[c]) for c in type_param.__constraints__] 

1432 ) 

1433 else: 

1434 return self._type_schema() 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1435 elif _typing_extra.origin_is_union(get_origin(type_param)): 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1436 return self._union_is_subclass_schema(type_param) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1437 else: 

1438 return core_schema.is_subclass_schema(type_param) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1439 

1440 def _sequence_schema(self, sequence_type: Any) -> core_schema.CoreSchema: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

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

1442 from ._std_types_schema import serialize_sequence_via_list 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1443 

1444 item_type = self._get_first_arg_or_any(sequence_type) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1445 item_type_schema = self.generate_schema(item_type) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1446 list_schema = core_schema.list_schema(item_type_schema) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1447 

1448 python_schema = core_schema.is_instance_schema(typing.Sequence, cls_repr='Sequence') 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1449 if item_type != Any: 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1450 from ._validators import sequence_validator 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1451 

1452 python_schema = core_schema.chain_schema( 1eiacnqryszkolmfgtuABCDhjbdpvwExF

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

1454 ) 

1455 

1456 serialization = core_schema.wrap_serializer_function_ser_schema( 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1457 serialize_sequence_via_list, schema=item_type_schema, info_arg=True 

1458 ) 

1459 return core_schema.json_or_python_schema( 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1460 json_schema=list_schema, python_schema=python_schema, serialization=serialization 

1461 ) 

1462 

1463 def _iterable_schema(self, type_: Any) -> core_schema.GeneratorSchema: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

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

1465 item_type = self._get_first_arg_or_any(type_) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1466 

1467 return core_schema.generator_schema(self.generate_schema(item_type)) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1468 

1469 def _pattern_schema(self, pattern_type: Any) -> core_schema.CoreSchema: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1470 from . import _validators 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1471 

1472 metadata = build_metadata_dict(js_functions=[lambda _1, _2: {'type': 'string', 'format': 'regex'}]) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1473 ser = core_schema.plain_serializer_function_ser_schema( 1eiacnqryszkolmfgtuABCDhjbdpvwExF

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

1475 ) 

1476 if pattern_type == typing.Pattern or pattern_type == re.Pattern: 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1477 # bare type 

1478 return core_schema.no_info_plain_validator_function( 1eiacnqryszkolmfgtuABCDhjbdpvwExF

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

1480 ) 

1481 

1482 param = self._get_args_resolving_forward_refs( 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1483 pattern_type, 

1484 required=True, 

1485 )[0] 

1486 if param == str: 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1487 return core_schema.no_info_plain_validator_function( 1eiacnqryszkolmfgtuABCDhjbdpvwExF

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

1489 ) 

1490 elif param == bytes: 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1491 return core_schema.no_info_plain_validator_function( 1eiacnqryszkolmfgtuABCDhjbdpvwExF

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

1493 ) 

1494 else: 

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

1496 

1497 def _hashable_schema(self) -> core_schema.CoreSchema: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1498 return core_schema.custom_error_schema( 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1499 core_schema.is_instance_schema(collections.abc.Hashable), 

1500 custom_error_type='is_hashable', 

1501 custom_error_message='Input should be hashable', 

1502 ) 

1503 

1504 def _dataclass_schema( 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

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

1506 ) -> core_schema.CoreSchema: 

1507 """Generate schema for a dataclass.""" 

1508 with self.model_type_stack.push(dataclass), self.defs.get_schema_or_ref(dataclass) as ( 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1509 dataclass_ref, 

1510 maybe_schema, 

1511 ): 

1512 if maybe_schema is not None: 1512 ↛ 1513line 1512 didn't jump to line 1513, because the condition on line 1512 was never true1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1513 return maybe_schema 

1514 

1515 typevars_map = get_standard_typevars_map(dataclass) 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1516 if origin is not None: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1517 dataclass = origin 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1518 

1519 with ExitStack() as dataclass_bases_stack: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1520 # Pushing a namespace prioritises items already in the stack, so iterate though the MRO forwards 

1521 for dataclass_base in dataclass.__mro__: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1522 if dataclasses.is_dataclass(dataclass_base): 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1523 dataclass_bases_stack.enter_context(self._types_namespace_stack.push(dataclass_base)) 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1524 

1525 # Pushing a config overwrites the previous config, so iterate though the MRO backwards 

1526 for dataclass_base in reversed(dataclass.__mro__): 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1527 if dataclasses.is_dataclass(dataclass_base): 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1528 config = getattr(dataclass_base, '__pydantic_config__', None) 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1529 dataclass_bases_stack.enter_context(self._config_wrapper_stack.push(config)) 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1530 

1531 core_config = self._config_wrapper.core_config(dataclass) 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1532 

1533 self = self._current_generate_schema 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1534 

1535 from ..dataclasses import is_pydantic_dataclass 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1536 

1537 if is_pydantic_dataclass(dataclass): 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1538 fields = deepcopy(dataclass.__pydantic_fields__) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1539 if typevars_map: 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1540 for field in fields.values(): 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1541 field.apply_typevars_map(typevars_map, self._types_namespace) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1542 else: 

1543 fields = collect_dataclass_fields( 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1544 dataclass, 

1545 self._types_namespace, 

1546 typevars_map=typevars_map, 

1547 ) 

1548 

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

1550 if self._config_wrapper_stack.tail.extra == 'allow': 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

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

1552 for field_name, field in fields.items(): 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1553 if field.init is False: 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1554 raise PydanticUserError( 1eiacnqryszkolmfgtuABCDhjbdpvwExF

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

1556 f'This combination is not allowed.', 

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

1558 ) 

1559 

1560 decorators = dataclass.__dict__.get('__pydantic_decorators__') or DecoratorInfos.build(dataclass) 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

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

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

1563 args = sorted( 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

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

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

1566 ) 

1567 has_post_init = hasattr(dataclass, '__post_init__') 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1568 has_slots = hasattr(dataclass, '__slots__') 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1569 

1570 args_schema = core_schema.dataclass_args_schema( 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1571 dataclass.__name__, 

1572 args, 

1573 computed_fields=[ 

1574 self._computed_field_schema(d, decorators.field_serializers) 

1575 for d in decorators.computed_fields.values() 

1576 ], 

1577 collect_init_only=has_post_init, 

1578 ) 

1579 

1580 inner_schema = apply_validators(args_schema, decorators.root_validators.values(), None) 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1581 

1582 model_validators = decorators.model_validators.values() 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1583 inner_schema = apply_model_validators(inner_schema, model_validators, 'inner') 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1584 

1585 dc_schema = core_schema.dataclass_schema( 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1586 dataclass, 

1587 inner_schema, 

1588 post_init=has_post_init, 

1589 ref=dataclass_ref, 

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

1591 slots=has_slots, 

1592 config=core_config, 

1593 ) 

1594 schema = self._apply_model_serializers(dc_schema, decorators.model_serializers.values()) 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1595 schema = apply_model_validators(schema, model_validators, 'outer') 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1596 self.defs.definitions[dataclass_ref] = schema 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1597 return core_schema.definition_reference_schema(dataclass_ref) 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1598 

1599 # Type checkers seem to assume ExitStack may suppress exceptions and therefore 

1600 # control flow can exit the `with` block without returning. 

1601 assert False, 'Unreachable' 1ackfgbd

1602 

1603 def _callable_schema(self, function: Callable[..., Any]) -> core_schema.CallSchema: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1604 """Generate schema for a Callable. 

1605 

1606 TODO support functional validators once we support them in Config 

1607 """ 

1608 sig = signature(function) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1609 

1610 type_hints = _typing_extra.get_function_type_hints(function) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1611 

1612 mode_lookup: dict[_ParameterKind, Literal['positional_only', 'positional_or_keyword', 'keyword_only']] = { 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1613 Parameter.POSITIONAL_ONLY: 'positional_only', 

1614 Parameter.POSITIONAL_OR_KEYWORD: 'positional_or_keyword', 

1615 Parameter.KEYWORD_ONLY: 'keyword_only', 

1616 } 

1617 

1618 arguments_list: list[core_schema.ArgumentsParameter] = [] 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1619 var_args_schema: core_schema.CoreSchema | None = None 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1620 var_kwargs_schema: core_schema.CoreSchema | None = None 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1621 

1622 for name, p in sig.parameters.items(): 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1623 if p.annotation is sig.empty: 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1624 annotation = typing.cast(Any, Any) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1625 else: 

1626 annotation = type_hints[name] 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1627 

1628 parameter_mode = mode_lookup.get(p.kind) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1629 if parameter_mode is not None: 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1630 arg_schema = self._generate_parameter_schema(name, annotation, p.default, parameter_mode) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1631 arguments_list.append(arg_schema) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1632 elif p.kind == Parameter.VAR_POSITIONAL: 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1633 var_args_schema = self.generate_schema(annotation) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1634 else: 

1635 assert p.kind == Parameter.VAR_KEYWORD, p.kind 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1636 var_kwargs_schema = self.generate_schema(annotation) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1637 

1638 return_schema: core_schema.CoreSchema | None = None 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1639 config_wrapper = self._config_wrapper 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1640 if config_wrapper.validate_return: 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1641 return_hint = type_hints.get('return') 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1642 if return_hint is not None: 1642 ↛ 1645line 1642 didn't jump to line 1645, because the condition on line 1642 was always true1eiacnqryszkolmfgtuABCDhjbdpvwExF

1643 return_schema = self.generate_schema(return_hint) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1644 

1645 return core_schema.call_schema( 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1646 core_schema.arguments_schema( 

1647 arguments_list, 

1648 var_args_schema=var_args_schema, 

1649 var_kwargs_schema=var_kwargs_schema, 

1650 populate_by_name=config_wrapper.populate_by_name, 

1651 ), 

1652 function, 

1653 return_schema=return_schema, 

1654 ) 

1655 

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

1657 assert isinstance(typevar, typing.TypeVar) 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1658 

1659 bound = typevar.__bound__ 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1660 constraints = typevar.__constraints__ 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1661 

1662 try: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1663 typevar_has_default = typevar.has_default() # type: ignore 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1664 except AttributeError: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1665 # could still have a default if it's an old version of typing_extensions.TypeVar 

1666 typevar_has_default = getattr(typevar, '__default__', None) is not None 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1667 

1668 if (bound is not None) + (len(constraints) != 0) + typevar_has_default > 1: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1669 raise NotImplementedError( 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1670 'Pydantic does not support mixing more than one of TypeVar bounds, constraints and defaults' 

1671 ) 

1672 

1673 if typevar_has_default: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1674 return self.generate_schema(typevar.__default__) # type: ignore 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1675 elif constraints: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1676 return self._union_schema(typing.Union[constraints]) # type: ignore 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1677 elif bound: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1678 schema = self.generate_schema(bound) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1679 schema['serialization'] = core_schema.wrap_serializer_function_ser_schema( 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1680 lambda x, h: h(x), schema=core_schema.any_schema() 

1681 ) 

1682 return schema 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1683 else: 

1684 return core_schema.any_schema() 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1685 

1686 def _computed_field_schema( 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1687 self, 

1688 d: Decorator[ComputedFieldInfo], 

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

1690 ) -> core_schema.ComputedField: 

1691 try: 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1692 return_type = _decorators.get_function_return_type(d.func, d.info.return_type, self._types_namespace) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1693 except NameError as e: 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1694 raise PydanticUndefinedAnnotation.from_name_error(e) from e 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1695 if return_type is PydanticUndefined: 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1696 raise PydanticUserError( 1eiacnqryszkolmfgtuABCDhjbdpvwExF

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

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

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

1700 ) 

1701 

1702 return_type = replace_types(return_type, self._typevars_map) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

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

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

1705 d.info = dataclasses.replace(d.info, return_type=return_type) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1706 return_type_schema = self.generate_schema(return_type) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1707 # Apply serializers to computed field if there exist 

1708 return_type_schema = self._apply_field_serializers( 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1709 return_type_schema, 

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

1711 computed_field=True, 

1712 ) 

1713 

1714 alias_generator = self._config_wrapper.alias_generator 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1715 if alias_generator is not None: 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1716 self._apply_alias_generator_to_computed_field_info( 1eiacnqryszkolmfgtuABCDhjbdpvwExF

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

1718 ) 

1719 

1720 def set_computed_field_metadata(schema: CoreSchemaOrField, handler: GetJsonSchemaHandler) -> JsonSchemaValue: 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1721 json_schema = handler(schema) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1722 

1723 json_schema['readOnly'] = True 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1724 

1725 title = d.info.title 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1726 if title is not None: 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1727 json_schema['title'] = title 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1728 

1729 description = d.info.description 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1730 if description is not None: 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1731 json_schema['description'] = description 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1732 

1733 if d.info.deprecated or d.info.deprecated == '': 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1734 json_schema['deprecated'] = True 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1735 

1736 examples = d.info.examples 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1737 if examples is not None: 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1738 json_schema['examples'] = to_jsonable_python(examples) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1739 

1740 json_schema_extra = d.info.json_schema_extra 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1741 if json_schema_extra is not None: 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1742 add_json_schema_extra(json_schema, json_schema_extra) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1743 

1744 return json_schema 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1745 

1746 metadata = build_metadata_dict(js_annotation_functions=[set_computed_field_metadata]) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1747 return core_schema.computed_field( 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1748 d.cls_var_name, return_schema=return_type_schema, alias=d.info.alias, metadata=metadata 

1749 ) 

1750 

1751 def _annotated_schema(self, annotated_type: Any) -> core_schema.CoreSchema: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

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

1753 from ..fields import FieldInfo 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1754 

1755 source_type, *annotations = self._get_args_resolving_forward_refs( 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1756 annotated_type, 

1757 required=True, 

1758 ) 

1759 schema = self._apply_annotations(source_type, annotations) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

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

1761 # even if there are function validators involved 

1762 for annotation in annotations: 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1763 if isinstance(annotation, FieldInfo): 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1764 schema = wrap_default(annotation, schema) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1765 return schema 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1766 

1767 def _get_prepare_pydantic_annotations_for_known_type( 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1768 self, obj: Any, annotations: tuple[Any, ...] 

1769 ) -> tuple[Any, list[Any]] | None: 

1770 from ._std_types_schema import PREPARE_METHODS 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1771 

1772 # Check for hashability 

1773 try: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1774 hash(obj) 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1775 except TypeError: 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1776 # obj is definitely not a known type if this fails 

1777 return None 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1778 

1779 for gen in PREPARE_METHODS: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1780 res = gen(obj, annotations, self._config_wrapper.config_dict) 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1781 if res is not None: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1782 return res 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1783 

1784 return None 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1785 

1786 def _apply_annotations( 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1787 self, 

1788 source_type: Any, 

1789 annotations: list[Any], 

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

1791 ) -> CoreSchema: 

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

1793 

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

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

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

1797 """ 

1798 annotations = list(_known_annotated_metadata.expand_grouped_metadata(annotations)) 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1799 res = self._get_prepare_pydantic_annotations_for_known_type(source_type, tuple(annotations)) 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1800 if res is not None: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1801 source_type, annotations = res 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1802 

1803 pydantic_js_annotation_functions: list[GetJsonSchemaFunction] = [] 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1804 

1805 def inner_handler(obj: Any) -> CoreSchema: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1806 from_property = self._generate_schema_from_property(obj, source_type) 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1807 if from_property is None: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1808 schema = self._generate_schema_inner(obj) 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1809 else: 

1810 schema = from_property 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1811 metadata_js_function = _extract_get_pydantic_json_schema(obj, schema) 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1812 if metadata_js_function is not None: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1813 metadata_schema = resolve_original_schema(schema, self.defs.definitions) 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1814 if metadata_schema is not None: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1815 self._add_js_function(metadata_schema, metadata_js_function) 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1816 return transform_inner_schema(schema) 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1817 

1818 get_inner_schema = CallbackGetCoreSchemaHandler(inner_handler, self) 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1819 

1820 for annotation in annotations: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1821 if annotation is None: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1822 continue 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1823 get_inner_schema = self._get_wrapped_inner_schema( 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1824 get_inner_schema, annotation, pydantic_js_annotation_functions 

1825 ) 

1826 

1827 schema = get_inner_schema(source_type) 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1828 if pydantic_js_annotation_functions: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1829 metadata = CoreMetadataHandler(schema).metadata 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1830 metadata.setdefault('pydantic_js_annotation_functions', []).extend(pydantic_js_annotation_functions) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1831 return _add_custom_serialization_from_json_encoders(self._config_wrapper.json_encoders, source_type, schema) 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1832 

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

1834 from ..fields import FieldInfo 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1835 

1836 if isinstance(metadata, FieldInfo): 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1837 for field_metadata in metadata.metadata: 1837 ↛ 1838line 1837 didn't jump to line 1838, because the loop on line 1837 never started1eiacnqryszkolmfgtuABCDhjbdpvwExF

1838 schema = self._apply_single_annotation(schema, field_metadata) 

1839 

1840 if metadata.discriminator is not None: 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1841 schema = self._apply_discriminator_to_union(schema, metadata.discriminator) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1842 return schema 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1843 

1844 if schema['type'] == 'nullable': 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

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

1846 inner = schema.get('schema', core_schema.any_schema()) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1847 inner = self._apply_single_annotation(inner, metadata) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1848 if inner: 1848 ↛ 1850line 1848 didn't jump to line 1850, because the condition on line 1848 was always true1eiacnqryszkolmfgtuABCDhjbdpvwExF

1849 schema['schema'] = inner 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1850 return schema 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1851 

1852 original_schema = schema 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1853 ref = schema.get('ref', None) 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1854 if ref is not None: 1854 ↛ 1855line 1854 didn't jump to line 1855, because the condition on line 1854 was never true1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1855 schema = schema.copy() 

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

1857 if new_ref in self.defs.definitions: 

1858 return self.defs.definitions[new_ref] 

1859 schema['ref'] = new_ref # type: ignore 

1860 elif schema['type'] == 'definition-ref': 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1861 ref = schema['schema_ref'] 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1862 if ref in self.defs.definitions: 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1863 schema = self.defs.definitions[ref].copy() 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1864 new_ref = ref + f'_{repr(metadata)}' 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1865 if new_ref in self.defs.definitions: 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1866 return self.defs.definitions[new_ref] 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1867 schema['ref'] = new_ref # type: ignore 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1868 

1869 maybe_updated_schema = _known_annotated_metadata.apply_known_metadata(metadata, schema.copy()) 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1870 

1871 if maybe_updated_schema is not None: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1872 return maybe_updated_schema 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1873 return original_schema 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1874 

1875 def _apply_single_annotation_json_schema( 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

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

1877 ) -> core_schema.CoreSchema: 

1878 from ..fields import FieldInfo 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1879 

1880 if isinstance(metadata, FieldInfo): 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1881 for field_metadata in metadata.metadata: 1881 ↛ 1882line 1881 didn't jump to line 1882, because the loop on line 1881 never started1eiacnqryszkolmfgtuABCDhjbdpvwExF

1882 schema = self._apply_single_annotation_json_schema(schema, field_metadata) 

1883 json_schema_update: JsonSchemaValue = {} 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1884 if metadata.title: 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1885 json_schema_update['title'] = metadata.title 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1886 if metadata.description: 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1887 json_schema_update['description'] = metadata.description 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1888 if metadata.examples: 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1889 json_schema_update['examples'] = to_jsonable_python(metadata.examples) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1890 

1891 json_schema_extra = metadata.json_schema_extra 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1892 if json_schema_update or json_schema_extra: 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1893 CoreMetadataHandler(schema).metadata.setdefault('pydantic_js_annotation_functions', []).append( 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1894 get_json_schema_update_func(json_schema_update, json_schema_extra) 

1895 ) 

1896 return schema 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1897 

1898 def _get_wrapped_inner_schema( 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1899 self, 

1900 get_inner_schema: GetCoreSchemaHandler, 

1901 annotation: Any, 

1902 pydantic_js_annotation_functions: list[GetJsonSchemaFunction], 

1903 ) -> CallbackGetCoreSchemaHandler: 

1904 metadata_get_schema: GetCoreSchemaFunction = getattr(annotation, '__get_pydantic_core_schema__', None) or ( 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1905 lambda source, handler: handler(source) 

1906 ) 

1907 

1908 def new_handler(source: Any) -> core_schema.CoreSchema: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1909 schema = metadata_get_schema(source, get_inner_schema) 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1910 schema = self._apply_single_annotation(schema, annotation) 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1911 schema = self._apply_single_annotation_json_schema(schema, annotation) 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1912 

1913 metadata_js_function = _extract_get_pydantic_json_schema(annotation, schema) 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1914 if metadata_js_function is not None: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1915 pydantic_js_annotation_functions.append(metadata_js_function) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1916 return schema 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1917 

1918 return CallbackGetCoreSchemaHandler(new_handler, self) 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1919 

1920 def _apply_field_serializers( 1eiacnqryszlmfgtuABCDGHIJKLMNOhjbdpvwExF

1921 self, 

1922 schema: core_schema.CoreSchema, 

1923 serializers: list[Decorator[FieldSerializerDecoratorInfo]], 

1924 computed_field: bool = False, 

1925 ) -> core_schema.CoreSchema: 

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

1927 if serializers: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1928 schema = copy(schema) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1929 if schema['type'] == 'definitions': 1929 ↛ 1930line 1929 didn't jump to line 1930, because the condition on line 1929 was never true1eiacnqryszkolmfgtuABCDhjbdpvwExF

1930 inner_schema = schema['schema'] 

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

1932 return schema 

1933 else: 

1934 ref = typing.cast('str|None', schema.get('ref', None)) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1935 if ref is not None: 1935 ↛ 1936line 1935 didn't jump to line 1936, because the condition on line 1935 was never true1eiacnqryszkolmfgtuABCDhjbdpvwExF

1936 schema = core_schema.definition_reference_schema(ref) 

1937 

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

1939 serializer = serializers[-1] 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1940 is_field_serializer, info_arg = inspect_field_serializer( 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1941 serializer.func, serializer.info.mode, computed_field=computed_field 

1942 ) 

1943 

1944 try: 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1945 return_type = _decorators.get_function_return_type( 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1946 serializer.func, serializer.info.return_type, self._types_namespace 

1947 ) 

1948 except NameError as e: 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1949 raise PydanticUndefinedAnnotation.from_name_error(e) from e 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1950 

1951 if return_type is PydanticUndefined: 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1952 return_schema = None 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1953 else: 

1954 return_schema = self.generate_schema(return_type) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1955 

1956 if serializer.info.mode == 'wrap': 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1957 schema['serialization'] = core_schema.wrap_serializer_function_ser_schema( 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1958 serializer.func, 

1959 is_field_serializer=is_field_serializer, 

1960 info_arg=info_arg, 

1961 return_schema=return_schema, 

1962 when_used=serializer.info.when_used, 

1963 ) 

1964 else: 

1965 assert serializer.info.mode == 'plain' 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1966 schema['serialization'] = core_schema.plain_serializer_function_ser_schema( 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1967 serializer.func, 

1968 is_field_serializer=is_field_serializer, 

1969 info_arg=info_arg, 

1970 return_schema=return_schema, 

1971 when_used=serializer.info.when_used, 

1972 ) 

1973 return schema 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1974 

1975 def _apply_model_serializers( 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

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

1977 ) -> core_schema.CoreSchema: 

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

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

1980 if serializers: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

1981 serializer = list(serializers)[-1] 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1982 info_arg = inspect_model_serializer(serializer.func, serializer.info.mode) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1983 

1984 try: 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1985 return_type = _decorators.get_function_return_type( 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1986 serializer.func, serializer.info.return_type, self._types_namespace 

1987 ) 

1988 except NameError as e: 

1989 raise PydanticUndefinedAnnotation.from_name_error(e) from e 

1990 if return_type is PydanticUndefined: 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1991 return_schema = None 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1992 else: 

1993 return_schema = self.generate_schema(return_type) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1994 

1995 if serializer.info.mode == 'wrap': 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1996 ser_schema: core_schema.SerSchema = core_schema.wrap_serializer_function_ser_schema( 1eiacnqryszkolmfgtuABCDhjbdpvwExF

1997 serializer.func, 

1998 info_arg=info_arg, 

1999 return_schema=return_schema, 

2000 when_used=serializer.info.when_used, 

2001 ) 

2002 else: 

2003 # plain 

2004 ser_schema = core_schema.plain_serializer_function_ser_schema( 1eiacnqryszkolmfgtuABCDhjbdpvwExF

2005 serializer.func, 

2006 info_arg=info_arg, 

2007 return_schema=return_schema, 

2008 when_used=serializer.info.when_used, 

2009 ) 

2010 schema['serialization'] = ser_schema 1eiacnqryszkolmfgtuABCDhjbdpvwExF

2011 if ref: 2011 ↛ 2013line 2011 didn't jump to line 2013, because the condition on line 2011 was always true1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

2012 schema['ref'] = ref # type: ignore 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

2013 return schema 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

2014 

2015 

2016_VALIDATOR_F_MATCH: Mapping[ 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

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

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

2019] = { 

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

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

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

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

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

2025 f, schema, field_name=field_name 

2026 ), 

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

2028 f, schema, field_name=field_name 

2029 ), 

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

2031 f, field_name=field_name 

2032 ), 

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

2034 f, schema, field_name=field_name 

2035 ), 

2036} 

2037 

2038 

2039def apply_validators( 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

2040 schema: core_schema.CoreSchema, 

2041 validators: Iterable[Decorator[RootValidatorDecoratorInfo]] 

2042 | Iterable[Decorator[ValidatorDecoratorInfo]] 

2043 | Iterable[Decorator[FieldValidatorDecoratorInfo]], 

2044 field_name: str | None, 

2045) -> core_schema.CoreSchema: 

2046 """Apply validators to a schema. 

2047 

2048 Args: 

2049 schema: The schema to apply validators on. 

2050 validators: An iterable of validators. 

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

2052 

2053 Returns: 

2054 The updated schema. 

2055 """ 

2056 for validator in validators: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

2057 info_arg = inspect_validator(validator.func, validator.info.mode) 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

2058 val_type = 'with-info' if info_arg else 'no-info' 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

2059 

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

2061 return schema 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

2062 

2063 

2064def _validators_require_validate_default(validators: Iterable[Decorator[ValidatorDecoratorInfo]]) -> bool: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

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

2066 

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

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

2069 

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

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

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

2073 """ 

2074 for validator in validators: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

2075 if validator.info.always: 1eiacnqryszkolmfgtuABCDhjbdpvwExF

2076 return True 1eiacnqryszkolmfgtuABCDhjbdpvwExF

2077 return False 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

2078 

2079 

2080def apply_model_validators( 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

2081 schema: core_schema.CoreSchema, 

2082 validators: Iterable[Decorator[ModelValidatorDecoratorInfo]], 

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

2084) -> core_schema.CoreSchema: 

2085 """Apply model validators to a schema. 

2086 

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

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

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

2090 

2091 Args: 

2092 schema: The schema to apply validators on. 

2093 validators: An iterable of validators. 

2094 mode: The validator mode. 

2095 

2096 Returns: 

2097 The updated schema. 

2098 """ 

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

2100 for validator in validators: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

2101 if mode == 'inner' and validator.info.mode != 'before': 1eiacnqryszkolmfgtuABCDhjbdpvwExF

2102 continue 1eiacnqryszkolmfgtuABCDhjbdpvwExF

2103 if mode == 'outer' and validator.info.mode == 'before': 1eiacnqryszkolmfgtuABCDhjbdpvwExF

2104 continue 1eiacnqryszkolmfgtuABCDhjbdpvwExF

2105 info_arg = inspect_validator(validator.func, validator.info.mode) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

2106 if validator.info.mode == 'wrap': 1eiacnqryszkolmfgtuABCDhjbdpvwExF

2107 if info_arg: 1eiacnqryszkolmfgtuABCDhjbdpvwExF

2108 schema = core_schema.with_info_wrap_validator_function(function=validator.func, schema=schema) 1szCDxF

2109 else: 

2110 schema = core_schema.no_info_wrap_validator_function(function=validator.func, schema=schema) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

2111 elif validator.info.mode == 'before': 1eiacnqryszkolmfgtuABCDhjbdpvwExF

2112 if info_arg: 1eiacnqryszkolmfgtuABCDhjbdpvwExF

2113 schema = core_schema.with_info_before_validator_function(function=validator.func, schema=schema) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

2114 else: 

2115 schema = core_schema.no_info_before_validator_function(function=validator.func, schema=schema) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

2116 else: 

2117 assert validator.info.mode == 'after' 1eiacnqryszkolmfgtuABCDhjbdpvwExF

2118 if info_arg: 1eiacnqryszkolmfgtuABCDhjbdpvwExF

2119 schema = core_schema.with_info_after_validator_function(function=validator.func, schema=schema) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

2120 else: 

2121 schema = core_schema.no_info_after_validator_function(function=validator.func, schema=schema) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

2122 if ref: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

2123 schema['ref'] = ref # type: ignore 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

2124 return schema 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

2125 

2126 

2127def wrap_default(field_info: FieldInfo, schema: core_schema.CoreSchema) -> core_schema.CoreSchema: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

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

2129 

2130 Args: 

2131 field_info: The field info object. 

2132 schema: The schema to apply default on. 

2133 

2134 Returns: 

2135 Updated schema by default value or `default_factory`. 

2136 """ 

2137 if field_info.default_factory: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

2138 return core_schema.with_default_schema( 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

2139 schema, default_factory=field_info.default_factory, validate_default=field_info.validate_default 

2140 ) 

2141 elif field_info.default is not PydanticUndefined: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

2142 return core_schema.with_default_schema( 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

2143 schema, default=field_info.default, validate_default=field_info.validate_default 

2144 ) 

2145 else: 

2146 return schema 1eiacnqryszkolmfgtuABCDhjbdpvwExF

2147 

2148 

2149def _extract_get_pydantic_json_schema(tp: Any, schema: CoreSchema) -> GetJsonSchemaFunction | None: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

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

2151 js_modify_function = getattr(tp, '__get_pydantic_json_schema__', None) 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

2152 

2153 if hasattr(tp, '__modify_schema__'): 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

2154 from pydantic import BaseModel # circular reference 1eiacnqryszkolmfgtuABCDhjbdpvwExF

2155 

2156 has_custom_v2_modify_js_func = ( 1eiacnqryszkolmfgtuABCDhjbdpvwExF

2157 js_modify_function is not None 

2158 and BaseModel.__get_pydantic_json_schema__.__func__ # type: ignore 

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

2160 ) 

2161 

2162 if not has_custom_v2_modify_js_func: 1eiacnqryszkolmfgtuABCDhjbdpvwExF

2163 cls_name = getattr(tp, '__name__', None) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

2164 raise PydanticUserError( 1eiacnqryszkolmfgtuABCDhjbdpvwExF

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

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

2167 code='custom-json-schema', 

2168 ) 

2169 

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

2171 if hasattr(tp, '__origin__') and not isinstance(tp, type(Annotated[int, 'placeholder'])): 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

2172 return _extract_get_pydantic_json_schema(tp.__origin__, schema) 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

2173 

2174 if js_modify_function is None: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

2175 return None 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

2176 

2177 return js_modify_function 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

2178 

2179 

2180def get_json_schema_update_func( 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

2181 json_schema_update: JsonSchemaValue, json_schema_extra: JsonDict | typing.Callable[[JsonDict], None] | None 

2182) -> GetJsonSchemaFunction: 

2183 def json_schema_update_func( 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

2184 core_schema_or_field: CoreSchemaOrField, handler: GetJsonSchemaHandler 

2185 ) -> JsonSchemaValue: 

2186 json_schema = {**handler(core_schema_or_field), **json_schema_update} 1eiacnqryszkolmfgtuABCDhjbdpvwExF

2187 add_json_schema_extra(json_schema, json_schema_extra) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

2188 return json_schema 1eiacnqryszkolmfgtuABCDhjbdpvwExF

2189 

2190 return json_schema_update_func 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

2191 

2192 

2193def add_json_schema_extra( 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

2194 json_schema: JsonSchemaValue, json_schema_extra: JsonDict | typing.Callable[[JsonDict], None] | None 

2195): 

2196 if isinstance(json_schema_extra, dict): 1eiacnqryszkolmfgtuABCDhjbdpvwExF

2197 json_schema.update(to_jsonable_python(json_schema_extra)) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

2198 elif callable(json_schema_extra): 1eiacnqryszkolmfgtuABCDhjbdpvwExF

2199 json_schema_extra(json_schema) 1eiacnqryszkolmfgtuABCDhjbdpvwExF

2200 

2201 

2202class _CommonField(TypedDict): 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

2203 schema: core_schema.CoreSchema 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

2204 validation_alias: str | list[str | int] | list[list[str | int]] | None 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

2205 serialization_alias: str | None 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

2206 serialization_exclude: bool | None 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

2207 frozen: bool | None 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

2208 metadata: dict[str, Any] 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

2209 

2210 

2211def _common_field( 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

2212 schema: core_schema.CoreSchema, 

2213 *, 

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

2215 serialization_alias: str | None = None, 

2216 serialization_exclude: bool | None = None, 

2217 frozen: bool | None = None, 

2218 metadata: Any = None, 

2219) -> _CommonField: 

2220 return { 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

2221 'schema': schema, 

2222 'validation_alias': validation_alias, 

2223 'serialization_alias': serialization_alias, 

2224 'serialization_exclude': serialization_exclude, 

2225 'frozen': frozen, 

2226 'metadata': metadata, 

2227 } 

2228 

2229 

2230class _Definitions: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

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

2232 

2233 def __init__(self) -> None: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

2234 self.seen: set[str] = set() 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

2235 self.definitions: dict[str, core_schema.CoreSchema] = {} 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

2236 

2237 @contextmanager 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

2238 def get_schema_or_ref(self, tp: Any) -> Iterator[tuple[str, None] | tuple[str, CoreSchema]]: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

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

2240 

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

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

2243 

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

2245 not the actual definition itself. 

2246 

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

2248 This includes any recursive types. 

2249 

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

2251 

2252 - BaseModel 

2253 - Dataclasses 

2254 - TypedDict 

2255 - TypeAliasType 

2256 """ 

2257 ref = get_type_ref(tp) 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

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

2259 if ref in self.seen or ref in self.definitions: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

2260 yield (ref, core_schema.definition_reference_schema(ref)) 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

2261 else: 

2262 self.seen.add(ref) 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

2263 try: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

2264 yield (ref, None) 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

2265 finally: 

2266 self.seen.discard(ref) 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

2267 

2268 

2269def resolve_original_schema(schema: CoreSchema, definitions: dict[str, CoreSchema]) -> CoreSchema | None: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

2270 if schema['type'] == 'definition-ref': 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

2271 return definitions.get(schema['schema_ref'], None) 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

2272 elif schema['type'] == 'definitions': 2272 ↛ 2273line 2272 didn't jump to line 2273, because the condition on line 2272 was never true1eiacnqryszkolmfgtuABCDhjbdpvwExF

2273 return schema['schema'] 

2274 else: 

2275 return schema 1eiacnqryszkolmfgtuABCDhjbdpvwExF

2276 

2277 

2278class _FieldNameStack: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

2279 __slots__ = ('_stack',) 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

2280 

2281 def __init__(self) -> None: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

2282 self._stack: list[str] = [] 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

2283 

2284 @contextmanager 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

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

2286 self._stack.append(field_name) 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

2287 yield 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

2288 self._stack.pop() 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

2289 

2290 def get(self) -> str | None: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

2291 if self._stack: 1eiacnqryszkolmfgtuABCDhjbdpvwExF

2292 return self._stack[-1] 1eiacnqryszkolmfgtuABCDhjbdpvwExF

2293 else: 

2294 return None 1eanrshbpwx

2295 

2296 

2297class _ModelTypeStack: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

2298 __slots__ = ('_stack',) 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

2299 

2300 def __init__(self) -> None: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

2301 self._stack: list[type] = [] 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

2302 

2303 @contextmanager 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

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

2305 self._stack.append(type_obj) 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

2306 yield 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

2307 self._stack.pop() 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

2308 

2309 def get(self) -> type | None: 1eiacnqryszkolmfgtuABCDGHIJKLMNOhjbdpvwExF

2310 if self._stack: 2310 ↛ 2313line 2310 didn't jump to line 2313, because the condition on line 2310 was always true1eiacnqryszkolmfgtuABCDhjbdpvwExF

2311 return self._stack[-1] 1eiacnqryszkolmfgtuABCDhjbdpvwExF

2312 else: 

2313 return None