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

1158 statements  

« prev     ^ index     » next       coverage.py v7.5.4, created at 2024-07-03 19:29 +0000

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

2 

3from __future__ import annotations as _annotations 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

4 

5import collections.abc 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

6import dataclasses 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

7import inspect 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

8import re 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

9import sys 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

10import typing 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

11import warnings 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

12from contextlib import ExitStack, contextmanager 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

13from copy import copy, deepcopy 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

14from enum import Enum 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

15from functools import partial 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

16from inspect import Parameter, _ParameterKind, signature 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

17from itertools import chain 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

18from operator import attrgetter 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

19from types import FunctionType, LambdaType, MethodType 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

20from typing import ( 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

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

37 

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

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

40 

41from ..aliases import AliasGenerator 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

42from ..annotated_handlers import GetCoreSchemaHandler, GetJsonSchemaHandler 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

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

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

45from ..json_schema import JsonSchemaValue 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

46from ..version import version_short 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

47from ..warnings import PydanticDeprecatedSince20 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

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

49from ._config import ConfigWrapper, ConfigWrapperStack 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

50from ._core_metadata import CoreMetadataHandler, build_metadata_dict 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

51from ._core_utils import ( 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

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

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

77from ._fields import collect_dataclass_fields, get_type_hints_infer_globalns 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

78from ._forward_ref import PydanticRecursiveRef 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

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

80from ._mock_val_ser import MockCoreSchema 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

81from ._schema_generation_shared import CallbackGetCoreSchemaHandler 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

82from ._typing_extra import is_finalvar, is_self_type 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

83from ._utils import lenient_issubclass 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

84 

85if TYPE_CHECKING: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

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

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

95 

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

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

98AnyFieldDecorator = Union[ 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

99 Decorator[ValidatorDecoratorInfo], 

100 Decorator[FieldValidatorDecoratorInfo], 

101 Decorator[FieldSerializerDecoratorInfo], 

102] 

103 

104ModifyCoreSchemaWrapHandler = GetCoreSchemaHandler 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

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

106 

107TUPLE_TYPES: list[type] = [tuple, typing.Tuple] 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

108LIST_TYPES: list[type] = [list, typing.List, collections.abc.MutableSequence] 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

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

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

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

112 

113 

114def check_validator_fields_against_field_name( 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

115 info: FieldDecoratorInfo, 

116 field: str, 

117) -> bool: 

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

119 

120 Args: 

121 info: The field info. 

122 field: The field name to check. 

123 

124 Returns: 

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

126 """ 

127 if '*' in info.fields: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

128 return True 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

129 for v_field_name in info.fields: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

130 if v_field_name == field: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

131 return True 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

132 return False 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

133 

134 

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

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

137 

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

139 

140 Args: 

141 decorators: An iterable of decorators. 

142 fields: An iterable of fields name. 

143 

144 Raises: 

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

146 """ 

147 fields = set(fields) 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

148 for dec in decorators: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

149 if '*' in dec.info.fields: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

150 continue 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

151 if dec.info.check_fields is False: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

152 continue 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

153 for field in dec.info.fields: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

154 if field not in fields: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

155 raise PydanticUserError( 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

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

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

158 code='decorator-missing-field', 

159 ) 

160 

161 

162def filter_field_decorator_info_by_field( 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

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

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

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

166 

167 

168def apply_each_item_validators( 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

169 schema: core_schema.CoreSchema, 

170 each_item_validators: list[Decorator[ValidatorDecoratorInfo]], 

171 field_name: str | None, 

172) -> core_schema.CoreSchema: 

173 # This V1 compatibility shim should eventually be removed 

174 

175 # push down any `each_item=True` validators 

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

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

178 if schema['type'] == 'nullable': 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

179 schema['schema'] = apply_each_item_validators(schema['schema'], each_item_validators, field_name) 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

180 return schema 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

181 elif schema['type'] == 'tuple': 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

182 if (variadic_item_index := schema.get('variadic_item_index')) is not None: 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

183 schema['items_schema'][variadic_item_index] = apply_validators( 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

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

185 ) 

186 elif is_list_like_schema_with_items_schema(schema): 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

187 inner_schema = schema.get('items_schema', None) 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

188 if inner_schema is None: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

189 inner_schema = core_schema.any_schema() 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

190 schema['items_schema'] = apply_validators(inner_schema, each_item_validators, field_name) 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

191 elif schema['type'] == 'dict': 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

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

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

194 inner_schema = schema.get('values_schema', None) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

195 if inner_schema is None: 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

196 inner_schema = core_schema.any_schema() 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

197 schema['values_schema'] = apply_validators(inner_schema, each_item_validators, field_name) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

198 elif each_item_validators: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

199 raise TypeError( 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

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

201 ) 

202 return schema 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

203 

204 

205def modify_model_json_schema( 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

206 schema_or_field: CoreSchemaOrField, 

207 handler: GetJsonSchemaHandler, 

208 *, 

209 cls: Any, 

210 title: str | None = None, 

211) -> JsonSchemaValue: 

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

213 

214 Args: 

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

216 handler: The `GetCoreSchemaHandler` instance. 

217 cls: The model-like class. 

218 title: The title to set for the model's schema, defaults to the model's name 

219 

220 Returns: 

221 JsonSchemaValue: The updated JSON schema. 

222 """ 

223 from ..dataclasses import is_pydantic_dataclass 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

224 from ..main import BaseModel 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

225 from ..root_model import RootModel 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

226 from ._dataclasses import is_builtin_dataclass 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

227 

228 json_schema = handler(schema_or_field) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

229 original_schema = handler.resolve_ref_schema(json_schema) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

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

231 if '$ref' in original_schema: 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

232 ref = original_schema['$ref'] 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

233 original_schema.clear() 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

234 original_schema['allOf'] = [{'$ref': ref}] 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

235 if title is not None: 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

236 original_schema['title'] = title 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

237 elif 'title' not in original_schema: 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

238 original_schema['title'] = cls.__name__ 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

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

240 docstring = None if cls is BaseModel or is_builtin_dataclass(cls) or is_pydantic_dataclass(cls) else cls.__doc__ 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

241 if docstring and 'description' not in original_schema: 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

242 original_schema['description'] = inspect.cleandoc(docstring) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

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

244 original_schema['description'] = cls.model_fields['root'].description 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

245 return json_schema 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

246 

247 

248JsonEncoders = Dict[Type[Any], JsonEncoder] 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

249 

250 

251def _add_custom_serialization_from_json_encoders( 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

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

253) -> CoreSchema: 

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

255 

256 Args: 

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

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

259 schema: The schema to add the encoder to. 

260 """ 

261 if not json_encoders: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

262 return schema 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

263 if 'serialization' in schema: 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

264 return schema 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

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

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

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

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

269 encoder = json_encoders.get(base) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

270 if encoder is None: 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

271 continue 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

272 

273 warnings.warn( 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

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

275 PydanticDeprecatedSince20, 

276 ) 

277 

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

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

280 return schema 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

281 

282 return schema 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

283 

284 

285TypesNamespace = Union[Dict[str, Any], None] 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

286 

287 

288class TypesNamespaceStack: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

289 """A stack of types namespaces.""" 

290 

291 def __init__(self, types_namespace: TypesNamespace): 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

292 self._types_namespace_stack: list[TypesNamespace] = [types_namespace] 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

293 

294 @property 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

295 def tail(self) -> TypesNamespace: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

296 return self._types_namespace_stack[-1] 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

297 

298 @contextmanager 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

299 def push(self, for_type: type[Any]): 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

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

301 self._types_namespace_stack.append(types_namespace) 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

302 try: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

303 yield 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

304 finally: 

305 self._types_namespace_stack.pop() 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

306 

307 

308def _get_first_non_null(a: Any, b: Any) -> Any: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

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

310 

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

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

313 """ 

314 return a if a is not None else b 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

315 

316 

317class GenerateSchema: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

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

319 

320 __slots__ = ( 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

321 '_config_wrapper_stack', 

322 '_types_namespace_stack', 

323 '_typevars_map', 

324 'field_name_stack', 

325 'model_type_stack', 

326 'defs', 

327 ) 

328 

329 def __init__( 1eiacmpqyrzGHklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

330 self, 

331 config_wrapper: ConfigWrapper, 

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

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

334 ) -> None: 

335 # we need a stack for recursing into child models 

336 self._config_wrapper_stack = ConfigWrapperStack(config_wrapper) 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

337 self._types_namespace_stack = TypesNamespaceStack(types_namespace) 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

338 self._typevars_map = typevars_map 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

339 self.field_name_stack = _FieldNameStack() 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

340 self.model_type_stack = _ModelTypeStack() 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

341 self.defs = _Definitions() 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

342 

343 @classmethod 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

344 def __from_parent( 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

345 cls, 

346 config_wrapper_stack: ConfigWrapperStack, 

347 types_namespace_stack: TypesNamespaceStack, 

348 model_type_stack: _ModelTypeStack, 

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

350 defs: _Definitions, 

351 ) -> GenerateSchema: 

352 obj = cls.__new__(cls) 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

353 obj._config_wrapper_stack = config_wrapper_stack 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

354 obj._types_namespace_stack = types_namespace_stack 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

355 obj.model_type_stack = model_type_stack 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

356 obj._typevars_map = typevars_map 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

357 obj.field_name_stack = _FieldNameStack() 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

358 obj.defs = defs 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

359 return obj 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

360 

361 @property 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

362 def _config_wrapper(self) -> ConfigWrapper: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

363 return self._config_wrapper_stack.tail 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

364 

365 @property 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

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

367 return self._types_namespace_stack.tail 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

368 

369 @property 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

370 def _current_generate_schema(self) -> GenerateSchema: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

371 cls = self._config_wrapper.schema_generator or GenerateSchema 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

372 return cls.__from_parent( 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

373 self._config_wrapper_stack, 

374 self._types_namespace_stack, 

375 self.model_type_stack, 

376 self._typevars_map, 

377 self.defs, 

378 ) 

379 

380 @property 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

381 def _arbitrary_types(self) -> bool: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

382 return self._config_wrapper.arbitrary_types_allowed 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

383 

384 def str_schema(self) -> CoreSchema: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

385 """Generate a CoreSchema for `str`""" 

386 return core_schema.str_schema() 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

387 

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

389 # unstable / private APIs 

390 def _list_schema(self, tp: Any, items_type: Any) -> CoreSchema: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

391 return core_schema.list_schema(self.generate_schema(items_type)) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

392 

393 def _dict_schema(self, tp: Any, keys_type: Any, values_type: Any) -> CoreSchema: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

394 return core_schema.dict_schema(self.generate_schema(keys_type), self.generate_schema(values_type)) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

395 

396 def _set_schema(self, tp: Any, items_type: Any) -> CoreSchema: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

397 return core_schema.set_schema(self.generate_schema(items_type)) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

398 

399 def _frozenset_schema(self, tp: Any, items_type: Any) -> CoreSchema: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

400 return core_schema.frozenset_schema(self.generate_schema(items_type)) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

401 

402 def _arbitrary_type_schema(self, tp: Any) -> CoreSchema: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

403 if not isinstance(tp, type): 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

404 warn( 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

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

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

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

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

409 UserWarning, 

410 ) 

411 return core_schema.any_schema() 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

412 return core_schema.is_instance_schema(tp) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

413 

414 def _unknown_type_schema(self, obj: Any) -> CoreSchema: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

415 raise PydanticSchemaGenerationError( 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

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

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

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

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

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

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

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

423 ) 

424 

425 def _apply_discriminator_to_union( 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

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

427 ) -> CoreSchema: 

428 if discriminator is None: 428 ↛ 429line 428 didn't jump to line 429 because the condition on line 428 was never true1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

429 return schema 

430 try: 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

431 return _discriminated_union.apply_discriminator( 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

432 schema, 

433 discriminator, 

434 ) 

435 except _discriminated_union.MissingDefinitionForUnionRef: 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

436 # defer until defs are resolved 

437 _discriminated_union.set_discriminator_in_metadata( 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

438 schema, 

439 discriminator, 

440 ) 

441 return schema 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

442 

443 class CollectedInvalid(Exception): 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

444 pass 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

445 

446 def clean_schema(self, schema: CoreSchema) -> CoreSchema: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

447 schema = self.collect_definitions(schema) 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

448 schema = simplify_schema_references(schema) 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

449 if collect_invalid_schemas(schema): 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

450 raise self.CollectedInvalid() 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

451 schema = _discriminated_union.apply_discriminators(schema) 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

452 schema = validate_core_schema(schema) 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

453 return schema 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

454 

455 def collect_definitions(self, schema: CoreSchema) -> CoreSchema: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

456 ref = cast('str | None', schema.get('ref', None)) 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

457 if ref: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

458 self.defs.definitions[ref] = schema 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

459 if 'ref' in schema: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

460 schema = core_schema.definition_reference_schema(schema['ref']) 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

461 return core_schema.definitions_schema( 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

462 schema, 

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

464 ) 

465 

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

467 metadata = CoreMetadataHandler(metadata_schema).metadata 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

468 pydantic_js_functions = metadata.setdefault('pydantic_js_functions', []) 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

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

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

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

472 # or something like that 

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

474 if js_function not in pydantic_js_functions: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

475 pydantic_js_functions.append(js_function) 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

476 

477 def generate_schema( 1eiacmpqyrzGHklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

478 self, 

479 obj: Any, 

480 from_dunder_get_core_schema: bool = True, 

481 ) -> core_schema.CoreSchema: 

482 """Generate core schema. 

483 

484 Args: 

485 obj: The object to generate core schema for. 

486 from_dunder_get_core_schema: Whether to generate schema from either the 

487 `__get_pydantic_core_schema__` function or `__pydantic_core_schema__` property. 

488 

489 Returns: 

490 The generated core schema. 

491 

492 Raises: 

493 PydanticUndefinedAnnotation: 

494 If it is not possible to evaluate forward reference. 

495 PydanticSchemaGenerationError: 

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

497 TypeError: 

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

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

500 PydanticUserError: 

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

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

503 """ 

504 schema: CoreSchema | None = None 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

505 

506 if from_dunder_get_core_schema: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

507 from_property = self._generate_schema_from_property(obj, obj) 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

508 if from_property is not None: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

509 schema = from_property 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

510 

511 if schema is None: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

512 schema = self._generate_schema_inner(obj) 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

513 

514 metadata_js_function = _extract_get_pydantic_json_schema(obj, schema) 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

515 if metadata_js_function is not None: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

516 metadata_schema = resolve_original_schema(schema, self.defs.definitions) 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

517 if metadata_schema: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

518 self._add_js_function(metadata_schema, metadata_js_function) 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

519 

520 schema = _add_custom_serialization_from_json_encoders(self._config_wrapper.json_encoders, obj, schema) 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

521 

522 return schema 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

523 

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

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

526 with self.defs.get_schema_or_ref(cls) as (model_ref, maybe_schema): 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

527 if maybe_schema is not None: 527 ↛ 528line 527 didn't jump to line 528 because the condition on line 527 was never true1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

528 return maybe_schema 

529 

530 fields = cls.model_fields 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

531 decorators = cls.__pydantic_decorators__ 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

532 computed_fields = decorators.computed_fields 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

533 check_decorator_fields_exist( 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

534 chain( 

535 decorators.field_validators.values(), 

536 decorators.field_serializers.values(), 

537 decorators.validators.values(), 

538 ), 

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

540 ) 

541 config_wrapper = ConfigWrapper(cls.model_config, check=False) 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

542 core_config = config_wrapper.core_config(cls) 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

543 title = self._get_model_title_from_config(cls, config_wrapper) 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

544 metadata = build_metadata_dict(js_functions=[partial(modify_model_json_schema, cls=cls, title=title)]) 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

545 

546 model_validators = decorators.model_validators.values() 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

547 

548 extras_schema = None 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

549 if core_config.get('extra_fields_behavior') == 'allow': 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

550 assert cls.__mro__[0] is cls 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

551 assert cls.__mro__[-1] is object 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

552 for candidate_cls in cls.__mro__[:-1]: 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

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

554 if extras_annotation is not None: 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

555 if isinstance(extras_annotation, str): 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

556 extras_annotation = _typing_extra.eval_type_backport( 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

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

558 self._types_namespace, 

559 ) 

560 tp = get_origin(extras_annotation) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

561 if tp not in (Dict, dict): 561 ↛ 562line 561 didn't jump to line 562 because the condition on line 561 was never true1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

562 raise PydanticSchemaGenerationError( 

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

564 ) 

565 extra_items_type = self._get_args_resolving_forward_refs( 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

566 extras_annotation, 

567 required=True, 

568 )[1] 

569 if extra_items_type is not Any: 569 ↛ 552line 569 didn't jump to line 552 because the condition on line 569 was always true1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

570 extras_schema = self.generate_schema(extra_items_type) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

571 break 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

572 

573 with self._config_wrapper_stack.push(config_wrapper), self._types_namespace_stack.push(cls): 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

574 self = self._current_generate_schema 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

575 if cls.__pydantic_root_model__: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

576 root_field = self._common_field_schema('root', fields['root'], decorators) 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

577 inner_schema = root_field['schema'] 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

578 inner_schema = apply_model_validators(inner_schema, model_validators, 'inner') 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

579 model_schema = core_schema.model_schema( 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

580 cls, 

581 inner_schema, 

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

583 root_model=True, 

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

585 config=core_config, 

586 ref=model_ref, 

587 metadata=metadata, 

588 ) 

589 else: 

590 fields_schema: core_schema.CoreSchema = core_schema.model_fields_schema( 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

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

592 computed_fields=[ 

593 self._computed_field_schema(d, decorators.field_serializers) 

594 for d in computed_fields.values() 

595 ], 

596 extras_schema=extras_schema, 

597 model_name=cls.__name__, 

598 ) 

599 inner_schema = apply_validators(fields_schema, decorators.root_validators.values(), None) 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

600 new_inner_schema = define_expected_missing_refs(inner_schema, recursively_defined_type_refs()) 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

601 if new_inner_schema is not None: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

602 inner_schema = new_inner_schema 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

603 inner_schema = apply_model_validators(inner_schema, model_validators, 'inner') 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

604 

605 model_schema = core_schema.model_schema( 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

606 cls, 

607 inner_schema, 

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

609 root_model=False, 

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

611 config=core_config, 

612 ref=model_ref, 

613 metadata=metadata, 

614 ) 

615 

616 schema = self._apply_model_serializers(model_schema, decorators.model_serializers.values()) 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

617 schema = apply_model_validators(schema, model_validators, 'outer') 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

618 self.defs.definitions[model_ref] = schema 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

619 return core_schema.definition_reference_schema(model_ref) 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

620 

621 @staticmethod 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

622 def _get_model_title_from_config( 1eiacmpqyrzGHklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

623 model: type[BaseModel | StandardDataclass], config_wrapper: ConfigWrapper | None = None 

624 ) -> str | None: 

625 """Get the title of a model if `model_title_generator` or `title` are set in the config, else return None""" 

626 if config_wrapper is None: 626 ↛ 627line 626 didn't jump to line 627 because the condition on line 626 was never true1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

627 return None 

628 

629 if config_wrapper.title: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

630 return config_wrapper.title 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

631 

632 model_title_generator = config_wrapper.model_title_generator 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

633 if model_title_generator: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

634 title = model_title_generator(model) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

635 if not isinstance(title, str): 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

636 raise TypeError(f'model_title_generator {model_title_generator} must return str, not {title.__class__}') 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

637 return title 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

638 

639 return None 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

640 

641 def _unpack_refs_defs(self, schema: CoreSchema) -> CoreSchema: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

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

643 and return the inner schema. 

644 """ 

645 

646 def get_ref(s: CoreSchema) -> str: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

647 return s['ref'] # type: ignore 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

648 

649 if schema['type'] == 'definitions': 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

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

651 schema = schema['schema'] 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

652 return schema 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

653 

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

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

656 `__pydantic_core_schema__` property. 

657 

658 Note: `__get_pydantic_core_schema__` takes priority so it can 

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

660 """ 

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

662 if is_self_type(obj): 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

663 obj = self.model_type_stack.get() 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

664 with self.defs.get_schema_or_ref(obj) as (_, maybe_schema): 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

665 if maybe_schema is not None: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

666 return maybe_schema 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

667 if obj is source: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

668 ref_mode = 'unpack' 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

669 else: 

670 ref_mode = 'to-def' 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

671 

672 schema: CoreSchema 

673 

674 if (get_schema := getattr(obj, '__get_pydantic_core_schema__', None)) is not None: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

675 if len(inspect.signature(get_schema).parameters) == 1: 675 ↛ 677line 675 didn't jump to line 677 because the condition on line 675 was never true1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

676 # (source) -> CoreSchema 

677 schema = get_schema(source) 

678 else: 

679 schema = get_schema( 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

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

681 ) 

682 # fmt: off 

683 elif ( 1eiacnsklfgMNhjbd

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

685 and not isinstance(existing_schema, MockCoreSchema) 

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

687 ): 

688 schema = existing_schema 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

689 # fmt: on 

690 elif (validators := getattr(obj, '__get_validators__', None)) is not None: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

691 warn( 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

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

693 PydanticDeprecatedSince20, 

694 ) 

695 schema = core_schema.chain_schema([core_schema.with_info_plain_validator_function(v) for v in validators()]) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

696 else: 

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

698 return None 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

699 

700 schema = self._unpack_refs_defs(schema) 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

701 

702 if is_function_with_inner_schema(schema): 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

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

704 if ref: 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

705 schema['ref'] = ref 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

706 else: 

707 ref = get_ref(schema) 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

708 

709 if ref: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

710 self.defs.definitions[ref] = schema 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

711 return core_schema.definition_reference_schema(ref) 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

712 

713 return schema 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

714 

715 def _resolve_forward_ref(self, obj: Any) -> Any: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

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

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

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

719 # `Validator(SomeImportedTypeAliasWithAForwardReference)` 

720 # or the equivalent for BaseModel 

721 # class Model(BaseModel): 

722 # x: SomeImportedTypeAliasWithAForwardReference 

723 try: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

724 obj = _typing_extra.eval_type_backport(obj, globalns=self._types_namespace) 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

725 except NameError as e: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

726 raise PydanticUndefinedAnnotation.from_name_error(e) from e 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

727 

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

729 if isinstance(obj, ForwardRef): 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

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

731 

732 if self._typevars_map: 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

733 obj = replace_types(obj, self._typevars_map) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

734 

735 return obj 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

736 

737 @overload 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

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

739 

740 @overload 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

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

742 

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

744 args = get_args(obj) 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

745 if args: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

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

747 elif required: # pragma: no cover 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

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

749 return args 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

750 

751 def _get_first_arg_or_any(self, obj: Any) -> Any: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

752 args = self._get_args_resolving_forward_refs(obj) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

753 if not args: 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

754 return Any 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

755 return args[0] 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

756 

757 def _get_first_two_args_or_any(self, obj: Any) -> tuple[Any, Any]: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

758 args = self._get_args_resolving_forward_refs(obj) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

759 if not args: 759 ↛ 761line 759 didn't jump to line 761 because the condition on line 759 was always true1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

760 return (Any, Any) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

761 if len(args) < 2: 

762 origin = get_origin(obj) 

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

764 return args[0], args[1] 

765 

766 def _generate_schema_inner(self, obj: Any) -> core_schema.CoreSchema: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

767 if isinstance(obj, _AnnotatedType): 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

768 return self._annotated_schema(obj) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

769 

770 if isinstance(obj, dict): 770 ↛ 772line 770 didn't jump to line 772 because the condition on line 770 was never true1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

771 # we assume this is already a valid schema 

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

773 

774 if isinstance(obj, str): 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

775 obj = ForwardRef(obj) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

776 

777 if isinstance(obj, ForwardRef): 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

778 return self.generate_schema(self._resolve_forward_ref(obj)) 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

779 

780 from ..main import BaseModel 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

781 

782 if lenient_issubclass(obj, BaseModel): 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

783 with self.model_type_stack.push(obj): 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

784 return self._model_schema(obj) 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

785 

786 if isinstance(obj, PydanticRecursiveRef): 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

787 return core_schema.definition_reference_schema(schema_ref=obj.type_ref) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

788 

789 return self.match_type(obj) 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

790 

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

792 """Main mapping of types to schemas. 

793 

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

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

796 

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

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

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

800 

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

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

803 """ 

804 if obj is str: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

805 return self.str_schema() 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

806 elif obj is bytes: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

807 return core_schema.bytes_schema() 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

808 elif obj is int: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

809 return core_schema.int_schema() 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

810 elif obj is float: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

811 return core_schema.float_schema() 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

812 elif obj is bool: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

813 return core_schema.bool_schema() 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

814 elif obj is Any or obj is object: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

815 return core_schema.any_schema() 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

816 elif obj is None or obj is _typing_extra.NoneType: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

817 return core_schema.none_schema() 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

818 elif obj in TUPLE_TYPES: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

819 return self._tuple_schema(obj) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

820 elif obj in LIST_TYPES: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

821 return self._list_schema(obj, self._get_first_arg_or_any(obj)) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

822 elif obj in SET_TYPES: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

823 return self._set_schema(obj, self._get_first_arg_or_any(obj)) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

824 elif obj in FROZEN_SET_TYPES: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

825 return self._frozenset_schema(obj, self._get_first_arg_or_any(obj)) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

826 elif obj in DICT_TYPES: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

827 return self._dict_schema(obj, *self._get_first_two_args_or_any(obj)) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

828 elif isinstance(obj, TypeAliasType): 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

829 return self._type_alias_type_schema(obj) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

830 elif obj is type: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

831 return self._type_schema() 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

832 elif _typing_extra.is_callable_type(obj): 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

833 return core_schema.callable_schema() 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

834 elif _typing_extra.is_literal_type(obj): 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

835 return self._literal_schema(obj) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

836 elif is_typeddict(obj): 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

837 return self._typed_dict_schema(obj, None) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

838 elif _typing_extra.is_namedtuple(obj): 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

839 return self._namedtuple_schema(obj, None) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

840 elif _typing_extra.is_new_type(obj): 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

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

842 return self.generate_schema(obj.__supertype__) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

843 elif obj == re.Pattern: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

844 return self._pattern_schema(obj) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

845 elif obj is collections.abc.Hashable or obj is typing.Hashable: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

846 return self._hashable_schema() 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

847 elif isinstance(obj, typing.TypeVar): 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

848 return self._unsubstituted_typevar_schema(obj) 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

849 elif is_finalvar(obj): 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

850 if obj is Final: 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

851 return core_schema.any_schema() 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

852 return self.generate_schema( 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

853 self._get_first_arg_or_any(obj), 

854 ) 

855 elif isinstance(obj, (FunctionType, LambdaType, MethodType, partial)): 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

856 return self._callable_schema(obj) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

857 elif inspect.isclass(obj) and issubclass(obj, Enum): 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

858 from ._std_types_schema import get_enum_core_schema 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

859 

860 return get_enum_core_schema(obj, self._config_wrapper.config_dict) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

861 

862 if _typing_extra.is_dataclass(obj): 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

863 return self._dataclass_schema(obj, None) 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

864 res = self._get_prepare_pydantic_annotations_for_known_type(obj, ()) 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

865 if res is not None: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

866 source_type, annotations = res 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

867 return self._apply_annotations(source_type, annotations) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

868 

869 origin = get_origin(obj) 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

870 if origin is not None: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

871 return self._match_generic_type(obj, origin) 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

872 

873 if self._arbitrary_types: 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

874 return self._arbitrary_type_schema(obj) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

875 return self._unknown_type_schema(obj) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

876 

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

878 if isinstance(origin, TypeAliasType): 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

879 return self._type_alias_type_schema(obj) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

880 

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

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

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

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

885 if _typing_extra.is_dataclass(origin): 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

886 return self._dataclass_schema(obj, origin) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

887 if _typing_extra.is_namedtuple(origin): 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

888 return self._namedtuple_schema(obj, origin) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

889 

890 from_property = self._generate_schema_from_property(origin, obj) 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

891 if from_property is not None: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

892 return from_property 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

893 

894 if _typing_extra.origin_is_union(origin): 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

895 return self._union_schema(obj) 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

896 elif origin in TUPLE_TYPES: 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

897 return self._tuple_schema(obj) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

898 elif origin in LIST_TYPES: 898 ↛ 899line 898 didn't jump to line 899 because the condition on line 898 was never true1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

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

900 elif origin in SET_TYPES: 900 ↛ 901line 900 didn't jump to line 901 because the condition on line 900 was never true1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

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

902 elif origin in FROZEN_SET_TYPES: 902 ↛ 903line 902 didn't jump to line 903 because the condition on line 902 was never true1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

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

904 elif origin in DICT_TYPES: 904 ↛ 905line 904 didn't jump to line 905 because the condition on line 904 was never true1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

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

906 elif is_typeddict(origin): 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

907 return self._typed_dict_schema(obj, origin) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

908 elif origin in (typing.Type, type): 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

909 return self._subclass_schema(obj) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

910 elif origin in {typing.Sequence, collections.abc.Sequence}: 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

911 return self._sequence_schema(obj) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

912 elif origin in {typing.Iterable, collections.abc.Iterable, typing.Generator, collections.abc.Generator}: 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

913 return self._iterable_schema(obj) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

914 elif origin in (re.Pattern, typing.Pattern): 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

915 return self._pattern_schema(obj) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

916 

917 if self._arbitrary_types: 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

918 return self._arbitrary_type_schema(origin) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

919 return self._unknown_type_schema(obj) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

920 

921 def _generate_td_field_schema( 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

922 self, 

923 name: str, 

924 field_info: FieldInfo, 

925 decorators: DecoratorInfos, 

926 *, 

927 required: bool = True, 

928 ) -> core_schema.TypedDictField: 

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

930 common_field = self._common_field_schema(name, field_info, decorators) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

931 return core_schema.typed_dict_field( 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

932 common_field['schema'], 

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

934 serialization_exclude=common_field['serialization_exclude'], 

935 validation_alias=common_field['validation_alias'], 

936 serialization_alias=common_field['serialization_alias'], 

937 metadata=common_field['metadata'], 

938 ) 

939 

940 def _generate_md_field_schema( 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

941 self, 

942 name: str, 

943 field_info: FieldInfo, 

944 decorators: DecoratorInfos, 

945 ) -> core_schema.ModelField: 

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

947 common_field = self._common_field_schema(name, field_info, decorators) 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

948 return core_schema.model_field( 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

949 common_field['schema'], 

950 serialization_exclude=common_field['serialization_exclude'], 

951 validation_alias=common_field['validation_alias'], 

952 serialization_alias=common_field['serialization_alias'], 

953 frozen=common_field['frozen'], 

954 metadata=common_field['metadata'], 

955 ) 

956 

957 def _generate_dc_field_schema( 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

958 self, 

959 name: str, 

960 field_info: FieldInfo, 

961 decorators: DecoratorInfos, 

962 ) -> core_schema.DataclassField: 

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

964 common_field = self._common_field_schema(name, field_info, decorators) 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

965 return core_schema.dataclass_field( 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

966 name, 

967 common_field['schema'], 

968 init=field_info.init, 

969 init_only=field_info.init_var or None, 

970 kw_only=None if field_info.kw_only else False, 

971 serialization_exclude=common_field['serialization_exclude'], 

972 validation_alias=common_field['validation_alias'], 

973 serialization_alias=common_field['serialization_alias'], 

974 frozen=common_field['frozen'], 

975 metadata=common_field['metadata'], 

976 ) 

977 

978 @staticmethod 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

979 def _apply_alias_generator_to_field_info( 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

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

981 ) -> None: 

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

983 

984 Args: 

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

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

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

988 """ 

989 # Apply an alias_generator if 

990 # 1. An alias is not specified 

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

992 if ( 1eiacnsklfghjbd

993 field_info.alias_priority is None 

994 or field_info.alias_priority <= 1 

995 or field_info.alias is None 

996 or field_info.validation_alias is None 

997 or field_info.serialization_alias is None 

998 ): 

999 alias, validation_alias, serialization_alias = None, None, None 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1000 

1001 if isinstance(alias_generator, AliasGenerator): 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1002 alias, validation_alias, serialization_alias = alias_generator.generate_aliases(field_name) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1003 elif isinstance(alias_generator, Callable): 1003 ↛ 1011line 1003 didn't jump to line 1011 because the condition on line 1003 was always true1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1004 alias = alias_generator(field_name) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1005 if not isinstance(alias, str): 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

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

1007 

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

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

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

1011 if field_info.alias_priority is None or field_info.alias_priority <= 1: 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1012 field_info.alias_priority = 1 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1013 

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

1015 if field_info.alias_priority == 1: 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1016 field_info.serialization_alias = _get_first_non_null(serialization_alias, alias) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1017 field_info.validation_alias = _get_first_non_null(validation_alias, alias) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1018 field_info.alias = alias 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1019 

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

1021 if field_info.alias is None: 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1022 field_info.alias = alias 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1023 if field_info.serialization_alias is None: 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1024 field_info.serialization_alias = _get_first_non_null(serialization_alias, alias) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1025 if field_info.validation_alias is None: 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1026 field_info.validation_alias = _get_first_non_null(validation_alias, alias) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1027 

1028 @staticmethod 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1029 def _apply_alias_generator_to_computed_field_info( 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

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

1031 computed_field_info: ComputedFieldInfo, 

1032 computed_field_name: str, 

1033 ): 

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

1035 

1036 Args: 

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

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

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

1040 """ 

1041 # Apply an alias_generator if 

1042 # 1. An alias is not specified 

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

1044 

1045 if ( 1eiacnshjbd

1046 computed_field_info.alias_priority is None 

1047 or computed_field_info.alias_priority <= 1 

1048 or computed_field_info.alias is None 

1049 ): 

1050 alias, validation_alias, serialization_alias = None, None, None 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1051 

1052 if isinstance(alias_generator, AliasGenerator): 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1053 alias, validation_alias, serialization_alias = alias_generator.generate_aliases(computed_field_name) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1054 elif isinstance(alias_generator, Callable): 1054 ↛ 1062line 1054 didn't jump to line 1062 because the condition on line 1054 was always true1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1055 alias = alias_generator(computed_field_name) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1056 if not isinstance(alias, str): 1056 ↛ 1057line 1056 didn't jump to line 1057 because the condition on line 1056 was never true1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

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

1058 

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

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

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

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

1063 computed_field_info.alias_priority = 1 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1064 

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

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

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

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

1069 computed_field_info.alias = _get_first_non_null(serialization_alias, alias) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1070 

1071 @staticmethod 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1072 def _apply_field_title_generator_to_field_info( 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

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

1074 ) -> None: 

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

1076 Args: 

1077 config_wrapper: The config of the model 

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

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

1080 """ 

1081 field_title_generator = field_info.field_title_generator or config_wrapper.field_title_generator 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1082 

1083 if field_title_generator is None: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1084 return 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1085 

1086 if field_info.title is None: 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1087 title = field_title_generator(field_name, field_info) # type: ignore 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1088 if not isinstance(title, str): 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

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

1090 

1091 field_info.title = title 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1092 

1093 def _common_field_schema( # C901 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

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

1095 ) -> _CommonField: 

1096 # Update FieldInfo annotation if appropriate: 

1097 from .. import AliasChoices, AliasPath 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1098 from ..fields import FieldInfo 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1099 

1100 if has_instance_in_type(field_info.annotation, (ForwardRef, str)): 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1101 types_namespace = self._types_namespace 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1102 if self._typevars_map: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1103 types_namespace = (types_namespace or {}).copy() 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

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

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

1106 

1107 evaluated = _typing_extra.eval_type_lenient(field_info.annotation, types_namespace) 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1108 if evaluated is not field_info.annotation and not has_instance_in_type(evaluated, PydanticRecursiveRef): 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1109 new_field_info = FieldInfo.from_annotation(evaluated) 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1110 field_info.annotation = new_field_info.annotation 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1111 

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

1113 for k, v in new_field_info._attributes_set.items(): 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

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

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

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

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

1118 if k not in field_info._attributes_set and k not in field_info.metadata_lookup: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1119 setattr(field_info, k, v) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1120 

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

1122 field_info.metadata = [*new_field_info.metadata, *field_info.metadata] 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1123 

1124 source_type, annotations = field_info.annotation, field_info.metadata 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1125 

1126 def set_discriminator(schema: CoreSchema) -> CoreSchema: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1127 schema = self._apply_discriminator_to_union(schema, field_info.discriminator) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1128 return schema 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1129 

1130 with self.field_name_stack.push(name): 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1131 if field_info.discriminator is not None: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1132 schema = self._apply_annotations(source_type, annotations, transform_inner_schema=set_discriminator) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1133 else: 

1134 schema = self._apply_annotations( 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1135 source_type, 

1136 annotations, 

1137 ) 

1138 

1139 # This V1 compatibility shim should eventually be removed 

1140 # push down any `each_item=True` validators 

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

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

1143 this_field_validators = filter_field_decorator_info_by_field(decorators.validators.values(), name) 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1144 if _validators_require_validate_default(this_field_validators): 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1145 field_info.validate_default = True 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1146 each_item_validators = [v for v in this_field_validators if v.info.each_item is True] 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1147 this_field_validators = [v for v in this_field_validators if v not in each_item_validators] 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1148 schema = apply_each_item_validators(schema, each_item_validators, name) 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1149 

1150 schema = apply_validators(schema, filter_field_decorator_info_by_field(this_field_validators, name), name) 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1151 schema = apply_validators( 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

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

1153 ) 

1154 

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

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

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

1158 if not field_info.is_required(): 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1159 schema = wrap_default(field_info, schema) 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1160 

1161 schema = self._apply_field_serializers( 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

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

1163 ) 

1164 self._apply_field_title_generator_to_field_info(self._config_wrapper, field_info, name) 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1165 

1166 json_schema_updates = { 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1167 'title': field_info.title, 

1168 'description': field_info.description, 

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

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

1171 } 

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

1173 

1174 json_schema_extra = field_info.json_schema_extra 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1175 

1176 metadata = build_metadata_dict( 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1177 js_annotation_functions=[get_json_schema_update_func(json_schema_updates, json_schema_extra)] 

1178 ) 

1179 

1180 alias_generator = self._config_wrapper.alias_generator 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1181 if alias_generator is not None: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1182 self._apply_alias_generator_to_field_info(alias_generator, field_info, name) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1183 

1184 if isinstance(field_info.validation_alias, (AliasChoices, AliasPath)): 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1185 validation_alias = field_info.validation_alias.convert_to_aliases() 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1186 else: 

1187 validation_alias = field_info.validation_alias 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1188 

1189 return _common_field( 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1190 schema, 

1191 serialization_exclude=True if field_info.exclude else None, 

1192 validation_alias=validation_alias, 

1193 serialization_alias=field_info.serialization_alias, 

1194 frozen=field_info.frozen, 

1195 metadata=metadata, 

1196 ) 

1197 

1198 def _union_schema(self, union_type: Any) -> core_schema.CoreSchema: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1199 """Generate schema for a Union.""" 

1200 args = self._get_args_resolving_forward_refs(union_type, required=True) 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1201 choices: list[CoreSchema] = [] 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1202 nullable = False 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1203 for arg in args: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1204 if arg is None or arg is _typing_extra.NoneType: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1205 nullable = True 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1206 else: 

1207 choices.append(self.generate_schema(arg)) 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1208 

1209 if len(choices) == 1: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1210 s = choices[0] 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1211 else: 

1212 choices_with_tags: list[CoreSchema | tuple[CoreSchema, str]] = [] 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1213 for choice in choices: 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1214 tag = choice.get('metadata', {}).get(_core_utils.TAGGED_UNION_TAG_KEY) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1215 if tag is not None: 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1216 choices_with_tags.append((choice, tag)) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1217 else: 

1218 choices_with_tags.append(choice) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1219 s = core_schema.union_schema(choices_with_tags) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1220 

1221 if nullable: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1222 s = core_schema.nullable_schema(s) 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1223 return s 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1224 

1225 def _type_alias_type_schema( 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1226 self, 

1227 obj: Any, # TypeAliasType 

1228 ) -> CoreSchema: 

1229 with self.defs.get_schema_or_ref(obj) as (ref, maybe_schema): 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1230 if maybe_schema is not None: 1230 ↛ 1231line 1230 didn't jump to line 1231 because the condition on line 1230 was never true1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1231 return maybe_schema 

1232 

1233 origin = get_origin(obj) or obj 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1234 

1235 annotation = origin.__value__ 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1236 typevars_map = get_standard_typevars_map(obj) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1237 

1238 with self._types_namespace_stack.push(origin): 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1239 annotation = _typing_extra.eval_type_lenient(annotation, self._types_namespace) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1240 annotation = replace_types(annotation, typevars_map) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1241 schema = self.generate_schema(annotation) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1242 assert schema['type'] != 'definitions' 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1243 schema['ref'] = ref # type: ignore 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1244 self.defs.definitions[ref] = schema 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1245 return core_schema.definition_reference_schema(ref) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1246 

1247 def _literal_schema(self, literal_type: Any) -> CoreSchema: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1248 """Generate schema for a Literal.""" 

1249 expected = _typing_extra.all_literal_values(literal_type) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

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

1251 schema = core_schema.literal_schema(expected) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1252 

1253 if self._config_wrapper.use_enum_values and any(isinstance(v, Enum) for v in expected): 1253 ↛ exitline 1253 didn't finish the generator expression on line 12531eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1254 schema = core_schema.no_info_after_validator_function( 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

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

1256 ) 

1257 

1258 return schema 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1259 

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

1261 """Generate schema for a TypedDict. 

1262 

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

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

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

1266 __required_keys__ was added in Python 3.9 

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

1268 however it is buggy 

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

1270 

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

1272 

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

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

1275 """ 

1276 from ..fields import FieldInfo 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1277 

1278 with self.model_type_stack.push(typed_dict_cls), self.defs.get_schema_or_ref(typed_dict_cls) as ( 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1279 typed_dict_ref, 

1280 maybe_schema, 

1281 ): 

1282 if maybe_schema is not None: 1282 ↛ 1283line 1282 didn't jump to line 1283 because the condition on line 1282 was never true1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1283 return maybe_schema 

1284 

1285 typevars_map = get_standard_typevars_map(typed_dict_cls) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1286 if origin is not None: 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1287 typed_dict_cls = origin 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1288 

1289 if not _SUPPORTS_TYPEDDICT and type(typed_dict_cls).__module__ == 'typing': 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1290 raise PydanticUserError( 1eiacmpqynsklfgtuABhjbdovwE

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

1292 code='typed-dict-version', 

1293 ) 

1294 

1295 try: 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1296 config: ConfigDict | None = get_attribute_from_bases(typed_dict_cls, '__pydantic_config__') 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1297 except AttributeError: 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1298 config = None 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1299 

1300 with self._config_wrapper_stack.push(config), self._types_namespace_stack.push(typed_dict_cls): 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1301 core_config = self._config_wrapper.core_config(typed_dict_cls) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1302 

1303 self = self._current_generate_schema 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1304 

1305 required_keys: frozenset[str] = typed_dict_cls.__required_keys__ 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1306 

1307 fields: dict[str, core_schema.TypedDictField] = {} 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1308 

1309 decorators = DecoratorInfos.build(typed_dict_cls) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1310 

1311 if self._config_wrapper.use_attribute_docstrings: 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1312 field_docstrings = extract_docstrings_from_cls(typed_dict_cls, use_inspect=True) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1313 else: 

1314 field_docstrings = None 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1315 

1316 for field_name, annotation in get_type_hints_infer_globalns( 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

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

1318 ).items(): 

1319 annotation = replace_types(annotation, typevars_map) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1320 required = field_name in required_keys 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1321 

1322 if get_origin(annotation) == _typing_extra.Required: 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1323 required = True 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1324 annotation = self._get_args_resolving_forward_refs( 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1325 annotation, 

1326 required=True, 

1327 )[0] 

1328 elif get_origin(annotation) == _typing_extra.NotRequired: 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1329 required = False 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1330 annotation = self._get_args_resolving_forward_refs( 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1331 annotation, 

1332 required=True, 

1333 )[0] 

1334 

1335 field_info = FieldInfo.from_annotation(annotation) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1336 if ( 1eiacnsklfghjbd

1337 field_docstrings is not None 

1338 and field_info.description is None 

1339 and field_name in field_docstrings 

1340 ): 

1341 field_info.description = field_docstrings[field_name] 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1342 self._apply_field_title_generator_to_field_info(self._config_wrapper, field_info, field_name) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1343 fields[field_name] = self._generate_td_field_schema( 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1344 field_name, field_info, decorators, required=required 

1345 ) 

1346 

1347 title = self._get_model_title_from_config(typed_dict_cls, ConfigWrapper(config)) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1348 metadata = build_metadata_dict( 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1349 js_functions=[partial(modify_model_json_schema, cls=typed_dict_cls, title=title)], 

1350 typed_dict_cls=typed_dict_cls, 

1351 ) 

1352 td_schema = core_schema.typed_dict_schema( 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1353 fields, 

1354 computed_fields=[ 

1355 self._computed_field_schema(d, decorators.field_serializers) 

1356 for d in decorators.computed_fields.values() 

1357 ], 

1358 ref=typed_dict_ref, 

1359 metadata=metadata, 

1360 config=core_config, 

1361 ) 

1362 

1363 schema = self._apply_model_serializers(td_schema, decorators.model_serializers.values()) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1364 schema = apply_model_validators(schema, decorators.model_validators.values(), 'all') 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1365 self.defs.definitions[typed_dict_ref] = schema 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1366 return core_schema.definition_reference_schema(typed_dict_ref) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1367 

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

1369 """Generate schema for a NamedTuple.""" 

1370 with self.model_type_stack.push(namedtuple_cls), self.defs.get_schema_or_ref(namedtuple_cls) as ( 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1371 namedtuple_ref, 

1372 maybe_schema, 

1373 ): 

1374 if maybe_schema is not None: 1374 ↛ 1375line 1374 didn't jump to line 1375 because the condition on line 1374 was never true1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1375 return maybe_schema 

1376 typevars_map = get_standard_typevars_map(namedtuple_cls) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1377 if origin is not None: 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1378 namedtuple_cls = origin 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1379 

1380 annotations: dict[str, Any] = get_type_hints_infer_globalns( 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

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

1382 ) 

1383 if not annotations: 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

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

1385 annotations = {k: Any for k in namedtuple_cls._fields} 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1386 

1387 if typevars_map: 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1388 annotations = { 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1389 field_name: replace_types(annotation, typevars_map) 

1390 for field_name, annotation in annotations.items() 

1391 } 

1392 

1393 arguments_schema = core_schema.arguments_schema( 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1394 [ 

1395 self._generate_parameter_schema( 

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

1397 ) 

1398 for field_name, annotation in annotations.items() 

1399 ], 

1400 metadata=build_metadata_dict(js_prefer_positional_arguments=True), 

1401 ) 

1402 return core_schema.call_schema(arguments_schema, namedtuple_cls, ref=namedtuple_ref) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1403 

1404 def _generate_parameter_schema( 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1405 self, 

1406 name: str, 

1407 annotation: type[Any], 

1408 default: Any = Parameter.empty, 

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

1410 ) -> core_schema.ArgumentsParameter: 

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

1412 from ..fields import FieldInfo 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1413 

1414 if default is Parameter.empty: 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1415 field = FieldInfo.from_annotation(annotation) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1416 else: 

1417 field = FieldInfo.from_annotated_attribute(annotation, default) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

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

1419 source_type, annotations = field.annotation, field.metadata 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1420 with self.field_name_stack.push(name): 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1421 schema = self._apply_annotations(source_type, annotations) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1422 

1423 if not field.is_required(): 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1424 schema = wrap_default(field, schema) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1425 

1426 parameter_schema = core_schema.arguments_parameter(name, schema) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1427 if mode is not None: 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1428 parameter_schema['mode'] = mode 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1429 if field.alias is not None: 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1430 parameter_schema['alias'] = field.alias 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1431 else: 

1432 alias_generator = self._config_wrapper.alias_generator 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

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

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

1435 elif isinstance(alias_generator, Callable): 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1436 parameter_schema['alias'] = alias_generator(name) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1437 return parameter_schema 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1438 

1439 def _tuple_schema(self, tuple_type: Any) -> core_schema.CoreSchema: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

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

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

1442 typevars_map = get_standard_typevars_map(tuple_type) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1443 params = self._get_args_resolving_forward_refs(tuple_type) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1444 

1445 if typevars_map and params: 1445 ↛ 1446line 1445 didn't jump to line 1446 because the condition on line 1445 was never true1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

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

1447 

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

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

1450 if not params: 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1451 if tuple_type in TUPLE_TYPES: 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1452 return core_schema.tuple_schema([core_schema.any_schema()], variadic_item_index=0) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1453 else: 

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

1455 return core_schema.tuple_schema([]) 1acmpqyrzGHnsfgtuABCDIJbdovwExFKL

1456 elif params[-1] is Ellipsis: 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1457 if len(params) == 2: 1457 ↛ 1461line 1457 didn't jump to line 1461 because the condition on line 1457 was always true1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

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

1459 else: 

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

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

1462 elif len(params) == 1 and params[0] == (): 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

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

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

1465 return core_schema.tuple_schema([]) 1eiacmpnsklfgtuhjbdov

1466 else: 

1467 return core_schema.tuple_schema([self.generate_schema(param) for param in params]) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1468 

1469 def _type_schema(self) -> core_schema.CoreSchema: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1470 return core_schema.custom_error_schema( 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1471 core_schema.is_instance_schema(type), 

1472 custom_error_type='is_type', 

1473 custom_error_message='Input should be a type', 

1474 ) 

1475 

1476 def _union_is_subclass_schema(self, union_type: Any) -> core_schema.CoreSchema: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

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

1478 args = self._get_args_resolving_forward_refs(union_type, required=True) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

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

1480 

1481 def _subclass_schema(self, type_: Any) -> core_schema.CoreSchema: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

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

1483 type_param = self._get_first_arg_or_any(type_) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1484 if type_param == Any: 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1485 return self._type_schema() 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1486 elif isinstance(type_param, typing.TypeVar): 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1487 if type_param.__bound__: 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1488 if _typing_extra.origin_is_union(get_origin(type_param.__bound__)): 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1489 return self._union_is_subclass_schema(type_param.__bound__) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1490 return core_schema.is_subclass_schema(type_param.__bound__) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1491 elif type_param.__constraints__: 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1492 return core_schema.union_schema( 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

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

1494 ) 

1495 else: 

1496 return self._type_schema() 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1497 elif _typing_extra.origin_is_union(get_origin(type_param)): 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1498 return self._union_is_subclass_schema(type_param) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1499 else: 

1500 return core_schema.is_subclass_schema(type_param) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1501 

1502 def _sequence_schema(self, sequence_type: Any) -> core_schema.CoreSchema: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

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

1504 from ._std_types_schema import serialize_sequence_via_list 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1505 

1506 item_type = self._get_first_arg_or_any(sequence_type) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1507 item_type_schema = self.generate_schema(item_type) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1508 list_schema = core_schema.list_schema(item_type_schema) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1509 

1510 python_schema = core_schema.is_instance_schema(typing.Sequence, cls_repr='Sequence') 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1511 if item_type != Any: 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1512 from ._validators import sequence_validator 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1513 

1514 python_schema = core_schema.chain_schema( 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

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

1516 ) 

1517 

1518 serialization = core_schema.wrap_serializer_function_ser_schema( 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1519 serialize_sequence_via_list, schema=item_type_schema, info_arg=True 

1520 ) 

1521 return core_schema.json_or_python_schema( 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1522 json_schema=list_schema, python_schema=python_schema, serialization=serialization 

1523 ) 

1524 

1525 def _iterable_schema(self, type_: Any) -> core_schema.GeneratorSchema: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

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

1527 item_type = self._get_first_arg_or_any(type_) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1528 

1529 return core_schema.generator_schema(self.generate_schema(item_type)) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1530 

1531 def _pattern_schema(self, pattern_type: Any) -> core_schema.CoreSchema: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1532 from . import _validators 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1533 

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

1535 ser = core_schema.plain_serializer_function_ser_schema( 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

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

1537 ) 

1538 if pattern_type == typing.Pattern or pattern_type == re.Pattern: 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1539 # bare type 

1540 return core_schema.no_info_plain_validator_function( 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

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

1542 ) 

1543 

1544 param = self._get_args_resolving_forward_refs( 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1545 pattern_type, 

1546 required=True, 

1547 )[0] 

1548 if param is str: 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1549 return core_schema.no_info_plain_validator_function( 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

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

1551 ) 

1552 elif param is bytes: 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1553 return core_schema.no_info_plain_validator_function( 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

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

1555 ) 

1556 else: 

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

1558 

1559 def _hashable_schema(self) -> core_schema.CoreSchema: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1560 return core_schema.custom_error_schema( 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

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

1562 custom_error_type='is_hashable', 

1563 custom_error_message='Input should be hashable', 

1564 ) 

1565 

1566 def _dataclass_schema( 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

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

1568 ) -> core_schema.CoreSchema: 

1569 """Generate schema for a dataclass.""" 

1570 with self.model_type_stack.push(dataclass), self.defs.get_schema_or_ref(dataclass) as ( 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1571 dataclass_ref, 

1572 maybe_schema, 

1573 ): 

1574 if maybe_schema is not None: 1574 ↛ 1575line 1574 didn't jump to line 1575 because the condition on line 1574 was never true1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1575 return maybe_schema 

1576 

1577 typevars_map = get_standard_typevars_map(dataclass) 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1578 if origin is not None: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1579 dataclass = origin 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1580 

1581 with ExitStack() as dataclass_bases_stack: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

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

1583 for dataclass_base in dataclass.__mro__: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1584 if dataclasses.is_dataclass(dataclass_base): 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1585 dataclass_bases_stack.enter_context(self._types_namespace_stack.push(dataclass_base)) 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1586 

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

1588 config = None 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1589 for dataclass_base in reversed(dataclass.__mro__): 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1590 if dataclasses.is_dataclass(dataclass_base): 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1591 config = getattr(dataclass_base, '__pydantic_config__', None) 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1592 dataclass_bases_stack.enter_context(self._config_wrapper_stack.push(config)) 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1593 

1594 core_config = self._config_wrapper.core_config(dataclass) 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1595 

1596 self = self._current_generate_schema 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1597 

1598 from ..dataclasses import is_pydantic_dataclass 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1599 

1600 if is_pydantic_dataclass(dataclass): 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1601 fields = deepcopy(dataclass.__pydantic_fields__) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1602 if typevars_map: 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1603 for field in fields.values(): 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1604 field.apply_typevars_map(typevars_map, self._types_namespace) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1605 else: 

1606 fields = collect_dataclass_fields( 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1607 dataclass, 

1608 self._types_namespace, 

1609 typevars_map=typevars_map, 

1610 ) 

1611 

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

1613 if self._config_wrapper_stack.tail.extra == 'allow': 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

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

1615 for field_name, field in fields.items(): 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1616 if field.init is False: 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1617 raise PydanticUserError( 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

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

1619 f'This combination is not allowed.', 

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

1621 ) 

1622 

1623 decorators = dataclass.__dict__.get('__pydantic_decorators__') or DecoratorInfos.build(dataclass) 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

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

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

1626 args = sorted( 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

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

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

1629 ) 

1630 has_post_init = hasattr(dataclass, '__post_init__') 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1631 has_slots = hasattr(dataclass, '__slots__') 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1632 

1633 args_schema = core_schema.dataclass_args_schema( 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1634 dataclass.__name__, 

1635 args, 

1636 computed_fields=[ 

1637 self._computed_field_schema(d, decorators.field_serializers) 

1638 for d in decorators.computed_fields.values() 

1639 ], 

1640 collect_init_only=has_post_init, 

1641 ) 

1642 

1643 inner_schema = apply_validators(args_schema, decorators.root_validators.values(), None) 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1644 

1645 model_validators = decorators.model_validators.values() 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1646 inner_schema = apply_model_validators(inner_schema, model_validators, 'inner') 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1647 

1648 title = self._get_model_title_from_config(dataclass, ConfigWrapper(config)) 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1649 metadata = build_metadata_dict( 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1650 js_functions=[partial(modify_model_json_schema, cls=dataclass, title=title)] 

1651 ) 

1652 

1653 dc_schema = core_schema.dataclass_schema( 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1654 dataclass, 

1655 inner_schema, 

1656 post_init=has_post_init, 

1657 ref=dataclass_ref, 

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

1659 slots=has_slots, 

1660 config=core_config, 

1661 metadata=metadata, 

1662 ) 

1663 schema = self._apply_model_serializers(dc_schema, decorators.model_serializers.values()) 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1664 schema = apply_model_validators(schema, model_validators, 'outer') 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1665 self.defs.definitions[dataclass_ref] = schema 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1666 return core_schema.definition_reference_schema(dataclass_ref) 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1667 

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

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

1670 assert False, 'Unreachable' 1acnfgbd

1671 

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

1673 """Generate schema for a Callable. 

1674 

1675 TODO support functional validators once we support them in Config 

1676 """ 

1677 sig = signature(function) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1678 

1679 type_hints = _typing_extra.get_function_type_hints(function, types_namespace=self._types_namespace) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1680 

1681 mode_lookup: dict[_ParameterKind, Literal['positional_only', 'positional_or_keyword', 'keyword_only']] = { 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1682 Parameter.POSITIONAL_ONLY: 'positional_only', 

1683 Parameter.POSITIONAL_OR_KEYWORD: 'positional_or_keyword', 

1684 Parameter.KEYWORD_ONLY: 'keyword_only', 

1685 } 

1686 

1687 arguments_list: list[core_schema.ArgumentsParameter] = [] 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1688 var_args_schema: core_schema.CoreSchema | None = None 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1689 var_kwargs_schema: core_schema.CoreSchema | None = None 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1690 

1691 for name, p in sig.parameters.items(): 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1692 if p.annotation is sig.empty: 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1693 annotation = typing.cast(Any, Any) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1694 else: 

1695 annotation = type_hints[name] 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1696 

1697 parameter_mode = mode_lookup.get(p.kind) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1698 if parameter_mode is not None: 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1699 arg_schema = self._generate_parameter_schema(name, annotation, p.default, parameter_mode) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1700 arguments_list.append(arg_schema) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1701 elif p.kind == Parameter.VAR_POSITIONAL: 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1702 var_args_schema = self.generate_schema(annotation) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1703 else: 

1704 assert p.kind == Parameter.VAR_KEYWORD, p.kind 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1705 var_kwargs_schema = self.generate_schema(annotation) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1706 

1707 return_schema: core_schema.CoreSchema | None = None 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1708 config_wrapper = self._config_wrapper 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1709 if config_wrapper.validate_return: 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1710 return_hint = type_hints.get('return') 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1711 if return_hint is not None: 1711 ↛ 1714line 1711 didn't jump to line 1714 because the condition on line 1711 was always true1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1712 return_schema = self.generate_schema(return_hint) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1713 

1714 return core_schema.call_schema( 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1715 core_schema.arguments_schema( 

1716 arguments_list, 

1717 var_args_schema=var_args_schema, 

1718 var_kwargs_schema=var_kwargs_schema, 

1719 populate_by_name=config_wrapper.populate_by_name, 

1720 ), 

1721 function, 

1722 return_schema=return_schema, 

1723 ) 

1724 

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

1726 assert isinstance(typevar, typing.TypeVar) 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1727 

1728 bound = typevar.__bound__ 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1729 constraints = typevar.__constraints__ 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1730 

1731 try: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1732 typevar_has_default = typevar.has_default() # type: ignore 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1733 except AttributeError: 1eiacmpqyrznsklfgtuABCDMNOPQRSTUhjbdovwExF

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

1735 typevar_has_default = getattr(typevar, '__default__', None) is not None 1eiacmpqyrznsklfgtuABCDMNOPQRSTUhjbdovwExF

1736 

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

1738 raise NotImplementedError( 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

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

1740 ) 

1741 

1742 if typevar_has_default: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1743 return self.generate_schema(typevar.__default__) # type: ignore 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1744 elif constraints: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

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

1746 elif bound: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1747 schema = self.generate_schema(bound) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1748 schema['serialization'] = core_schema.wrap_serializer_function_ser_schema( 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

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

1750 ) 

1751 return schema 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1752 else: 

1753 return core_schema.any_schema() 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1754 

1755 def _computed_field_schema( 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1756 self, 

1757 d: Decorator[ComputedFieldInfo], 

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

1759 ) -> core_schema.ComputedField: 

1760 try: 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1761 return_type = _decorators.get_function_return_type(d.func, d.info.return_type, self._types_namespace) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1762 except NameError as e: 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1763 raise PydanticUndefinedAnnotation.from_name_error(e) from e 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1764 if return_type is PydanticUndefined: 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1765 raise PydanticUserError( 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

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

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

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

1769 ) 

1770 

1771 return_type = replace_types(return_type, self._typevars_map) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

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

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

1774 d.info = dataclasses.replace(d.info, return_type=return_type) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1775 return_type_schema = self.generate_schema(return_type) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1776 # Apply serializers to computed field if there exist 

1777 return_type_schema = self._apply_field_serializers( 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1778 return_type_schema, 

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

1780 computed_field=True, 

1781 ) 

1782 

1783 alias_generator = self._config_wrapper.alias_generator 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1784 if alias_generator is not None: 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1785 self._apply_alias_generator_to_computed_field_info( 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

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

1787 ) 

1788 self._apply_field_title_generator_to_field_info(self._config_wrapper, d.info, d.cls_var_name) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1789 

1790 def set_computed_field_metadata(schema: CoreSchemaOrField, handler: GetJsonSchemaHandler) -> JsonSchemaValue: 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1791 json_schema = handler(schema) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1792 

1793 json_schema['readOnly'] = True 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1794 

1795 title = d.info.title 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1796 if title is not None: 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1797 json_schema['title'] = title 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1798 

1799 description = d.info.description 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1800 if description is not None: 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1801 json_schema['description'] = description 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1802 

1803 if d.info.deprecated or d.info.deprecated == '': 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1804 json_schema['deprecated'] = True 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1805 

1806 examples = d.info.examples 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1807 if examples is not None: 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1808 json_schema['examples'] = to_jsonable_python(examples) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1809 

1810 json_schema_extra = d.info.json_schema_extra 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1811 if json_schema_extra is not None: 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1812 add_json_schema_extra(json_schema, json_schema_extra) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1813 

1814 return json_schema 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1815 

1816 metadata = build_metadata_dict(js_annotation_functions=[set_computed_field_metadata]) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1817 return core_schema.computed_field( 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

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

1819 ) 

1820 

1821 def _annotated_schema(self, annotated_type: Any) -> core_schema.CoreSchema: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

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

1823 from ..fields import FieldInfo 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1824 

1825 source_type, *annotations = self._get_args_resolving_forward_refs( 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1826 annotated_type, 

1827 required=True, 

1828 ) 

1829 schema = self._apply_annotations(source_type, annotations) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

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

1831 # even if there are function validators involved 

1832 for annotation in annotations: 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1833 if isinstance(annotation, FieldInfo): 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1834 schema = wrap_default(annotation, schema) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1835 return schema 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1836 

1837 def _get_prepare_pydantic_annotations_for_known_type( 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

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

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

1840 from ._std_types_schema import PREPARE_METHODS 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1841 

1842 # Check for hashability 

1843 try: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1844 hash(obj) 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1845 except TypeError: 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

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

1847 return None 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1848 

1849 for gen in PREPARE_METHODS: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1850 res = gen(obj, annotations, self._config_wrapper.config_dict) 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1851 if res is not None: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1852 return res 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1853 

1854 return None 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1855 

1856 def _apply_annotations( 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1857 self, 

1858 source_type: Any, 

1859 annotations: list[Any], 

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

1861 ) -> CoreSchema: 

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

1863 

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

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

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

1867 """ 

1868 annotations = list(_known_annotated_metadata.expand_grouped_metadata(annotations)) 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1869 res = self._get_prepare_pydantic_annotations_for_known_type(source_type, tuple(annotations)) 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1870 if res is not None: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1871 source_type, annotations = res 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1872 

1873 pydantic_js_annotation_functions: list[GetJsonSchemaFunction] = [] 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1874 

1875 def inner_handler(obj: Any) -> CoreSchema: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1876 from_property = self._generate_schema_from_property(obj, source_type) 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1877 if from_property is None: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1878 schema = self._generate_schema_inner(obj) 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1879 else: 

1880 schema = from_property 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1881 metadata_js_function = _extract_get_pydantic_json_schema(obj, schema) 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1882 if metadata_js_function is not None: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1883 metadata_schema = resolve_original_schema(schema, self.defs.definitions) 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1884 if metadata_schema is not None: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1885 self._add_js_function(metadata_schema, metadata_js_function) 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1886 return transform_inner_schema(schema) 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1887 

1888 get_inner_schema = CallbackGetCoreSchemaHandler(inner_handler, self) 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1889 

1890 for annotation in annotations: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1891 if annotation is None: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1892 continue 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1893 get_inner_schema = self._get_wrapped_inner_schema( 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1894 get_inner_schema, annotation, pydantic_js_annotation_functions 

1895 ) 

1896 

1897 schema = get_inner_schema(source_type) 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1898 if pydantic_js_annotation_functions: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1899 metadata = CoreMetadataHandler(schema).metadata 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1900 metadata.setdefault('pydantic_js_annotation_functions', []).extend(pydantic_js_annotation_functions) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1901 return _add_custom_serialization_from_json_encoders(self._config_wrapper.json_encoders, source_type, schema) 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1902 

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

1904 from ..fields import FieldInfo 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1905 

1906 if isinstance(metadata, FieldInfo): 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1907 for field_metadata in metadata.metadata: 1907 ↛ 1908line 1907 didn't jump to line 1908 because the loop on line 1907 never started1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1908 schema = self._apply_single_annotation(schema, field_metadata) 

1909 

1910 if metadata.discriminator is not None: 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1911 schema = self._apply_discriminator_to_union(schema, metadata.discriminator) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1912 return schema 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1913 

1914 if schema['type'] == 'nullable': 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

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

1916 inner = schema.get('schema', core_schema.any_schema()) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1917 inner = self._apply_single_annotation(inner, metadata) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1918 if inner: 1918 ↛ 1920line 1918 didn't jump to line 1920 because the condition on line 1918 was always true1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1919 schema['schema'] = inner 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1920 return schema 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1921 

1922 original_schema = schema 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1923 ref = schema.get('ref', None) 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1924 if ref is not None: 1924 ↛ 1925line 1924 didn't jump to line 1925 because the condition on line 1924 was never true1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1925 schema = schema.copy() 

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

1927 if new_ref in self.defs.definitions: 

1928 return self.defs.definitions[new_ref] 

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

1930 elif schema['type'] == 'definition-ref': 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1931 ref = schema['schema_ref'] 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1932 if ref in self.defs.definitions: 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1933 schema = self.defs.definitions[ref].copy() 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1934 new_ref = ref + f'_{repr(metadata)}' 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1935 if new_ref in self.defs.definitions: 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1936 return self.defs.definitions[new_ref] 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1937 schema['ref'] = new_ref # type: ignore 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1938 

1939 maybe_updated_schema = _known_annotated_metadata.apply_known_metadata(metadata, schema.copy()) 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1940 

1941 if maybe_updated_schema is not None: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1942 return maybe_updated_schema 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1943 return original_schema 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1944 

1945 def _apply_single_annotation_json_schema( 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

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

1947 ) -> core_schema.CoreSchema: 

1948 from ..fields import FieldInfo 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1949 

1950 if isinstance(metadata, FieldInfo): 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1951 for field_metadata in metadata.metadata: 1951 ↛ 1952line 1951 didn't jump to line 1952 because the loop on line 1951 never started1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1952 schema = self._apply_single_annotation_json_schema(schema, field_metadata) 

1953 json_schema_update: JsonSchemaValue = {} 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1954 if metadata.title: 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1955 json_schema_update['title'] = metadata.title 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1956 if metadata.description: 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1957 json_schema_update['description'] = metadata.description 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1958 if metadata.examples: 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1959 json_schema_update['examples'] = to_jsonable_python(metadata.examples) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1960 

1961 json_schema_extra = metadata.json_schema_extra 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1962 if json_schema_update or json_schema_extra: 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1963 CoreMetadataHandler(schema).metadata.setdefault('pydantic_js_annotation_functions', []).append( 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1964 get_json_schema_update_func(json_schema_update, json_schema_extra) 

1965 ) 

1966 return schema 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1967 

1968 def _get_wrapped_inner_schema( 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1969 self, 

1970 get_inner_schema: GetCoreSchemaHandler, 

1971 annotation: Any, 

1972 pydantic_js_annotation_functions: list[GetJsonSchemaFunction], 

1973 ) -> CallbackGetCoreSchemaHandler: 

1974 metadata_get_schema: GetCoreSchemaFunction = getattr(annotation, '__get_pydantic_core_schema__', None) or ( 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1975 lambda source, handler: handler(source) 

1976 ) 

1977 

1978 def new_handler(source: Any) -> core_schema.CoreSchema: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1979 schema = metadata_get_schema(source, get_inner_schema) 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1980 schema = self._apply_single_annotation(schema, annotation) 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1981 schema = self._apply_single_annotation_json_schema(schema, annotation) 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1982 

1983 metadata_js_function = _extract_get_pydantic_json_schema(annotation, schema) 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1984 if metadata_js_function is not None: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1985 pydantic_js_annotation_functions.append(metadata_js_function) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1986 return schema 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1987 

1988 return CallbackGetCoreSchemaHandler(new_handler, self) 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1989 

1990 def _apply_field_serializers( 1eiacmpqyrzGHklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1991 self, 

1992 schema: core_schema.CoreSchema, 

1993 serializers: list[Decorator[FieldSerializerDecoratorInfo]], 

1994 computed_field: bool = False, 

1995 ) -> core_schema.CoreSchema: 

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

1997 if serializers: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

1998 schema = copy(schema) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

1999 if schema['type'] == 'definitions': 1999 ↛ 2000line 1999 didn't jump to line 2000 because the condition on line 1999 was never true1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

2000 inner_schema = schema['schema'] 

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

2002 return schema 

2003 else: 

2004 ref = typing.cast('str|None', schema.get('ref', None)) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

2005 if ref is not None: 2005 ↛ 2006line 2005 didn't jump to line 2006 because the condition on line 2005 was never true1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

2006 schema = core_schema.definition_reference_schema(ref) 

2007 

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

2009 serializer = serializers[-1] 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

2010 is_field_serializer, info_arg = inspect_field_serializer( 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

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

2012 ) 

2013 

2014 try: 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

2015 return_type = _decorators.get_function_return_type( 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

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

2017 ) 

2018 except NameError as e: 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

2019 raise PydanticUndefinedAnnotation.from_name_error(e) from e 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

2020 

2021 if return_type is PydanticUndefined: 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

2022 return_schema = None 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

2023 else: 

2024 return_schema = self.generate_schema(return_type) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

2025 

2026 if serializer.info.mode == 'wrap': 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

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

2028 serializer.func, 

2029 is_field_serializer=is_field_serializer, 

2030 info_arg=info_arg, 

2031 return_schema=return_schema, 

2032 when_used=serializer.info.when_used, 

2033 ) 

2034 else: 

2035 assert serializer.info.mode == 'plain' 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

2036 schema['serialization'] = core_schema.plain_serializer_function_ser_schema( 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

2037 serializer.func, 

2038 is_field_serializer=is_field_serializer, 

2039 info_arg=info_arg, 

2040 return_schema=return_schema, 

2041 when_used=serializer.info.when_used, 

2042 ) 

2043 return schema 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

2044 

2045 def _apply_model_serializers( 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

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

2047 ) -> core_schema.CoreSchema: 

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

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

2050 if serializers: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

2051 serializer = list(serializers)[-1] 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

2052 info_arg = inspect_model_serializer(serializer.func, serializer.info.mode) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

2053 

2054 try: 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

2055 return_type = _decorators.get_function_return_type( 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

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

2057 ) 

2058 except NameError as e: 

2059 raise PydanticUndefinedAnnotation.from_name_error(e) from e 

2060 if return_type is PydanticUndefined: 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

2061 return_schema = None 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

2062 else: 

2063 return_schema = self.generate_schema(return_type) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

2064 

2065 if serializer.info.mode == 'wrap': 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

2066 ser_schema: core_schema.SerSchema = core_schema.wrap_serializer_function_ser_schema( 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

2067 serializer.func, 

2068 info_arg=info_arg, 

2069 return_schema=return_schema, 

2070 when_used=serializer.info.when_used, 

2071 ) 

2072 else: 

2073 # plain 

2074 ser_schema = core_schema.plain_serializer_function_ser_schema( 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

2075 serializer.func, 

2076 info_arg=info_arg, 

2077 return_schema=return_schema, 

2078 when_used=serializer.info.when_used, 

2079 ) 

2080 schema['serialization'] = ser_schema 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

2081 if ref: 2081 ↛ 2083line 2081 didn't jump to line 2083 because the condition on line 2081 was always true1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

2082 schema['ref'] = ref # type: ignore 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

2083 return schema 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

2084 

2085 

2086_VALIDATOR_F_MATCH: Mapping[ 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

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

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

2089] = { 

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

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

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

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

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

2095 f, schema, field_name=field_name 

2096 ), 

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

2098 f, schema, field_name=field_name 

2099 ), 

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

2101 f, field_name=field_name 

2102 ), 

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

2104 f, schema, field_name=field_name 

2105 ), 

2106} 

2107 

2108 

2109def apply_validators( 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

2110 schema: core_schema.CoreSchema, 

2111 validators: Iterable[Decorator[RootValidatorDecoratorInfo]] 

2112 | Iterable[Decorator[ValidatorDecoratorInfo]] 

2113 | Iterable[Decorator[FieldValidatorDecoratorInfo]], 

2114 field_name: str | None, 

2115) -> core_schema.CoreSchema: 

2116 """Apply validators to a schema. 

2117 

2118 Args: 

2119 schema: The schema to apply validators on. 

2120 validators: An iterable of validators. 

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

2122 

2123 Returns: 

2124 The updated schema. 

2125 """ 

2126 for validator in validators: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

2127 info_arg = inspect_validator(validator.func, validator.info.mode) 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

2128 val_type = 'with-info' if info_arg else 'no-info' 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

2129 

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

2131 return schema 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

2132 

2133 

2134def _validators_require_validate_default(validators: Iterable[Decorator[ValidatorDecoratorInfo]]) -> bool: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

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

2136 

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

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

2139 

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

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

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

2143 """ 

2144 for validator in validators: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

2145 if validator.info.always: 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

2146 return True 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

2147 return False 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

2148 

2149 

2150def apply_model_validators( 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

2151 schema: core_schema.CoreSchema, 

2152 validators: Iterable[Decorator[ModelValidatorDecoratorInfo]], 

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

2154) -> core_schema.CoreSchema: 

2155 """Apply model validators to a schema. 

2156 

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

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

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

2160 

2161 Args: 

2162 schema: The schema to apply validators on. 

2163 validators: An iterable of validators. 

2164 mode: The validator mode. 

2165 

2166 Returns: 

2167 The updated schema. 

2168 """ 

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

2170 for validator in validators: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

2171 if mode == 'inner' and validator.info.mode != 'before': 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

2172 continue 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

2173 if mode == 'outer' and validator.info.mode == 'before': 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

2174 continue 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

2175 info_arg = inspect_validator(validator.func, validator.info.mode) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

2176 if validator.info.mode == 'wrap': 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

2177 if info_arg: 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

2178 schema = core_schema.with_info_wrap_validator_function(function=validator.func, schema=schema) 1rzGHCDIJxFKL

2179 else: 

2180 schema = core_schema.no_info_wrap_validator_function(function=validator.func, schema=schema) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

2181 elif validator.info.mode == 'before': 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

2182 if info_arg: 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

2183 schema = core_schema.with_info_before_validator_function(function=validator.func, schema=schema) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

2184 else: 

2185 schema = core_schema.no_info_before_validator_function(function=validator.func, schema=schema) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

2186 else: 

2187 assert validator.info.mode == 'after' 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

2188 if info_arg: 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

2189 schema = core_schema.with_info_after_validator_function(function=validator.func, schema=schema) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

2190 else: 

2191 schema = core_schema.no_info_after_validator_function(function=validator.func, schema=schema) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

2192 if ref: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

2193 schema['ref'] = ref # type: ignore 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

2194 return schema 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

2195 

2196 

2197def wrap_default(field_info: FieldInfo, schema: core_schema.CoreSchema) -> core_schema.CoreSchema: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

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

2199 

2200 Args: 

2201 field_info: The field info object. 

2202 schema: The schema to apply default on. 

2203 

2204 Returns: 

2205 Updated schema by default value or `default_factory`. 

2206 """ 

2207 if field_info.default_factory: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

2208 return core_schema.with_default_schema( 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

2209 schema, default_factory=field_info.default_factory, validate_default=field_info.validate_default 

2210 ) 

2211 elif field_info.default is not PydanticUndefined: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

2212 return core_schema.with_default_schema( 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

2213 schema, default=field_info.default, validate_default=field_info.validate_default 

2214 ) 

2215 else: 

2216 return schema 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

2217 

2218 

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

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

2221 js_modify_function = getattr(tp, '__get_pydantic_json_schema__', None) 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

2222 

2223 if hasattr(tp, '__modify_schema__'): 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

2224 from pydantic import BaseModel # circular reference 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

2225 

2226 has_custom_v2_modify_js_func = ( 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

2227 js_modify_function is not None 

2228 and BaseModel.__get_pydantic_json_schema__.__func__ # type: ignore 

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

2230 ) 

2231 

2232 if not has_custom_v2_modify_js_func: 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

2233 cls_name = getattr(tp, '__name__', None) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

2234 raise PydanticUserError( 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

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

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

2237 code='custom-json-schema', 

2238 ) 

2239 

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

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

2242 return _extract_get_pydantic_json_schema(tp.__origin__, schema) 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

2243 

2244 if js_modify_function is None: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

2245 return None 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

2246 

2247 return js_modify_function 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

2248 

2249 

2250def get_json_schema_update_func( 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

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

2252) -> GetJsonSchemaFunction: 

2253 def json_schema_update_func( 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

2254 core_schema_or_field: CoreSchemaOrField, handler: GetJsonSchemaHandler 

2255 ) -> JsonSchemaValue: 

2256 json_schema = {**handler(core_schema_or_field), **json_schema_update} 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

2257 add_json_schema_extra(json_schema, json_schema_extra) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

2258 return json_schema 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

2259 

2260 return json_schema_update_func 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

2261 

2262 

2263def add_json_schema_extra( 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

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

2265): 

2266 if isinstance(json_schema_extra, dict): 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

2267 json_schema.update(to_jsonable_python(json_schema_extra)) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

2268 elif callable(json_schema_extra): 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

2269 json_schema_extra(json_schema) 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

2270 

2271 

2272class _CommonField(TypedDict): 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

2273 schema: core_schema.CoreSchema 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

2274 validation_alias: str | list[str | int] | list[list[str | int]] | None 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

2275 serialization_alias: str | None 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

2276 serialization_exclude: bool | None 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

2277 frozen: bool | None 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

2278 metadata: dict[str, Any] 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

2279 

2280 

2281def _common_field( 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

2282 schema: core_schema.CoreSchema, 

2283 *, 

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

2285 serialization_alias: str | None = None, 

2286 serialization_exclude: bool | None = None, 

2287 frozen: bool | None = None, 

2288 metadata: Any = None, 

2289) -> _CommonField: 

2290 return { 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

2291 'schema': schema, 

2292 'validation_alias': validation_alias, 

2293 'serialization_alias': serialization_alias, 

2294 'serialization_exclude': serialization_exclude, 

2295 'frozen': frozen, 

2296 'metadata': metadata, 

2297 } 

2298 

2299 

2300class _Definitions: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

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

2302 

2303 def __init__(self) -> None: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

2304 self.seen: set[str] = set() 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

2305 self.definitions: dict[str, core_schema.CoreSchema] = {} 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

2306 

2307 @contextmanager 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

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

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

2310 

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

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

2313 

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

2315 not the actual definition itself. 

2316 

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

2318 This includes any recursive types. 

2319 

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

2321 

2322 - BaseModel 

2323 - Dataclasses 

2324 - TypedDict 

2325 - TypeAliasType 

2326 """ 

2327 ref = get_type_ref(tp) 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

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

2329 if ref in self.seen or ref in self.definitions: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

2330 yield (ref, core_schema.definition_reference_schema(ref)) 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

2331 else: 

2332 self.seen.add(ref) 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

2333 try: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

2334 yield (ref, None) 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

2335 finally: 

2336 self.seen.discard(ref) 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

2337 

2338 

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

2340 if schema['type'] == 'definition-ref': 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

2341 return definitions.get(schema['schema_ref'], None) 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

2342 elif schema['type'] == 'definitions': 2342 ↛ 2343line 2342 didn't jump to line 2343 because the condition on line 2342 was never true1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

2343 return schema['schema'] 

2344 else: 

2345 return schema 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

2346 

2347 

2348class _FieldNameStack: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

2349 __slots__ = ('_stack',) 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

2350 

2351 def __init__(self) -> None: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

2352 self._stack: list[str] = [] 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

2353 

2354 @contextmanager 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

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

2356 self._stack.append(field_name) 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

2357 yield 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

2358 self._stack.pop() 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

2359 

2360 def get(self) -> str | None: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

2361 if self._stack: 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

2362 return self._stack[-1] 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

2363 else: 

2364 return None 1eamqrhbowx

2365 

2366 

2367class _ModelTypeStack: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

2368 __slots__ = ('_stack',) 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

2369 

2370 def __init__(self) -> None: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

2371 self._stack: list[type] = [] 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

2372 

2373 @contextmanager 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

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

2375 self._stack.append(type_obj) 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

2376 yield 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

2377 self._stack.pop() 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

2378 

2379 def get(self) -> type | None: 1eiacmpqyrzGHnsklfgtuABCDIJMNOPQRSTUVhjbdovwExFKL

2380 if self._stack: 2380 ↛ 2383line 2380 didn't jump to line 2383 because the condition on line 2380 was always true1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

2381 return self._stack[-1] 1eiacmpqyrzGHnsklfgtuABCDIJhjbdovwExFKL

2382 else: 

2383 return None