encommon 0.10.0__tar.gz → 0.11.0__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.0}/PKG-INFO +1 -1
  2. {encommon-0.10.0 → encommon-0.11.0}/encommon/config/__init__.py +3 -3
  3. {encommon-0.10.0 → encommon-0.11.0}/encommon/config/config.py +17 -1
  4. {encommon-0.10.0 → encommon-0.11.0}/encommon/config/files.py +3 -3
  5. {encommon-0.10.0 → encommon-0.11.0}/encommon/config/logger.py +37 -6
  6. {encommon-0.10.0 → encommon-0.11.0}/encommon/config/params.py +21 -1
  7. {encommon-0.10.0 → encommon-0.11.0}/encommon/config/paths.py +2 -2
  8. {encommon-0.10.0 → encommon-0.11.0}/encommon/config/test/test_logger.py +3 -0
  9. encommon-0.10.0/encommon/config/test/test_common.py → encommon-0.11.0/encommon/config/test/test_utils.py +3 -3
  10. encommon-0.10.0/encommon/config/common.py → encommon-0.11.0/encommon/config/utils.py +1 -10
  11. {encommon-0.10.0 → encommon-0.11.0}/encommon/conftest.py +2 -1
  12. {encommon-0.10.0 → encommon-0.11.0}/encommon/crypts/crypts.py +23 -22
  13. {encommon-0.10.0 → encommon-0.11.0}/encommon/crypts/params.py +14 -1
  14. {encommon-0.10.0 → encommon-0.11.0}/encommon/crypts/test/test_crypts.py +8 -20
  15. {encommon-0.10.0 → encommon-0.11.0}/encommon/times/__init__.py +14 -2
  16. encommon-0.11.0/encommon/times/common.py +63 -0
  17. encommon-0.11.0/encommon/times/params.py +155 -0
  18. {encommon-0.10.0 → encommon-0.11.0}/encommon/times/parse.py +5 -5
  19. encommon-0.11.0/encommon/times/test/test_params.py +64 -0
  20. {encommon-0.10.0 → encommon-0.11.0}/encommon/times/test/test_parse.py +1 -1
  21. encommon-0.11.0/encommon/times/test/test_timer.py +86 -0
  22. {encommon-0.10.0 → encommon-0.11.0}/encommon/times/test/test_timers.py +87 -36
  23. encommon-0.10.0/encommon/times/test/test_common.py → encommon-0.11.0/encommon/times/test/test_utils.py +3 -3
  24. {encommon-0.10.0 → encommon-0.11.0}/encommon/times/test/test_window.py +101 -51
  25. encommon-0.11.0/encommon/times/test/test_windows.py +264 -0
  26. encommon-0.11.0/encommon/times/timer.py +147 -0
  27. encommon-0.11.0/encommon/times/timers.py +392 -0
  28. {encommon-0.10.0 → encommon-0.11.0}/encommon/times/times.py +6 -6
  29. encommon-0.10.0/encommon/times/common.py → encommon-0.11.0/encommon/times/utils.py +24 -66
  30. {encommon-0.10.0 → encommon-0.11.0}/encommon/times/window.py +124 -85
  31. encommon-0.11.0/encommon/times/windows.py +459 -0
  32. {encommon-0.10.0 → encommon-0.11.0}/encommon/types/notate.py +0 -2
  33. {encommon-0.10.0 → encommon-0.11.0}/encommon/utils/__init__.py +2 -2
  34. encommon-0.11.0/encommon/utils/common.py +33 -0
  35. encommon-0.10.0/encommon/utils/common.py → encommon-0.11.0/encommon/utils/files.py +22 -23
  36. {encommon-0.10.0 → encommon-0.11.0}/encommon/utils/paths.py +1 -1
  37. {encommon-0.10.0 → encommon-0.11.0}/encommon/utils/sample.py +2 -2
  38. encommon-0.10.0/encommon/utils/test/test_common.py → encommon-0.11.0/encommon/utils/test/test_files.py +2 -2
  39. {encommon-0.10.0 → encommon-0.11.0}/encommon/utils/test/test_paths.py +2 -1
  40. encommon-0.11.0/encommon/version.txt +1 -0
  41. {encommon-0.10.0 → encommon-0.11.0/encommon.egg-info}/PKG-INFO +1 -1
  42. {encommon-0.10.0 → encommon-0.11.0}/encommon.egg-info/SOURCES.txt +12 -4
  43. {encommon-0.10.0 → encommon-0.11.0}/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.0}/LICENSE +0 -0
  47. {encommon-0.10.0 → encommon-0.11.0}/MANIFEST.in +0 -0
  48. {encommon-0.10.0 → encommon-0.11.0}/README.md +0 -0
  49. {encommon-0.10.0 → encommon-0.11.0}/encommon/__init__.py +0 -0
  50. {encommon-0.10.0 → encommon-0.11.0}/encommon/config/test/__init__.py +0 -0
  51. {encommon-0.10.0 → encommon-0.11.0}/encommon/config/test/test_config.py +0 -0
  52. {encommon-0.10.0 → encommon-0.11.0}/encommon/config/test/test_files.py +0 -0
  53. {encommon-0.10.0 → encommon-0.11.0}/encommon/config/test/test_paths.py +0 -0
  54. {encommon-0.10.0 → encommon-0.11.0}/encommon/crypts/__init__.py +0 -0
  55. {encommon-0.10.0 → encommon-0.11.0}/encommon/crypts/hashes.py +0 -0
  56. {encommon-0.10.0 → encommon-0.11.0}/encommon/crypts/test/__init__.py +0 -0
  57. {encommon-0.10.0 → encommon-0.11.0}/encommon/crypts/test/test_hashes.py +0 -0
  58. {encommon-0.10.0 → encommon-0.11.0}/encommon/py.typed +0 -0
  59. {encommon-0.10.0 → encommon-0.11.0}/encommon/times/duration.py +0 -0
  60. {encommon-0.10.0 → encommon-0.11.0}/encommon/times/test/__init__.py +0 -0
  61. {encommon-0.10.0 → encommon-0.11.0}/encommon/times/test/test_duration.py +0 -0
  62. {encommon-0.10.0 → encommon-0.11.0}/encommon/times/test/test_times.py +0 -0
  63. {encommon-0.10.0 → encommon-0.11.0}/encommon/types/__init__.py +0 -0
  64. {encommon-0.10.0 → encommon-0.11.0}/encommon/types/dicts.py +0 -0
  65. {encommon-0.10.0 → encommon-0.11.0}/encommon/types/empty.py +0 -0
  66. {encommon-0.10.0 → encommon-0.11.0}/encommon/types/strings.py +0 -0
  67. {encommon-0.10.0 → encommon-0.11.0}/encommon/types/test/__init__.py +0 -0
  68. {encommon-0.10.0 → encommon-0.11.0}/encommon/types/test/test_dicts.py +0 -0
  69. {encommon-0.10.0 → encommon-0.11.0}/encommon/types/test/test_empty.py +0 -0
  70. {encommon-0.10.0 → encommon-0.11.0}/encommon/types/test/test_notate.py +0 -0
  71. {encommon-0.10.0 → encommon-0.11.0}/encommon/types/test/test_strings.py +0 -0
  72. {encommon-0.10.0 → encommon-0.11.0}/encommon/utils/match.py +0 -0
  73. {encommon-0.10.0 → encommon-0.11.0}/encommon/utils/stdout.py +0 -0
  74. {encommon-0.10.0 → encommon-0.11.0}/encommon/utils/test/__init__.py +0 -0
  75. {encommon-0.10.0 → encommon-0.11.0}/encommon/utils/test/test_match.py +0 -0
  76. {encommon-0.10.0 → encommon-0.11.0}/encommon/utils/test/test_sample.py +0 -0
  77. {encommon-0.10.0 → encommon-0.11.0}/encommon/utils/test/test_stdout.py +0 -0
  78. {encommon-0.10.0 → encommon-0.11.0}/encommon.egg-info/dependency_links.txt +0 -0
  79. {encommon-0.10.0 → encommon-0.11.0}/encommon.egg-info/requires.txt +0 -0
  80. {encommon-0.10.0 → encommon-0.11.0}/encommon.egg-info/top_level.txt +0 -0
  81. {encommon-0.10.0 → encommon-0.11.0}/pyproject.toml +0 -0
  82. {encommon-0.10.0 → encommon-0.11.0}/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.0
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,6 +210,8 @@ 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:
@@ -220,6 +232,8 @@ class Config:
220
232
  ) -> Crypts:
221
233
  """
222
234
  Initialize the encryption instance using the parameters.
235
+
236
+ :returns: Instance of the encryption instance created.
223
237
  """
224
238
 
225
239
  if self.__crypts is not None:
@@ -228,6 +242,8 @@ class Config:
228
242
  encrypts = (
229
243
  self.params.encrypts)
230
244
 
245
+ assert encrypts is not None
246
+
231
247
  self.__crypts = (
232
248
  Crypts(params=encrypts))
233
249
 
@@ -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:
@@ -26,8 +26,7 @@ from typing import Literal
26
26
  from typing import Optional
27
27
  from typing import TYPE_CHECKING
28
28
 
29
- from .common import LOGLEVELS
30
- from .common import config_path
29
+ from .utils import config_path
31
30
  from ..times import Times
32
31
  from ..types import Empty
33
32
  from ..types.strings import COMMAD
@@ -45,6 +44,13 @@ if TYPE_CHECKING:
45
44
  LOGR_FILE = 'encommon.logger.file'
46
45
  LOGR_STDO = 'encommon.logger.stdo'
47
46
 
47
+ LOGLEVELS = Literal[
48
+ 'critical',
49
+ 'debug',
50
+ 'error',
51
+ 'info',
52
+ 'warning']
53
+
48
54
  LOGSEVERS = {
49
55
  'critical': int(CRITICAL),
50
56
  'debug': int(DEBUG),
@@ -270,6 +276,7 @@ class FileFormatter(Formatter):
270
276
  Specifically overrides method for formatting exceptions.
271
277
 
272
278
  :param ei: Exception information provided by the logger.
279
+ :returns: String representation for the filesystem path.
273
280
  """
274
281
 
275
282
  reason = super().formatException(ei)
@@ -316,6 +323,8 @@ class Logger:
316
323
  :param params: Parameters for instantiating the instance.
317
324
  """
318
325
 
326
+ __params: 'LoggerParams'
327
+
319
328
  __stdo_level: Optional[LOGLEVELS]
320
329
  __file_level: Optional[LOGLEVELS]
321
330
  __file_path: Optional[Path]
@@ -338,10 +347,19 @@ class Logger:
338
347
  Initialize instance for class using provided parameters.
339
348
  """
340
349
 
341
- if params is not None:
342
- stdo_level = params.stdo_level
343
- file_level = params.file_level
344
- file_path = params.file_path
350
+ from .params import LoggerParams
351
+
352
+ if params is None:
353
+ params = LoggerParams(
354
+ stdo_level=stdo_level,
355
+ file_level=file_level,
356
+ file_path=file_path)
357
+
358
+ self.__params = params
359
+
360
+ stdo_level = params.stdo_level
361
+ file_level = params.file_level
362
+ file_path = params.file_path
345
363
 
346
364
  if file_path is not None:
347
365
  file_path = config_path(file_path)
@@ -359,6 +377,19 @@ class Logger:
359
377
  self.__logr_file = logr_file
360
378
 
361
379
 
380
+ @property
381
+ def params(
382
+ self,
383
+ ) -> 'LoggerParams':
384
+ """
385
+ Return the Pydantic model containing the configuration.
386
+
387
+ :returns: Pydantic model containing the configuration.
388
+ """
389
+
390
+ return self.__params
391
+
392
+
362
393
  @property
363
394
  def stdo_level(
364
395
  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
@@ -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
 
@@ -10,7 +10,6 @@ is permitted, for more information consult the project license file.
10
10
  from re import compile
11
11
  from re import match as re_match
12
12
  from re import sub as re_sub
13
- from typing import Optional
14
13
  from typing import TYPE_CHECKING
15
14
 
16
15
  from cryptography.fernet import Fernet
@@ -31,52 +30,49 @@ class Crypts:
31
30
  """
32
31
  Encrypt and decrypt values using passphrase dictionary.
33
32
 
33
+ .. testsetup::
34
+ >>> from .params import CryptsParams
35
+
34
36
  Example
35
37
  -------
36
38
  >>> phrase = Crypts.keygen()
37
- >>> crypts = Crypts({'default': phrase})
39
+ >>> source = {'default': {'phrase': phrase}}
40
+ >>> params = CryptsParams(phrases=source)
41
+ >>> crypts = Crypts(params)
38
42
  >>> encrypt = crypts.encrypt('example')
43
+ >>> encrypt
44
+ '$ENCRYPT;1.0;default;...
39
45
  >>> crypts.decrypt(encrypt)
40
46
  'example'
41
47
 
42
- :param phrases: Passphrases that are used in operations.
43
48
  :param params: Parameters for instantiating the instance.
44
49
  """
45
50
 
46
- __phrases: dict[str, str]
51
+ __params: 'CryptsParams'
47
52
 
48
53
 
49
54
  def __init__(
50
55
  self,
51
- phrases: Optional[dict[str, str]] = None,
52
- params: Optional['CryptsParams'] = None,
56
+ params: 'CryptsParams',
53
57
  ) -> None:
54
58
  """
55
59
  Initialize instance for class using provided parameters.
56
60
  """
57
61
 
58
- phrases = phrases or {}
59
-
60
- if params is not None:
61
- phrases |= params.phrases
62
-
63
- if 'default' not in phrases:
64
- raise ValueError('default')
65
-
66
- self.__phrases = dict(phrases)
62
+ self.__params = params
67
63
 
68
64
 
69
65
  @property
70
- def phrases(
66
+ def params(
71
67
  self,
72
- ) -> dict[str, str]:
68
+ ) -> 'CryptsParams':
73
69
  """
74
- Return the value for the attribute from class instance.
70
+ Return the Pydantic model containing the configuration.
75
71
 
76
- :returns: Value for the attribute from class instance.
72
+ :returns: Pydantic model containing the configuration.
77
73
  """
78
74
 
79
- return dict(self.__phrases)
75
+ return self.__params
80
76
 
81
77
 
82
78
  def encrypt(
@@ -92,7 +88,9 @@ class Crypts:
92
88
  :returns: Encrypted value using the relevant passphrase.
93
89
  """
94
90
 
95
- phrase = self.__phrases[unique]
91
+ phrases = self.params.phrases
92
+
93
+ phrase = phrases[unique].phrase
96
94
 
97
95
  encrypt = (
98
96
  Fernet(phrase)
@@ -115,6 +113,8 @@ class Crypts:
115
113
  :returns: Decrypted value using the relevant passphrase.
116
114
  """
117
115
 
116
+ phrases = self.params.phrases
117
+
118
118
  value = crypt_clean(value)
119
119
 
120
120
  if not re_match(ENCRYPT, value):
@@ -126,7 +126,7 @@ class Crypts:
126
126
  if version != '1.0':
127
127
  raise ValueError('version')
128
128
 
129
- phrase = self.__phrases[unique]
129
+ phrase = phrases[unique].phrase
130
130
 
131
131
  return (
132
132
  Fernet(phrase)
@@ -157,6 +157,7 @@ def crypt_clean(
157
157
  Return the parsed and normalized encrypted string value.
158
158
 
159
159
  :param value: String value that will returned decrypted.
160
+ :returns: Parsed and normalized encrypted string value.
160
161
  """
161
162
 
162
163
  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,6 +7,8 @@ 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
@@ -26,12 +28,12 @@ def crypts() -> Crypts:
26
28
  :returns: Newly constructed instance of related class.
27
29
  """
28
30
 
29
- phrases = {
30
- 'default': Crypts.keygen(),
31
- 'secrets': Crypts.keygen()}
31
+ source: dict[str, Any] = {
32
+ 'default': {'phrase': Crypts.keygen()},
33
+ 'secrets': {'phrase': Crypts.keygen()}}
32
34
 
33
35
  params = CryptsParams(
34
- phrases=phrases)
36
+ phrases=source)
35
37
 
36
38
  return Crypts(params=params)
37
39
 
@@ -50,7 +52,7 @@ def test_Crypts(
50
52
  attrs = list(crypts.__dict__)
51
53
 
52
54
  assert attrs == [
53
- '_Crypts__phrases']
55
+ '_Crypts__params']
54
56
 
55
57
 
56
58
  assert inrepr(
@@ -64,7 +66,7 @@ def test_Crypts(
64
66
  crypts)
65
67
 
66
68
 
67
- assert len(crypts.phrases) == 2
69
+ assert crypts.params is not None
68
70
 
69
71
  assert len(crypts.keygen()) == 44
70
72
 
@@ -111,20 +113,6 @@ def test_Crypts_raises(
111
113
  """
112
114
 
113
115
 
114
- _raises = raises(ValueError)
115
-
116
- with _raises as reason:
117
- Crypts({'foo': 'bar'})
118
-
119
- _reason = str(reason.value)
120
-
121
- assert _reason == 'default'
122
-
123
-
124
- crypts = Crypts(
125
- crypts.phrases)
126
-
127
-
128
116
  _raises = raises(ValueError)
129
117
 
130
118
  with _raises as reason:
@@ -7,24 +7,36 @@ is permitted, for more information consult the project license file.
7
7
 
8
8
 
9
9
 
10
- from .common import findtz
11
10
  from .duration import Duration
11
+ from .params import TimerParams
12
+ from .params import TimersParams
13
+ from .params import WindowParams
14
+ from .params import WindowsParams
12
15
  from .parse import parse_time
13
16
  from .parse import shift_time
14
17
  from .parse import since_time
15
18
  from .parse import string_time
19
+ from .timer import Timer
16
20
  from .timers import Timers
17
21
  from .times import Times
22
+ from .utils import findtz
18
23
  from .window import Window
24
+ from .windows import Windows
19
25
 
20
26
 
21
27
 
22
28
  __all__ = [
23
29
  'Duration',
24
- 'findtz',
30
+ 'Timer',
31
+ 'TimerParams',
25
32
  'Timers',
33
+ 'TimersParams',
26
34
  'Times',
27
35
  'Window',
36
+ 'WindowParams',
37
+ 'Windows',
38
+ 'WindowsParams',
39
+ 'findtz',
28
40
  'parse_time',
29
41
  'shift_time',
30
42
  'since_time',
@@ -0,0 +1,63 @@
1
+ """
2
+ Functions and routines associated with Enasis Network Common Library.
3
+
4
+ This file is part of Enasis Network software eco-system. Distribution
5
+ is permitted, for more information consult the project license file.
6
+ """
7
+
8
+
9
+
10
+ from datetime import datetime
11
+ from re import compile
12
+ from typing import TYPE_CHECKING
13
+ from typing import Union
14
+
15
+ if TYPE_CHECKING:
16
+ from .times import Times
17
+
18
+
19
+
20
+ NUMERISH = compile(
21
+ r'^\-?\d+(\.\d+)?$')
22
+
23
+ SNAPABLE = compile(
24
+ r'^(\-|\+)[\d\@a-z\-\+]+$')
25
+
26
+ STRINGNOW = {
27
+ 'None', 'null', 'now'}
28
+
29
+
30
+
31
+ NUMERIC = Union[int, float]
32
+
33
+ PARSABLE = Union[
34
+ str, NUMERIC,
35
+ datetime, 'Times']
36
+
37
+ SCHEDULE = Union[
38
+ str, dict[str, int]]
39
+
40
+
41
+
42
+ UNIXEPOCH = (
43
+ '1970-01-01T00:00:00+0000')
44
+
45
+ UNIXMPOCH = (
46
+ '1970-01-01T00:00:00.000000+0000')
47
+
48
+ UNIXSPOCH = (
49
+ '1970-01-01T00:00:00Z')
50
+
51
+ UNIXHPOCH = (
52
+ '01/01/1970 12:00AM UTC')
53
+
54
+
55
+
56
+ STAMP_SIMPLE = (
57
+ '%Y-%m-%dT%H:%M:%S%z')
58
+
59
+ STAMP_SUBSEC = (
60
+ '%Y-%m-%dT%H:%M:%S.%f%z')
61
+
62
+ STAMP_HUMAN = (
63
+ '%m/%d/%Y %I:%M%p %Z')