Coverage for pydantic/_internal/_config.py: 100.00%
137 statements
« prev ^ index » next coverage.py v7.5.4, created at 2024-07-03 19:29 +0000
« prev ^ index » next coverage.py v7.5.4, created at 2024-07-03 19:29 +0000
1from __future__ import annotations as _annotations 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL
3import warnings 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL
4from contextlib import contextmanager 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL
5from typing import ( 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL
6 TYPE_CHECKING,
7 Any,
8 Callable,
9 cast,
10)
12from pydantic_core import core_schema 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL
13from typing_extensions import ( 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL
14 Literal,
15 Self,
16)
18from ..aliases import AliasGenerator 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL
19from ..config import ConfigDict, ExtraValues, JsonDict, JsonEncoder, JsonSchemaExtraCallable 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL
20from ..errors import PydanticUserError 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL
21from ..warnings import PydanticDeprecatedSince20 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL
23if not TYPE_CHECKING: 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL
24 # See PyCharm issues https://youtrack.jetbrains.com/issue/PY-21915
25 # and https://youtrack.jetbrains.com/issue/PY-51428
26 DeprecationWarning = PydanticDeprecatedSince20 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL
28if TYPE_CHECKING: 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL
29 from .._internal._schema_generation_shared import GenerateSchema
30 from ..fields import ComputedFieldInfo, FieldInfo
32DEPRECATION_MESSAGE = 'Support for class-based `config` is deprecated, use ConfigDict instead.' 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL
35class ConfigWrapper: 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL
36 """Internal wrapper for Config which exposes ConfigDict items as attributes."""
38 __slots__ = ('config_dict',) 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL
40 config_dict: ConfigDict 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL
42 # all annotations are copied directly from ConfigDict, and should be kept up to date, a test will fail if they
43 # stop matching
44 title: str | None 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL
45 str_to_lower: bool 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL
46 str_to_upper: bool 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL
47 str_strip_whitespace: bool 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL
48 str_min_length: int 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL
49 str_max_length: int | None 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL
50 extra: ExtraValues | None 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL
51 frozen: bool 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL
52 populate_by_name: bool 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL
53 use_enum_values: bool 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL
54 validate_assignment: bool 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL
55 arbitrary_types_allowed: bool 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL
56 from_attributes: bool 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL
57 # whether to use the actual key provided in the data (e.g. alias or first alias for "field required" errors) instead of field_names
58 # to construct error `loc`s, default `True`
59 loc_by_alias: bool 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL
60 alias_generator: Callable[[str], str] | AliasGenerator | None 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL
61 model_title_generator: Callable[[type], str] | None 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL
62 field_title_generator: Callable[[str, FieldInfo | ComputedFieldInfo], str] | None 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL
63 ignored_types: tuple[type, ...] 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL
64 allow_inf_nan: bool 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL
65 json_schema_extra: JsonDict | JsonSchemaExtraCallable | None 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL
66 json_encoders: dict[type[object], JsonEncoder] | None 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL
68 # new in V2
69 strict: bool 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL
70 # whether instances of models and dataclasses (including subclass instances) should re-validate, default 'never'
71 revalidate_instances: Literal['always', 'never', 'subclass-instances'] 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL
72 ser_json_timedelta: Literal['iso8601', 'float'] 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL
73 ser_json_bytes: Literal['utf8', 'base64'] 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL
74 ser_json_inf_nan: Literal['null', 'constants', 'strings'] 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL
75 # whether to validate default values during validation, default False
76 validate_default: bool 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL
77 validate_return: bool 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL
78 protected_namespaces: tuple[str, ...] 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL
79 hide_input_in_errors: bool 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL
80 defer_build: bool 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL
81 experimental_defer_build_mode: tuple[Literal['model', 'type_adapter'], ...] 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL
82 plugin_settings: dict[str, object] | None 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL
83 schema_generator: type[GenerateSchema] | None 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL
84 json_schema_serialization_defaults_required: bool 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL
85 json_schema_mode_override: Literal['validation', 'serialization', None] 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL
86 coerce_numbers_to_str: bool 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL
87 regex_engine: Literal['rust-regex', 'python-re'] 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL
88 validation_error_cause: bool 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL
89 use_attribute_docstrings: bool 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL
90 cache_strings: bool | Literal['all', 'keys', 'none'] 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL
92 def __init__(self, config: ConfigDict | dict[str, Any] | type[Any] | None, *, check: bool = True): 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL
93 if check: 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL
94 self.config_dict = prepare_config(config) 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL
95 else:
96 self.config_dict = cast(ConfigDict, config) 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL
98 @classmethod 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL
99 def for_model(cls, bases: tuple[type[Any], ...], namespace: dict[str, Any], kwargs: dict[str, Any]) -> Self: 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL
100 """Build a new `ConfigWrapper` instance for a `BaseModel`.
102 The config wrapper built based on (in descending order of priority):
103 - options from `kwargs`
104 - options from the `namespace`
105 - options from the base classes (`bases`)
107 Args:
108 bases: A tuple of base classes.
109 namespace: The namespace of the class being created.
110 kwargs: The kwargs passed to the class being created.
112 Returns:
113 A `ConfigWrapper` instance for `BaseModel`.
114 """
115 config_new = ConfigDict() 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL
116 for base in bases: 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL
117 config = getattr(base, 'model_config', None) 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL
118 if config: 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL
119 config_new.update(config.copy()) 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL
121 config_class_from_namespace = namespace.get('Config') 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL
122 config_dict_from_namespace = namespace.get('model_config') 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL
124 raw_annotations = namespace.get('__annotations__', {}) 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL
125 if raw_annotations.get('model_config') and not config_dict_from_namespace: 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL
126 raise PydanticUserError( 1abcdefghijklmnopqrstuvwxyzABCDEFGHIJKL
127 '`model_config` cannot be used as a model field name. Use `model_config` for model configuration.',
128 code='model-config-invalid-field-name',
129 )
131 if config_class_from_namespace and config_dict_from_namespace: 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL
132 raise PydanticUserError('"Config" and "model_config" cannot be used together', code='config-both') 1abcdefghijklmnopqrstuvwxyzABCDEFGHIJKL
134 config_from_namespace = config_dict_from_namespace or prepare_config(config_class_from_namespace) 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL
136 config_new.update(config_from_namespace) 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL
138 for k in list(kwargs.keys()): 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL
139 if k in config_keys: 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL
140 config_new[k] = kwargs.pop(k) 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL
142 return cls(config_new) 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL
144 # we don't show `__getattr__` to type checkers so missing attributes cause errors
145 if not TYPE_CHECKING: # pragma: no branch 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL
147 def __getattr__(self, name: str) -> Any: 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL
148 try: 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL
149 return self.config_dict[name] 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL
150 except KeyError: 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL
151 try: 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL
152 return config_defaults[name] 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL
153 except KeyError: 1abcdefghijklmnopqrstuvwxyzABCDEFGHIJKL
154 raise AttributeError(f'Config has no attribute {name!r}') from None 1abcdefghijklmnopqrstuvwxyzABCDEFGHIJKL
156 def core_config(self, obj: Any) -> core_schema.CoreConfig: 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL
157 """Create a pydantic-core config, `obj` is just used to populate `title` if not set in config.
159 Pass `obj=None` if you do not want to attempt to infer the `title`.
161 We don't use getattr here since we don't want to populate with defaults.
163 Args:
164 obj: An object used to populate `title` if not set in config.
166 Returns:
167 A `CoreConfig` object created from config.
168 """
170 def dict_not_none(**kwargs: Any) -> Any: 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL
171 return {k: v for k, v in kwargs.items() if v is not None} 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL
173 core_config = core_schema.CoreConfig( 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL
174 **dict_not_none(
175 title=self.config_dict.get('title') or (obj and obj.__name__),
176 extra_fields_behavior=self.config_dict.get('extra'),
177 allow_inf_nan=self.config_dict.get('allow_inf_nan'),
178 populate_by_name=self.config_dict.get('populate_by_name'),
179 str_strip_whitespace=self.config_dict.get('str_strip_whitespace'),
180 str_to_lower=self.config_dict.get('str_to_lower'),
181 str_to_upper=self.config_dict.get('str_to_upper'),
182 strict=self.config_dict.get('strict'),
183 ser_json_timedelta=self.config_dict.get('ser_json_timedelta'),
184 ser_json_bytes=self.config_dict.get('ser_json_bytes'),
185 ser_json_inf_nan=self.config_dict.get('ser_json_inf_nan'),
186 from_attributes=self.config_dict.get('from_attributes'),
187 loc_by_alias=self.config_dict.get('loc_by_alias'),
188 revalidate_instances=self.config_dict.get('revalidate_instances'),
189 validate_default=self.config_dict.get('validate_default'),
190 str_max_length=self.config_dict.get('str_max_length'),
191 str_min_length=self.config_dict.get('str_min_length'),
192 hide_input_in_errors=self.config_dict.get('hide_input_in_errors'),
193 coerce_numbers_to_str=self.config_dict.get('coerce_numbers_to_str'),
194 regex_engine=self.config_dict.get('regex_engine'),
195 validation_error_cause=self.config_dict.get('validation_error_cause'),
196 cache_strings=self.config_dict.get('cache_strings'),
197 )
198 )
199 return core_config 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL
201 def __repr__(self): 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL
202 c = ', '.join(f'{k}={v!r}' for k, v in self.config_dict.items()) 1abcdefghijklmnopqrstuvwxyzABCDEFGHIJKL
203 return f'ConfigWrapper({c})' 1abcdefghijklmnopqrstuvwxyzABCDEFGHIJKL
206class ConfigWrapperStack: 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL
207 """A stack of `ConfigWrapper` instances."""
209 def __init__(self, config_wrapper: ConfigWrapper): 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL
210 self._config_wrapper_stack: list[ConfigWrapper] = [config_wrapper] 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL
212 @property 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL
213 def tail(self) -> ConfigWrapper: 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL
214 return self._config_wrapper_stack[-1] 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL
216 @contextmanager 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL
217 def push(self, config_wrapper: ConfigWrapper | ConfigDict | None): 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL
218 if config_wrapper is None: 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL
219 yield 1abcdefghijklmnopqrstuvwxyzABCDEFGHIJKL
220 return 1abcdefghijklmnopqrstuvwxyzABCDEFGHIJKL
222 if not isinstance(config_wrapper, ConfigWrapper): 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL
223 config_wrapper = ConfigWrapper(config_wrapper, check=False) 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL
225 self._config_wrapper_stack.append(config_wrapper) 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL
226 try: 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL
227 yield 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL
228 finally:
229 self._config_wrapper_stack.pop() 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL
232config_defaults = ConfigDict( 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL
233 title=None,
234 str_to_lower=False,
235 str_to_upper=False,
236 str_strip_whitespace=False,
237 str_min_length=0,
238 str_max_length=None,
239 # let the model / dataclass decide how to handle it
240 extra=None,
241 frozen=False,
242 populate_by_name=False,
243 use_enum_values=False,
244 validate_assignment=False,
245 arbitrary_types_allowed=False,
246 from_attributes=False,
247 loc_by_alias=True,
248 alias_generator=None,
249 model_title_generator=None,
250 field_title_generator=None,
251 ignored_types=(),
252 allow_inf_nan=True,
253 json_schema_extra=None,
254 strict=False,
255 revalidate_instances='never',
256 ser_json_timedelta='iso8601',
257 ser_json_bytes='utf8',
258 ser_json_inf_nan='null',
259 validate_default=False,
260 validate_return=False,
261 protected_namespaces=('model_',),
262 hide_input_in_errors=False,
263 json_encoders=None,
264 defer_build=False,
265 experimental_defer_build_mode=('model',),
266 plugin_settings=None,
267 schema_generator=None,
268 json_schema_serialization_defaults_required=False,
269 json_schema_mode_override=None,
270 coerce_numbers_to_str=False,
271 regex_engine='rust-regex',
272 validation_error_cause=False,
273 use_attribute_docstrings=False,
274 cache_strings=True,
275)
278def prepare_config(config: ConfigDict | dict[str, Any] | type[Any] | None) -> ConfigDict: 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL
279 """Create a `ConfigDict` instance from an existing dict, a class (e.g. old class-based config) or None.
281 Args:
282 config: The input config.
284 Returns:
285 A ConfigDict object created from config.
286 """
287 if config is None: 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL
288 return ConfigDict() 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL
290 if not isinstance(config, dict): 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL
291 warnings.warn(DEPRECATION_MESSAGE, DeprecationWarning) 1abcdefghijklmnopqrstuvwxyzABCDEFGHIJKL
292 config = {k: getattr(config, k) for k in dir(config) if not k.startswith('__')} 1abcdefghijklmnopqrstuvwxyzABCDEFGHIJKL
294 config_dict = cast(ConfigDict, config) 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL
295 check_deprecated(config_dict) 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL
296 return config_dict 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL
299config_keys = set(ConfigDict.__annotations__.keys()) 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL
302V2_REMOVED_KEYS = { 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL
303 'allow_mutation',
304 'error_msg_templates',
305 'fields',
306 'getter_dict',
307 'smart_union',
308 'underscore_attrs_are_private',
309 'json_loads',
310 'json_dumps',
311 'copy_on_model_validation',
312 'post_init_call',
313}
314V2_RENAMED_KEYS = { 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL
315 'allow_population_by_field_name': 'populate_by_name',
316 'anystr_lower': 'str_to_lower',
317 'anystr_strip_whitespace': 'str_strip_whitespace',
318 'anystr_upper': 'str_to_upper',
319 'keep_untouched': 'ignored_types',
320 'max_anystr_length': 'str_max_length',
321 'min_anystr_length': 'str_min_length',
322 'orm_mode': 'from_attributes',
323 'schema_extra': 'json_schema_extra',
324 'validate_all': 'validate_default',
325}
328def check_deprecated(config_dict: ConfigDict) -> None: 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL
329 """Check for deprecated config keys and warn the user.
331 Args:
332 config_dict: The input config.
333 """
334 deprecated_removed_keys = V2_REMOVED_KEYS & config_dict.keys() 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL
335 deprecated_renamed_keys = V2_RENAMED_KEYS.keys() & config_dict.keys() 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL
336 if deprecated_removed_keys or deprecated_renamed_keys: 1abcdefghijklmnopqrstuvwxyzMNOPQRSTUVABCDEFGHIJKL
337 renamings = {k: V2_RENAMED_KEYS[k] for k in sorted(deprecated_renamed_keys)} 1abcdefghijklmnopqrstuvwxyzABCDEFGHIJKL
338 renamed_bullets = [f'* {k!r} has been renamed to {v!r}' for k, v in renamings.items()] 1abcdefghijklmnopqrstuvwxyzABCDEFGHIJKL
339 removed_bullets = [f'* {k!r} has been removed' for k in sorted(deprecated_removed_keys)] 1abcdefghijklmnopqrstuvwxyzABCDEFGHIJKL
340 message = '\n'.join(['Valid config keys have changed in V2:'] + renamed_bullets + removed_bullets) 1abcdefghijklmnopqrstuvwxyzABCDEFGHIJKL
341 warnings.warn(message, UserWarning) 1abcdefghijklmnopqrstuvwxyzABCDEFGHIJKL