Coverage for pydantic/main.py: 100.00%
502 statements
« prev ^ index » next coverage.py v7.6.1, created at 2024-08-15 13:26 +0000
« prev ^ index » next coverage.py v7.6.1, created at 2024-08-15 13:26 +0000
1import warnings 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
2from abc import ABCMeta 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
3from copy import deepcopy 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
4from enum import Enum 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
5from functools import partial 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
6from pathlib import Path 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
7from types import FunctionType, prepare_class, resolve_bases 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
8from typing import ( 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
9 TYPE_CHECKING,
10 AbstractSet,
11 Any,
12 Callable,
13 ClassVar,
14 Dict,
15 List,
16 Mapping,
17 Optional,
18 Tuple,
19 Type,
20 TypeVar,
21 Union,
22 cast,
23 no_type_check,
24 overload,
25)
27from typing_extensions import dataclass_transform 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
29from pydantic.class_validators import ValidatorGroup, extract_root_validators, extract_validators, inherit_validators 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
30from pydantic.config import BaseConfig, Extra, inherit_config, prepare_config 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
31from pydantic.error_wrappers import ErrorWrapper, ValidationError 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
32from pydantic.errors import ConfigError, DictError, ExtraError, MissingError 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
33from pydantic.fields import ( 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
34 MAPPING_LIKE_SHAPES,
35 Field,
36 ModelField,
37 ModelPrivateAttr,
38 PrivateAttr,
39 Undefined,
40 is_finalvar_with_default_val,
41)
42from pydantic.json import custom_pydantic_encoder, pydantic_encoder 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
43from pydantic.parse import Protocol, load_file, load_str_bytes 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
44from pydantic.schema import default_ref_template, model_schema 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
45from pydantic.types import PyObject, StrBytes 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
46from pydantic.typing import ( 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
47 AnyCallable,
48 get_args,
49 get_origin,
50 is_classvar,
51 is_namedtuple,
52 is_union,
53 resolve_annotations,
54 update_model_forward_refs,
55)
56from pydantic.utils import ( 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
57 DUNDER_ATTRIBUTES,
58 ROOT_KEY,
59 ClassAttribute,
60 GetterDict,
61 Representation,
62 ValueItems,
63 generate_model_signature,
64 is_valid_field,
65 is_valid_private_name,
66 lenient_issubclass,
67 sequence_like,
68 smart_deepcopy,
69 unique_list,
70 validate_field_name,
71)
73if TYPE_CHECKING: 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
74 from inspect import Signature
76 from pydantic.class_validators import ValidatorListDict
77 from pydantic.types import ModelOrDc
78 from pydantic.typing import (
79 AbstractSetIntStr,
80 AnyClassMethod,
81 CallableGenerator,
82 DictAny,
83 DictStrAny,
84 MappingIntStrAny,
85 ReprArgs,
86 SetStr,
87 TupleGenerator,
88 )
90 Model = TypeVar('Model', bound='BaseModel')
92__all__ = 'BaseModel', 'create_model', 'validate_model' 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
94_T = TypeVar('_T') 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
97def validate_custom_root_type(fields: Dict[str, ModelField]) -> None: 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
98 if len(fields) > 1: 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
99 raise ValueError(f'{ROOT_KEY} cannot be mixed with other fields') 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
102def generate_hash_function(frozen: bool) -> Optional[Callable[[Any], int]]: 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
103 def hash_function(self_: Any) -> int: 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
104 return hash(self_.__class__) + hash(tuple(self_.__dict__.values())) 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
106 return hash_function if frozen else None 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
109# If a field is of type `Callable`, its default value should be a function and cannot to ignored.
110ANNOTATED_FIELD_UNTOUCHED_TYPES: Tuple[Any, ...] = (property, type, classmethod, staticmethod) 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
111# When creating a `BaseModel` instance, we bypass all the methods, properties... added to the model
112UNTOUCHED_TYPES: Tuple[Any, ...] = (FunctionType,) + ANNOTATED_FIELD_UNTOUCHED_TYPES 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
113# Note `ModelMetaclass` refers to `BaseModel`, but is also used to *create* `BaseModel`, so we need to add this extra
114# (somewhat hacky) boolean to keep track of whether we've created the `BaseModel` class yet, and therefore whether it's
115# safe to refer to it. If it *hasn't* been created, we assume that the `__new__` call we're in the middle of is for
116# the `BaseModel` class, since that's defined immediately after the metaclass.
117_is_base_model_class_defined = False 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
120@dataclass_transform(kw_only_default=True, field_specifiers=(Field,)) 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
121class ModelMetaclass(ABCMeta): 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
122 @no_type_check # noqa C901 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
123 def __new__(mcs, name, bases, namespace, **kwargs): # noqa C901 1abcdefghyzijklmnopABEFGHPQRSTUIqrstuvwxCD
124 fields: Dict[str, ModelField] = {} 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
125 config = BaseConfig 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
126 validators: 'ValidatorListDict' = {} 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
128 pre_root_validators, post_root_validators = [], [] 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
129 private_attributes: Dict[str, ModelPrivateAttr] = {} 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
130 base_private_attributes: Dict[str, ModelPrivateAttr] = {} 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
131 slots: SetStr = namespace.get('__slots__', ()) 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
132 slots = {slots} if isinstance(slots, str) else set(slots) 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
133 class_vars: SetStr = set() 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
134 hash_func: Optional[Callable[[Any], int]] = None 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
136 for base in reversed(bases): 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
137 if _is_base_model_class_defined and issubclass(base, BaseModel) and base != BaseModel: 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
138 fields.update(smart_deepcopy(base.__fields__)) 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
139 config = inherit_config(base.__config__, config) 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
140 validators = inherit_validators(base.__validators__, validators) 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
141 pre_root_validators += base.__pre_root_validators__ 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
142 post_root_validators += base.__post_root_validators__ 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
143 base_private_attributes.update(base.__private_attributes__) 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
144 class_vars.update(base.__class_vars__) 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
145 hash_func = base.__hash__ 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
147 resolve_forward_refs = kwargs.pop('__resolve_forward_refs__', True) 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
148 allowed_config_kwargs: SetStr = { 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
149 key
150 for key in dir(config)
151 if not (key.startswith('__') and key.endswith('__')) # skip dunder methods and attributes
152 }
153 config_kwargs = {key: kwargs.pop(key) for key in kwargs.keys() & allowed_config_kwargs} 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
154 config_from_namespace = namespace.get('Config') 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
155 if config_kwargs and config_from_namespace: 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
156 raise TypeError('Specifying config in two places is ambiguous, use either Config attribute or class kwargs') 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
157 config = inherit_config(config_from_namespace, config, **config_kwargs) 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
159 validators = inherit_validators(extract_validators(namespace), validators) 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
160 vg = ValidatorGroup(validators) 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
162 for f in fields.values(): 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
163 f.set_config(config) 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
164 extra_validators = vg.get_validators(f.name) 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
165 if extra_validators: 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
166 f.class_validators.update(extra_validators) 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
167 # re-run prepare to add extra validators
168 f.populate_validators() 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
170 prepare_config(config, name) 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
172 untouched_types = ANNOTATED_FIELD_UNTOUCHED_TYPES 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
174 def is_untouched(v: Any) -> bool: 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
175 return isinstance(v, untouched_types) or v.__class__.__name__ == 'cython_function_or_method' 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
177 if (namespace.get('__module__'), namespace.get('__qualname__')) != ('pydantic.main', 'BaseModel'): 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
178 annotations = resolve_annotations(namespace.get('__annotations__', {}), namespace.get('__module__', None)) 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
179 # annotation only fields need to come first in fields
180 for ann_name, ann_type in annotations.items(): 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
181 if is_classvar(ann_type): 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
182 class_vars.add(ann_name) 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
183 elif is_finalvar_with_default_val(ann_type, namespace.get(ann_name, Undefined)): 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
184 class_vars.add(ann_name) 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
185 elif is_valid_field(ann_name): 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
186 validate_field_name(bases, ann_name) 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
187 value = namespace.get(ann_name, Undefined) 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
188 allowed_types = get_args(ann_type) if is_union(get_origin(ann_type)) else (ann_type,) 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
189 if ( 1abcdefghijklmnopEFGHPQRSTUIqrstuvwx
190 is_untouched(value)
191 and ann_type != PyObject
192 and not any(
193 lenient_issubclass(get_origin(allowed_type), Type) for allowed_type in allowed_types
194 )
195 ):
196 continue 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
197 fields[ann_name] = ModelField.infer( 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
198 name=ann_name,
199 value=value,
200 annotation=ann_type,
201 class_validators=vg.get_validators(ann_name),
202 config=config,
203 )
204 elif ann_name not in namespace and config.underscore_attrs_are_private: 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
205 private_attributes[ann_name] = PrivateAttr() 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
207 untouched_types = UNTOUCHED_TYPES + config.keep_untouched 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
208 for var_name, value in namespace.items(): 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
209 can_be_changed = var_name not in class_vars and not is_untouched(value) 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
210 if isinstance(value, ModelPrivateAttr): 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
211 if not is_valid_private_name(var_name): 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
212 raise NameError( 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
213 f'Private attributes "{var_name}" must not be a valid field name; '
214 f'Use sunder or dunder names, e. g. "_{var_name}" or "__{var_name}__"'
215 )
216 private_attributes[var_name] = value 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
217 elif config.underscore_attrs_are_private and is_valid_private_name(var_name) and can_be_changed: 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
218 private_attributes[var_name] = PrivateAttr(default=value) 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
219 elif is_valid_field(var_name) and var_name not in annotations and can_be_changed: 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
220 validate_field_name(bases, var_name) 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
221 inferred = ModelField.infer( 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
222 name=var_name,
223 value=value,
224 annotation=annotations.get(var_name, Undefined),
225 class_validators=vg.get_validators(var_name),
226 config=config,
227 )
228 if var_name in fields: 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
229 if lenient_issubclass(inferred.type_, fields[var_name].type_): 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
230 inferred.type_ = fields[var_name].type_ 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
231 else:
232 raise TypeError( 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
233 f'The type of {name}.{var_name} differs from the new default value; '
234 f'if you wish to change the type of this field, please use a type annotation'
235 )
236 fields[var_name] = inferred 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
238 _custom_root_type = ROOT_KEY in fields 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
239 if _custom_root_type: 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
240 validate_custom_root_type(fields) 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
241 vg.check_for_unused() 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
242 if config.json_encoders: 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
243 json_encoder = partial(custom_pydantic_encoder, config.json_encoders) 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
244 else:
245 json_encoder = pydantic_encoder 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
246 pre_rv_new, post_rv_new = extract_root_validators(namespace) 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
248 if hash_func is None: 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
249 hash_func = generate_hash_function(config.frozen) 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
251 exclude_from_namespace = fields | private_attributes.keys() | {'__slots__'} 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
252 new_namespace = { 1abcdefghyzijklmnopABPQRSTUqrstuvwxCD
253 '__config__': config,
254 '__fields__': fields,
255 '__exclude_fields__': {
256 name: field.field_info.exclude for name, field in fields.items() if field.field_info.exclude is not None
257 }
258 or None,
259 '__include_fields__': {
260 name: field.field_info.include for name, field in fields.items() if field.field_info.include is not None
261 }
262 or None,
263 '__validators__': vg.validators,
264 '__pre_root_validators__': unique_list(
265 pre_root_validators + pre_rv_new,
266 name_factory=lambda v: v.__name__,
267 ),
268 '__post_root_validators__': unique_list(
269 post_root_validators + post_rv_new,
270 name_factory=lambda skip_on_failure_and_v: skip_on_failure_and_v[1].__name__,
271 ),
272 '__schema_cache__': {},
273 '__json_encoder__': staticmethod(json_encoder),
274 '__custom_root_type__': _custom_root_type,
275 '__private_attributes__': {**base_private_attributes, **private_attributes},
276 '__slots__': slots | private_attributes.keys(),
277 '__hash__': hash_func,
278 '__class_vars__': class_vars,
279 **{n: v for n, v in namespace.items() if n not in exclude_from_namespace},
280 }
282 cls = super().__new__(mcs, name, bases, new_namespace, **kwargs) 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
283 # set __signature__ attr only for model class, but not for its instances
284 cls.__signature__ = ClassAttribute('__signature__', generate_model_signature(cls.__init__, fields, config)) 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
285 if resolve_forward_refs: 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
286 cls.__try_update_forward_refs__() 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
288 # preserve `__set_name__` protocol defined in https://peps.python.org/pep-0487
289 # for attributes not in `new_namespace` (e.g. private attributes)
290 for name, obj in namespace.items(): 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
291 if name not in new_namespace: 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
292 set_name = getattr(obj, '__set_name__', None) 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
293 if callable(set_name): 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
294 set_name(cls, name) 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
296 return cls 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
298 def __instancecheck__(self, instance: Any) -> bool: 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
299 """
300 Avoid calling ABC _abc_subclasscheck unless we're pretty sure.
302 See #3829 and python/cpython#92810
303 """
304 return hasattr(instance, '__fields__') and super().__instancecheck__(instance) 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
307object_setattr = object.__setattr__ 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
310class BaseModel(Representation, metaclass=ModelMetaclass): 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
311 if TYPE_CHECKING: 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
312 # populated by the metaclass, defined here to help IDEs only
313 __fields__: ClassVar[Dict[str, ModelField]] = {}
314 __include_fields__: ClassVar[Optional[Mapping[str, Any]]] = None
315 __exclude_fields__: ClassVar[Optional[Mapping[str, Any]]] = None
316 __validators__: ClassVar[Dict[str, AnyCallable]] = {}
317 __pre_root_validators__: ClassVar[List[AnyCallable]]
318 __post_root_validators__: ClassVar[List[Tuple[bool, AnyCallable]]]
319 __config__: ClassVar[Type[BaseConfig]] = BaseConfig
320 __json_encoder__: ClassVar[Callable[[Any], Any]] = lambda x: x
321 __schema_cache__: ClassVar['DictAny'] = {}
322 __custom_root_type__: ClassVar[bool] = False
323 __signature__: ClassVar['Signature']
324 __private_attributes__: ClassVar[Dict[str, ModelPrivateAttr]]
325 __class_vars__: ClassVar[SetStr]
326 __fields_set__: ClassVar[SetStr] = set()
328 Config = BaseConfig 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
329 __slots__ = ('__dict__', '__fields_set__') 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
330 __doc__ = '' # Null out the Representation docstring 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
332 def __init__(__pydantic_self__, **data: Any) -> None: 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
333 """
334 Create a new model by parsing and validating input data from keyword arguments.
336 Raises ValidationError if the input data cannot be parsed to form a valid model.
337 """
338 # Uses something other than `self` the first arg to allow "self" as a settable attribute
339 values, fields_set, validation_error = validate_model(__pydantic_self__.__class__, data) 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
340 if validation_error: 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
341 raise validation_error 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
342 try: 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
343 object_setattr(__pydantic_self__, '__dict__', values) 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
344 except TypeError as e: 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
345 raise TypeError( 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
346 'Model values must be a dict; you may not have returned a dictionary from a root validator'
347 ) from e
348 object_setattr(__pydantic_self__, '__fields_set__', fields_set) 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
349 __pydantic_self__._init_private_attributes() 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
351 @no_type_check 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
352 def __setattr__(self, name, value): # noqa: C901 (ignore complexity) 1abcdefghyzijklmnopABEFGHPQRSTUIqrstuvwxCD
353 if name in self.__private_attributes__ or name in DUNDER_ATTRIBUTES: 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
354 return object_setattr(self, name, value) 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
356 if self.__config__.extra is not Extra.allow and name not in self.__fields__: 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
357 raise ValueError(f'"{self.__class__.__name__}" object has no field "{name}"') 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
358 elif not self.__config__.allow_mutation or self.__config__.frozen: 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
359 raise TypeError(f'"{self.__class__.__name__}" is immutable and does not support item assignment') 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
360 elif name in self.__fields__ and self.__fields__[name].final: 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
361 raise TypeError( 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
362 f'"{self.__class__.__name__}" object "{name}" field is final and does not support reassignment'
363 )
364 elif self.__config__.validate_assignment: 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
365 new_values = {**self.__dict__, name: value} 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
367 for validator in self.__pre_root_validators__: 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
368 try: 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
369 new_values = validator(self.__class__, new_values) 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
370 except (ValueError, TypeError, AssertionError) as exc: 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
371 raise ValidationError([ErrorWrapper(exc, loc=ROOT_KEY)], self.__class__) 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
373 known_field = self.__fields__.get(name, None) 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
374 if known_field: 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
375 # We want to
376 # - make sure validators are called without the current value for this field inside `values`
377 # - keep other values (e.g. submodels) untouched (using `BaseModel.dict()` will change them into dicts)
378 # - keep the order of the fields
379 if not known_field.field_info.allow_mutation: 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
380 raise TypeError(f'"{known_field.name}" has allow_mutation set to False and cannot be assigned') 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
381 dict_without_original_value = {k: v for k, v in self.__dict__.items() if k != name} 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
382 value, error_ = known_field.validate(value, dict_without_original_value, loc=name, cls=self.__class__) 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
383 if error_: 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
384 raise ValidationError([error_], self.__class__) 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
385 else:
386 new_values[name] = value 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
388 errors = [] 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
389 for skip_on_failure, validator in self.__post_root_validators__: 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
390 if skip_on_failure and errors: 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
391 continue 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
392 try: 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
393 new_values = validator(self.__class__, new_values) 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
394 except (ValueError, TypeError, AssertionError) as exc: 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
395 errors.append(ErrorWrapper(exc, loc=ROOT_KEY)) 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
396 if errors: 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
397 raise ValidationError(errors, self.__class__) 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
399 # update the whole __dict__ as other values than just `value`
400 # may be changed (e.g. with `root_validator`)
401 object_setattr(self, '__dict__', new_values) 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
402 else:
403 self.__dict__[name] = value 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
405 self.__fields_set__.add(name) 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
407 def __getstate__(self) -> 'DictAny': 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
408 private_attrs = ((k, getattr(self, k, Undefined)) for k in self.__private_attributes__) 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
409 return { 1abcdefghyzijklmnopABEFGHIqrstuvwxCD
410 '__dict__': self.__dict__,
411 '__fields_set__': self.__fields_set__,
412 '__private_attribute_values__': {k: v for k, v in private_attrs if v is not Undefined},
413 }
415 def __setstate__(self, state: 'DictAny') -> None: 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
416 object_setattr(self, '__dict__', state['__dict__']) 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
417 object_setattr(self, '__fields_set__', state['__fields_set__']) 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
418 for name, value in state.get('__private_attribute_values__', {}).items(): 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
419 object_setattr(self, name, value) 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
421 def _init_private_attributes(self) -> None: 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
422 for name, private_attr in self.__private_attributes__.items(): 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
423 default = private_attr.get_default() 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
424 if default is not Undefined: 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
425 object_setattr(self, name, default) 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
427 def dict( 1abcdefghyzijklmnopABEFGHPQRSTUIqrstuvwxCD
428 self,
429 *,
430 include: Optional[Union['AbstractSetIntStr', 'MappingIntStrAny']] = None,
431 exclude: Optional[Union['AbstractSetIntStr', 'MappingIntStrAny']] = None,
432 by_alias: bool = False,
433 skip_defaults: Optional[bool] = None,
434 exclude_unset: bool = False,
435 exclude_defaults: bool = False,
436 exclude_none: bool = False,
437 ) -> 'DictStrAny':
438 """
439 Generate a dictionary representation of the model, optionally specifying which fields to include or exclude.
441 """
442 if skip_defaults is not None: 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
443 warnings.warn( 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
444 f'{self.__class__.__name__}.dict(): "skip_defaults" is deprecated and replaced by "exclude_unset"',
445 DeprecationWarning,
446 )
447 exclude_unset = skip_defaults 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
449 return dict( 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
450 self._iter(
451 to_dict=True,
452 by_alias=by_alias,
453 include=include,
454 exclude=exclude,
455 exclude_unset=exclude_unset,
456 exclude_defaults=exclude_defaults,
457 exclude_none=exclude_none,
458 )
459 )
461 def json( 1abcdefghyzijklmnopABEFGHPQRSTUIqrstuvwxCD
462 self,
463 *,
464 include: Optional[Union['AbstractSetIntStr', 'MappingIntStrAny']] = None,
465 exclude: Optional[Union['AbstractSetIntStr', 'MappingIntStrAny']] = None,
466 by_alias: bool = False,
467 skip_defaults: Optional[bool] = None,
468 exclude_unset: bool = False,
469 exclude_defaults: bool = False,
470 exclude_none: bool = False,
471 encoder: Optional[Callable[[Any], Any]] = None,
472 models_as_dict: bool = True,
473 **dumps_kwargs: Any,
474 ) -> str:
475 """
476 Generate a JSON representation of the model, `include` and `exclude` arguments as per `dict()`.
478 `encoder` is an optional function to supply as `default` to json.dumps(), other arguments as per `json.dumps()`.
479 """
480 if skip_defaults is not None: 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
481 warnings.warn( 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
482 f'{self.__class__.__name__}.json(): "skip_defaults" is deprecated and replaced by "exclude_unset"',
483 DeprecationWarning,
484 )
485 exclude_unset = skip_defaults 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
486 encoder = cast(Callable[[Any], Any], encoder or self.__json_encoder__) 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
488 # We don't directly call `self.dict()`, which does exactly this with `to_dict=True`
489 # because we want to be able to keep raw `BaseModel` instances and not as `dict`.
490 # This allows users to write custom JSON encoders for given `BaseModel` classes.
491 data = dict( 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
492 self._iter(
493 to_dict=models_as_dict,
494 by_alias=by_alias,
495 include=include,
496 exclude=exclude,
497 exclude_unset=exclude_unset,
498 exclude_defaults=exclude_defaults,
499 exclude_none=exclude_none,
500 )
501 )
502 if self.__custom_root_type__: 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
503 data = data[ROOT_KEY] 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
504 return self.__config__.json_dumps(data, default=encoder, **dumps_kwargs) 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
506 @classmethod 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
507 def _enforce_dict_if_root(cls, obj: Any) -> Any: 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
508 if cls.__custom_root_type__ and ( 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
509 not (isinstance(obj, dict) and obj.keys() == {ROOT_KEY})
510 and not (isinstance(obj, BaseModel) and obj.__fields__.keys() == {ROOT_KEY})
511 or cls.__fields__[ROOT_KEY].shape in MAPPING_LIKE_SHAPES
512 ):
513 return {ROOT_KEY: obj} 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
514 else:
515 return obj 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
517 @classmethod 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
518 def parse_obj(cls: Type['Model'], obj: Any) -> 'Model': 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
519 obj = cls._enforce_dict_if_root(obj) 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
520 if not isinstance(obj, dict): 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
521 try: 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
522 obj = dict(obj) 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
523 except (TypeError, ValueError) as e: 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
524 exc = TypeError(f'{cls.__name__} expected dict not {obj.__class__.__name__}') 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
525 raise ValidationError([ErrorWrapper(exc, loc=ROOT_KEY)], cls) from e 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
526 return cls(**obj) 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
528 @classmethod 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
529 def parse_raw( 1abcdefghyzijklmnopABEFGHPQRSTUIqrstuvwxCD
530 cls: Type['Model'],
531 b: StrBytes,
532 *,
533 content_type: str = None,
534 encoding: str = 'utf8',
535 proto: Protocol = None,
536 allow_pickle: bool = False,
537 ) -> 'Model':
538 try: 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
539 obj = load_str_bytes( 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
540 b,
541 proto=proto,
542 content_type=content_type,
543 encoding=encoding,
544 allow_pickle=allow_pickle,
545 json_loads=cls.__config__.json_loads,
546 )
547 except (ValueError, TypeError, UnicodeDecodeError) as e: 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
548 raise ValidationError([ErrorWrapper(e, loc=ROOT_KEY)], cls) 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
549 return cls.parse_obj(obj) 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
551 @classmethod 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
552 def parse_file( 1abcdefghyzijklmnopABEFGHPQRSTUIqrstuvwxCD
553 cls: Type['Model'],
554 path: Union[str, Path],
555 *,
556 content_type: str = None,
557 encoding: str = 'utf8',
558 proto: Protocol = None,
559 allow_pickle: bool = False,
560 ) -> 'Model':
561 obj = load_file( 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
562 path,
563 proto=proto,
564 content_type=content_type,
565 encoding=encoding,
566 allow_pickle=allow_pickle,
567 json_loads=cls.__config__.json_loads,
568 )
569 return cls.parse_obj(obj) 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
571 @classmethod 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
572 def from_orm(cls: Type['Model'], obj: Any) -> 'Model': 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
573 if not cls.__config__.orm_mode: 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
574 raise ConfigError('You must have the config attribute orm_mode=True to use from_orm') 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
575 obj = {ROOT_KEY: obj} if cls.__custom_root_type__ else cls._decompose_class(obj) 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
576 m = cls.__new__(cls) 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
577 values, fields_set, validation_error = validate_model(cls, obj) 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
578 if validation_error: 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
579 raise validation_error 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
580 object_setattr(m, '__dict__', values) 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
581 object_setattr(m, '__fields_set__', fields_set) 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
582 m._init_private_attributes() 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
583 return m 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
585 @classmethod 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
586 def construct(cls: Type['Model'], _fields_set: Optional['SetStr'] = None, **values: Any) -> 'Model': 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
587 """
588 Creates a new model setting __dict__ and __fields_set__ from trusted or pre-validated data.
589 Default values are respected, but no other validation is performed.
590 Behaves as if `Config.extra = 'allow'` was set since it adds all passed values
591 """
592 m = cls.__new__(cls) 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
593 fields_values: Dict[str, Any] = {} 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
594 for name, field in cls.__fields__.items(): 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
595 if field.alt_alias and field.alias in values: 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
596 fields_values[name] = values[field.alias] 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
597 elif name in values: 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
598 fields_values[name] = values[name] 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
599 elif not field.required: 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
600 fields_values[name] = field.get_default() 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
601 fields_values.update(values) 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
602 object_setattr(m, '__dict__', fields_values) 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
603 if _fields_set is None: 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
604 _fields_set = set(values.keys()) 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
605 object_setattr(m, '__fields_set__', _fields_set) 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
606 m._init_private_attributes() 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
607 return m 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
609 def _copy_and_set_values(self: 'Model', values: 'DictStrAny', fields_set: 'SetStr', *, deep: bool) -> 'Model': 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
610 if deep: 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
611 # chances of having empty dict here are quite low for using smart_deepcopy
612 values = deepcopy(values) 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
614 cls = self.__class__ 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
615 m = cls.__new__(cls) 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
616 object_setattr(m, '__dict__', values) 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
617 object_setattr(m, '__fields_set__', fields_set) 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
618 for name in self.__private_attributes__: 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
619 value = getattr(self, name, Undefined) 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
620 if value is not Undefined: 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
621 if deep: 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
622 value = deepcopy(value) 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
623 object_setattr(m, name, value) 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
625 return m 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
627 def copy( 1abcdefghyzijklmnopABEFGHPQRSTUIqrstuvwxCD
628 self: 'Model',
629 *,
630 include: Optional[Union['AbstractSetIntStr', 'MappingIntStrAny']] = None,
631 exclude: Optional[Union['AbstractSetIntStr', 'MappingIntStrAny']] = None,
632 update: Optional['DictStrAny'] = None,
633 deep: bool = False,
634 ) -> 'Model':
635 """
636 Duplicate a model, optionally choose which fields to include, exclude and change.
638 :param include: fields to include in new model
639 :param exclude: fields to exclude from new model, as with values this takes precedence over include
640 :param update: values to change/add in the new model. Note: the data is not validated before creating
641 the new model: you should trust this data
642 :param deep: set to `True` to make a deep copy of the model
643 :return: new model instance
644 """
646 values = dict( 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
647 self._iter(to_dict=False, by_alias=False, include=include, exclude=exclude, exclude_unset=False),
648 **(update or {}),
649 )
651 # new `__fields_set__` can have unset optional fields with a set value in `update` kwarg
652 if update: 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
653 fields_set = self.__fields_set__ | update.keys() 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
654 else:
655 fields_set = set(self.__fields_set__) 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
657 return self._copy_and_set_values(values, fields_set, deep=deep) 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
659 @classmethod 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
660 def schema(cls, by_alias: bool = True, ref_template: str = default_ref_template) -> 'DictStrAny': 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
661 cached = cls.__schema_cache__.get((by_alias, ref_template)) 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
662 if cached is not None: 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
663 return cached 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
664 s = model_schema(cls, by_alias=by_alias, ref_template=ref_template) 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
665 cls.__schema_cache__[(by_alias, ref_template)] = s 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
666 return s 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
668 @classmethod 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
669 def schema_json( 1abcdefghyzijklmnopABEFGHPQRSTUIqrstuvwxCD
670 cls, *, by_alias: bool = True, ref_template: str = default_ref_template, **dumps_kwargs: Any
671 ) -> str:
672 from pydantic.json import pydantic_encoder 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
674 return cls.__config__.json_dumps( 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
675 cls.schema(by_alias=by_alias, ref_template=ref_template), default=pydantic_encoder, **dumps_kwargs
676 )
678 @classmethod 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
679 def __get_validators__(cls) -> 'CallableGenerator': 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
680 yield cls.validate 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
682 @classmethod 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
683 def validate(cls: Type['Model'], value: Any) -> 'Model': 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
684 if isinstance(value, cls): 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
685 copy_on_model_validation = cls.__config__.copy_on_model_validation 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
686 # whether to deep or shallow copy the model on validation, None means do not copy
687 deep_copy: Optional[bool] = None 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
688 if copy_on_model_validation not in {'deep', 'shallow', 'none'}: 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
689 # Warn about deprecated behavior
690 warnings.warn( 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
691 "`copy_on_model_validation` should be a string: 'deep', 'shallow' or 'none'", DeprecationWarning
692 )
693 if copy_on_model_validation: 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
694 deep_copy = False 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
696 if copy_on_model_validation == 'shallow': 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
697 # shallow copy
698 deep_copy = False 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
699 elif copy_on_model_validation == 'deep': 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
700 # deep copy
701 deep_copy = True 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
703 if deep_copy is None: 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
704 return value 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
705 else:
706 return value._copy_and_set_values(value.__dict__, value.__fields_set__, deep=deep_copy) 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
708 value = cls._enforce_dict_if_root(value) 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
710 if isinstance(value, dict): 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
711 return cls(**value) 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
712 elif cls.__config__.orm_mode: 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
713 return cls.from_orm(value) 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
714 else:
715 try: 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
716 value_as_dict = dict(value) 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
717 except (TypeError, ValueError) as e: 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
718 raise DictError() from e 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
719 return cls(**value_as_dict) 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
721 @classmethod 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
722 def _decompose_class(cls: Type['Model'], obj: Any) -> GetterDict: 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
723 if isinstance(obj, GetterDict): 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
724 return obj 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
725 return cls.__config__.getter_dict(obj) 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
727 @classmethod 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
728 @no_type_check 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
729 def _get_value( 1abcdefghyzijklmnopABEFGHPQRSTUIqrstuvwxCD
730 cls,
731 v: Any,
732 to_dict: bool,
733 by_alias: bool,
734 include: Optional[Union['AbstractSetIntStr', 'MappingIntStrAny']],
735 exclude: Optional[Union['AbstractSetIntStr', 'MappingIntStrAny']],
736 exclude_unset: bool,
737 exclude_defaults: bool,
738 exclude_none: bool,
739 ) -> Any:
740 if isinstance(v, BaseModel): 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
741 if to_dict: 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
742 v_dict = v.dict( 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
743 by_alias=by_alias,
744 exclude_unset=exclude_unset,
745 exclude_defaults=exclude_defaults,
746 include=include,
747 exclude=exclude,
748 exclude_none=exclude_none,
749 )
750 if ROOT_KEY in v_dict: 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
751 return v_dict[ROOT_KEY] 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
752 return v_dict 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
753 else:
754 return v.copy(include=include, exclude=exclude) 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
756 value_exclude = ValueItems(v, exclude) if exclude else None 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
757 value_include = ValueItems(v, include) if include else None 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
759 if isinstance(v, dict): 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
760 return { 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
761 k_: cls._get_value(
762 v_,
763 to_dict=to_dict,
764 by_alias=by_alias,
765 exclude_unset=exclude_unset,
766 exclude_defaults=exclude_defaults,
767 include=value_include and value_include.for_element(k_),
768 exclude=value_exclude and value_exclude.for_element(k_),
769 exclude_none=exclude_none,
770 )
771 for k_, v_ in v.items()
772 if (not value_exclude or not value_exclude.is_excluded(k_))
773 and (not value_include or value_include.is_included(k_))
774 }
776 elif sequence_like(v): 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
777 seq_args = ( 1abcdefghyzijklmnopABqrstuvwxCD
778 cls._get_value(
779 v_,
780 to_dict=to_dict,
781 by_alias=by_alias,
782 exclude_unset=exclude_unset,
783 exclude_defaults=exclude_defaults,
784 include=value_include and value_include.for_element(i),
785 exclude=value_exclude and value_exclude.for_element(i),
786 exclude_none=exclude_none,
787 )
788 for i, v_ in enumerate(v)
789 if (not value_exclude or not value_exclude.is_excluded(i))
790 and (not value_include or value_include.is_included(i))
791 )
793 return v.__class__(*seq_args) if is_namedtuple(v.__class__) else v.__class__(seq_args) 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
795 elif isinstance(v, Enum) and getattr(cls.Config, 'use_enum_values', False): 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
796 return v.value 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
798 else:
799 return v 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
801 @classmethod 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
802 def __try_update_forward_refs__(cls, **localns: Any) -> None: 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
803 """
804 Same as update_forward_refs but will not raise exception
805 when forward references are not defined.
806 """
807 update_model_forward_refs(cls, cls.__fields__.values(), cls.__config__.json_encoders, localns, (NameError,)) 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
809 @classmethod 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
810 def update_forward_refs(cls, **localns: Any) -> None: 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
811 """
812 Try to update ForwardRefs on fields based on this Model, globalns and localns.
813 """
814 update_model_forward_refs(cls, cls.__fields__.values(), cls.__config__.json_encoders, localns) 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
816 def __iter__(self) -> 'TupleGenerator': 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
817 """
818 so `dict(model)` works
819 """
820 yield from self.__dict__.items() 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
822 def _iter( 1abcdefghyzijklmnopABEFGHPQRSTUIqrstuvwxCD
823 self,
824 to_dict: bool = False,
825 by_alias: bool = False,
826 include: Optional[Union['AbstractSetIntStr', 'MappingIntStrAny']] = None,
827 exclude: Optional[Union['AbstractSetIntStr', 'MappingIntStrAny']] = None,
828 exclude_unset: bool = False,
829 exclude_defaults: bool = False,
830 exclude_none: bool = False,
831 ) -> 'TupleGenerator':
832 # Merge field set excludes with explicit exclude parameter with explicit overriding field set options.
833 # The extra "is not None" guards are not logically necessary but optimizes performance for the simple case.
834 if exclude is not None or self.__exclude_fields__ is not None: 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
835 exclude = ValueItems.merge(self.__exclude_fields__, exclude) 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
837 if include is not None or self.__include_fields__ is not None: 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
838 include = ValueItems.merge(self.__include_fields__, include, intersect=True) 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
840 allowed_keys = self._calculate_keys( 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
841 include=include, exclude=exclude, exclude_unset=exclude_unset # type: ignore
842 )
843 if allowed_keys is None and not (to_dict or by_alias or exclude_unset or exclude_defaults or exclude_none): 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
844 # huge boost for plain _iter()
845 yield from self.__dict__.items() 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
846 return 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
848 value_exclude = ValueItems(self, exclude) if exclude is not None else None 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
849 value_include = ValueItems(self, include) if include is not None else None 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
851 for field_key, v in self.__dict__.items(): 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
852 if (allowed_keys is not None and field_key not in allowed_keys) or (exclude_none and v is None): 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
853 continue 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
855 if exclude_defaults: 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
856 model_field = self.__fields__.get(field_key) 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
857 if not getattr(model_field, 'required', True) and getattr(model_field, 'default', _missing) == v: 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
858 continue 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
860 if by_alias and field_key in self.__fields__: 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
861 dict_key = self.__fields__[field_key].alias 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
862 else:
863 dict_key = field_key 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
865 if to_dict or value_include or value_exclude: 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
866 v = self._get_value( 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
867 v,
868 to_dict=to_dict,
869 by_alias=by_alias,
870 include=value_include and value_include.for_element(field_key),
871 exclude=value_exclude and value_exclude.for_element(field_key),
872 exclude_unset=exclude_unset,
873 exclude_defaults=exclude_defaults,
874 exclude_none=exclude_none,
875 )
876 yield dict_key, v 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
878 def _calculate_keys( 1abcdefghyzijklmnopABEFGHPQRSTUIqrstuvwxCD
879 self,
880 include: Optional['MappingIntStrAny'],
881 exclude: Optional['MappingIntStrAny'],
882 exclude_unset: bool,
883 update: Optional['DictStrAny'] = None,
884 ) -> Optional[AbstractSet[str]]:
885 if include is None and exclude is None and exclude_unset is False: 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
886 return None 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
888 keys: AbstractSet[str]
889 if exclude_unset: 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
890 keys = self.__fields_set__.copy() 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
891 else:
892 keys = self.__dict__.keys() 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
894 if include is not None: 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
895 keys &= include.keys() 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
897 if update: 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
898 keys -= update.keys() 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
900 if exclude: 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
901 keys -= {k for k, v in exclude.items() if ValueItems.is_true(v)} 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
903 return keys 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
905 def __eq__(self, other: Any) -> bool: 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
906 if isinstance(other, BaseModel): 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
907 return self.dict() == other.dict() 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
908 else:
909 return self.dict() == other 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
911 def __repr_args__(self) -> 'ReprArgs': 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
912 return [ 1abcdefghyzijklmnopABEFGHIqrstuvwxCD
913 (k, v)
914 for k, v in self.__dict__.items()
915 if k not in DUNDER_ATTRIBUTES and (k not in self.__fields__ or self.__fields__[k].field_info.repr)
916 ]
919_is_base_model_class_defined = True 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
922@overload 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
923def create_model( 1abcdefghyzijklmnopABEFGHPQRSTUIqrstuvwxCD
924 __model_name: str, 1abcdefghyzijklmnopABPQRSTUqrstuvwxCD
925 *,
926 __config__: Optional[Type[BaseConfig]] = None, 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
927 __base__: None = None, 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
928 __module__: str = __name__, 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
929 __validators__: Dict[str, 'AnyClassMethod'] = None, 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
930 __cls_kwargs__: Dict[str, Any] = None, 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
931 **field_definitions: Any, 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
932) -> Type['BaseModel']: 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
933 ...
936@overload 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
937def create_model( 1abcdefghyzijklmnopABEFGHPQRSTUIqrstuvwxCD
938 __model_name: str, 1abcdefghyzijklmnopABPQRSTUqrstuvwxCD
939 *,
940 __config__: Optional[Type[BaseConfig]] = None, 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
941 __base__: Union[Type['Model'], Tuple[Type['Model'], ...]], 1abcdefghyzijklmnopABEFGHPQRSTUIqrstuvwxCD
942 __module__: str = __name__, 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
943 __validators__: Dict[str, 'AnyClassMethod'] = None, 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
944 __cls_kwargs__: Dict[str, Any] = None, 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
945 **field_definitions: Any, 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
946) -> Type['Model']: 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
947 ...
950def create_model( 1abcdefghyzijklmnopABEFGHPQRSTUIqrstuvwxCD
951 __model_name: str,
952 *,
953 __config__: Optional[Type[BaseConfig]] = None,
954 __base__: Union[None, Type['Model'], Tuple[Type['Model'], ...]] = None,
955 __module__: str = __name__,
956 __validators__: Dict[str, 'AnyClassMethod'] = None,
957 __cls_kwargs__: Dict[str, Any] = None,
958 __slots__: Optional[Tuple[str, ...]] = None,
959 **field_definitions: Any,
960) -> Type['Model']:
961 """
962 Dynamically create a model.
963 :param __model_name: name of the created model
964 :param __config__: config class to use for the new model
965 :param __base__: base class for the new model to inherit from
966 :param __module__: module of the created model
967 :param __validators__: a dict of method names and @validator class methods
968 :param __cls_kwargs__: a dict for class creation
969 :param __slots__: Deprecated, `__slots__` should not be passed to `create_model`
970 :param field_definitions: fields of the model (or extra fields if a base is supplied)
971 in the format `<name>=(<type>, <default default>)` or `<name>=<default value>, e.g.
972 `foobar=(str, ...)` or `foobar=123`, or, for complex use-cases, in the format
973 `<name>=<Field>` or `<name>=(<type>, <FieldInfo>)`, e.g.
974 `foo=Field(datetime, default_factory=datetime.utcnow, alias='bar')` or
975 `foo=(str, FieldInfo(title='Foo'))`
976 """
977 if __slots__ is not None: 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
978 # __slots__ will be ignored from here on
979 warnings.warn('__slots__ should not be passed to create_model', RuntimeWarning) 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
981 if __base__ is not None: 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
982 if __config__ is not None: 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
983 raise ConfigError('to avoid confusion __config__ and __base__ cannot be used together') 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
984 if not isinstance(__base__, tuple): 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
985 __base__ = (__base__,) 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
986 else:
987 __base__ = (cast(Type['Model'], BaseModel),) 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
989 __cls_kwargs__ = __cls_kwargs__ or {} 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
991 fields = {} 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
992 annotations = {} 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
994 for f_name, f_def in field_definitions.items(): 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
995 if not is_valid_field(f_name): 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
996 warnings.warn(f'fields may not start with an underscore, ignoring "{f_name}"', RuntimeWarning) 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
997 if isinstance(f_def, tuple): 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
998 try: 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
999 f_annotation, f_value = f_def 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
1000 except ValueError as e: 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
1001 raise ConfigError( 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
1002 'field definitions should either be a tuple of (<type>, <default>) or just a '
1003 'default value, unfortunately this means tuples as '
1004 'default values are not allowed'
1005 ) from e
1006 else:
1007 f_annotation, f_value = None, f_def 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
1009 if f_annotation: 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
1010 annotations[f_name] = f_annotation 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
1011 fields[f_name] = f_value 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
1013 namespace: 'DictStrAny' = {'__annotations__': annotations, '__module__': __module__} 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
1014 if __validators__: 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
1015 namespace.update(__validators__) 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
1016 namespace.update(fields) 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
1017 if __config__: 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
1018 namespace['Config'] = inherit_config(__config__, BaseConfig) 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
1019 resolved_bases = resolve_bases(__base__) 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
1020 meta, ns, kwds = prepare_class(__model_name, resolved_bases, kwds=__cls_kwargs__) 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
1021 if resolved_bases is not __base__: 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
1022 ns['__orig_bases__'] = __base__ 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
1023 namespace.update(ns) 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
1024 return meta(__model_name, resolved_bases, namespace, **kwds) 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
1027_missing = object() 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
1030def validate_model( # noqa: C901 (ignore complexity) 1abcdefghyzijklmnopABEFGHPQRSTUIqrstuvwxCD
1031 model: Type[BaseModel], input_data: 'DictStrAny', cls: 'ModelOrDc' = None
1032) -> Tuple['DictStrAny', 'SetStr', Optional[ValidationError]]:
1033 """
1034 validate data against a model.
1035 """
1036 values = {} 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
1037 errors = [] 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
1038 # input_data names, possibly alias
1039 names_used = set() 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
1040 # field names, never aliases
1041 fields_set = set() 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
1042 config = model.__config__ 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
1043 check_extra = config.extra is not Extra.ignore 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
1044 cls_ = cls or model 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
1046 for validator in model.__pre_root_validators__: 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
1047 try: 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
1048 input_data = validator(cls_, input_data) 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
1049 except (ValueError, TypeError, AssertionError) as exc: 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
1050 return {}, set(), ValidationError([ErrorWrapper(exc, loc=ROOT_KEY)], cls_) 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
1052 for name, field in model.__fields__.items(): 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
1053 value = input_data.get(field.alias, _missing) 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
1054 using_name = False 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
1055 if value is _missing and config.allow_population_by_field_name and field.alt_alias: 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
1056 value = input_data.get(field.name, _missing) 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
1057 using_name = True 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
1059 if value is _missing: 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
1060 if field.required: 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
1061 errors.append(ErrorWrapper(MissingError(), loc=field.alias)) 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
1062 continue 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
1064 value = field.get_default() 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
1066 if not config.validate_all and not field.validate_always: 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
1067 values[name] = value 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
1068 continue 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
1069 else:
1070 fields_set.add(name) 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
1071 if check_extra: 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
1072 names_used.add(field.name if using_name else field.alias) 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
1074 v_, errors_ = field.validate(value, values, loc=field.alias, cls=cls_) 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
1075 if isinstance(errors_, ErrorWrapper): 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
1076 errors.append(errors_) 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
1077 elif isinstance(errors_, list): 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
1078 errors.extend(errors_) 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
1079 else:
1080 values[name] = v_ 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
1082 if check_extra: 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
1083 if isinstance(input_data, GetterDict): 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
1084 extra = input_data.extra_keys() - names_used 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
1085 else:
1086 extra = input_data.keys() - names_used 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
1087 if extra: 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
1088 fields_set |= extra 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
1089 if config.extra is Extra.allow: 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
1090 for f in extra: 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
1091 values[f] = input_data[f] 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
1092 else:
1093 for f in sorted(extra): 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
1094 errors.append(ErrorWrapper(ExtraError(), loc=f)) 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
1096 for skip_on_failure, validator in model.__post_root_validators__: 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
1097 if skip_on_failure and errors: 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
1098 continue 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
1099 try: 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
1100 values = validator(cls_, values) 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
1101 except (ValueError, TypeError, AssertionError) as exc: 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
1102 errors.append(ErrorWrapper(exc, loc=ROOT_KEY)) 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
1104 if errors: 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD
1105 return values, fields_set, ValidationError(errors, cls_) 1JKabcdefghyzLMijklmnopABEFGHINOqrstuvwxCD
1106 else:
1107 return values, fields_set, None 1JKabcdefghyzLMijklmnopABEFGHPQRSTUINOqrstuvwxCD