Nie możesz wybrać więcej, niż 25 tematów Tematy muszą się zaczynać od litery lub cyfry, mogą zawierać myślniki ('-') i mogą mieć do 35 znaków.
 
 
 
 

1056 wiersze
40 KiB

  1. import warnings
  2. from abc import ABCMeta
  3. from copy import deepcopy
  4. from enum import Enum
  5. from functools import partial
  6. from pathlib import Path
  7. from types import FunctionType
  8. from typing import (
  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. )
  26. from .class_validators import ValidatorGroup, extract_root_validators, extract_validators, inherit_validators
  27. from .config import BaseConfig, Extra, inherit_config, prepare_config
  28. from .error_wrappers import ErrorWrapper, ValidationError
  29. from .errors import ConfigError, DictError, ExtraError, MissingError
  30. from .fields import MAPPING_LIKE_SHAPES, Field, FieldInfo, ModelField, ModelPrivateAttr, PrivateAttr, Undefined
  31. from .json import custom_pydantic_encoder, pydantic_encoder
  32. from .parse import Protocol, load_file, load_str_bytes
  33. from .schema import default_ref_template, model_schema
  34. from .types import PyObject, StrBytes
  35. from .typing import (
  36. AnyCallable,
  37. get_args,
  38. get_origin,
  39. is_classvar,
  40. is_namedtuple,
  41. is_union,
  42. resolve_annotations,
  43. update_model_forward_refs,
  44. )
  45. from .utils import (
  46. ROOT_KEY,
  47. ClassAttribute,
  48. GetterDict,
  49. Representation,
  50. ValueItems,
  51. generate_model_signature,
  52. is_valid_field,
  53. is_valid_private_name,
  54. lenient_issubclass,
  55. sequence_like,
  56. smart_deepcopy,
  57. unique_list,
  58. validate_field_name,
  59. )
  60. if TYPE_CHECKING:
  61. from inspect import Signature
  62. from .class_validators import ValidatorListDict
  63. from .types import ModelOrDc
  64. from .typing import (
  65. AbstractSetIntStr,
  66. AnyClassMethod,
  67. CallableGenerator,
  68. DictAny,
  69. DictStrAny,
  70. MappingIntStrAny,
  71. ReprArgs,
  72. SetStr,
  73. TupleGenerator,
  74. )
  75. Model = TypeVar('Model', bound='BaseModel')
  76. try:
  77. import cython # type: ignore
  78. except ImportError:
  79. compiled: bool = False
  80. else: # pragma: no cover
  81. try:
  82. compiled = cython.compiled
  83. except AttributeError:
  84. compiled = False
  85. __all__ = 'BaseModel', 'compiled', 'create_model', 'validate_model'
  86. _T = TypeVar('_T')
  87. def __dataclass_transform__(
  88. *,
  89. eq_default: bool = True,
  90. order_default: bool = False,
  91. kw_only_default: bool = False,
  92. field_descriptors: Tuple[Union[type, Callable[..., Any]], ...] = (()),
  93. ) -> Callable[[_T], _T]:
  94. return lambda a: a
  95. def validate_custom_root_type(fields: Dict[str, ModelField]) -> None:
  96. if len(fields) > 1:
  97. raise ValueError(f'{ROOT_KEY} cannot be mixed with other fields')
  98. def generate_hash_function(frozen: bool) -> Optional[Callable[[Any], int]]:
  99. def hash_function(self_: Any) -> int:
  100. return hash(self_.__class__) + hash(tuple(self_.__dict__.values()))
  101. return hash_function if frozen else None
  102. # If a field is of type `Callable`, its default value should be a function and cannot to ignored.
  103. ANNOTATED_FIELD_UNTOUCHED_TYPES: Tuple[Any, ...] = (property, type, classmethod, staticmethod)
  104. # When creating a `BaseModel` instance, we bypass all the methods, properties... added to the model
  105. UNTOUCHED_TYPES: Tuple[Any, ...] = (FunctionType,) + ANNOTATED_FIELD_UNTOUCHED_TYPES
  106. # Note `ModelMetaclass` refers to `BaseModel`, but is also used to *create* `BaseModel`, so we need to add this extra
  107. # (somewhat hacky) boolean to keep track of whether we've created the `BaseModel` class yet, and therefore whether it's
  108. # 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
  109. # the `BaseModel` class, since that's defined immediately after the metaclass.
  110. _is_base_model_class_defined = False
  111. @__dataclass_transform__(kw_only_default=True, field_descriptors=(Field, FieldInfo))
  112. class ModelMetaclass(ABCMeta):
  113. @no_type_check # noqa C901
  114. def __new__(mcs, name, bases, namespace, **kwargs): # noqa C901
  115. fields: Dict[str, ModelField] = {}
  116. config = BaseConfig
  117. validators: 'ValidatorListDict' = {}
  118. pre_root_validators, post_root_validators = [], []
  119. private_attributes: Dict[str, ModelPrivateAttr] = {}
  120. base_private_attributes: Dict[str, ModelPrivateAttr] = {}
  121. slots: SetStr = namespace.get('__slots__', ())
  122. slots = {slots} if isinstance(slots, str) else set(slots)
  123. class_vars: SetStr = set()
  124. hash_func: Optional[Callable[[Any], int]] = None
  125. for base in reversed(bases):
  126. if _is_base_model_class_defined and issubclass(base, BaseModel) and base != BaseModel:
  127. fields.update(smart_deepcopy(base.__fields__))
  128. config = inherit_config(base.__config__, config)
  129. validators = inherit_validators(base.__validators__, validators)
  130. pre_root_validators += base.__pre_root_validators__
  131. post_root_validators += base.__post_root_validators__
  132. base_private_attributes.update(base.__private_attributes__)
  133. class_vars.update(base.__class_vars__)
  134. hash_func = base.__hash__
  135. allowed_config_kwargs: SetStr = {
  136. key
  137. for key in dir(config)
  138. if not (key.startswith('__') and key.endswith('__')) # skip dunder methods and attributes
  139. }
  140. config_kwargs = {key: kwargs.pop(key) for key in kwargs.keys() & allowed_config_kwargs}
  141. config_from_namespace = namespace.get('Config')
  142. if config_kwargs and config_from_namespace:
  143. raise TypeError('Specifying config in two places is ambiguous, use either Config attribute or class kwargs')
  144. config = inherit_config(config_from_namespace, config, **config_kwargs)
  145. validators = inherit_validators(extract_validators(namespace), validators)
  146. vg = ValidatorGroup(validators)
  147. for f in fields.values():
  148. f.set_config(config)
  149. extra_validators = vg.get_validators(f.name)
  150. if extra_validators:
  151. f.class_validators.update(extra_validators)
  152. # re-run prepare to add extra validators
  153. f.populate_validators()
  154. prepare_config(config, name)
  155. untouched_types = ANNOTATED_FIELD_UNTOUCHED_TYPES
  156. def is_untouched(v: Any) -> bool:
  157. return isinstance(v, untouched_types) or v.__class__.__name__ == 'cython_function_or_method'
  158. if (namespace.get('__module__'), namespace.get('__qualname__')) != ('pydantic.main', 'BaseModel'):
  159. annotations = resolve_annotations(namespace.get('__annotations__', {}), namespace.get('__module__', None))
  160. # annotation only fields need to come first in fields
  161. for ann_name, ann_type in annotations.items():
  162. if is_classvar(ann_type):
  163. class_vars.add(ann_name)
  164. elif is_valid_field(ann_name):
  165. validate_field_name(bases, ann_name)
  166. value = namespace.get(ann_name, Undefined)
  167. allowed_types = get_args(ann_type) if is_union(get_origin(ann_type)) else (ann_type,)
  168. if (
  169. is_untouched(value)
  170. and ann_type != PyObject
  171. and not any(
  172. lenient_issubclass(get_origin(allowed_type), Type) for allowed_type in allowed_types
  173. )
  174. ):
  175. continue
  176. fields[ann_name] = ModelField.infer(
  177. name=ann_name,
  178. value=value,
  179. annotation=ann_type,
  180. class_validators=vg.get_validators(ann_name),
  181. config=config,
  182. )
  183. elif ann_name not in namespace and config.underscore_attrs_are_private:
  184. private_attributes[ann_name] = PrivateAttr()
  185. untouched_types = UNTOUCHED_TYPES + config.keep_untouched
  186. for var_name, value in namespace.items():
  187. can_be_changed = var_name not in class_vars and not is_untouched(value)
  188. if isinstance(value, ModelPrivateAttr):
  189. if not is_valid_private_name(var_name):
  190. raise NameError(
  191. f'Private attributes "{var_name}" must not be a valid field name; '
  192. f'Use sunder or dunder names, e. g. "_{var_name}" or "__{var_name}__"'
  193. )
  194. private_attributes[var_name] = value
  195. elif config.underscore_attrs_are_private and is_valid_private_name(var_name) and can_be_changed:
  196. private_attributes[var_name] = PrivateAttr(default=value)
  197. elif is_valid_field(var_name) and var_name not in annotations and can_be_changed:
  198. validate_field_name(bases, var_name)
  199. inferred = ModelField.infer(
  200. name=var_name,
  201. value=value,
  202. annotation=annotations.get(var_name, Undefined),
  203. class_validators=vg.get_validators(var_name),
  204. config=config,
  205. )
  206. if var_name in fields:
  207. if lenient_issubclass(inferred.type_, fields[var_name].type_):
  208. inferred.type_ = fields[var_name].type_
  209. else:
  210. raise TypeError(
  211. f'The type of {name}.{var_name} differs from the new default value; '
  212. f'if you wish to change the type of this field, please use a type annotation'
  213. )
  214. fields[var_name] = inferred
  215. _custom_root_type = ROOT_KEY in fields
  216. if _custom_root_type:
  217. validate_custom_root_type(fields)
  218. vg.check_for_unused()
  219. if config.json_encoders:
  220. json_encoder = partial(custom_pydantic_encoder, config.json_encoders)
  221. else:
  222. json_encoder = pydantic_encoder
  223. pre_rv_new, post_rv_new = extract_root_validators(namespace)
  224. if hash_func is None:
  225. hash_func = generate_hash_function(config.frozen)
  226. exclude_from_namespace = fields | private_attributes.keys() | {'__slots__'}
  227. new_namespace = {
  228. '__config__': config,
  229. '__fields__': fields,
  230. '__exclude_fields__': {
  231. name: field.field_info.exclude for name, field in fields.items() if field.field_info.exclude is not None
  232. }
  233. or None,
  234. '__include_fields__': {
  235. name: field.field_info.include for name, field in fields.items() if field.field_info.include is not None
  236. }
  237. or None,
  238. '__validators__': vg.validators,
  239. '__pre_root_validators__': unique_list(
  240. pre_root_validators + pre_rv_new,
  241. name_factory=lambda v: v.__name__,
  242. ),
  243. '__post_root_validators__': unique_list(
  244. post_root_validators + post_rv_new,
  245. name_factory=lambda skip_on_failure_and_v: skip_on_failure_and_v[1].__name__,
  246. ),
  247. '__schema_cache__': {},
  248. '__json_encoder__': staticmethod(json_encoder),
  249. '__custom_root_type__': _custom_root_type,
  250. '__private_attributes__': {**base_private_attributes, **private_attributes},
  251. '__slots__': slots | private_attributes.keys(),
  252. '__hash__': hash_func,
  253. '__class_vars__': class_vars,
  254. **{n: v for n, v in namespace.items() if n not in exclude_from_namespace},
  255. }
  256. cls = super().__new__(mcs, name, bases, new_namespace, **kwargs)
  257. # set __signature__ attr only for model class, but not for its instances
  258. cls.__signature__ = ClassAttribute('__signature__', generate_model_signature(cls.__init__, fields, config))
  259. cls.__try_update_forward_refs__()
  260. return cls
  261. object_setattr = object.__setattr__
  262. class BaseModel(Representation, metaclass=ModelMetaclass):
  263. if TYPE_CHECKING:
  264. # populated by the metaclass, defined here to help IDEs only
  265. __fields__: ClassVar[Dict[str, ModelField]] = {}
  266. __include_fields__: ClassVar[Optional[Mapping[str, Any]]] = None
  267. __exclude_fields__: ClassVar[Optional[Mapping[str, Any]]] = None
  268. __validators__: ClassVar[Dict[str, AnyCallable]] = {}
  269. __pre_root_validators__: ClassVar[List[AnyCallable]]
  270. __post_root_validators__: ClassVar[List[Tuple[bool, AnyCallable]]]
  271. __config__: ClassVar[Type[BaseConfig]] = BaseConfig
  272. __json_encoder__: ClassVar[Callable[[Any], Any]] = lambda x: x
  273. __schema_cache__: ClassVar['DictAny'] = {}
  274. __custom_root_type__: ClassVar[bool] = False
  275. __signature__: ClassVar['Signature']
  276. __private_attributes__: ClassVar[Dict[str, ModelPrivateAttr]]
  277. __class_vars__: ClassVar[SetStr]
  278. __fields_set__: ClassVar[SetStr] = set()
  279. Config = BaseConfig
  280. __slots__ = ('__dict__', '__fields_set__')
  281. __doc__ = '' # Null out the Representation docstring
  282. def __init__(__pydantic_self__, **data: Any) -> None:
  283. """
  284. Create a new model by parsing and validating input data from keyword arguments.
  285. Raises ValidationError if the input data cannot be parsed to form a valid model.
  286. """
  287. # Uses something other than `self` the first arg to allow "self" as a settable attribute
  288. values, fields_set, validation_error = validate_model(__pydantic_self__.__class__, data)
  289. if validation_error:
  290. raise validation_error
  291. try:
  292. object_setattr(__pydantic_self__, '__dict__', values)
  293. except TypeError as e:
  294. raise TypeError(
  295. 'Model values must be a dict; you may not have returned a dictionary from a root validator'
  296. ) from e
  297. object_setattr(__pydantic_self__, '__fields_set__', fields_set)
  298. __pydantic_self__._init_private_attributes()
  299. @no_type_check
  300. def __setattr__(self, name, value): # noqa: C901 (ignore complexity)
  301. if name in self.__private_attributes__:
  302. return object_setattr(self, name, value)
  303. if self.__config__.extra is not Extra.allow and name not in self.__fields__:
  304. raise ValueError(f'"{self.__class__.__name__}" object has no field "{name}"')
  305. elif not self.__config__.allow_mutation or self.__config__.frozen:
  306. raise TypeError(f'"{self.__class__.__name__}" is immutable and does not support item assignment')
  307. elif self.__config__.validate_assignment:
  308. new_values = {**self.__dict__, name: value}
  309. for validator in self.__pre_root_validators__:
  310. try:
  311. new_values = validator(self.__class__, new_values)
  312. except (ValueError, TypeError, AssertionError) as exc:
  313. raise ValidationError([ErrorWrapper(exc, loc=ROOT_KEY)], self.__class__)
  314. known_field = self.__fields__.get(name, None)
  315. if known_field:
  316. # We want to
  317. # - make sure validators are called without the current value for this field inside `values`
  318. # - keep other values (e.g. submodels) untouched (using `BaseModel.dict()` will change them into dicts)
  319. # - keep the order of the fields
  320. if not known_field.field_info.allow_mutation:
  321. raise TypeError(f'"{known_field.name}" has allow_mutation set to False and cannot be assigned')
  322. dict_without_original_value = {k: v for k, v in self.__dict__.items() if k != name}
  323. value, error_ = known_field.validate(value, dict_without_original_value, loc=name, cls=self.__class__)
  324. if error_:
  325. raise ValidationError([error_], self.__class__)
  326. else:
  327. new_values[name] = value
  328. errors = []
  329. for skip_on_failure, validator in self.__post_root_validators__:
  330. if skip_on_failure and errors:
  331. continue
  332. try:
  333. new_values = validator(self.__class__, new_values)
  334. except (ValueError, TypeError, AssertionError) as exc:
  335. errors.append(ErrorWrapper(exc, loc=ROOT_KEY))
  336. if errors:
  337. raise ValidationError(errors, self.__class__)
  338. # update the whole __dict__ as other values than just `value`
  339. # may be changed (e.g. with `root_validator`)
  340. object_setattr(self, '__dict__', new_values)
  341. else:
  342. self.__dict__[name] = value
  343. self.__fields_set__.add(name)
  344. def __getstate__(self) -> 'DictAny':
  345. private_attrs = ((k, getattr(self, k, Undefined)) for k in self.__private_attributes__)
  346. return {
  347. '__dict__': self.__dict__,
  348. '__fields_set__': self.__fields_set__,
  349. '__private_attribute_values__': {k: v for k, v in private_attrs if v is not Undefined},
  350. }
  351. def __setstate__(self, state: 'DictAny') -> None:
  352. object_setattr(self, '__dict__', state['__dict__'])
  353. object_setattr(self, '__fields_set__', state['__fields_set__'])
  354. for name, value in state.get('__private_attribute_values__', {}).items():
  355. object_setattr(self, name, value)
  356. def _init_private_attributes(self) -> None:
  357. for name, private_attr in self.__private_attributes__.items():
  358. default = private_attr.get_default()
  359. if default is not Undefined:
  360. object_setattr(self, name, default)
  361. def dict(
  362. self,
  363. *,
  364. include: Union['AbstractSetIntStr', 'MappingIntStrAny'] = None,
  365. exclude: Union['AbstractSetIntStr', 'MappingIntStrAny'] = None,
  366. by_alias: bool = False,
  367. skip_defaults: bool = None,
  368. exclude_unset: bool = False,
  369. exclude_defaults: bool = False,
  370. exclude_none: bool = False,
  371. ) -> 'DictStrAny':
  372. """
  373. Generate a dictionary representation of the model, optionally specifying which fields to include or exclude.
  374. """
  375. if skip_defaults is not None:
  376. warnings.warn(
  377. f'{self.__class__.__name__}.dict(): "skip_defaults" is deprecated and replaced by "exclude_unset"',
  378. DeprecationWarning,
  379. )
  380. exclude_unset = skip_defaults
  381. return dict(
  382. self._iter(
  383. to_dict=True,
  384. by_alias=by_alias,
  385. include=include,
  386. exclude=exclude,
  387. exclude_unset=exclude_unset,
  388. exclude_defaults=exclude_defaults,
  389. exclude_none=exclude_none,
  390. )
  391. )
  392. def json(
  393. self,
  394. *,
  395. include: Union['AbstractSetIntStr', 'MappingIntStrAny'] = None,
  396. exclude: Union['AbstractSetIntStr', 'MappingIntStrAny'] = None,
  397. by_alias: bool = False,
  398. skip_defaults: bool = None,
  399. exclude_unset: bool = False,
  400. exclude_defaults: bool = False,
  401. exclude_none: bool = False,
  402. encoder: Optional[Callable[[Any], Any]] = None,
  403. models_as_dict: bool = True,
  404. **dumps_kwargs: Any,
  405. ) -> str:
  406. """
  407. Generate a JSON representation of the model, `include` and `exclude` arguments as per `dict()`.
  408. `encoder` is an optional function to supply as `default` to json.dumps(), other arguments as per `json.dumps()`.
  409. """
  410. if skip_defaults is not None:
  411. warnings.warn(
  412. f'{self.__class__.__name__}.json(): "skip_defaults" is deprecated and replaced by "exclude_unset"',
  413. DeprecationWarning,
  414. )
  415. exclude_unset = skip_defaults
  416. encoder = cast(Callable[[Any], Any], encoder or self.__json_encoder__)
  417. # We don't directly call `self.dict()`, which does exactly this with `to_dict=True`
  418. # because we want to be able to keep raw `BaseModel` instances and not as `dict`.
  419. # This allows users to write custom JSON encoders for given `BaseModel` classes.
  420. data = dict(
  421. self._iter(
  422. to_dict=models_as_dict,
  423. by_alias=by_alias,
  424. include=include,
  425. exclude=exclude,
  426. exclude_unset=exclude_unset,
  427. exclude_defaults=exclude_defaults,
  428. exclude_none=exclude_none,
  429. )
  430. )
  431. if self.__custom_root_type__:
  432. data = data[ROOT_KEY]
  433. return self.__config__.json_dumps(data, default=encoder, **dumps_kwargs)
  434. @classmethod
  435. def _enforce_dict_if_root(cls, obj: Any) -> Any:
  436. if cls.__custom_root_type__ and (
  437. not (isinstance(obj, dict) and obj.keys() == {ROOT_KEY})
  438. or cls.__fields__[ROOT_KEY].shape in MAPPING_LIKE_SHAPES
  439. ):
  440. return {ROOT_KEY: obj}
  441. else:
  442. return obj
  443. @classmethod
  444. def parse_obj(cls: Type['Model'], obj: Any) -> 'Model':
  445. obj = cls._enforce_dict_if_root(obj)
  446. if not isinstance(obj, dict):
  447. try:
  448. obj = dict(obj)
  449. except (TypeError, ValueError) as e:
  450. exc = TypeError(f'{cls.__name__} expected dict not {obj.__class__.__name__}')
  451. raise ValidationError([ErrorWrapper(exc, loc=ROOT_KEY)], cls) from e
  452. return cls(**obj)
  453. @classmethod
  454. def parse_raw(
  455. cls: Type['Model'],
  456. b: StrBytes,
  457. *,
  458. content_type: str = None,
  459. encoding: str = 'utf8',
  460. proto: Protocol = None,
  461. allow_pickle: bool = False,
  462. ) -> 'Model':
  463. try:
  464. obj = load_str_bytes(
  465. b,
  466. proto=proto,
  467. content_type=content_type,
  468. encoding=encoding,
  469. allow_pickle=allow_pickle,
  470. json_loads=cls.__config__.json_loads,
  471. )
  472. except (ValueError, TypeError, UnicodeDecodeError) as e:
  473. raise ValidationError([ErrorWrapper(e, loc=ROOT_KEY)], cls)
  474. return cls.parse_obj(obj)
  475. @classmethod
  476. def parse_file(
  477. cls: Type['Model'],
  478. path: Union[str, Path],
  479. *,
  480. content_type: str = None,
  481. encoding: str = 'utf8',
  482. proto: Protocol = None,
  483. allow_pickle: bool = False,
  484. ) -> 'Model':
  485. obj = load_file(
  486. path,
  487. proto=proto,
  488. content_type=content_type,
  489. encoding=encoding,
  490. allow_pickle=allow_pickle,
  491. json_loads=cls.__config__.json_loads,
  492. )
  493. return cls.parse_obj(obj)
  494. @classmethod
  495. def from_orm(cls: Type['Model'], obj: Any) -> 'Model':
  496. if not cls.__config__.orm_mode:
  497. raise ConfigError('You must have the config attribute orm_mode=True to use from_orm')
  498. obj = {ROOT_KEY: obj} if cls.__custom_root_type__ else cls._decompose_class(obj)
  499. m = cls.__new__(cls)
  500. values, fields_set, validation_error = validate_model(cls, obj)
  501. if validation_error:
  502. raise validation_error
  503. object_setattr(m, '__dict__', values)
  504. object_setattr(m, '__fields_set__', fields_set)
  505. m._init_private_attributes()
  506. return m
  507. @classmethod
  508. def construct(cls: Type['Model'], _fields_set: Optional['SetStr'] = None, **values: Any) -> 'Model':
  509. """
  510. Creates a new model setting __dict__ and __fields_set__ from trusted or pre-validated data.
  511. Default values are respected, but no other validation is performed.
  512. Behaves as if `Config.extra = 'allow'` was set since it adds all passed values
  513. """
  514. m = cls.__new__(cls)
  515. fields_values: Dict[str, Any] = {}
  516. for name, field in cls.__fields__.items():
  517. if name in values:
  518. fields_values[name] = values[name]
  519. elif not field.required:
  520. fields_values[name] = field.get_default()
  521. fields_values.update(values)
  522. object_setattr(m, '__dict__', fields_values)
  523. if _fields_set is None:
  524. _fields_set = set(values.keys())
  525. object_setattr(m, '__fields_set__', _fields_set)
  526. m._init_private_attributes()
  527. return m
  528. def _copy_and_set_values(self: 'Model', values: 'DictStrAny', fields_set: 'SetStr', *, deep: bool) -> 'Model':
  529. if deep:
  530. # chances of having empty dict here are quite low for using smart_deepcopy
  531. values = deepcopy(values)
  532. cls = self.__class__
  533. m = cls.__new__(cls)
  534. object_setattr(m, '__dict__', values)
  535. object_setattr(m, '__fields_set__', fields_set)
  536. for name in self.__private_attributes__:
  537. value = getattr(self, name, Undefined)
  538. if value is not Undefined:
  539. if deep:
  540. value = deepcopy(value)
  541. object_setattr(m, name, value)
  542. return m
  543. def copy(
  544. self: 'Model',
  545. *,
  546. include: Union['AbstractSetIntStr', 'MappingIntStrAny'] = None,
  547. exclude: Union['AbstractSetIntStr', 'MappingIntStrAny'] = None,
  548. update: 'DictStrAny' = None,
  549. deep: bool = False,
  550. ) -> 'Model':
  551. """
  552. Duplicate a model, optionally choose which fields to include, exclude and change.
  553. :param include: fields to include in new model
  554. :param exclude: fields to exclude from new model, as with values this takes precedence over include
  555. :param update: values to change/add in the new model. Note: the data is not validated before creating
  556. the new model: you should trust this data
  557. :param deep: set to `True` to make a deep copy of the model
  558. :return: new model instance
  559. """
  560. values = dict(
  561. self._iter(to_dict=False, by_alias=False, include=include, exclude=exclude, exclude_unset=False),
  562. **(update or {}),
  563. )
  564. # new `__fields_set__` can have unset optional fields with a set value in `update` kwarg
  565. if update:
  566. fields_set = self.__fields_set__ | update.keys()
  567. else:
  568. fields_set = set(self.__fields_set__)
  569. return self._copy_and_set_values(values, fields_set, deep=deep)
  570. @classmethod
  571. def schema(cls, by_alias: bool = True, ref_template: str = default_ref_template) -> 'DictStrAny':
  572. cached = cls.__schema_cache__.get((by_alias, ref_template))
  573. if cached is not None:
  574. return cached
  575. s = model_schema(cls, by_alias=by_alias, ref_template=ref_template)
  576. cls.__schema_cache__[(by_alias, ref_template)] = s
  577. return s
  578. @classmethod
  579. def schema_json(
  580. cls, *, by_alias: bool = True, ref_template: str = default_ref_template, **dumps_kwargs: Any
  581. ) -> str:
  582. from .json import pydantic_encoder
  583. return cls.__config__.json_dumps(
  584. cls.schema(by_alias=by_alias, ref_template=ref_template), default=pydantic_encoder, **dumps_kwargs
  585. )
  586. @classmethod
  587. def __get_validators__(cls) -> 'CallableGenerator':
  588. yield cls.validate
  589. @classmethod
  590. def validate(cls: Type['Model'], value: Any) -> 'Model':
  591. if isinstance(value, cls):
  592. if cls.__config__.copy_on_model_validation:
  593. return value._copy_and_set_values(value.__dict__, value.__fields_set__, deep=False)
  594. else:
  595. return value
  596. value = cls._enforce_dict_if_root(value)
  597. if isinstance(value, dict):
  598. return cls(**value)
  599. elif cls.__config__.orm_mode:
  600. return cls.from_orm(value)
  601. else:
  602. try:
  603. value_as_dict = dict(value)
  604. except (TypeError, ValueError) as e:
  605. raise DictError() from e
  606. return cls(**value_as_dict)
  607. @classmethod
  608. def _decompose_class(cls: Type['Model'], obj: Any) -> GetterDict:
  609. if isinstance(obj, GetterDict):
  610. return obj
  611. return cls.__config__.getter_dict(obj)
  612. @classmethod
  613. @no_type_check
  614. def _get_value(
  615. cls,
  616. v: Any,
  617. to_dict: bool,
  618. by_alias: bool,
  619. include: Optional[Union['AbstractSetIntStr', 'MappingIntStrAny']],
  620. exclude: Optional[Union['AbstractSetIntStr', 'MappingIntStrAny']],
  621. exclude_unset: bool,
  622. exclude_defaults: bool,
  623. exclude_none: bool,
  624. ) -> Any:
  625. if isinstance(v, BaseModel):
  626. if to_dict:
  627. v_dict = v.dict(
  628. by_alias=by_alias,
  629. exclude_unset=exclude_unset,
  630. exclude_defaults=exclude_defaults,
  631. include=include,
  632. exclude=exclude,
  633. exclude_none=exclude_none,
  634. )
  635. if ROOT_KEY in v_dict:
  636. return v_dict[ROOT_KEY]
  637. return v_dict
  638. else:
  639. return v.copy(include=include, exclude=exclude)
  640. value_exclude = ValueItems(v, exclude) if exclude else None
  641. value_include = ValueItems(v, include) if include else None
  642. if isinstance(v, dict):
  643. return {
  644. k_: cls._get_value(
  645. v_,
  646. to_dict=to_dict,
  647. by_alias=by_alias,
  648. exclude_unset=exclude_unset,
  649. exclude_defaults=exclude_defaults,
  650. include=value_include and value_include.for_element(k_),
  651. exclude=value_exclude and value_exclude.for_element(k_),
  652. exclude_none=exclude_none,
  653. )
  654. for k_, v_ in v.items()
  655. if (not value_exclude or not value_exclude.is_excluded(k_))
  656. and (not value_include or value_include.is_included(k_))
  657. }
  658. elif sequence_like(v):
  659. seq_args = (
  660. cls._get_value(
  661. v_,
  662. to_dict=to_dict,
  663. by_alias=by_alias,
  664. exclude_unset=exclude_unset,
  665. exclude_defaults=exclude_defaults,
  666. include=value_include and value_include.for_element(i),
  667. exclude=value_exclude and value_exclude.for_element(i),
  668. exclude_none=exclude_none,
  669. )
  670. for i, v_ in enumerate(v)
  671. if (not value_exclude or not value_exclude.is_excluded(i))
  672. and (not value_include or value_include.is_included(i))
  673. )
  674. return v.__class__(*seq_args) if is_namedtuple(v.__class__) else v.__class__(seq_args)
  675. elif isinstance(v, Enum) and getattr(cls.Config, 'use_enum_values', False):
  676. return v.value
  677. else:
  678. return v
  679. @classmethod
  680. def __try_update_forward_refs__(cls) -> None:
  681. """
  682. Same as update_forward_refs but will not raise exception
  683. when forward references are not defined.
  684. """
  685. update_model_forward_refs(cls, cls.__fields__.values(), cls.__config__.json_encoders, {}, (NameError,))
  686. @classmethod
  687. def update_forward_refs(cls, **localns: Any) -> None:
  688. """
  689. Try to update ForwardRefs on fields based on this Model, globalns and localns.
  690. """
  691. update_model_forward_refs(cls, cls.__fields__.values(), cls.__config__.json_encoders, localns)
  692. def __iter__(self) -> 'TupleGenerator':
  693. """
  694. so `dict(model)` works
  695. """
  696. yield from self.__dict__.items()
  697. def _iter(
  698. self,
  699. to_dict: bool = False,
  700. by_alias: bool = False,
  701. include: Union['AbstractSetIntStr', 'MappingIntStrAny'] = None,
  702. exclude: Union['AbstractSetIntStr', 'MappingIntStrAny'] = None,
  703. exclude_unset: bool = False,
  704. exclude_defaults: bool = False,
  705. exclude_none: bool = False,
  706. ) -> 'TupleGenerator':
  707. # Merge field set excludes with explicit exclude parameter with explicit overriding field set options.
  708. # The extra "is not None" guards are not logically necessary but optimizes performance for the simple case.
  709. if exclude is not None or self.__exclude_fields__ is not None:
  710. exclude = ValueItems.merge(self.__exclude_fields__, exclude)
  711. if include is not None or self.__include_fields__ is not None:
  712. include = ValueItems.merge(self.__include_fields__, include, intersect=True)
  713. allowed_keys = self._calculate_keys(
  714. include=include, exclude=exclude, exclude_unset=exclude_unset # type: ignore
  715. )
  716. if allowed_keys is None and not (to_dict or by_alias or exclude_unset or exclude_defaults or exclude_none):
  717. # huge boost for plain _iter()
  718. yield from self.__dict__.items()
  719. return
  720. value_exclude = ValueItems(self, exclude) if exclude is not None else None
  721. value_include = ValueItems(self, include) if include is not None else None
  722. for field_key, v in self.__dict__.items():
  723. if (allowed_keys is not None and field_key not in allowed_keys) or (exclude_none and v is None):
  724. continue
  725. if exclude_defaults:
  726. model_field = self.__fields__.get(field_key)
  727. if not getattr(model_field, 'required', True) and getattr(model_field, 'default', _missing) == v:
  728. continue
  729. if by_alias and field_key in self.__fields__:
  730. dict_key = self.__fields__[field_key].alias
  731. else:
  732. dict_key = field_key
  733. if to_dict or value_include or value_exclude:
  734. v = self._get_value(
  735. v,
  736. to_dict=to_dict,
  737. by_alias=by_alias,
  738. include=value_include and value_include.for_element(field_key),
  739. exclude=value_exclude and value_exclude.for_element(field_key),
  740. exclude_unset=exclude_unset,
  741. exclude_defaults=exclude_defaults,
  742. exclude_none=exclude_none,
  743. )
  744. yield dict_key, v
  745. def _calculate_keys(
  746. self,
  747. include: Optional['MappingIntStrAny'],
  748. exclude: Optional['MappingIntStrAny'],
  749. exclude_unset: bool,
  750. update: Optional['DictStrAny'] = None,
  751. ) -> Optional[AbstractSet[str]]:
  752. if include is None and exclude is None and exclude_unset is False:
  753. return None
  754. keys: AbstractSet[str]
  755. if exclude_unset:
  756. keys = self.__fields_set__.copy()
  757. else:
  758. keys = self.__dict__.keys()
  759. if include is not None:
  760. keys &= include.keys()
  761. if update:
  762. keys -= update.keys()
  763. if exclude:
  764. keys -= {k for k, v in exclude.items() if ValueItems.is_true(v)}
  765. return keys
  766. def __eq__(self, other: Any) -> bool:
  767. if isinstance(other, BaseModel):
  768. return self.dict() == other.dict()
  769. else:
  770. return self.dict() == other
  771. def __repr_args__(self) -> 'ReprArgs':
  772. return [
  773. (k, v) for k, v in self.__dict__.items() if k not in self.__fields__ or self.__fields__[k].field_info.repr
  774. ]
  775. _is_base_model_class_defined = True
  776. @overload
  777. def create_model(
  778. __model_name: str,
  779. *,
  780. __config__: Optional[Type[BaseConfig]] = None,
  781. __base__: None = None,
  782. __module__: str = __name__,
  783. __validators__: Dict[str, 'AnyClassMethod'] = None,
  784. **field_definitions: Any,
  785. ) -> Type['BaseModel']:
  786. ...
  787. @overload
  788. def create_model(
  789. __model_name: str,
  790. *,
  791. __config__: Optional[Type[BaseConfig]] = None,
  792. __base__: Union[Type['Model'], Tuple[Type['Model'], ...]],
  793. __module__: str = __name__,
  794. __validators__: Dict[str, 'AnyClassMethod'] = None,
  795. **field_definitions: Any,
  796. ) -> Type['Model']:
  797. ...
  798. def create_model(
  799. __model_name: str,
  800. *,
  801. __config__: Optional[Type[BaseConfig]] = None,
  802. __base__: Union[None, Type['Model'], Tuple[Type['Model'], ...]] = None,
  803. __module__: str = __name__,
  804. __validators__: Dict[str, 'AnyClassMethod'] = None,
  805. **field_definitions: Any,
  806. ) -> Type['Model']:
  807. """
  808. Dynamically create a model.
  809. :param __model_name: name of the created model
  810. :param __config__: config class to use for the new model
  811. :param __base__: base class for the new model to inherit from
  812. :param __module__: module of the created model
  813. :param __validators__: a dict of method names and @validator class methods
  814. :param field_definitions: fields of the model (or extra fields if a base is supplied)
  815. in the format `<name>=(<type>, <default default>)` or `<name>=<default value>, e.g.
  816. `foobar=(str, ...)` or `foobar=123`, or, for complex use-cases, in the format
  817. `<name>=<FieldInfo>`, e.g. `foo=Field(default_factory=datetime.utcnow, alias='bar')`
  818. """
  819. if __base__ is not None:
  820. if __config__ is not None:
  821. raise ConfigError('to avoid confusion __config__ and __base__ cannot be used together')
  822. if not isinstance(__base__, tuple):
  823. __base__ = (__base__,)
  824. else:
  825. __base__ = (cast(Type['Model'], BaseModel),)
  826. fields = {}
  827. annotations = {}
  828. for f_name, f_def in field_definitions.items():
  829. if not is_valid_field(f_name):
  830. warnings.warn(f'fields may not start with an underscore, ignoring "{f_name}"', RuntimeWarning)
  831. if isinstance(f_def, tuple):
  832. try:
  833. f_annotation, f_value = f_def
  834. except ValueError as e:
  835. raise ConfigError(
  836. 'field definitions should either be a tuple of (<type>, <default>) or just a '
  837. 'default value, unfortunately this means tuples as '
  838. 'default values are not allowed'
  839. ) from e
  840. else:
  841. f_annotation, f_value = None, f_def
  842. if f_annotation:
  843. annotations[f_name] = f_annotation
  844. fields[f_name] = f_value
  845. namespace: 'DictStrAny' = {'__annotations__': annotations, '__module__': __module__}
  846. if __validators__:
  847. namespace.update(__validators__)
  848. namespace.update(fields)
  849. if __config__:
  850. namespace['Config'] = inherit_config(__config__, BaseConfig)
  851. return type(__model_name, __base__, namespace)
  852. _missing = object()
  853. def validate_model( # noqa: C901 (ignore complexity)
  854. model: Type[BaseModel], input_data: 'DictStrAny', cls: 'ModelOrDc' = None
  855. ) -> Tuple['DictStrAny', 'SetStr', Optional[ValidationError]]:
  856. """
  857. validate data against a model.
  858. """
  859. values = {}
  860. errors = []
  861. # input_data names, possibly alias
  862. names_used = set()
  863. # field names, never aliases
  864. fields_set = set()
  865. config = model.__config__
  866. check_extra = config.extra is not Extra.ignore
  867. cls_ = cls or model
  868. for validator in model.__pre_root_validators__:
  869. try:
  870. input_data = validator(cls_, input_data)
  871. except (ValueError, TypeError, AssertionError) as exc:
  872. return {}, set(), ValidationError([ErrorWrapper(exc, loc=ROOT_KEY)], cls_)
  873. for name, field in model.__fields__.items():
  874. value = input_data.get(field.alias, _missing)
  875. using_name = False
  876. if value is _missing and config.allow_population_by_field_name and field.alt_alias:
  877. value = input_data.get(field.name, _missing)
  878. using_name = True
  879. if value is _missing:
  880. if field.required:
  881. errors.append(ErrorWrapper(MissingError(), loc=field.alias))
  882. continue
  883. value = field.get_default()
  884. if not config.validate_all and not field.validate_always:
  885. values[name] = value
  886. continue
  887. else:
  888. fields_set.add(name)
  889. if check_extra:
  890. names_used.add(field.name if using_name else field.alias)
  891. v_, errors_ = field.validate(value, values, loc=field.alias, cls=cls_)
  892. if isinstance(errors_, ErrorWrapper):
  893. errors.append(errors_)
  894. elif isinstance(errors_, list):
  895. errors.extend(errors_)
  896. else:
  897. values[name] = v_
  898. if check_extra:
  899. if isinstance(input_data, GetterDict):
  900. extra = input_data.extra_keys() - names_used
  901. else:
  902. extra = input_data.keys() - names_used
  903. if extra:
  904. fields_set |= extra
  905. if config.extra is Extra.allow:
  906. for f in extra:
  907. values[f] = input_data[f]
  908. else:
  909. for f in sorted(extra):
  910. errors.append(ErrorWrapper(ExtraError(), loc=f))
  911. for skip_on_failure, validator in model.__post_root_validators__:
  912. if skip_on_failure and errors:
  913. continue
  914. try:
  915. values = validator(cls_, values)
  916. except (ValueError, TypeError, AssertionError) as exc:
  917. errors.append(ErrorWrapper(exc, loc=ROOT_KEY))
  918. if errors:
  919. return values, fields_set, ValidationError(errors, cls_)
  920. else:
  921. return values, fields_set, None