Coverage for /pythoncovmergedfiles/medio/medio/src/pydantic/pydantic/deprecated/copy_internals.py: 17%
87 statements
« prev ^ index » next coverage.py v7.2.3, created at 2023-04-27 07:38 +0000
« prev ^ index » next coverage.py v7.2.3, created at 2023-04-27 07:38 +0000
1from __future__ import annotations as _annotations
3import typing
4from copy import deepcopy
5from enum import Enum
6from typing import Any, Tuple
8import typing_extensions
10from .._internal import (
11 _model_construction,
12 _typing_extra,
13 _utils,
14)
15from .._internal._fields import Undefined
17if typing.TYPE_CHECKING:
18 from .. import BaseModel
19 from .._internal._utils import AbstractSetIntStr, MappingIntStrAny
21 AnyClassMethod = classmethod[Any, Any, Any]
22 TupleGenerator = typing.Generator[Tuple[str, Any], None, None]
23 Model = typing.TypeVar('Model', bound='BaseModel')
24 # should be `set[int] | set[str] | dict[int, IncEx] | dict[str, IncEx] | None`, but mypy can't cope
25 IncEx: typing_extensions.TypeAlias = 'set[int] | set[str] | dict[int, Any] | dict[str, Any] | None'
27_object_setattr = _model_construction.object_setattr
30def _iter(
31 self: BaseModel,
32 to_dict: bool = False,
33 by_alias: bool = False,
34 include: AbstractSetIntStr | MappingIntStrAny | None = None,
35 exclude: AbstractSetIntStr | MappingIntStrAny | None = None,
36 exclude_unset: bool = False,
37 exclude_defaults: bool = False,
38 exclude_none: bool = False,
39) -> TupleGenerator:
40 # Merge field set excludes with explicit exclude parameter with explicit overriding field set options.
41 # The extra "is not None" guards are not logically necessary but optimizes performance for the simple case.
42 if exclude is not None:
43 exclude = _utils.ValueItems.merge(
44 {k: v.exclude for k, v in self.model_fields.items() if v.exclude is not None}, exclude
45 )
47 if include is not None:
48 include = _utils.ValueItems.merge({k: v.include for k, v in self.model_fields.items()}, include, intersect=True)
50 allowed_keys = _calculate_keys(self, include=include, exclude=exclude, exclude_unset=exclude_unset) # type: ignore
51 if allowed_keys is None and not (to_dict or by_alias or exclude_unset or exclude_defaults or exclude_none):
52 # huge boost for plain _iter()
53 yield from self.__dict__.items()
54 return
56 value_exclude = _utils.ValueItems(self, exclude) if exclude is not None else None
57 value_include = _utils.ValueItems(self, include) if include is not None else None
59 for field_key, v in self.__dict__.items():
60 if (allowed_keys is not None and field_key not in allowed_keys) or (exclude_none and v is None):
61 continue
63 if exclude_defaults:
64 try:
65 field = self.model_fields[field_key]
66 except KeyError:
67 pass
68 else:
69 if not field.is_required() and field.default == v:
70 continue
72 if by_alias and field_key in self.model_fields:
73 dict_key = self.model_fields[field_key].alias or field_key
74 else:
75 dict_key = field_key
77 if to_dict or value_include or value_exclude:
78 v = _get_value( # type: ignore[no-untyped-call]
79 type(self),
80 v,
81 to_dict=to_dict,
82 by_alias=by_alias,
83 include=value_include and value_include.for_element(field_key),
84 exclude=value_exclude and value_exclude.for_element(field_key),
85 exclude_unset=exclude_unset,
86 exclude_defaults=exclude_defaults,
87 exclude_none=exclude_none,
88 )
89 yield dict_key, v
92def _copy_and_set_values(
93 self: Model, values: typing.Dict[str, Any], fields_set: set[str], *, deep: bool # noqa UP006
94) -> Model:
95 if deep:
96 # chances of having empty dict here are quite low for using smart_deepcopy
97 values = deepcopy(values)
99 cls = self.__class__
100 m = cls.__new__(cls)
101 _object_setattr(m, '__dict__', values)
102 _object_setattr(m, '__pydantic_fields_set__', fields_set)
103 for name in self.__private_attributes__:
104 value = getattr(self, name, Undefined)
105 if value is not Undefined:
106 if deep:
107 value = deepcopy(value)
108 _object_setattr(m, name, value)
110 return m
113@typing.no_type_check
114def _get_value(
115 cls: type[BaseModel],
116 v: Any,
117 to_dict: bool,
118 by_alias: bool,
119 include: AbstractSetIntStr | MappingIntStrAny | None,
120 exclude: AbstractSetIntStr | MappingIntStrAny | None,
121 exclude_unset: bool,
122 exclude_defaults: bool,
123 exclude_none: bool,
124) -> Any:
125 from .. import BaseModel
127 if isinstance(v, BaseModel):
128 if to_dict:
129 return v.model_dump(
130 by_alias=by_alias,
131 exclude_unset=exclude_unset,
132 exclude_defaults=exclude_defaults,
133 include=include, # type: ignore
134 exclude=exclude, # type: ignore
135 exclude_none=exclude_none,
136 )
137 else:
138 return v.copy(include=include, exclude=exclude)
140 value_exclude = _utils.ValueItems(v, exclude) if exclude else None
141 value_include = _utils.ValueItems(v, include) if include else None
143 if isinstance(v, dict):
144 return {
145 k_: _get_value(
146 cls,
147 v_,
148 to_dict=to_dict,
149 by_alias=by_alias,
150 exclude_unset=exclude_unset,
151 exclude_defaults=exclude_defaults,
152 include=value_include and value_include.for_element(k_),
153 exclude=value_exclude and value_exclude.for_element(k_),
154 exclude_none=exclude_none,
155 )
156 for k_, v_ in v.items()
157 if (not value_exclude or not value_exclude.is_excluded(k_))
158 and (not value_include or value_include.is_included(k_))
159 }
161 elif _utils.sequence_like(v):
162 seq_args = (
163 _get_value(
164 cls,
165 v_,
166 to_dict=to_dict,
167 by_alias=by_alias,
168 exclude_unset=exclude_unset,
169 exclude_defaults=exclude_defaults,
170 include=value_include and value_include.for_element(i),
171 exclude=value_exclude and value_exclude.for_element(i),
172 exclude_none=exclude_none,
173 )
174 for i, v_ in enumerate(v)
175 if (not value_exclude or not value_exclude.is_excluded(i))
176 and (not value_include or value_include.is_included(i))
177 )
179 return v.__class__(*seq_args) if _typing_extra.is_namedtuple(v.__class__) else v.__class__(seq_args)
181 elif isinstance(v, Enum) and getattr(cls.model_config, 'use_enum_values', False):
182 return v.value
184 else:
185 return v
188def _calculate_keys(
189 self: BaseModel,
190 include: MappingIntStrAny | None,
191 exclude: MappingIntStrAny | None,
192 exclude_unset: bool,
193 update: typing.Dict[str, Any] | None = None, # noqa UP006
194) -> typing.AbstractSet[str] | None:
195 if include is None and exclude is None and exclude_unset is False:
196 return None
198 keys: typing.AbstractSet[str]
199 if exclude_unset:
200 keys = self.__pydantic_fields_set__.copy()
201 else:
202 keys = self.__dict__.keys()
204 if include is not None:
205 keys &= include.keys()
207 if update:
208 keys -= update.keys()
210 if exclude:
211 keys -= {k for k, v in exclude.items() if _utils.ValueItems.is_true(v)}
213 return keys