Coverage for pydantic/_internal/_model_construction.py: 99.11%
306 statements
« prev ^ index » next coverage.py v7.5.3, created at 2024-06-21 17:00 +0000
« prev ^ index » next coverage.py v7.5.3, created at 2024-06-21 17:00 +0000
1"""Private logic for creating models."""
3from __future__ import annotations as _annotations 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
5import builtins 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
6import operator 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
7import typing 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
8import warnings 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
9import weakref 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
10from abc import ABCMeta 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
11from functools import partial 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
12from types import FunctionType 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
13from typing import Any, Callable, Generic, NoReturn 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
15import typing_extensions 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
16from pydantic_core import PydanticUndefined, SchemaSerializer 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
17from typing_extensions import dataclass_transform, deprecated 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
19from ..errors import PydanticUndefinedAnnotation, PydanticUserError 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
20from ..plugin._schema_validator import create_schema_validator 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
21from ..warnings import GenericBeforeBaseModelWarning, PydanticDeprecatedSince20 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
22from ._config import ConfigWrapper 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
23from ._decorators import DecoratorInfos, PydanticDescriptorProxy, get_attribute_from_bases, unwrap_wrapped_function 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
24from ._fields import collect_model_fields, is_valid_field_name, is_valid_privateattr_name 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
25from ._generate_schema import GenerateSchema 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
26from ._generics import PydanticGenericMetadata, get_model_typevars_map 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
27from ._mock_val_ser import set_model_mocks 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
28from ._schema_generation_shared import CallbackGetCoreSchemaHandler 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
29from ._signature import generate_pydantic_signature 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
30from ._typing_extra import get_cls_types_namespace, is_annotated, is_classvar, parent_frame_namespace 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
31from ._utils import ClassAttribute, SafeGetItemProxy 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
32from ._validate_call import ValidateCallWrapper 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
34if typing.TYPE_CHECKING: 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
35 from ..fields import Field as PydanticModelField
36 from ..fields import FieldInfo, ModelPrivateAttr
37 from ..fields import PrivateAttr as PydanticModelPrivateAttr
38 from ..main import BaseModel
39else:
40 # See PyCharm issues https://youtrack.jetbrains.com/issue/PY-21915
41 # and https://youtrack.jetbrains.com/issue/PY-51428
42 DeprecationWarning = PydanticDeprecatedSince20 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
43 PydanticModelField = object() 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
44 PydanticModelPrivateAttr = object() 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
46object_setattr = object.__setattr__ 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
49class _ModelNamespaceDict(dict): 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
50 """A dictionary subclass that intercepts attribute setting on model classes and
51 warns about overriding of decorators.
52 """
54 def __setitem__(self, k: str, v: object) -> None: 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
55 existing: Any = self.get(k, None) 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
56 if existing and v is not existing and isinstance(existing, PydanticDescriptorProxy): 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
57 warnings.warn(f'`{k}` overrides an existing Pydantic `{existing.decorator_info.decorator_repr}` decorator') 1abcdmnopABqrefghstuvCDijklwxyzEF
59 return super().__setitem__(k, v) 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
62@dataclass_transform(kw_only_default=True, field_specifiers=(PydanticModelField, PydanticModelPrivateAttr)) 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
63class ModelMetaclass(ABCMeta): 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
64 def __new__( 1abcdmnopABefghstuvCDGHIJKLMNOijklwxyzEF
65 mcs,
66 cls_name: str,
67 bases: tuple[type[Any], ...],
68 namespace: dict[str, Any],
69 __pydantic_generic_metadata__: PydanticGenericMetadata | None = None,
70 __pydantic_reset_parent_namespace__: bool = True,
71 _create_model_module: str | None = None,
72 **kwargs: Any,
73 ) -> type:
74 """Metaclass for creating Pydantic models.
76 Args:
77 cls_name: The name of the class to be created.
78 bases: The base classes of the class to be created.
79 namespace: The attribute dictionary of the class to be created.
80 __pydantic_generic_metadata__: Metadata for generic models.
81 __pydantic_reset_parent_namespace__: Reset parent namespace.
82 _create_model_module: The module of the class to be created, if created by `create_model`.
83 **kwargs: Catch-all for any other keyword arguments.
85 Returns:
86 The new class created by the metaclass.
87 """
88 # Note `ModelMetaclass` refers to `BaseModel`, but is also used to *create* `BaseModel`, so we rely on the fact
89 # that `BaseModel` itself won't have any bases, but any subclass of it will, to determine whether the `__new__`
90 # call we're in the middle of is for the `BaseModel` class.
91 if bases: 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
92 base_field_names, class_vars, base_private_attributes = mcs._collect_bases_data(bases) 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
94 config_wrapper = ConfigWrapper.for_model(bases, namespace, kwargs) 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
95 namespace['model_config'] = config_wrapper.config_dict 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
96 private_attributes = inspect_namespace( 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
97 namespace, config_wrapper.ignored_types, class_vars, base_field_names
98 )
99 if private_attributes or base_private_attributes: 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
100 original_model_post_init = get_model_post_init(namespace, bases) 1abcdmnopABqrefghstuvCDijklwxyzEF
101 if original_model_post_init is not None: 1abcdmnopABqrefghstuvCDijklwxyzEF
102 # if there are private_attributes and a model_post_init function, we handle both
104 def wrapped_model_post_init(self: BaseModel, context: Any, /) -> None: 1abcdmnopABqrefghstuvCDijklwxyzEF
105 """We need to both initialize private attributes and call the user-defined model_post_init
106 method.
107 """
108 init_private_attributes(self, context) 1abcdmnopABqrefghstuvCDijklwxyzEF
109 original_model_post_init(self, context) 1abcdmnopABqrefghstuvCDijklwxyzEF
111 namespace['model_post_init'] = wrapped_model_post_init 1abcdmnopABqrefghstuvCDijklwxyzEF
112 else:
113 namespace['model_post_init'] = init_private_attributes 1abcdmnopABqrefghstuvCDijklwxyzEF
115 namespace['__class_vars__'] = class_vars 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
116 namespace['__private_attributes__'] = {**base_private_attributes, **private_attributes} 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
118 cls: type[BaseModel] = super().__new__(mcs, cls_name, bases, namespace, **kwargs) # type: ignore 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
120 from ..main import BaseModel 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
122 mro = cls.__mro__ 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
123 if Generic in mro and mro.index(Generic) < mro.index(BaseModel): 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
124 warnings.warn( 1abcdmnopABqrefghstuvCDijklwxyzEF
125 GenericBeforeBaseModelWarning(
126 'Classes should inherit from `BaseModel` before generic classes (e.g. `typing.Generic[T]`) '
127 'for pydantic generics to work properly.'
128 ),
129 stacklevel=2,
130 )
132 cls.__pydantic_custom_init__ = not getattr(cls.__init__, '__pydantic_base_init__', False) 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
133 cls.__pydantic_post_init__ = None if cls.model_post_init is BaseModel.model_post_init else 'model_post_init' 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
135 cls.__pydantic_decorators__ = DecoratorInfos.build(cls) 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
137 # Use the getattr below to grab the __parameters__ from the `typing.Generic` parent class
138 if __pydantic_generic_metadata__: 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
139 cls.__pydantic_generic_metadata__ = __pydantic_generic_metadata__ 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
140 else:
141 parent_parameters = getattr(cls, '__pydantic_generic_metadata__', {}).get('parameters', ()) 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
142 parameters = getattr(cls, '__parameters__', None) or parent_parameters 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
143 if parameters and parent_parameters and not all(x in parameters for x in parent_parameters): 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
144 from ..root_model import RootModelRootType 1abcdmnopABqrefghstuvCDijklwxyzEF
146 missing_parameters = tuple(x for x in parameters if x not in parent_parameters) 1abcdmnopABqrefghstuvCDijklwxyzEF
147 if RootModelRootType in parent_parameters and RootModelRootType not in parameters: 1abcdmnopABqrefghstuvCDijklwxyzEF
148 # This is a special case where the user has subclassed `RootModel`, but has not parametrized
149 # RootModel with the generic type identifiers being used. Ex:
150 # class MyModel(RootModel, Generic[T]):
151 # root: T
152 # Should instead just be:
153 # class MyModel(RootModel[T]):
154 # root: T
155 parameters_str = ', '.join([x.__name__ for x in missing_parameters]) 1abcdmnopABqrefghstuvCDijklwxyzEF
156 error_message = ( 1abcdmnopABqrefghstuvCDijklwxyzEF
157 f'{cls.__name__} is a subclass of `RootModel`, but does not include the generic type identifier(s) '
158 f'{parameters_str} in its parameters. '
159 f'You should parametrize RootModel directly, e.g., `class {cls.__name__}(RootModel[{parameters_str}]): ...`.'
160 )
161 else:
162 combined_parameters = parent_parameters + missing_parameters 1abcdmnopABqrefghstuvCDijklwxyzEF
163 parameters_str = ', '.join([str(x) for x in combined_parameters]) 1abcdmnopABqrefghstuvCDijklwxyzEF
164 generic_type_label = f'typing.Generic[{parameters_str}]' 1abcdmnopABqrefghstuvCDijklwxyzEF
165 error_message = ( 1abcdmnopABqrefghstuvCDijklwxyzEF
166 f'All parameters must be present on typing.Generic;'
167 f' you should inherit from {generic_type_label}.'
168 )
169 if Generic not in bases: # pragma: no cover 1abcdmnopABqrefghstuvCDijklwxyzEF
170 # We raise an error here not because it is desirable, but because some cases are mishandled.
171 # It would be nice to remove this error and still have things behave as expected, it's just
172 # challenging because we are using a custom `__class_getitem__` to parametrize generic models,
173 # and not returning a typing._GenericAlias from it.
174 bases_str = ', '.join([x.__name__ for x in bases] + [generic_type_label]) 1abcdmnopABqrefghstuvCDijklwxyzEF
175 error_message += ( 1abcdmnopABqrefghstuvCDijklwxyzEF
176 f' Note: `typing.Generic` must go last: `class {cls.__name__}({bases_str}): ...`)'
177 )
178 raise TypeError(error_message) 1abcdmnopABqrefghstuvCDijklwxyzEF
180 cls.__pydantic_generic_metadata__ = { 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
181 'origin': None,
182 'args': (),
183 'parameters': parameters,
184 }
186 cls.__pydantic_complete__ = False # Ensure this specific class gets completed 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
188 # preserve `__set_name__` protocol defined in https://peps.python.org/pep-0487
189 # for attributes not in `new_namespace` (e.g. private attributes)
190 for name, obj in private_attributes.items(): 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
191 obj.__set_name__(cls, name) 1abcdmnopABqrefghstuvCDijklwxyzEF
193 if __pydantic_reset_parent_namespace__: 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
194 cls.__pydantic_parent_namespace__ = build_lenient_weakvaluedict(parent_frame_namespace()) 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
195 parent_namespace = getattr(cls, '__pydantic_parent_namespace__', None) 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
196 if isinstance(parent_namespace, dict): 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
197 parent_namespace = unpack_lenient_weakvaluedict(parent_namespace) 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
199 types_namespace = get_cls_types_namespace(cls, parent_namespace) 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
200 set_model_fields(cls, bases, config_wrapper, types_namespace) 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
202 if config_wrapper.frozen and '__hash__' not in namespace: 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
203 set_default_hash_func(cls, bases) 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
205 complete_model_class( 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
206 cls,
207 cls_name,
208 config_wrapper,
209 raise_errors=False,
210 types_namespace=types_namespace,
211 create_model_module=_create_model_module,
212 )
214 # If this is placed before the complete_model_class call above,
215 # the generic computed fields return type is set to PydanticUndefined
216 cls.model_computed_fields = {k: v.info for k, v in cls.__pydantic_decorators__.computed_fields.items()} 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
218 set_deprecated_descriptors(cls) 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
220 # using super(cls, cls) on the next line ensures we only call the parent class's __pydantic_init_subclass__
221 # I believe the `type: ignore` is only necessary because mypy doesn't realize that this code branch is
222 # only hit for _proper_ subclasses of BaseModel
223 super(cls, cls).__pydantic_init_subclass__(**kwargs) # type: ignore[misc] 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
224 return cls 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
225 else:
226 # this is the BaseModel class itself being created, no logic required
227 return super().__new__(mcs, cls_name, bases, namespace, **kwargs) 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
229 if not typing.TYPE_CHECKING: # pragma: no branch 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
230 # We put `__getattr__` in a non-TYPE_CHECKING block because otherwise, mypy allows arbitrary attribute access
232 def __getattr__(self, item: str) -> Any: 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
233 """This is necessary to keep attribute access working for class attribute access."""
234 private_attributes = self.__dict__.get('__private_attributes__') 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
235 if private_attributes and item in private_attributes: 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
236 return private_attributes[item] 1abcdmnopABqrefghstuvCDijklwxyzEF
237 raise AttributeError(item) 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
239 @classmethod 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
240 def __prepare__(cls, *args: Any, **kwargs: Any) -> dict[str, object]: 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
241 return _ModelNamespaceDict() 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
243 def __instancecheck__(self, instance: Any) -> bool: 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
244 """Avoid calling ABC _abc_subclasscheck unless we're pretty sure.
246 See #3829 and python/cpython#92810
247 """
248 return hasattr(instance, '__pydantic_validator__') and super().__instancecheck__(instance) 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
250 @staticmethod 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
251 def _collect_bases_data(bases: tuple[type[Any], ...]) -> tuple[set[str], set[str], dict[str, ModelPrivateAttr]]: 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
252 from ..main import BaseModel 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
254 field_names: set[str] = set() 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
255 class_vars: set[str] = set() 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
256 private_attributes: dict[str, ModelPrivateAttr] = {} 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
257 for base in bases: 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
258 if issubclass(base, BaseModel) and base is not BaseModel: 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
259 # model_fields might not be defined yet in the case of generics, so we use getattr here:
260 field_names.update(getattr(base, 'model_fields', {}).keys()) 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
261 class_vars.update(base.__class_vars__) 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
262 private_attributes.update(base.__private_attributes__) 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
263 return field_names, class_vars, private_attributes 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
265 @property 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
266 @deprecated('The `__fields__` attribute is deprecated, use `model_fields` instead.', category=None) 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
267 def __fields__(self) -> dict[str, FieldInfo]: 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
268 warnings.warn( 1abcdmnopABqrefghstuvCDijklwxyzEF
269 'The `__fields__` attribute is deprecated, use `model_fields` instead.', PydanticDeprecatedSince20
270 )
271 return self.model_fields # type: ignore 1abcdmnopABqrefghstuvCDijklwxyzEF
273 def __dir__(self) -> list[str]: 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
274 attributes = list(super().__dir__()) 1abcdmnopABqrefghstuvCDijklwxyzEF
275 if '__fields__' in attributes: 275 ↛ 277line 275 didn't jump to line 277, because the condition on line 275 was always true1abcdmnopABqrefghstuvCDijklwxyzEF
276 attributes.remove('__fields__') 1abcdmnopABqrefghstuvCDijklwxyzEF
277 return attributes 1abcdmnopABqrefghstuvCDijklwxyzEF
280def init_private_attributes(self: BaseModel, context: Any, /) -> None: 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
281 """This function is meant to behave like a BaseModel method to initialise private attributes.
283 It takes context as an argument since that's what pydantic-core passes when calling it.
285 Args:
286 self: The BaseModel instance.
287 context: The context.
288 """
289 if getattr(self, '__pydantic_private__', None) is None: 1abcdmnopABqrefghstuvCDijklwxyzEF
290 pydantic_private = {} 1abcdmnopABqrefghstuvCDijklwxyzEF
291 for name, private_attr in self.__private_attributes__.items(): 1abcdmnopABqrefghstuvCDijklwxyzEF
292 default = private_attr.get_default() 1abcdmnopABqrefghstuvCDijklwxyzEF
293 if default is not PydanticUndefined: 1abcdmnopABqrefghstuvCDijklwxyzEF
294 pydantic_private[name] = default 1abcdmnopABqrefghstuvCDijklwxyzEF
295 object_setattr(self, '__pydantic_private__', pydantic_private) 1abcdmnopABqrefghstuvCDijklwxyzEF
298def get_model_post_init(namespace: dict[str, Any], bases: tuple[type[Any], ...]) -> Callable[..., Any] | None: 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
299 """Get the `model_post_init` method from the namespace or the class bases, or `None` if not defined."""
300 if 'model_post_init' in namespace: 1abcdmnopABqrefghstuvCDijklwxyzEF
301 return namespace['model_post_init'] 1abcdmnopABqrefghstuvCDijklwxyzEF
303 from ..main import BaseModel 1abcdmnopABqrefghstuvCDijklwxyzEF
305 model_post_init = get_attribute_from_bases(bases, 'model_post_init') 1abcdmnopABqrefghstuvCDijklwxyzEF
306 if model_post_init is not BaseModel.model_post_init: 1abcdmnopABqrefghstuvCDijklwxyzEF
307 return model_post_init 1abcdmnopABqrefghstuvCDijklwxyzEF
310def inspect_namespace( # noqa C901 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
311 namespace: dict[str, Any],
312 ignored_types: tuple[type[Any], ...],
313 base_class_vars: set[str],
314 base_class_fields: set[str],
315) -> dict[str, ModelPrivateAttr]:
316 """Iterate over the namespace and:
317 * gather private attributes
318 * check for items which look like fields but are not (e.g. have no annotation) and warn.
320 Args:
321 namespace: The attribute dictionary of the class to be created.
322 ignored_types: A tuple of ignore types.
323 base_class_vars: A set of base class class variables.
324 base_class_fields: A set of base class fields.
326 Returns:
327 A dict contains private attributes info.
329 Raises:
330 TypeError: If there is a `__root__` field in model.
331 NameError: If private attribute name is invalid.
332 PydanticUserError:
333 - If a field does not have a type annotation.
334 - If a field on base class was overridden by a non-annotated attribute.
335 """
336 from ..fields import FieldInfo, ModelPrivateAttr, PrivateAttr 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
338 all_ignored_types = ignored_types + default_ignored_types() 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
340 private_attributes: dict[str, ModelPrivateAttr] = {} 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
341 raw_annotations = namespace.get('__annotations__', {}) 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
343 if '__root__' in raw_annotations or '__root__' in namespace: 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
344 raise TypeError("To define root models, use `pydantic.RootModel` rather than a field called '__root__'") 1abcdmnopABqrefghstuvCDijklwxyzEF
346 ignored_names: set[str] = set() 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
347 for var_name, value in list(namespace.items()): 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
348 if var_name == 'model_config' or var_name == '__pydantic_extra__': 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
349 continue 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
350 elif ( 1abcdmnopqrefghstuvGHIJKLMNijklwxyz
351 isinstance(value, type)
352 and value.__module__ == namespace['__module__']
353 and '__qualname__' in namespace
354 and value.__qualname__.startswith(namespace['__qualname__'])
355 ):
356 # `value` is a nested type defined in this namespace; don't error
357 continue 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
358 elif isinstance(value, all_ignored_types) or value.__class__.__module__ == 'functools': 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
359 ignored_names.add(var_name) 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
360 continue 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
361 elif isinstance(value, ModelPrivateAttr): 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
362 if var_name.startswith('__'): 1abcdmnopABqrefghstuvCDijklwxyzEF
363 raise NameError( 1abcdmnopABqrefghstuvCDijklwxyzEF
364 'Private attributes must not use dunder names;'
365 f' use a single underscore prefix instead of {var_name!r}.'
366 )
367 elif is_valid_field_name(var_name): 1abcdmnopABqrefghstuvCDijklwxyzEF
368 raise NameError( 1abcdmnopABqrefghstuvCDijklwxyzEF
369 'Private attributes must not use valid field names;'
370 f' use sunder names, e.g. {"_" + var_name!r} instead of {var_name!r}.'
371 )
372 private_attributes[var_name] = value 1abcdmnopABqrefghstuvCDijklwxyzEF
373 del namespace[var_name] 1abcdmnopABqrefghstuvCDijklwxyzEF
374 elif isinstance(value, FieldInfo) and not is_valid_field_name(var_name): 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
375 suggested_name = var_name.lstrip('_') or 'my_field' # don't suggest '' for all-underscore name 1abcdmnopABqrefghstuvCDijklwxyzEF
376 raise NameError( 1abcdmnopABqrefghstuvCDijklwxyzEF
377 f'Fields must not use names with leading underscores;'
378 f' e.g., use {suggested_name!r} instead of {var_name!r}.'
379 )
381 elif var_name.startswith('__'): 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
382 continue 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
383 elif is_valid_privateattr_name(var_name): 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
384 if var_name not in raw_annotations or not is_classvar(raw_annotations[var_name]): 1abcdmnopABqrefghstuvCDijklwxyzEF
385 private_attributes[var_name] = PrivateAttr(default=value) 1abcdmnopABqrefghstuvCDijklwxyzEF
386 del namespace[var_name] 1abcdmnopABqrefghstuvCDijklwxyzEF
387 elif var_name in base_class_vars: 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
388 continue 1abcdmnopABqrefghstuvCDijklwxyzEF
389 elif var_name not in raw_annotations: 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
390 if var_name in base_class_fields: 1abcdmnopABqrefghstuvCDijklwxyzEF
391 raise PydanticUserError( 1abcdmnopABqrefghstuvCDijklwxyzEF
392 f'Field {var_name!r} defined on a base class was overridden by a non-annotated attribute. '
393 f'All field definitions, including overrides, require a type annotation.',
394 code='model-field-overridden',
395 )
396 elif isinstance(value, FieldInfo): 1abcdmnopABqrefghstuvCDijklwxyzEF
397 raise PydanticUserError( 1abcdmnopABqrefghstuvCDijklwxyzEF
398 f'Field {var_name!r} requires a type annotation', code='model-field-missing-annotation'
399 )
400 else:
401 raise PydanticUserError( 1abcdmnopABqrefghstuvCDijklwxyzEF
402 f'A non-annotated attribute was detected: `{var_name} = {value!r}`. All model fields require a '
403 f'type annotation; if `{var_name}` is not meant to be a field, you may be able to resolve this '
404 f"error by annotating it as a `ClassVar` or updating `model_config['ignored_types']`.",
405 code='model-field-missing-annotation',
406 )
408 for ann_name, ann_type in raw_annotations.items(): 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
409 if ( 1abcdmnopqrefghstuvGHIJKLMNijklwxyz
410 is_valid_privateattr_name(ann_name)
411 and ann_name not in private_attributes
412 and ann_name not in ignored_names
413 and not is_classvar(ann_type)
414 and ann_type not in all_ignored_types
415 and getattr(ann_type, '__module__', None) != 'functools'
416 ):
417 if is_annotated(ann_type): 1abcdmnopABqrefghstuvCDijklwxyzEF
418 _, *metadata = typing_extensions.get_args(ann_type) 1abcdmnopABqrefghstuvCDijklwxyzEF
419 private_attr = next((v for v in metadata if isinstance(v, ModelPrivateAttr)), None) 1abcdmnopABqrefghstuvCDijklwxyzEF
420 if private_attr is not None: 1abcdmnopABqrefghstuvCDijklwxyzEF
421 private_attributes[ann_name] = private_attr 1abcdmnopABqrefghstuvCDijklwxyzEF
422 continue 1abcdmnopABqrefghstuvCDijklwxyzEF
423 private_attributes[ann_name] = PrivateAttr() 1abcdmnopABqrefghstuvCDijklwxyzEF
425 return private_attributes 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
428def set_default_hash_func(cls: type[BaseModel], bases: tuple[type[Any], ...]) -> None: 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
429 base_hash_func = get_attribute_from_bases(bases, '__hash__') 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
430 new_hash_func = make_hash_func(cls) 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
431 if base_hash_func in {None, object.__hash__} or getattr(base_hash_func, '__code__', None) == new_hash_func.__code__: 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
432 # If `__hash__` is some default, we generate a hash function.
433 # It will be `None` if not overridden from BaseModel.
434 # It may be `object.__hash__` if there is another
435 # parent class earlier in the bases which doesn't override `__hash__` (e.g. `typing.Generic`).
436 # It may be a value set by `set_default_hash_func` if `cls` is a subclass of another frozen model.
437 # In the last case we still need a new hash function to account for new `model_fields`.
438 cls.__hash__ = new_hash_func 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
441def make_hash_func(cls: type[BaseModel]) -> Any: 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
442 getter = operator.itemgetter(*cls.model_fields.keys()) if cls.model_fields else lambda _: 0 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
444 def hash_func(self: Any) -> int: 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
445 try: 1abcdmnopABqrefghstuvCDijklwxyzEF
446 return hash(getter(self.__dict__)) 1abcdmnopABqrefghstuvCDijklwxyzEF
447 except KeyError: 1abcdmnopABqrefghstuvCDijklwxyzEF
448 # In rare cases (such as when using the deprecated copy method), the __dict__ may not contain
449 # all model fields, which is how we can get here.
450 # getter(self.__dict__) is much faster than any 'safe' method that accounts for missing keys,
451 # and wrapping it in a `try` doesn't slow things down much in the common case.
452 return hash(getter(SafeGetItemProxy(self.__dict__))) 1abcdmnopABqrefghstuvCDijklwxyzEF
454 return hash_func 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
457def set_model_fields( 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
458 cls: type[BaseModel], bases: tuple[type[Any], ...], config_wrapper: ConfigWrapper, types_namespace: dict[str, Any]
459) -> None:
460 """Collect and set `cls.model_fields` and `cls.__class_vars__`.
462 Args:
463 cls: BaseModel or dataclass.
464 bases: Parents of the class, generally `cls.__bases__`.
465 config_wrapper: The config wrapper instance.
466 types_namespace: Optional extra namespace to look for types in.
467 """
468 typevars_map = get_model_typevars_map(cls) 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
469 fields, class_vars = collect_model_fields(cls, bases, config_wrapper, types_namespace, typevars_map=typevars_map) 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
471 cls.model_fields = fields 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
472 cls.__class_vars__.update(class_vars) 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
474 for k in class_vars: 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
475 # Class vars should not be private attributes
476 # We remove them _here_ and not earlier because we rely on inspecting the class to determine its classvars,
477 # but private attributes are determined by inspecting the namespace _prior_ to class creation.
478 # In the case that a classvar with a leading-'_' is defined via a ForwardRef (e.g., when using
479 # `__future__.annotations`), we want to remove the private attribute which was detected _before_ we knew it
480 # evaluated to a classvar
482 value = cls.__private_attributes__.pop(k, None) 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
483 if value is not None and value.default is not PydanticUndefined: 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
484 setattr(cls, k, value.default) 1abcdmnopABqrefghstuvCDijklwxyzEF
487def complete_model_class( 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
488 cls: type[BaseModel],
489 cls_name: str,
490 config_wrapper: ConfigWrapper,
491 *,
492 raise_errors: bool = True,
493 types_namespace: dict[str, Any] | None,
494 create_model_module: str | None = None,
495) -> bool:
496 """Finish building a model class.
498 This logic must be called after class has been created since validation functions must be bound
499 and `get_type_hints` requires a class object.
501 Args:
502 cls: BaseModel or dataclass.
503 cls_name: The model or dataclass name.
504 config_wrapper: The config wrapper instance.
505 raise_errors: Whether to raise errors.
506 types_namespace: Optional extra namespace to look for types in.
507 create_model_module: The module of the class to be created, if created by `create_model`.
509 Returns:
510 `True` if the model is successfully completed, else `False`.
512 Raises:
513 PydanticUndefinedAnnotation: If `PydanticUndefinedAnnotation` occurs in`__get_pydantic_core_schema__`
514 and `raise_errors=True`.
515 """
516 typevars_map = get_model_typevars_map(cls) 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
517 gen_schema = GenerateSchema( 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
518 config_wrapper,
519 types_namespace,
520 typevars_map,
521 )
523 handler = CallbackGetCoreSchemaHandler( 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
524 partial(gen_schema.generate_schema, from_dunder_get_core_schema=False),
525 gen_schema,
526 ref_mode='unpack',
527 )
529 if config_wrapper.defer_build and 'model' in config_wrapper.experimental_defer_build_mode: 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
530 set_model_mocks(cls, cls_name) 1abcdmnopABqrefghstuvCDijklwxyzEF
531 return False 1abcdmnopABqrefghstuvCDijklwxyzEF
533 try: 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
534 schema = cls.__get_pydantic_core_schema__(cls, handler) 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
535 except PydanticUndefinedAnnotation as e: 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
536 if raise_errors: 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
537 raise 1abcdmnopABqrefghstuvCDijklwxyzEF
538 set_model_mocks(cls, cls_name, f'`{e.name}`') 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
539 return False 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
541 core_config = config_wrapper.core_config(cls) 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
543 try: 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
544 schema = gen_schema.clean_schema(schema) 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
545 except gen_schema.CollectedInvalid: 1abcdmnopABqrefghstuvCDijklwxyzEF
546 set_model_mocks(cls, cls_name) 1abcdmnopABqrefghstuvCDijklwxyzEF
547 return False 1abcdmnopABqrefghstuvCDijklwxyzEF
549 # debug(schema)
550 cls.__pydantic_core_schema__ = schema 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
552 cls.__pydantic_validator__ = create_schema_validator( 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
553 schema,
554 cls,
555 create_model_module or cls.__module__,
556 cls.__qualname__,
557 'create_model' if create_model_module else 'BaseModel',
558 core_config,
559 config_wrapper.plugin_settings,
560 )
561 cls.__pydantic_serializer__ = SchemaSerializer(schema, core_config) 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
562 cls.__pydantic_complete__ = True 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
564 # set __signature__ attr only for model class, but not for its instances
565 cls.__signature__ = ClassAttribute( 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
566 '__signature__',
567 generate_pydantic_signature(init=cls.__init__, fields=cls.model_fields, config_wrapper=config_wrapper),
568 )
569 return True 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
572def set_deprecated_descriptors(cls: type[BaseModel]) -> None: 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
573 """Set data descriptors on the class for deprecated fields."""
574 for field, field_info in cls.model_fields.items(): 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
575 if (msg := field_info.deprecation_message) is not None: 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
576 desc = _DeprecatedFieldDescriptor(msg) 1abcdmnopABqrefghstuvCDijklwxyzEF
577 desc.__set_name__(cls, field) 1abcdmnopABqrefghstuvCDijklwxyzEF
578 setattr(cls, field, desc) 1abcdmnopABqrefghstuvCDijklwxyzEF
580 for field, computed_field_info in cls.model_computed_fields.items(): 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
581 if ( 1abcdqrefghijkl
582 (msg := computed_field_info.deprecation_message) is not None
583 # Avoid having two warnings emitted:
584 and not hasattr(unwrap_wrapped_function(computed_field_info.wrapped_property), '__deprecated__')
585 ):
586 desc = _DeprecatedFieldDescriptor(msg, computed_field_info.wrapped_property) 1abcdmnopABqrefghstuvCDijklwxyzEF
587 desc.__set_name__(cls, field) 1abcdmnopABqrefghstuvCDijklwxyzEF
588 setattr(cls, field, desc) 1abcdmnopABqrefghstuvCDijklwxyzEF
591class _DeprecatedFieldDescriptor: 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
592 """Data descriptor used to emit a runtime deprecation warning before accessing a deprecated field.
594 Attributes:
595 msg: The deprecation message to be emitted.
596 wrapped_property: The property instance if the deprecated field is a computed field, or `None`.
597 field_name: The name of the field being deprecated.
598 """
600 field_name: str 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
602 def __init__(self, msg: str, wrapped_property: property | None = None) -> None: 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
603 self.msg = msg 1abcdmnopABqrefghstuvCDijklwxyzEF
604 self.wrapped_property = wrapped_property 1abcdmnopABqrefghstuvCDijklwxyzEF
606 def __set_name__(self, cls: type[BaseModel], name: str) -> None: 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
607 self.field_name = name 1abcdmnopABqrefghstuvCDijklwxyzEF
609 def __get__(self, obj: BaseModel | None, obj_type: type[BaseModel] | None = None) -> Any: 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
610 if obj is None: 1abcdmnopABqrefghstuvCDijklwxyzEF
611 raise AttributeError(self.field_name) 1abcdmnopABqrefghstuvCDijklwxyzEF
613 warnings.warn(self.msg, builtins.DeprecationWarning, stacklevel=2) 1abcdmnopABqrefghstuvCDijklwxyzEF
615 if self.wrapped_property is not None: 1abcdmnopABqrefghstuvCDijklwxyzEF
616 return self.wrapped_property.__get__(obj, obj_type) 1abcdmnopABqrefghstuvCDijklwxyzEF
617 return obj.__dict__[self.field_name] 1abcdmnopABqrefghstuvCDijklwxyzEF
619 # Defined to take precedence over the instance's dictionary
620 # Note that it will not be called when setting a value on a model instance
621 # as `BaseModel.__setattr__` is defined and takes priority.
622 def __set__(self, obj: Any, value: Any) -> NoReturn: 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
623 raise AttributeError(self.field_name)
626class _PydanticWeakRef: 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
627 """Wrapper for `weakref.ref` that enables `pickle` serialization.
629 Cloudpickle fails to serialize `weakref.ref` objects due to an arcane error related
630 to abstract base classes (`abc.ABC`). This class works around the issue by wrapping
631 `weakref.ref` instead of subclassing it.
633 See https://github.com/pydantic/pydantic/issues/6763 for context.
635 Semantics:
636 - If not pickled, behaves the same as a `weakref.ref`.
637 - If pickled along with the referenced object, the same `weakref.ref` behavior
638 will be maintained between them after unpickling.
639 - If pickled without the referenced object, after unpickling the underlying
640 reference will be cleared (`__call__` will always return `None`).
641 """
643 def __init__(self, obj: Any): 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
644 if obj is None: 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
645 # The object will be `None` upon deserialization if the serialized weakref
646 # had lost its underlying object.
647 self._wr = None 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
648 else:
649 self._wr = weakref.ref(obj) 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
651 def __call__(self) -> Any: 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
652 if self._wr is None: 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
653 return None 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
654 else:
655 return self._wr() 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
657 def __reduce__(self) -> tuple[Callable, tuple[weakref.ReferenceType | None]]: 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
658 return _PydanticWeakRef, (self(),) 1abcdmnopABqrefghstuvCDijklwxyzEF
661def build_lenient_weakvaluedict(d: dict[str, Any] | None) -> dict[str, Any] | None: 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
662 """Takes an input dictionary, and produces a new value that (invertibly) replaces the values with weakrefs.
664 We can't just use a WeakValueDictionary because many types (including int, str, etc.) can't be stored as values
665 in a WeakValueDictionary.
667 The `unpack_lenient_weakvaluedict` function can be used to reverse this operation.
668 """
669 if d is None: 669 ↛ 670line 669 didn't jump to line 670, because the condition on line 669 was never true1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
670 return None
671 result = {} 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
672 for k, v in d.items(): 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
673 try: 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
674 proxy = _PydanticWeakRef(v) 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
675 except TypeError: 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
676 proxy = v 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
677 result[k] = proxy 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
678 return result 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
681def unpack_lenient_weakvaluedict(d: dict[str, Any] | None) -> dict[str, Any] | None: 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
682 """Inverts the transform performed by `build_lenient_weakvaluedict`."""
683 if d is None: 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
684 return None 1abcdmnopABqrefghstuvCDijklwxyzEF
686 result = {} 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
687 for k, v in d.items(): 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
688 if isinstance(v, _PydanticWeakRef): 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
689 v = v() 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
690 if v is not None: 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
691 result[k] = v 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
692 else:
693 result[k] = v 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
694 return result 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
697def default_ignored_types() -> tuple[type[Any], ...]: 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
698 from ..fields import ComputedFieldInfo 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
700 return ( 1abcdmnopABqrefghstuvCDGHIJKLMNOijklwxyzEF
701 FunctionType,
702 property,
703 classmethod,
704 staticmethod,
705 PydanticDescriptorProxy,
706 ComputedFieldInfo,
707 ValidateCallWrapper,
708 )