encommon 0.10.0__tar.gz → 0.11.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. {encommon-0.10.0/encommon.egg-info → encommon-0.11.1}/PKG-INFO +1 -1
  2. {encommon-0.10.0 → encommon-0.11.1}/encommon/config/__init__.py +3 -3
  3. {encommon-0.10.0 → encommon-0.11.1}/encommon/config/config.py +19 -7
  4. {encommon-0.10.0 → encommon-0.11.1}/encommon/config/files.py +3 -3
  5. {encommon-0.10.0 → encommon-0.11.1}/encommon/config/logger.py +39 -7
  6. {encommon-0.10.0 → encommon-0.11.1}/encommon/config/params.py +21 -1
  7. {encommon-0.10.0 → encommon-0.11.1}/encommon/config/paths.py +2 -2
  8. {encommon-0.10.0 → encommon-0.11.1}/encommon/config/test/test_logger.py +4 -1
  9. encommon-0.10.0/encommon/config/test/test_common.py → encommon-0.11.1/encommon/config/test/test_utils.py +3 -3
  10. encommon-0.10.0/encommon/config/common.py → encommon-0.11.1/encommon/config/utils.py +1 -10
  11. {encommon-0.10.0 → encommon-0.11.1}/encommon/conftest.py +2 -1
  12. {encommon-0.10.0 → encommon-0.11.1}/encommon/crypts/crypts.py +68 -18
  13. {encommon-0.10.0 → encommon-0.11.1}/encommon/crypts/params.py +14 -1
  14. {encommon-0.10.0 → encommon-0.11.1}/encommon/crypts/test/test_crypts.py +56 -13
  15. {encommon-0.10.0 → encommon-0.11.1}/encommon/times/__init__.py +14 -2
  16. encommon-0.11.1/encommon/times/common.py +63 -0
  17. encommon-0.11.1/encommon/times/params.py +155 -0
  18. {encommon-0.10.0 → encommon-0.11.1}/encommon/times/parse.py +5 -5
  19. encommon-0.11.1/encommon/times/test/test_params.py +64 -0
  20. {encommon-0.10.0 → encommon-0.11.1}/encommon/times/test/test_parse.py +1 -1
  21. encommon-0.11.1/encommon/times/test/test_timer.py +86 -0
  22. {encommon-0.10.0 → encommon-0.11.1}/encommon/times/test/test_timers.py +81 -41
  23. encommon-0.10.0/encommon/times/test/test_common.py → encommon-0.11.1/encommon/times/test/test_utils.py +3 -3
  24. {encommon-0.10.0 → encommon-0.11.1}/encommon/times/test/test_window.py +101 -51
  25. encommon-0.11.1/encommon/times/test/test_windows.py +250 -0
  26. encommon-0.11.1/encommon/times/timer.py +147 -0
  27. encommon-0.11.1/encommon/times/timers.py +405 -0
  28. {encommon-0.10.0 → encommon-0.11.1}/encommon/times/times.py +6 -6
  29. encommon-0.10.0/encommon/times/common.py → encommon-0.11.1/encommon/times/utils.py +24 -66
  30. {encommon-0.10.0 → encommon-0.11.1}/encommon/times/window.py +124 -85
  31. encommon-0.11.1/encommon/times/windows.py +472 -0
  32. {encommon-0.10.0 → encommon-0.11.1}/encommon/types/notate.py +0 -2
  33. {encommon-0.10.0 → encommon-0.11.1}/encommon/utils/__init__.py +2 -2
  34. encommon-0.11.1/encommon/utils/common.py +33 -0
  35. encommon-0.10.0/encommon/utils/common.py → encommon-0.11.1/encommon/utils/files.py +22 -23
  36. {encommon-0.10.0 → encommon-0.11.1}/encommon/utils/paths.py +1 -1
  37. {encommon-0.10.0 → encommon-0.11.1}/encommon/utils/sample.py +2 -2
  38. encommon-0.10.0/encommon/utils/test/test_common.py → encommon-0.11.1/encommon/utils/test/test_files.py +2 -2
  39. {encommon-0.10.0 → encommon-0.11.1}/encommon/utils/test/test_paths.py +2 -1
  40. encommon-0.11.1/encommon/version.txt +1 -0
  41. {encommon-0.10.0 → encommon-0.11.1/encommon.egg-info}/PKG-INFO +1 -1
  42. {encommon-0.10.0 → encommon-0.11.1}/encommon.egg-info/SOURCES.txt +12 -4
  43. {encommon-0.10.0 → encommon-0.11.1}/setup.cfg +3 -1
  44. encommon-0.10.0/encommon/times/timers.py +0 -318
  45. encommon-0.10.0/encommon/version.txt +0 -1
  46. {encommon-0.10.0 → encommon-0.11.1}/LICENSE +0 -0
  47. {encommon-0.10.0 → encommon-0.11.1}/MANIFEST.in +0 -0
  48. {encommon-0.10.0 → encommon-0.11.1}/README.md +0 -0
  49. {encommon-0.10.0 → encommon-0.11.1}/encommon/__init__.py +0 -0
  50. {encommon-0.10.0 → encommon-0.11.1}/encommon/config/test/__init__.py +0 -0
  51. {encommon-0.10.0 → encommon-0.11.1}/encommon/config/test/test_config.py +0 -0
  52. {encommon-0.10.0 → encommon-0.11.1}/encommon/config/test/test_files.py +0 -0
  53. {encommon-0.10.0 → encommon-0.11.1}/encommon/config/test/test_paths.py +0 -0
  54. {encommon-0.10.0 → encommon-0.11.1}/encommon/crypts/__init__.py +0 -0
  55. {encommon-0.10.0 → encommon-0.11.1}/encommon/crypts/hashes.py +0 -0
  56. {encommon-0.10.0 → encommon-0.11.1}/encommon/crypts/test/__init__.py +0 -0
  57. {encommon-0.10.0 → encommon-0.11.1}/encommon/crypts/test/test_hashes.py +0 -0
  58. {encommon-0.10.0 → encommon-0.11.1}/encommon/py.typed +0 -0
  59. {encommon-0.10.0 → encommon-0.11.1}/encommon/times/duration.py +0 -0
  60. {encommon-0.10.0 → encommon-0.11.1}/encommon/times/test/__init__.py +0 -0
  61. {encommon-0.10.0 → encommon-0.11.1}/encommon/times/test/test_duration.py +0 -0
  62. {encommon-0.10.0 → encommon-0.11.1}/encommon/times/test/test_times.py +0 -0
  63. {encommon-0.10.0 → encommon-0.11.1}/encommon/types/__init__.py +0 -0
  64. {encommon-0.10.0 → encommon-0.11.1}/encommon/types/dicts.py +0 -0
  65. {encommon-0.10.0 → encommon-0.11.1}/encommon/types/empty.py +0 -0
  66. {encommon-0.10.0 → encommon-0.11.1}/encommon/types/strings.py +0 -0
  67. {encommon-0.10.0 → encommon-0.11.1}/encommon/types/test/__init__.py +0 -0
  68. {encommon-0.10.0 → encommon-0.11.1}/encommon/types/test/test_dicts.py +0 -0
  69. {encommon-0.10.0 → encommon-0.11.1}/encommon/types/test/test_empty.py +0 -0
  70. {encommon-0.10.0 → encommon-0.11.1}/encommon/types/test/test_notate.py +0 -0
  71. {encommon-0.10.0 → encommon-0.11.1}/encommon/types/test/test_strings.py +0 -0
  72. {encommon-0.10.0 → encommon-0.11.1}/encommon/utils/match.py +0 -0
  73. {encommon-0.10.0 → encommon-0.11.1}/encommon/utils/stdout.py +0 -0
  74. {encommon-0.10.0 → encommon-0.11.1}/encommon/utils/test/__init__.py +0 -0
  75. {encommon-0.10.0 → encommon-0.11.1}/encommon/utils/test/test_match.py +0 -0
  76. {encommon-0.10.0 → encommon-0.11.1}/encommon/utils/test/test_sample.py +0 -0
  77. {encommon-0.10.0 → encommon-0.11.1}/encommon/utils/test/test_stdout.py +0 -0
  78. {encommon-0.10.0 → encommon-0.11.1}/encommon.egg-info/dependency_links.txt +0 -0
  79. {encommon-0.10.0 → encommon-0.11.1}/encommon.egg-info/requires.txt +0 -0
  80. {encommon-0.10.0 → encommon-0.11.1}/encommon.egg-info/top_level.txt +0 -0
  81. {encommon-0.10.0 → encommon-0.11.1}/pyproject.toml +0 -0
  82. {encommon-0.10.0 → encommon-0.11.1}/reqs-install.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: encommon
3
- Version: 0.10.0
3
+ Version: 0.11.1
4
4
  Summary: Enasis Network Common Library
5
5
  License: MIT
6
6
  Classifier: Programming Language :: Python :: 3
@@ -7,9 +7,6 @@ is permitted, for more information consult the project license file.
7
7
 
8
8
 
9
9
 
10
- from .common import config_load
11
- from .common import config_path
12
- from .common import config_paths
13
10
  from .config import Config
14
11
  from .files import ConfigFile
15
12
  from .files import ConfigFiles
@@ -20,6 +17,9 @@ from .params import LoggerParams
20
17
  from .params import Params
21
18
  from .paths import ConfigPath
22
19
  from .paths import ConfigPaths
20
+ from .utils import config_load
21
+ from .utils import config_path
22
+ from .utils import config_paths
23
23
 
24
24
 
25
25
 
@@ -13,11 +13,11 @@ from typing import Callable
13
13
  from typing import Optional
14
14
  from typing import TYPE_CHECKING
15
15
 
16
- from .common import config_paths
17
16
  from .files import ConfigFiles
18
17
  from .logger import Logger
19
18
  from .params import Params
20
19
  from .paths import ConfigPaths
20
+ from .utils import config_paths
21
21
  from ..crypts import Crypts
22
22
  from ..types import merge_dicts
23
23
  from ..types import setate
@@ -35,6 +35,16 @@ class Config:
35
35
  Configuration loaded from files is validated with the
36
36
  Pydantic model :class:`encommon.config.Params`.
37
37
 
38
+ .. testsetup::
39
+ >>> from pathlib import Path
40
+ >>> path = str(getfixture('tmpdir'))
41
+
42
+ Example
43
+ -------
44
+ >>> config = Config()
45
+ >>> config.config
46
+ {'enconfig': None, 'enlogger': None, 'encrypts': None}
47
+
38
48
  :param files: Complete or relative path to config files.
39
49
  :param paths: Complete or relative path to config paths.
40
50
  :param cargs: Configuration arguments in dictionary form,
@@ -200,16 +210,17 @@ class Config:
200
210
  ) -> Logger:
201
211
  """
202
212
  Initialize the Python logging library using parameters.
213
+
214
+ :returns: Instance of Python logging library created.
203
215
  """
204
216
 
205
217
  if self.__logger is not None:
206
218
  return self.__logger
207
219
 
208
- enlogger = (
220
+ logger = Logger(
209
221
  self.params.enlogger)
210
222
 
211
- self.__logger = (
212
- Logger(params=enlogger))
223
+ self.__logger = logger
213
224
 
214
225
  return self.__logger
215
226
 
@@ -220,15 +231,16 @@ class Config:
220
231
  ) -> Crypts:
221
232
  """
222
233
  Initialize the encryption instance using the parameters.
234
+
235
+ :returns: Instance of the encryption instance created.
223
236
  """
224
237
 
225
238
  if self.__crypts is not None:
226
239
  return self.__crypts
227
240
 
228
- encrypts = (
241
+ crypts = Crypts(
229
242
  self.params.encrypts)
230
243
 
231
- self.__crypts = (
232
- Crypts(params=encrypts))
244
+ self.__crypts = crypts
233
245
 
234
246
  return self.__crypts
@@ -13,9 +13,9 @@ from typing import Any
13
13
  from typing import Optional
14
14
  from typing import TYPE_CHECKING
15
15
 
16
- from .common import config_load
17
- from .common import config_path
18
- from .common import config_paths
16
+ from .utils import config_load
17
+ from .utils import config_path
18
+ from .utils import config_paths
19
19
  from ..types import merge_dicts
20
20
 
21
21
  if TYPE_CHECKING:
@@ -7,6 +7,7 @@ is permitted, for more information consult the project license file.
7
7
 
8
8
 
9
9
 
10
+ from copy import deepcopy
10
11
  from json import dumps
11
12
  from logging import CRITICAL
12
13
  from logging import DEBUG
@@ -26,8 +27,7 @@ from typing import Literal
26
27
  from typing import Optional
27
28
  from typing import TYPE_CHECKING
28
29
 
29
- from .common import LOGLEVELS
30
- from .common import config_path
30
+ from .utils import config_path
31
31
  from ..times import Times
32
32
  from ..types import Empty
33
33
  from ..types.strings import COMMAD
@@ -45,6 +45,13 @@ if TYPE_CHECKING:
45
45
  LOGR_FILE = 'encommon.logger.file'
46
46
  LOGR_STDO = 'encommon.logger.stdo'
47
47
 
48
+ LOGLEVELS = Literal[
49
+ 'critical',
50
+ 'debug',
51
+ 'error',
52
+ 'info',
53
+ 'warning']
54
+
48
55
  LOGSEVERS = {
49
56
  'critical': int(CRITICAL),
50
57
  'debug': int(DEBUG),
@@ -270,6 +277,7 @@ class FileFormatter(Formatter):
270
277
  Specifically overrides method for formatting exceptions.
271
278
 
272
279
  :param ei: Exception information provided by the logger.
280
+ :returns: String representation for the filesystem path.
273
281
  """
274
282
 
275
283
  reason = super().formatException(ei)
@@ -316,6 +324,8 @@ class Logger:
316
324
  :param params: Parameters for instantiating the instance.
317
325
  """
318
326
 
327
+ __params: 'LoggerParams'
328
+
319
329
  __stdo_level: Optional[LOGLEVELS]
320
330
  __file_level: Optional[LOGLEVELS]
321
331
  __file_path: Optional[Path]
@@ -328,20 +338,29 @@ class Logger:
328
338
 
329
339
  def __init__(
330
340
  self,
341
+ params: Optional['LoggerParams'] = None,
331
342
  *,
332
343
  stdo_level: Optional[LOGLEVELS] = None,
333
344
  file_level: Optional[LOGLEVELS] = None,
334
345
  file_path: Optional[str | Path] = None,
335
- params: Optional['LoggerParams'] = None,
336
346
  ) -> None:
337
347
  """
338
348
  Initialize instance for class using provided parameters.
339
349
  """
340
350
 
341
- if params is not None:
342
- stdo_level = params.stdo_level
343
- file_level = params.file_level
344
- file_path = params.file_path
351
+ from .params import LoggerParams
352
+
353
+ if params is None:
354
+ params = LoggerParams(
355
+ stdo_level=stdo_level,
356
+ file_level=file_level,
357
+ file_path=file_path)
358
+
359
+ self.__params = deepcopy(params)
360
+
361
+ stdo_level = params.stdo_level
362
+ file_level = params.file_level
363
+ file_path = params.file_path
345
364
 
346
365
  if file_path is not None:
347
366
  file_path = config_path(file_path)
@@ -359,6 +378,19 @@ class Logger:
359
378
  self.__logr_file = logr_file
360
379
 
361
380
 
381
+ @property
382
+ def params(
383
+ self,
384
+ ) -> 'LoggerParams':
385
+ """
386
+ Return the Pydantic model containing the configuration.
387
+
388
+ :returns: Pydantic model containing the configuration.
389
+ """
390
+
391
+ return self.__params
392
+
393
+
362
394
  @property
363
395
  def stdo_level(
364
396
  self,
@@ -7,11 +7,12 @@ is permitted, for more information consult the project license file.
7
7
 
8
8
 
9
9
 
10
+ from pathlib import Path
10
11
  from typing import Optional
11
12
 
12
13
  from pydantic import BaseModel
13
14
 
14
- from .common import LOGLEVELS
15
+ from .logger import LOGLEVELS
15
16
  from ..crypts import CryptsParams
16
17
 
17
18
 
@@ -45,6 +46,25 @@ class LoggerParams(BaseModel, extra='forbid'):
45
46
  file_path: Optional[str] = None
46
47
 
47
48
 
49
+ def __init__(
50
+ self,
51
+ stdo_level: Optional[LOGLEVELS] = None,
52
+ file_level: Optional[LOGLEVELS] = None,
53
+ file_path: Optional[str | Path] = None,
54
+ ) -> None:
55
+ """
56
+ Initialize instance for class using provided parameters.
57
+ """
58
+
59
+ if file_path is not None:
60
+ file_path = str(file_path)
61
+
62
+ super().__init__(
63
+ stdo_level=stdo_level,
64
+ file_level=file_level,
65
+ file_path=file_path)
66
+
67
+
48
68
 
49
69
  class Params(BaseModel, extra='forbid'):
50
70
  """
@@ -14,9 +14,9 @@ from typing import Any
14
14
  from typing import Optional
15
15
  from typing import TYPE_CHECKING
16
16
 
17
- from .common import config_path
18
- from .common import config_paths
19
17
  from .files import ConfigFile
18
+ from .utils import config_path
19
+ from .utils import config_paths
20
20
 
21
21
  if TYPE_CHECKING:
22
22
  from ..utils.common import PATHABLE
@@ -44,7 +44,7 @@ def logger(
44
44
  file_level='info',
45
45
  file_path=f'{tmp_path}/test.log')
46
46
 
47
- return Logger(params=params)
47
+ return Logger(params)
48
48
 
49
49
 
50
50
 
@@ -142,6 +142,7 @@ def test_Logger(
142
142
  attrs = list(logger.__dict__)
143
143
 
144
144
  assert attrs == [
145
+ '_Logger__params',
145
146
  '_Logger__stdo_level',
146
147
  '_Logger__file_level',
147
148
  '_Logger__file_path',
@@ -161,6 +162,8 @@ def test_Logger(
161
162
  logger)
162
163
 
163
164
 
165
+ assert logger.params is not None
166
+
164
167
  assert logger.stdo_level == 'info'
165
168
 
166
169
  assert logger.file_level == 'info'
@@ -7,9 +7,9 @@ is permitted, for more information consult the project license file.
7
7
 
8
8
 
9
9
 
10
- from ..common import config_load
11
- from ..common import config_path
12
- from ..common import config_paths
10
+ from ..utils import config_load
11
+ from ..utils import config_path
12
+ from ..utils import config_paths
13
13
  from ... import PROJECT
14
14
  from ... import WORKSPACE
15
15
 
@@ -9,7 +9,6 @@ is permitted, for more information consult the project license file.
9
9
 
10
10
  from pathlib import Path
11
11
  from typing import Any
12
- from typing import Literal
13
12
  from typing import Optional
14
13
  from typing import TYPE_CHECKING
15
14
 
@@ -28,15 +27,6 @@ if TYPE_CHECKING:
28
27
 
29
28
 
30
29
 
31
- LOGLEVELS = Literal[
32
- 'critical',
33
- 'debug',
34
- 'error',
35
- 'info',
36
- 'warning']
37
-
38
-
39
-
40
30
  def config_load(
41
31
  path: str | Path,
42
32
  ) -> dict[str, Any]:
@@ -90,6 +80,7 @@ def config_paths(
90
80
  This function simply wraps one from utils subpackage.
91
81
 
92
82
  :param paths: Complete or relative paths for processing.
83
+ :param replace: Optional values to replace in the path.
93
84
  :returns: New resolved filesystem path object instances.
94
85
  """
95
86
 
@@ -38,7 +38,8 @@ def config_factory(
38
38
  ' stdo_level: info\n'
39
39
  'encrypts:\n'
40
40
  ' phrases:\n'
41
- ' default: phrase\n'))
41
+ ' default:\n'
42
+ ' phrase: phrase\n'))
42
43
 
43
44
  config_log = f'{tmp_path}/config.log'
44
45
 
@@ -7,6 +7,7 @@ is permitted, for more information consult the project license file.
7
7
 
8
8
 
9
9
 
10
+ from copy import deepcopy
10
11
  from re import compile
11
12
  from re import match as re_match
12
13
  from re import sub as re_sub
@@ -18,6 +19,7 @@ from cryptography.fernet import Fernet
18
19
  from ..types.strings import SEMPTY
19
20
 
20
21
  if TYPE_CHECKING:
22
+ from .params import CryptParams
21
23
  from .params import CryptsParams
22
24
 
23
25
 
@@ -31,52 +33,54 @@ class Crypts:
31
33
  """
32
34
  Encrypt and decrypt values using passphrase dictionary.
33
35
 
36
+ .. testsetup::
37
+ >>> from .params import CryptsParams
38
+
34
39
  Example
35
40
  -------
36
41
  >>> phrase = Crypts.keygen()
37
- >>> crypts = Crypts({'default': phrase})
42
+ >>> source = {'default': {'phrase': phrase}}
43
+ >>> params = CryptsParams(phrases=source)
44
+ >>> crypts = Crypts(params)
38
45
  >>> encrypt = crypts.encrypt('example')
46
+ >>> encrypt
47
+ '$ENCRYPT;1.0;default;...
39
48
  >>> crypts.decrypt(encrypt)
40
49
  'example'
41
50
 
42
- :param phrases: Passphrases that are used in operations.
43
51
  :param params: Parameters for instantiating the instance.
44
52
  """
45
53
 
46
- __phrases: dict[str, str]
54
+ __params: 'CryptsParams'
47
55
 
48
56
 
49
57
  def __init__(
50
58
  self,
51
- phrases: Optional[dict[str, str]] = None,
52
59
  params: Optional['CryptsParams'] = None,
53
60
  ) -> None:
54
61
  """
55
62
  Initialize instance for class using provided parameters.
56
63
  """
57
64
 
58
- phrases = phrases or {}
59
-
60
- if params is not None:
61
- phrases |= params.phrases
65
+ from .params import CryptsParams
62
66
 
63
- if 'default' not in phrases:
64
- raise ValueError('default')
67
+ if params is None:
68
+ params = CryptsParams()
65
69
 
66
- self.__phrases = dict(phrases)
70
+ self.__params = deepcopy(params)
67
71
 
68
72
 
69
73
  @property
70
- def phrases(
74
+ def params(
71
75
  self,
72
- ) -> dict[str, str]:
76
+ ) -> 'CryptsParams':
73
77
  """
74
- Return the value for the attribute from class instance.
78
+ Return the Pydantic model containing the configuration.
75
79
 
76
- :returns: Value for the attribute from class instance.
80
+ :returns: Pydantic model containing the configuration.
77
81
  """
78
82
 
79
- return dict(self.__phrases)
83
+ return self.__params
80
84
 
81
85
 
82
86
  def encrypt(
@@ -92,7 +96,12 @@ class Crypts:
92
96
  :returns: Encrypted value using the relevant passphrase.
93
97
  """
94
98
 
95
- phrase = self.__phrases[unique]
99
+ phrases = self.params.phrases
100
+
101
+ if unique not in phrases:
102
+ raise ValueError('unique')
103
+
104
+ phrase = phrases[unique].phrase
96
105
 
97
106
  encrypt = (
98
107
  Fernet(phrase)
@@ -115,6 +124,8 @@ class Crypts:
115
124
  :returns: Decrypted value using the relevant passphrase.
116
125
  """
117
126
 
127
+ phrases = self.params.phrases
128
+
118
129
  value = crypt_clean(value)
119
130
 
120
131
  if not re_match(ENCRYPT, value):
@@ -126,7 +137,7 @@ class Crypts:
126
137
  if version != '1.0':
127
138
  raise ValueError('version')
128
139
 
129
- phrase = self.__phrases[unique]
140
+ phrase = phrases[unique].phrase
130
141
 
131
142
  return (
132
143
  Fernet(phrase)
@@ -134,6 +145,44 @@ class Crypts:
134
145
  .decode())
135
146
 
136
147
 
148
+ def create(
149
+ self,
150
+ unique: str,
151
+ params: 'CryptParams',
152
+ ) -> None:
153
+ """
154
+ Create a new phrase using the provided input parameters.
155
+
156
+ :param unique: Unique identifier of mapping passphrase.
157
+ :param params: Parameters for instantiating the instance.
158
+ """
159
+
160
+ phrases = self.params.phrases
161
+
162
+ if unique in phrases:
163
+ raise ValueError('unique')
164
+
165
+ phrases[unique] = params
166
+
167
+
168
+ def delete(
169
+ self,
170
+ unique: str,
171
+ ) -> None:
172
+ """
173
+ Delete the phrase from the internal dictionary reference.
174
+
175
+ :param unique: Unique identifier of mapping passphrase.
176
+ """
177
+
178
+ phrases = self.params.phrases
179
+
180
+ if unique not in phrases:
181
+ raise ValueError('unique')
182
+
183
+ del phrases[unique]
184
+
185
+
137
186
  @classmethod
138
187
  def keygen(
139
188
  cls: object,
@@ -157,6 +206,7 @@ def crypt_clean(
157
206
  Return the parsed and normalized encrypted string value.
158
207
 
159
208
  :param value: String value that will returned decrypted.
209
+ :returns: Parsed and normalized encrypted string value.
160
210
  """
161
211
 
162
212
  return re_sub(r'[\n\s]', SEMPTY, value)
@@ -11,6 +11,19 @@ from pydantic import BaseModel
11
11
 
12
12
 
13
13
 
14
+ class CryptParams(BaseModel, extra='forbid'):
15
+ """
16
+ Process and validate the core configuration parameters.
17
+
18
+ :param phrase: Passphrases that are used in operations.
19
+ :param data: Keyword arguments passed to Pydantic model.
20
+ Parameter is picked up by autodoc, please ignore.
21
+ """
22
+
23
+ phrase: str
24
+
25
+
26
+
14
27
  class CryptsParams(BaseModel, extra='forbid'):
15
28
  """
16
29
  Process and validate the core configuration parameters.
@@ -20,4 +33,4 @@ class CryptsParams(BaseModel, extra='forbid'):
20
33
  Parameter is picked up by autodoc, please ignore.
21
34
  """
22
35
 
23
- phrases: dict[str, str]
36
+ phrases: dict[str, CryptParams] = {}
@@ -7,11 +7,14 @@ is permitted, for more information consult the project license file.
7
7
 
8
8
 
9
9
 
10
+ from typing import Any
11
+
10
12
  from pytest import fixture
11
13
  from pytest import mark
12
14
  from pytest import raises
13
15
 
14
16
  from ..crypts import Crypts
17
+ from ..params import CryptParams
15
18
  from ..params import CryptsParams
16
19
  from ...types import inrepr
17
20
  from ...types import instr
@@ -26,14 +29,14 @@ def crypts() -> Crypts:
26
29
  :returns: Newly constructed instance of related class.
27
30
  """
28
31
 
29
- phrases = {
30
- 'default': Crypts.keygen(),
31
- 'secrets': Crypts.keygen()}
32
+ source: dict[str, Any] = {
33
+ 'default': {'phrase': Crypts.keygen()},
34
+ 'secrets': {'phrase': Crypts.keygen()}}
32
35
 
33
36
  params = CryptsParams(
34
- phrases=phrases)
37
+ phrases=source)
35
38
 
36
- return Crypts(params=params)
39
+ return Crypts(params)
37
40
 
38
41
 
39
42
 
@@ -50,7 +53,7 @@ def test_Crypts(
50
53
  attrs = list(crypts.__dict__)
51
54
 
52
55
  assert attrs == [
53
- '_Crypts__phrases']
56
+ '_Crypts__params']
54
57
 
55
58
 
56
59
  assert inrepr(
@@ -64,7 +67,7 @@ def test_Crypts(
64
67
  crypts)
65
68
 
66
69
 
67
- assert len(crypts.phrases) == 2
70
+ assert crypts.params is not None
68
71
 
69
72
  assert len(crypts.keygen()) == 44
70
73
 
@@ -101,6 +104,28 @@ def test_Crypts_iterate(
101
104
 
102
105
 
103
106
 
107
+ def test_Crypts_cover(
108
+ crypts: Crypts,
109
+ ) -> None:
110
+ """
111
+ Perform various tests associated with relevant routines.
112
+
113
+ :param crypts: Primary class instance for the encryption.
114
+ """
115
+
116
+
117
+ crypts = Crypts()
118
+
119
+
120
+ params = CryptParams(
121
+ phrase=Crypts.keygen())
122
+
123
+ crypts.create('testing', params)
124
+
125
+ crypts.delete('testing')
126
+
127
+
128
+
104
129
  def test_Crypts_raises(
105
130
  crypts: Crypts,
106
131
  ) -> None:
@@ -114,15 +139,11 @@ def test_Crypts_raises(
114
139
  _raises = raises(ValueError)
115
140
 
116
141
  with _raises as reason:
117
- Crypts({'foo': 'bar'})
142
+ crypts.encrypt('foo', 'dne')
118
143
 
119
144
  _reason = str(reason.value)
120
145
 
121
- assert _reason == 'default'
122
-
123
-
124
- crypts = Crypts(
125
- crypts.phrases)
146
+ assert _reason == 'unique'
126
147
 
127
148
 
128
149
  _raises = raises(ValueError)
@@ -144,3 +165,25 @@ def test_Crypts_raises(
144
165
  _reason = str(reason.value)
145
166
 
146
167
  assert _reason == 'version'
168
+
169
+
170
+ _raises = raises(ValueError)
171
+
172
+ params = CryptParams(phrase='foo')
173
+
174
+ with _raises as reason:
175
+ crypts.create('default', params)
176
+
177
+ _reason = str(reason.value)
178
+
179
+ assert _reason == 'unique'
180
+
181
+
182
+ _raises = raises(ValueError)
183
+
184
+ with _raises as reason:
185
+ crypts.delete('dne')
186
+
187
+ _reason = str(reason.value)
188
+
189
+ assert _reason == 'unique'