Retire `allow_derivepassphrase_extensions` argument to `validate_vault_config`
Marco Ricci

Marco Ricci commited on 2024-12-19 15:04:11
Zeige 3 geänderte Dateien mit 59 Einfügungen und 50 Löschungen.


As the Unicode normalization form is now set via the central
configuration file instead of the `vault` data file, there are currently
no defined `derivepassphrase` extensions to the vault configuration file
schema.  Given the new central configuration file and the commitment to
preserve compatibility of the `vault` configuration import/export, we do
not anticipate any future `derivepassphrase` extensions to the schema.
Thus, retire the `allow_derivepassphrase_extensions` validation option.

Also adapt all tests and test datasets accordingly.
... ...
@@ -16,6 +16,8 @@ from typing_extensions import (
16 16
     NamedTuple,
17 17
     NotRequired,
18 18
     TypedDict,
19
+    deprecated,
20
+    overload,
19 21
 )
20 22
 
21 23
 if TYPE_CHECKING:
... ...
@@ -212,11 +214,36 @@ def json_path(path: Sequence[str | int], /) -> str:
212 214
     return ''.join(chunks)
213 215
 
214 216
 
215
-def validate_vault_config(  # noqa: C901,PLR0912,PLR0915
217
+@overload
218
+@deprecated(
219
+    'allow_derivepassphrase_extensions argument is deprecated since v0.4.0, '
220
+    'to be removed in v1.0: no extensions are defined'
221
+)
222
+def validate_vault_config(
223
+    obj: Any,  # noqa: ANN401
224
+    /,
225
+    *,
226
+    allow_derivepassphrase_extensions: bool,
227
+    allow_unknown_settings: bool = False,
228
+) -> None:
229
+    ...  # pragma: no cover
230
+
231
+
232
+@overload
233
+def validate_vault_config(
216 234
     obj: Any,  # noqa: ANN401
217 235
     /,
218 236
     *,
219 237
     allow_unknown_settings: bool = False,
238
+) -> None:
239
+    ...  # pragma: no cover
240
+
241
+
242
+def validate_vault_config(  # noqa: C901,PLR0912
243
+    obj: Any,
244
+    /,
245
+    *,
246
+    allow_unknown_settings: bool = False,
220 247
     allow_derivepassphrase_extensions: bool = False,
221 248
 ) -> None:
222 249
     """Check that `obj` is a valid vault config.
... ...
@@ -227,7 +254,7 @@ def validate_vault_config(  # noqa: C901,PLR0912,PLR0915
227 254
         allow_unknown_settings:
228 255
             If false, abort on unknown settings.
229 256
         allow_derivepassphrase_extensions:
230
-            If true, allow `derivepassphrase` extensions.
257
+            (Deprecated.)  Ignored since v0.4.0.
231 258
 
232 259
     Raises:
233 260
         TypeError:
... ...
@@ -237,6 +264,11 @@ def validate_vault_config(  # noqa: C901,PLR0912,PLR0915
237 264
             An entry in the vault config is not allowed, or has a
238 265
             disallowed value.
239 266
 
267
+    Deprecated:
268
+        Since v0.4.0: The `allow_derivepassphrase_extensions` keyword
269
+        argument is deprecated, and will be removed in v1.0.  There are
270
+        no specified `derivepassphrase` extensions.
271
+
240 272
     """
241 273
     err_obj_not_a_dict = 'vault config is not a dict'
242 274
     err_non_str_service_name = (
... ...
@@ -255,15 +287,6 @@ def validate_vault_config(  # noqa: C901,PLR0912,PLR0915
255 287
         json_path_str = json_path(path)
256 288
         return f'vault config entry {json_path_str} is not an integer'
257 289
 
258
-    def err_derivepassphrase_extension(
259
-        key: str, path: Sequence[str], /
260
-    ) -> str:
261
-        json_path_str = json_path(path)
262
-        return (
263
-            f'vault config entry {json_path_str} uses '
264
-            f'`derivepassphrase` extension {key!r}'
265
-        )
266
-
267 290
     def err_unknown_setting(key: str, path: Sequence[str], /) -> str:
268 291
         json_path_str = json_path(path)
269 292
         return (
... ...
@@ -308,19 +331,16 @@ def validate_vault_config(  # noqa: C901,PLR0912,PLR0915
308 331
             elif key == 'unicode_normalization_form' and path == ('global',):
309 332
                 if not isinstance(value, str):
310 333
                     raise TypeError(err_not_a_string((*path, key)))
311
-                if not allow_derivepassphrase_extensions:
312
-                    raise ValueError(err_derivepassphrase_extension(key, path))
334
+                if (
335
+                    not allow_derivepassphrase_extensions
336
+                    and not allow_unknown_settings
337
+                ):
338
+                    raise ValueError(err_unknown_setting(key, path))
313 339
             elif key == 'notes' and path != ('global',):
314 340
                 if not isinstance(value, str):
315 341
                     raise TypeError(err_not_a_string((*path, key)))
316
-            elif key == 'length':
317
-                if not isinstance(value, int):
318
-                    raise TypeError(err_not_an_int((*path, key)))
319
-                if value < 1:
320
-                    raise ValueError(
321
-                        err_bad_number(key, path, strictly_positive=True)
322
-                    )
323 342
             elif key in {
343
+                'length',
324 344
                 'repeat',
325 345
                 'lower',
326 346
                 'upper',
... ...
@@ -331,7 +351,11 @@ def validate_vault_config(  # noqa: C901,PLR0912,PLR0915
331 351
             }:
332 352
                 if not isinstance(value, int):
333 353
                     raise TypeError(err_not_an_int((*path, key)))
334
-                if value < 0:
354
+                if key == 'length' and value < 1:
355
+                    raise ValueError(
356
+                        err_bad_number(key, path, strictly_positive=True)
357
+                    )
358
+                if key != 'length' and value < 0:
335 359
                     raise ValueError(
336 360
                         err_bad_number(key, path, strictly_positive=False)
337 361
                     )
... ...
@@ -47,7 +47,6 @@ if TYPE_CHECKING:
47 47
 
48 48
 class ValidationSettings(NamedTuple):
49 49
     allow_unknown_settings: bool
50
-    allow_derivepassphrase_extensions: bool
51 50
 
52 51
 
53 52
 class VaultTestConfig(NamedTuple):
... ...
@@ -205,7 +204,7 @@ TEST_CONFIGS: list[VaultTestConfig] = [
205 204
             },
206 205
         },
207 206
         '',
208
-        ValidationSettings(False, True),
207
+        ValidationSettings(True),
209 208
     ),
210 209
     VaultTestConfig(
211 210
         {
... ...
@@ -215,8 +214,8 @@ TEST_CONFIGS: list[VaultTestConfig] = [
215 214
                 'sv2': {'length': 10, 'repeat': 1, 'lower': 1},
216 215
             },
217 216
         },
218
-        'extension key: .global.unicode_normalization_form',
219
-        ValidationSettings(False, False),
217
+        'extension/unknown key: .global.unicode_normalization_form',
218
+        ValidationSettings(False),
220 219
     ),
221 220
     VaultTestConfig(
222 221
         {
... ...
@@ -227,7 +226,7 @@ TEST_CONFIGS: list[VaultTestConfig] = [
227 226
             },
228 227
         },
229 228
         '',
230
-        ValidationSettings(True, False),
229
+        ValidationSettings(True),
231 230
     ),
232 231
     VaultTestConfig(
233 232
         {
... ...
@@ -238,7 +237,7 @@ TEST_CONFIGS: list[VaultTestConfig] = [
238 237
             },
239 238
         },
240 239
         'unknown key: .global.unknown_key',
241
-        ValidationSettings(False, False),
240
+        ValidationSettings(False),
242 241
     ),
243 242
     VaultTestConfig(
244 243
         {
... ...
@@ -253,8 +252,8 @@ TEST_CONFIGS: list[VaultTestConfig] = [
253 252
                 },
254 253
             },
255 254
         },
256
-        'unknown_key: .services.sv2.unknown_key',
257
-        ValidationSettings(False, False),
255
+        'unknown key: .services.sv2.unknown_key',
256
+        ValidationSettings(False),
258 257
     ),
259 258
     VaultTestConfig(
260 259
         {
... ...
@@ -270,7 +269,7 @@ TEST_CONFIGS: list[VaultTestConfig] = [
270 269
             },
271 270
         },
272 271
         '',
273
-        ValidationSettings(True, True),
272
+        ValidationSettings(True),
274 273
     ),
275 274
     VaultTestConfig(
276 275
         {
... ...
@@ -285,11 +284,8 @@ TEST_CONFIGS: list[VaultTestConfig] = [
285 284
                 },
286 285
             },
287 286
         },
288
-        (
289
-            'extension key (permitted): .global.unicode_normalization_form; '
290
-            'unknown key: .services.sv2.unknown_key'
291
-        ),
292
-        ValidationSettings(False, True),
287
+        '',
288
+        ValidationSettings(True),
293 289
     ),
294 290
     VaultTestConfig(
295 291
         {
... ...
@@ -304,11 +300,8 @@ TEST_CONFIGS: list[VaultTestConfig] = [
304 300
                 },
305 301
             },
306 302
         },
307
-        (
308
-            'unknown key (permitted): .services.sv2.unknown_key; '
309
-            'extension key: .global.unicode_normalization_form'
310
-        ),
311
-        ValidationSettings(True, False),
303
+        '',
304
+        ValidationSettings(True),
312 305
     ),
313 306
 ]
314 307
 
... ...
@@ -117,9 +117,7 @@ def test_200a_is_vault_config_smudged(
117 117
 )
118 118
 def test_400_validate_vault_config(test_config: tests.VaultTestConfig) -> None:
119 119
     obj, comment, validation_settings = test_config
120
-    allow_unknown_settings, allow_derivepassphrase_extensions = (
121
-        validation_settings or (True, True)
122
-    )
120
+    (allow_unknown_settings,) = validation_settings or (True,)
123 121
     obj = copy.deepcopy(obj)
124 122
     _types.clean_up_falsy_vault_config_values(obj)
125 123
     if comment:
... ...
@@ -127,14 +125,12 @@ def test_400_validate_vault_config(test_config: tests.VaultTestConfig) -> None:
127 125
             _types.validate_vault_config(
128 126
                 obj,
129 127
                 allow_unknown_settings=allow_unknown_settings,
130
-                allow_derivepassphrase_extensions=allow_derivepassphrase_extensions,
131 128
             )
132 129
     else:
133 130
         try:
134 131
             _types.validate_vault_config(
135 132
                 obj,
136 133
                 allow_unknown_settings=allow_unknown_settings,
137
-                allow_derivepassphrase_extensions=allow_derivepassphrase_extensions,
138 134
             )
139 135
         except (TypeError, ValueError) as exc:  # pragma: no cover
140 136
             assert not exc, 'failed to validate valid example'  # noqa: PT017
... ...
@@ -152,9 +148,7 @@ def test_400a_validate_vault_config_smudged(
152 148
     test_config: tests.VaultTestConfig,
153 149
 ) -> None:
154 150
     _obj, comment, validation_settings = test_config
155
-    allow_unknown_settings, allow_derivepassphrase_extensions = (
156
-        validation_settings or (True, True)
157
-    )
151
+    (allow_unknown_settings,) = validation_settings or (True,)
158 152
     obj = copy.deepcopy(_obj)
159 153
     did_cleanup = _types.clean_up_falsy_vault_config_values(obj)
160 154
     if comment:
... ...
@@ -162,14 +156,12 @@ def test_400a_validate_vault_config_smudged(
162 156
             _types.validate_vault_config(
163 157
                 obj,
164 158
                 allow_unknown_settings=allow_unknown_settings,
165
-                allow_derivepassphrase_extensions=allow_derivepassphrase_extensions,
166 159
             )
167 160
     else:
168 161
         try:
169 162
             _types.validate_vault_config(
170 163
                 obj,
171 164
                 allow_unknown_settings=allow_unknown_settings,
172
-                allow_derivepassphrase_extensions=allow_derivepassphrase_extensions,
173 165
             )
174 166
         except (TypeError, ValueError) as exc:  # pragma: no cover
175 167
             assert not exc, 'failed to validate valid example'  # noqa: PT017
176 168