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.
- encommon/colors/__init__.py +2 -2
- encommon/colors/{colors.py → color.py} +24 -24
- encommon/colors/test/{test_colors.py → test_color.py} +16 -16
- encommon/config/config.py +15 -15
- encommon/config/files.py +14 -14
- encommon/config/logger.py +6 -6
- encommon/config/params.py +47 -30
- encommon/config/paths.py +13 -13
- encommon/config/test/__init__.py +1 -1
- encommon/config/test/test_config.py +10 -16
- encommon/config/test/test_files.py +8 -7
- encommon/config/test/test_logger.py +11 -10
- encommon/config/test/test_paths.py +11 -10
- encommon/config/utils.py +2 -2
- encommon/crypts/params.py +28 -12
- encommon/crypts/test/test_crypts.py +5 -5
- encommon/crypts/test/test_hashes.py +2 -1
- encommon/times/__init__.py +2 -2
- encommon/times/common.py +2 -2
- encommon/times/params.py +76 -48
- encommon/times/parse.py +3 -3
- encommon/times/test/test_duration.py +3 -2
- encommon/times/test/test_time.py +123 -0
- encommon/times/test/test_timer.py +5 -4
- encommon/times/test/test_timers.py +10 -9
- encommon/times/test/test_window.py +4 -3
- encommon/times/test/test_windows.py +7 -6
- encommon/times/{times.py → time.py} +61 -12
- encommon/times/timer.py +10 -10
- encommon/times/timers.py +3 -3
- encommon/times/unitime.py +9 -0
- encommon/times/window.py +31 -31
- encommon/times/windows.py +10 -10
- encommon/types/classes.py +0 -13
- encommon/types/lists.py +6 -0
- encommon/types/notate.py +2 -1
- encommon/types/strings.py +5 -0
- encommon/types/test/test_empty.py +2 -1
- encommon/utils/sample.py +6 -5
- encommon/utils/stdout.py +2 -2
- encommon/utils/test/test_paths.py +3 -3
- encommon/utils/test/test_sample.py +2 -2
- encommon/utils/test/test_stdout.py +3 -3
- encommon/version.txt +1 -1
- {encommon-0.14.0.dist-info → encommon-0.15.0.dist-info}/METADATA +1 -1
- encommon-0.15.0.dist-info/RECORD +84 -0
- {encommon-0.14.0.dist-info → encommon-0.15.0.dist-info}/WHEEL +1 -1
- encommon/times/test/test_times.py +0 -122
- encommon-0.14.0.dist-info/RECORD +0 -84
- {encommon-0.14.0.dist-info → encommon-0.15.0.dist-info}/LICENSE +0 -0
- {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
|
-
|
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.
|
91
|
+
self.__merge = None
|
92
92
|
|
93
93
|
|
94
94
|
@property
|
95
|
-
def
|
95
|
+
def merge(
|
96
96
|
self,
|
97
|
-
) ->
|
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
|
-
|
105
|
+
merge = self.__merge
|
106
106
|
|
107
|
-
if
|
108
|
-
return deepcopy(
|
107
|
+
if merge is not None:
|
108
|
+
return deepcopy(merge)
|
109
109
|
|
110
|
-
|
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
|
-
|
119
|
+
merge[key] = file.config
|
120
120
|
|
121
121
|
|
122
|
-
|
122
|
+
merge = sort_dict(merge)
|
123
123
|
|
124
|
-
self.
|
124
|
+
self.__merge = merge
|
125
125
|
|
126
|
-
return deepcopy(
|
126
|
+
return deepcopy(merge)
|
encommon/config/test/__init__.py
CHANGED
@@ -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 =
|
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
|
66
|
-
'files.ConfigFiles object',
|
67
|
-
config.files)
|
63
|
+
assert config.files.merge
|
68
64
|
|
69
|
-
assert
|
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
|
77
|
+
assert callable(config.model)
|
84
78
|
|
85
|
-
assert
|
79
|
+
assert config.params
|
86
80
|
|
87
|
-
assert
|
81
|
+
assert config.logger
|
88
82
|
|
89
|
-
assert
|
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
|
-
|
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
|
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 =
|
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 =
|
87
|
+
attrs = lattrs(files)
|
87
88
|
|
88
89
|
assert attrs == [
|
89
90
|
'paths',
|
90
91
|
'config',
|
91
|
-
'
|
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.
|
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
|
-
|
124
|
-
|
124
|
+
merge1 = files.merge
|
125
|
+
merge2 = files.merge
|
125
126
|
|
126
|
-
assert
|
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
|
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 =
|
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 =
|
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
|
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
|
173
|
+
assert logger.file_path
|
173
174
|
|
174
|
-
assert logger.started
|
175
|
+
assert not logger.started
|
175
176
|
|
176
|
-
assert logger.logger_stdo
|
177
|
+
assert logger.logger_stdo
|
177
178
|
|
178
|
-
assert logger.logger_file
|
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
|
-
|
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=
|
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 =
|
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 =
|
90
|
+
attrs = lattrs(paths)
|
90
91
|
|
91
92
|
assert attrs == [
|
92
93
|
'paths', 'config',
|
93
|
-
'
|
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
|
-
|
117
|
+
SAMPLES / 'paths.json')
|
117
118
|
|
118
119
|
sample = load_sample(
|
119
120
|
path=sample_path,
|
120
121
|
update=ENPYRWS,
|
121
|
-
content=paths.
|
122
|
+
content=paths.merge,
|
122
123
|
replace=replaces)
|
123
124
|
|
124
125
|
expect = prep_sample(
|
125
|
-
content=paths.
|
126
|
+
content=paths.merge,
|
126
127
|
replace=replaces)
|
127
128
|
|
128
|
-
assert
|
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
|
-
|
142
|
-
|
142
|
+
merge1 = paths.merge
|
143
|
+
merge2 = paths.merge
|
143
144
|
|
144
|
-
assert
|
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
|
-
) ->
|
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:
|
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:
|
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
|
-
|
52
|
-
phrases = {}
|
68
|
+
phrases = phrases or {}
|
53
69
|
|
54
|
-
super().__init__(
|
55
|
-
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:
|
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 =
|
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
|
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 =
|
25
|
+
attrs = lattrs(hashes)
|
25
26
|
|
26
27
|
assert attrs == [
|
27
28
|
'_Hashes__string']
|
encommon/times/__init__.py
CHANGED
@@ -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
|
-
'
|
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 .
|
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, '
|
36
|
+
datetime, 'Time']
|
37
37
|
|
38
38
|
SCHEDULE = Union[
|
39
39
|
str, dict[str, int]]
|