encommon 0.14.0__py3-none-any.whl → 0.15.0__py3-none-any.whl

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 (51) hide show
  1. encommon/colors/__init__.py +2 -2
  2. encommon/colors/{colors.py → color.py} +24 -24
  3. encommon/colors/test/{test_colors.py → test_color.py} +16 -16
  4. encommon/config/config.py +15 -15
  5. encommon/config/files.py +14 -14
  6. encommon/config/logger.py +6 -6
  7. encommon/config/params.py +47 -30
  8. encommon/config/paths.py +13 -13
  9. encommon/config/test/__init__.py +1 -1
  10. encommon/config/test/test_config.py +10 -16
  11. encommon/config/test/test_files.py +8 -7
  12. encommon/config/test/test_logger.py +11 -10
  13. encommon/config/test/test_paths.py +11 -10
  14. encommon/config/utils.py +2 -2
  15. encommon/crypts/params.py +28 -12
  16. encommon/crypts/test/test_crypts.py +5 -5
  17. encommon/crypts/test/test_hashes.py +2 -1
  18. encommon/times/__init__.py +2 -2
  19. encommon/times/common.py +2 -2
  20. encommon/times/params.py +76 -48
  21. encommon/times/parse.py +3 -3
  22. encommon/times/test/test_duration.py +3 -2
  23. encommon/times/test/test_time.py +123 -0
  24. encommon/times/test/test_timer.py +5 -4
  25. encommon/times/test/test_timers.py +10 -9
  26. encommon/times/test/test_window.py +4 -3
  27. encommon/times/test/test_windows.py +7 -6
  28. encommon/times/{times.py → time.py} +61 -12
  29. encommon/times/timer.py +10 -10
  30. encommon/times/timers.py +3 -3
  31. encommon/times/unitime.py +9 -0
  32. encommon/times/window.py +31 -31
  33. encommon/times/windows.py +10 -10
  34. encommon/types/classes.py +0 -13
  35. encommon/types/lists.py +6 -0
  36. encommon/types/notate.py +2 -1
  37. encommon/types/strings.py +5 -0
  38. encommon/types/test/test_empty.py +2 -1
  39. encommon/utils/sample.py +6 -5
  40. encommon/utils/stdout.py +2 -2
  41. encommon/utils/test/test_paths.py +3 -3
  42. encommon/utils/test/test_sample.py +2 -2
  43. encommon/utils/test/test_stdout.py +3 -3
  44. encommon/version.txt +1 -1
  45. {encommon-0.14.0.dist-info → encommon-0.15.0.dist-info}/METADATA +1 -1
  46. encommon-0.15.0.dist-info/RECORD +84 -0
  47. {encommon-0.14.0.dist-info → encommon-0.15.0.dist-info}/WHEEL +1 -1
  48. encommon/times/test/test_times.py +0 -122
  49. encommon-0.14.0.dist-info/RECORD +0 -84
  50. {encommon-0.14.0.dist-info → encommon-0.15.0.dist-info}/LICENSE +0 -0
  51. {encommon-0.14.0.dist-info → encommon-0.15.0.dist-info}/top_level.txt +0 -0
encommon/config/paths.py CHANGED
@@ -10,13 +10,13 @@ is permitted, for more information consult the project license file.
10
10
  from copy import deepcopy
11
11
  from glob import glob
12
12
  from pathlib import Path
13
- from typing import Any
14
13
  from typing import Optional
15
14
  from typing import TYPE_CHECKING
16
15
 
17
16
  from .files import ConfigFile
18
17
  from .utils import config_path
19
18
  from .utils import config_paths
19
+ from ..types import DictStrAny
20
20
  from ..types import sort_dict
21
21
 
22
22
  if TYPE_CHECKING:
@@ -70,7 +70,7 @@ class ConfigPaths:
70
70
  paths: tuple[Path, ...]
71
71
  config: dict[str, ConfigPath]
72
72
 
73
- __merged: Optional[dict[str, Any]]
73
+ __merge: Optional[DictStrAny]
74
74
 
75
75
 
76
76
  def __init__(
@@ -88,13 +88,13 @@ class ConfigPaths:
88
88
  str(x): ConfigPath(x)
89
89
  for x in self.paths}
90
90
 
91
- self.__merged = None
91
+ self.__merge = None
92
92
 
93
93
 
94
94
  @property
95
- def merged(
95
+ def merge(
96
96
  self,
97
- ) -> dict[str, Any]:
97
+ ) -> DictStrAny:
98
98
  """
99
99
  Return the configuration in dictionary format for paths.
100
100
 
@@ -102,12 +102,12 @@ class ConfigPaths:
102
102
  """
103
103
 
104
104
  config = self.config
105
- merged = self.__merged
105
+ merge = self.__merge
106
106
 
107
- if merged is not None:
108
- return deepcopy(merged)
107
+ if merge is not None:
108
+ return deepcopy(merge)
109
109
 
110
- merged = {}
110
+ merge = {}
111
111
 
112
112
 
113
113
  for path in config.values():
@@ -116,11 +116,11 @@ class ConfigPaths:
116
116
 
117
117
  for key, file in items:
118
118
 
119
- merged[key] = file.config
119
+ merge[key] = file.config
120
120
 
121
121
 
122
- merged = sort_dict(merged)
122
+ merge = sort_dict(merge)
123
123
 
124
- self.__merged = merged
124
+ self.__merge = merge
125
125
 
126
- return deepcopy(merged)
126
+ return deepcopy(merge)
@@ -13,4 +13,4 @@ from pathlib import Path
13
13
 
14
14
  SAMPLES = (
15
15
  Path(__file__).parent
16
- .joinpath('samples'))
16
+ / 'samples')
@@ -11,12 +11,10 @@ from pathlib import Path
11
11
  from typing import TYPE_CHECKING
12
12
 
13
13
  from . import SAMPLES
14
- from ..logger import Logger
15
- from ..params import Params
16
14
  from ... import PROJECT
17
- from ...crypts import Crypts
18
15
  from ...types import inrepr
19
16
  from ...types import instr
17
+ from ...types import lattrs
20
18
  from ...utils import load_sample
21
19
  from ...utils import prep_sample
22
20
  from ...utils.sample import ENPYRWS
@@ -38,7 +36,7 @@ def test_Config(
38
36
  """
39
37
 
40
38
 
41
- attrs = list(config.__dict__)
39
+ attrs = lattrs(config)
42
40
 
43
41
  assert attrs == [
44
42
  '_Config__model',
@@ -62,13 +60,9 @@ def test_Config(
62
60
  config)
63
61
 
64
62
 
65
- assert instr(
66
- 'files.ConfigFiles object',
67
- config.files)
63
+ assert config.files.merge
68
64
 
69
- assert instr(
70
- 'paths.ConfigPaths object',
71
- config.paths)
65
+ assert config.paths.merge
72
66
 
73
67
  assert len(config.cargs) == 1
74
68
 
@@ -80,13 +74,13 @@ def test_Config(
80
74
 
81
75
  assert len(config.merge) == 5
82
76
 
83
- assert config.model is Params
77
+ assert callable(config.model)
84
78
 
85
- assert isinstance(config.params, Params)
79
+ assert config.params
86
80
 
87
- assert isinstance(config.logger, Logger)
81
+ assert config.logger
88
82
 
89
- assert isinstance(config.crypts, Crypts)
83
+ assert config.crypts
90
84
 
91
85
 
92
86
  replaces = {
@@ -94,7 +88,7 @@ def test_Config(
94
88
  'PROJECT': PROJECT}
95
89
 
96
90
  sample_path = (
97
- f'{SAMPLES}/config.json')
91
+ SAMPLES / 'config.json')
98
92
 
99
93
  sample = load_sample(
100
94
  path=sample_path,
@@ -106,7 +100,7 @@ def test_Config(
106
100
  content=config.config,
107
101
  replace=replaces)
108
102
 
109
- assert sample == expect
103
+ assert expect == sample
110
104
 
111
105
 
112
106
 
@@ -16,6 +16,7 @@ from ..files import ConfigFile
16
16
  from ..files import ConfigFiles
17
17
  from ...types import inrepr
18
18
  from ...types import instr
19
+ from ...types import lattrs
19
20
 
20
21
 
21
22
 
@@ -49,7 +50,7 @@ def test_ConfigFile(
49
50
  f'{config_path}/config.yml')
50
51
 
51
52
 
52
- attrs = list(file.__dict__)
53
+ attrs = lattrs(file)
53
54
 
54
55
  assert attrs == [
55
56
  'path',
@@ -83,12 +84,12 @@ def test_ConfigFiles(
83
84
  """
84
85
 
85
86
 
86
- attrs = list(files.__dict__)
87
+ attrs = lattrs(files)
87
88
 
88
89
  assert attrs == [
89
90
  'paths',
90
91
  'config',
91
- '_ConfigFiles__merged']
92
+ '_ConfigFiles__merge']
92
93
 
93
94
 
94
95
  assert inrepr(
@@ -106,7 +107,7 @@ def test_ConfigFiles(
106
107
 
107
108
  assert len(files.config) == 2
108
109
 
109
- assert files.merged == {
110
+ assert files.merge == {
110
111
  'name': 'Bruce Wayne'}
111
112
 
112
113
 
@@ -120,7 +121,7 @@ def test_ConfigFiles_cover(
120
121
  :param files: Custom fixture for the configuration files.
121
122
  """
122
123
 
123
- merged1 = files.merged
124
- merged2 = files.merged
124
+ merge1 = files.merge
125
+ merge2 = files.merge
125
126
 
126
- assert merged1 is not merged2
127
+ assert merge1 is not merge2
@@ -16,11 +16,12 @@ from pytest import fixture
16
16
  from ..logger import Logger
17
17
  from ..logger import Message
18
18
  from ..params import LoggerParams
19
- from ...times import Times
19
+ from ...times import Time
20
20
  from ...times.common import UNIXMPOCH
21
21
  from ...times.common import UNIXSPOCH
22
22
  from ...types import inrepr
23
23
  from ...types import instr
24
+ from ...types import lattrs
24
25
  from ...utils import strip_ansi
25
26
 
26
27
 
@@ -70,7 +71,7 @@ def test_Message() -> None:
70
71
  elapsed=3.69420)
71
72
 
72
73
 
73
- attrs = list(message.__dict__)
74
+ attrs = lattrs(message)
74
75
 
75
76
  assert attrs == [
76
77
  '_Message__level',
@@ -140,7 +141,7 @@ def test_Logger(
140
141
  """
141
142
 
142
143
 
143
- attrs = list(logger.__dict__)
144
+ attrs = lattrs(logger)
144
145
 
145
146
  assert attrs == [
146
147
  '_Logger__params',
@@ -163,19 +164,19 @@ def test_Logger(
163
164
  logger)
164
165
 
165
166
 
166
- assert logger.params is not None
167
+ assert logger.params
167
168
 
168
169
  assert logger.stdo_level == 'info'
169
170
 
170
171
  assert logger.file_level == 'info'
171
172
 
172
- assert logger.file_path is not None
173
+ assert logger.file_path
173
174
 
174
- assert logger.started is False
175
+ assert not logger.started
175
176
 
176
- assert logger.logger_stdo is not None
177
+ assert logger.logger_stdo
177
178
 
178
- assert logger.logger_file is not None
179
+ assert logger.logger_file
179
180
 
180
181
 
181
182
  logger.log_d(msg='pytest')
@@ -197,7 +198,7 @@ def test_Logger_cover(
197
198
  :param caplog: pytest object for capturing log message.
198
199
  """
199
200
 
200
- times = Times('now')
201
+ time = Time('now')
201
202
 
202
203
 
203
204
  def _logger_logs() -> None:
@@ -206,7 +207,7 @@ def test_Logger_cover(
206
207
  logger.log_e(msg='pytest')
207
208
  logger.log_i(msg='pytest')
208
209
  logger.log_w(msg='pytest')
209
- logger.log_i(elapsed=times)
210
+ logger.log_i(elapsed=time)
210
211
 
211
212
 
212
213
  def _logger_stdo() -> _CAPLOG:
@@ -17,6 +17,7 @@ from ..paths import ConfigPaths
17
17
  from ... import PROJECT
18
18
  from ...types import inrepr
19
19
  from ...types import instr
20
+ from ...types import lattrs
20
21
  from ...utils import load_sample
21
22
  from ...utils import prep_sample
22
23
  from ...utils.sample import ENPYRWS
@@ -52,7 +53,7 @@ def test_ConfigPath(
52
53
  path = ConfigPath(config_path)
53
54
 
54
55
 
55
- attrs = list(path.__dict__)
56
+ attrs = lattrs(path)
56
57
 
57
58
  assert attrs == [
58
59
  'path',
@@ -86,11 +87,11 @@ def test_ConfigPaths(
86
87
  """
87
88
 
88
89
 
89
- attrs = list(paths.__dict__)
90
+ attrs = lattrs(paths)
90
91
 
91
92
  assert attrs == [
92
93
  'paths', 'config',
93
- '_ConfigPaths__merged']
94
+ '_ConfigPaths__merge']
94
95
 
95
96
 
96
97
  assert inrepr(
@@ -113,19 +114,19 @@ def test_ConfigPaths(
113
114
  'PROJECT': PROJECT}
114
115
 
115
116
  sample_path = (
116
- f'{SAMPLES}/paths.json')
117
+ SAMPLES / 'paths.json')
117
118
 
118
119
  sample = load_sample(
119
120
  path=sample_path,
120
121
  update=ENPYRWS,
121
- content=paths.merged,
122
+ content=paths.merge,
122
123
  replace=replaces)
123
124
 
124
125
  expect = prep_sample(
125
- content=paths.merged,
126
+ content=paths.merge,
126
127
  replace=replaces)
127
128
 
128
- assert sample == expect
129
+ assert expect == sample
129
130
 
130
131
 
131
132
 
@@ -138,7 +139,7 @@ def test_ConfigPaths_cover(
138
139
  :param paths: Custom fixture for the configuration paths.
139
140
  """
140
141
 
141
- merged1 = paths.merged
142
- merged2 = paths.merged
142
+ merge1 = paths.merge
143
+ merge2 = paths.merge
143
144
 
144
- assert merged1 is not merged2
145
+ assert merge1 is not merge2
encommon/config/utils.py CHANGED
@@ -8,7 +8,6 @@ is permitted, for more information consult the project license file.
8
8
 
9
9
 
10
10
  from pathlib import Path
11
- from typing import Any
12
11
  from typing import Optional
13
12
  from typing import TYPE_CHECKING
14
13
 
@@ -17,6 +16,7 @@ from yaml import load
17
16
 
18
17
  from .. import PROJECT
19
18
  from .. import WORKSPACE
19
+ from ..types import DictStrAny
20
20
  from ..utils import read_text
21
21
  from ..utils import resolve_path
22
22
  from ..utils import resolve_paths
@@ -29,7 +29,7 @@ if TYPE_CHECKING:
29
29
 
30
30
  def config_load(
31
31
  path: str | Path,
32
- ) -> dict[str, Any]:
32
+ ) -> DictStrAny:
33
33
  """
34
34
  Load configuration using the directory or file provided.
35
35
 
encommon/crypts/params.py CHANGED
@@ -7,8 +7,11 @@ is permitted, for more information consult the project license file.
7
7
 
8
8
 
9
9
 
10
+ from typing import Annotated
10
11
  from typing import Optional
11
12
 
13
+ from pydantic import Field
14
+
12
15
  from ..types import BaseModel
13
16
 
14
17
 
@@ -20,24 +23,38 @@ _CRYPTS = dict[str, 'CryptParams']
20
23
  class CryptParams(BaseModel, extra='forbid'):
21
24
  """
22
25
  Process and validate the core configuration parameters.
23
-
24
- :param phrase: Passphrases that are used in operations.
25
- :param data: Keyword arguments passed to Pydantic model.
26
- Parameter is picked up by autodoc, please ignore.
27
26
  """
28
27
 
29
- phrase: str
28
+ phrase: Annotated[
29
+ str,
30
+ Field(...,
31
+ description='Passphrase for the operations',
32
+ min_length=1)]
33
+
34
+
35
+ def __init__(
36
+ self,
37
+ phrase: str,
38
+ ) -> None:
39
+ """
40
+ Initialize instance for class using provided parameters.
41
+ """
42
+
43
+ super().__init__(**{
44
+ 'phrase': phrase})
30
45
 
31
46
 
32
47
 
33
48
  class CryptsParams(BaseModel, extra='forbid'):
34
49
  """
35
50
  Process and validate the core configuration parameters.
36
-
37
- :param phrases: Passphrases that are used in operations.
38
51
  """
39
52
 
40
- phrases: _CRYPTS
53
+ phrases: Annotated[
54
+ _CRYPTS,
55
+ Field(...,
56
+ description='Passphrases for the operations',
57
+ min_length=0)]
41
58
 
42
59
 
43
60
  def __init__(
@@ -48,8 +65,7 @@ class CryptsParams(BaseModel, extra='forbid'):
48
65
  Initialize instance for class using provided parameters.
49
66
  """
50
67
 
51
- if phrases is None:
52
- phrases = {}
68
+ phrases = phrases or {}
53
69
 
54
- super().__init__(
55
- phrases=phrases)
70
+ super().__init__(**{
71
+ 'phrases': phrases})
@@ -7,8 +7,6 @@ is permitted, for more information consult the project license file.
7
7
 
8
8
 
9
9
 
10
- from typing import Any
11
-
12
10
  from pytest import fixture
13
11
  from pytest import mark
14
12
  from pytest import raises
@@ -16,8 +14,10 @@ from pytest import raises
16
14
  from ..crypts import Crypts
17
15
  from ..params import CryptParams
18
16
  from ..params import CryptsParams
17
+ from ...types import DictStrAny
19
18
  from ...types import inrepr
20
19
  from ...types import instr
20
+ from ...types import lattrs
21
21
 
22
22
 
23
23
 
@@ -29,7 +29,7 @@ def crypts() -> Crypts:
29
29
  :returns: Newly constructed instance of related class.
30
30
  """
31
31
 
32
- source: dict[str, Any] = {
32
+ source: DictStrAny = {
33
33
  'default': {'phrase': Crypts.keygen()},
34
34
  'secrets': {'phrase': Crypts.keygen()}}
35
35
 
@@ -50,7 +50,7 @@ def test_Crypts(
50
50
  """
51
51
 
52
52
 
53
- attrs = list(crypts.__dict__)
53
+ attrs = lattrs(crypts)
54
54
 
55
55
  assert attrs == [
56
56
  '_Crypts__params']
@@ -67,7 +67,7 @@ def test_Crypts(
67
67
  crypts)
68
68
 
69
69
 
70
- assert crypts.params is not None
70
+ assert crypts.params
71
71
 
72
72
  assert len(crypts.keygen()) == 44
73
73
 
@@ -10,6 +10,7 @@ is permitted, for more information consult the project license file.
10
10
  from ..hashes import Hashes
11
11
  from ...types import inrepr
12
12
  from ...types import instr
13
+ from ...types import lattrs
13
14
 
14
15
 
15
16
 
@@ -21,7 +22,7 @@ def test_Hashes() -> None:
21
22
  hashes = Hashes('string')
22
23
 
23
24
 
24
- attrs = list(hashes.__dict__)
25
+ attrs = lattrs(hashes)
25
26
 
26
27
  assert attrs == [
27
28
  '_Hashes__string']
@@ -16,9 +16,9 @@ from .parse import parse_time
16
16
  from .parse import shift_time
17
17
  from .parse import since_time
18
18
  from .parse import string_time
19
+ from .time import Time
19
20
  from .timer import Timer
20
21
  from .timers import Timers
21
- from .times import Times
22
22
  from .unitime import unitime
23
23
  from .utils import findtz
24
24
  from .window import Window
@@ -32,7 +32,7 @@ __all__ = [
32
32
  'TimerParams',
33
33
  'Timers',
34
34
  'TimersParams',
35
- 'Times',
35
+ 'Time',
36
36
  'Window',
37
37
  'WindowParams',
38
38
  'Windows',
encommon/times/common.py CHANGED
@@ -13,7 +13,7 @@ from typing import TYPE_CHECKING
13
13
  from typing import Union
14
14
 
15
15
  if TYPE_CHECKING:
16
- from .times import Times
16
+ from .time import Time
17
17
 
18
18
 
19
19
 
@@ -33,7 +33,7 @@ NUMERIC = Union[int, float]
33
33
 
34
34
  PARSABLE = Union[
35
35
  str, NUMERIC,
36
- datetime, 'Times']
36
+ datetime, 'Time']
37
37
 
38
38
  SCHEDULE = Union[
39
39
  str, dict[str, int]]