encommon 0.4.1__py3-none-any.whl → 0.6.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/config/config.py +2 -2
- encommon/config/params.py +10 -0
- encommon/config/test/test_config.py +21 -1
- encommon/{config/test/conftest.py → conftest.py} +2 -1
- encommon/times/common.py +1 -1
- encommon/times/test/test_timers.py +46 -3
- encommon/times/timers.py +173 -30
- encommon/types/__init__.py +5 -1
- encommon/types/dicts.py +26 -0
- encommon/types/strings.py +25 -0
- encommon/types/test/test_dicts.py +33 -13
- encommon/types/test/test_strings.py +19 -0
- encommon/utils/sample.py +1 -1
- encommon/version.txt +1 -1
- {encommon-0.4.1.dist-info → encommon-0.6.0.dist-info}/LICENSE +1 -1
- {encommon-0.4.1.dist-info → encommon-0.6.0.dist-info}/METADATA +7 -6
- {encommon-0.4.1.dist-info → encommon-0.6.0.dist-info}/RECORD +19 -17
- {encommon-0.4.1.dist-info → encommon-0.6.0.dist-info}/WHEEL +1 -1
- {encommon-0.4.1.dist-info → encommon-0.6.0.dist-info}/top_level.txt +0 -0
encommon/config/config.py
CHANGED
@@ -155,9 +155,9 @@ class Config:
|
|
155
155
|
self,
|
156
156
|
) -> Params:
|
157
157
|
"""
|
158
|
-
Return the
|
158
|
+
Return the Pydantic model containing the configuration.
|
159
159
|
|
160
|
-
:returns:
|
160
|
+
:returns: Pydantic model containing the configuration.
|
161
161
|
"""
|
162
162
|
|
163
163
|
if self.__params is not None:
|
encommon/config/params.py
CHANGED
@@ -20,7 +20,9 @@ class ConfigParams(BaseModel, extra='forbid'):
|
|
20
20
|
"""
|
21
21
|
Process and validate the common configuration parameters.
|
22
22
|
|
23
|
+
:param paths: Complete or relative path to config paths.
|
23
24
|
:param data: Keyword arguments passed to Pydantic model.
|
25
|
+
This parameter is picked up by autodoc, please ignore.
|
24
26
|
"""
|
25
27
|
|
26
28
|
paths: Optional[list[str]] = None
|
@@ -31,7 +33,11 @@ class LoggerParams(BaseModel, extra='forbid'):
|
|
31
33
|
"""
|
32
34
|
Process and validate the common configuration parameters.
|
33
35
|
|
36
|
+
:param stdo_level: Minimum log message severity level.
|
37
|
+
:param file_level: Minimum log message severity level.
|
38
|
+
:param file_path: Enables writing to the filesystem path.
|
34
39
|
:param data: Keyword arguments passed to Pydantic model.
|
40
|
+
This parameter is picked up by autodoc, please ignore.
|
35
41
|
"""
|
36
42
|
|
37
43
|
stdo_level: Optional[LOGLEVELS] = None
|
@@ -44,7 +50,11 @@ class Params(BaseModel, extra='forbid'):
|
|
44
50
|
"""
|
45
51
|
Process and validate the common configuration parameters.
|
46
52
|
|
53
|
+
:param enconfig: Configuration for the `.Config` object.
|
54
|
+
:param enlogger: Configuration for the `.Logger` object.
|
55
|
+
:param encrypts: Configuration for the `.Crypts` object.
|
47
56
|
:param data: Keyword arguments passed to Pydantic model.
|
57
|
+
This parameter is picked up by autodoc, please ignore.
|
48
58
|
"""
|
49
59
|
|
50
60
|
enconfig: Optional[ConfigParams] = None
|
@@ -25,7 +25,7 @@ SAMPLES = (
|
|
25
25
|
|
26
26
|
|
27
27
|
|
28
|
-
def test_Config(
|
28
|
+
def test_Config( # noqa: CFQ001
|
29
29
|
config_path: Path,
|
30
30
|
) -> None:
|
31
31
|
"""
|
@@ -108,6 +108,26 @@ def test_Config(
|
|
108
108
|
assert sample == expect
|
109
109
|
|
110
110
|
|
111
|
+
_params1 = config.params
|
112
|
+
_params2 = config.params
|
113
|
+
|
114
|
+
assert _params1 is _params2
|
115
|
+
|
116
|
+
sample = load_sample(
|
117
|
+
path=SAMPLES.joinpath('params.json'),
|
118
|
+
update=ENPYRWS,
|
119
|
+
content=_params1.model_dump(),
|
120
|
+
replace={
|
121
|
+
'config_path': str(config_path)})
|
122
|
+
|
123
|
+
expect = prep_sample(
|
124
|
+
content=_params2.model_dump(),
|
125
|
+
replace={
|
126
|
+
'config_path': str(config_path)})
|
127
|
+
|
128
|
+
assert sample == expect
|
129
|
+
|
130
|
+
|
111
131
|
logger = config.logger
|
112
132
|
|
113
133
|
assert isinstance(logger, Logger)
|
@@ -21,6 +21,7 @@ def config_path(
|
|
21
21
|
Construct the directory and files needed for the tests.
|
22
22
|
|
23
23
|
:param tmp_path: pytest object for temporal filesystem.
|
24
|
+
:returns: New resolved filesystem path object instance.
|
24
25
|
"""
|
25
26
|
|
26
27
|
|
@@ -40,4 +41,4 @@ def config_path(
|
|
40
41
|
.write_text('name: Tony Stark'))
|
41
42
|
|
42
43
|
|
43
|
-
return tmp_path
|
44
|
+
return tmp_path.resolve()
|
encommon/times/common.py
CHANGED
@@ -7,6 +7,7 @@ is permitted, for more information consult the project license file.
|
|
7
7
|
|
8
8
|
|
9
9
|
|
10
|
+
from pathlib import Path
|
10
11
|
from time import sleep
|
11
12
|
|
12
13
|
from pytest import raises
|
@@ -25,8 +26,10 @@ def test_Timers() -> None:
|
|
25
26
|
attrs = list(timers.__dict__)
|
26
27
|
|
27
28
|
assert attrs == [
|
28
|
-
'
|
29
|
-
'
|
29
|
+
'_Timers__timers',
|
30
|
+
'_Timers__cache_file',
|
31
|
+
'_Timers__cache_name',
|
32
|
+
'_Timers__cache_dict']
|
30
33
|
|
31
34
|
|
32
35
|
assert repr(timers).startswith(
|
@@ -36,7 +39,11 @@ def test_Timers() -> None:
|
|
36
39
|
'<encommon.times.timers.Timers')
|
37
40
|
|
38
41
|
|
39
|
-
assert timers.
|
42
|
+
assert timers.timers == {'one': 1}
|
43
|
+
assert timers.cache_file is not None
|
44
|
+
assert len(timers.cache_dict) == 1
|
45
|
+
assert timers.cache_name is not None
|
46
|
+
|
40
47
|
|
41
48
|
assert not timers.ready('one')
|
42
49
|
sleep(1.1)
|
@@ -50,6 +57,42 @@ def test_Timers() -> None:
|
|
50
57
|
|
51
58
|
|
52
59
|
|
60
|
+
def test_Timers_cache(
|
61
|
+
tmp_path: Path,
|
62
|
+
) -> None:
|
63
|
+
"""
|
64
|
+
Perform various tests associated with relevant routines.
|
65
|
+
|
66
|
+
:param tmp_path: pytest object for temporal filesystem.
|
67
|
+
"""
|
68
|
+
|
69
|
+
cache_file = (
|
70
|
+
f'{tmp_path}/timers.db')
|
71
|
+
|
72
|
+
timers1 = Timers(
|
73
|
+
timers={'one': 1},
|
74
|
+
cache_file=cache_file)
|
75
|
+
|
76
|
+
assert not timers1.ready('one')
|
77
|
+
|
78
|
+
sleep(0.75)
|
79
|
+
|
80
|
+
timers2 = Timers(
|
81
|
+
timers={'one': 1},
|
82
|
+
cache_file=cache_file)
|
83
|
+
|
84
|
+
assert not timers1.ready('one')
|
85
|
+
assert not timers2.ready('one')
|
86
|
+
|
87
|
+
sleep(0.25)
|
88
|
+
|
89
|
+
timers2.load_cache()
|
90
|
+
|
91
|
+
assert timers1.ready('one')
|
92
|
+
assert timers2.ready('one')
|
93
|
+
|
94
|
+
|
95
|
+
|
53
96
|
def test_Timers_raises() -> None:
|
54
97
|
"""
|
55
98
|
Perform various tests associated with relevant routines.
|
encommon/times/timers.py
CHANGED
@@ -7,59 +7,155 @@ is permitted, for more information consult the project license file.
|
|
7
7
|
|
8
8
|
|
9
9
|
|
10
|
+
from sqlite3 import connect as SQLite
|
10
11
|
from typing import Optional
|
12
|
+
from typing import TYPE_CHECKING
|
11
13
|
|
12
14
|
from .common import NUMERIC
|
13
15
|
from .common import PARSABLE
|
14
16
|
from .times import Times
|
15
17
|
|
18
|
+
if TYPE_CHECKING:
|
19
|
+
from sqlite3 import Connection
|
20
|
+
|
21
|
+
|
22
|
+
TABLE = (
|
23
|
+
"""
|
24
|
+
create table
|
25
|
+
if not exists
|
26
|
+
{0} (
|
27
|
+
"unique" text not null,
|
28
|
+
"update" text not null,
|
29
|
+
primary key ("unique"));
|
30
|
+
""") # noqa: LIT003
|
31
|
+
|
16
32
|
|
17
33
|
|
18
34
|
class Timers:
|
19
35
|
"""
|
20
36
|
Track timers on unique key and determine when to proceed.
|
21
37
|
|
38
|
+
.. warning::
|
39
|
+
This class will use an in-memory database for cache,
|
40
|
+
unless a cache file is explicity defined.
|
41
|
+
|
22
42
|
.. testsetup::
|
23
43
|
>>> from time import sleep
|
24
44
|
|
25
45
|
Example
|
26
46
|
-------
|
27
|
-
>>>
|
28
|
-
>>> timers
|
29
|
-
>>> timers.ready('test')
|
47
|
+
>>> timers = Timers({'one': 1})
|
48
|
+
>>> timers.ready('one')
|
30
49
|
False
|
31
50
|
>>> sleep(1)
|
32
|
-
>>> timers.ready('
|
51
|
+
>>> timers.ready('one')
|
33
52
|
True
|
34
53
|
|
35
|
-
:param
|
54
|
+
:param timers: Seconds that are used for each of timers.
|
55
|
+
:param cache_file: Optional path to SQLite database for
|
56
|
+
cache. This will allow for use between executions.
|
57
|
+
:param cache_name: Optional override default table name.
|
36
58
|
"""
|
37
59
|
|
38
|
-
|
39
|
-
|
60
|
+
__timers: dict[str, float]
|
61
|
+
__cache_file: 'Connection'
|
62
|
+
__cache_name: str
|
63
|
+
__cache_dict: dict[str, Times]
|
40
64
|
|
41
65
|
|
42
66
|
def __init__(
|
43
67
|
self,
|
44
|
-
|
68
|
+
timers: Optional[dict[str, NUMERIC]] = None,
|
69
|
+
cache_file: str = ':memory:',
|
70
|
+
cache_name: str = 'encommon_timers',
|
45
71
|
) -> None:
|
46
72
|
"""
|
47
73
|
Initialize instance for class using provided parameters.
|
48
74
|
"""
|
49
75
|
|
50
|
-
|
76
|
+
timers = timers or {}
|
51
77
|
|
52
|
-
|
78
|
+
|
79
|
+
self.__timers = {
|
53
80
|
k: float(v)
|
54
|
-
for k, v in
|
81
|
+
for k, v in
|
82
|
+
timers.items()}
|
83
|
+
|
84
|
+
|
85
|
+
cached = SQLite(cache_file)
|
86
|
+
|
87
|
+
cached.execute(
|
88
|
+
TABLE.format(cache_name))
|
55
89
|
|
56
|
-
|
90
|
+
cached.commit()
|
91
|
+
|
92
|
+
self.__cache_file = cached
|
93
|
+
self.__cache_name = cache_name
|
94
|
+
|
95
|
+
|
96
|
+
self.__cache_dict = {
|
57
97
|
x: Times()
|
58
|
-
for x in
|
98
|
+
for x in
|
99
|
+
self.__timers}
|
100
|
+
|
101
|
+
|
102
|
+
self.load_cache()
|
103
|
+
self.save_cache()
|
104
|
+
|
105
|
+
|
106
|
+
def load_cache(
|
107
|
+
self,
|
108
|
+
) -> None:
|
109
|
+
"""
|
110
|
+
Load the timers cache from the database into attribute.
|
111
|
+
"""
|
112
|
+
|
113
|
+
cached = self.__cache_file
|
114
|
+
table = self.__cache_name
|
115
|
+
cachem = self.__cache_dict
|
116
|
+
|
117
|
+
cursor = cached.execute(
|
118
|
+
f'select * from {table}'
|
119
|
+
' order by "unique" asc')
|
120
|
+
|
121
|
+
records = cursor.fetchall()
|
122
|
+
|
123
|
+
for record in records:
|
124
|
+
|
125
|
+
unique = record[0]
|
126
|
+
update = record[1]
|
127
|
+
|
128
|
+
times = Times(update)
|
129
|
+
|
130
|
+
cachem[unique] = times
|
131
|
+
|
132
|
+
|
133
|
+
def save_cache(
|
134
|
+
self,
|
135
|
+
) -> None:
|
136
|
+
"""
|
137
|
+
Save the timers cache from the attribute into database.
|
138
|
+
"""
|
139
|
+
|
140
|
+
cached = self.__cache_file
|
141
|
+
table = self.__cache_name
|
142
|
+
cachem = self.__cache_dict
|
143
|
+
|
144
|
+
insert = [
|
145
|
+
(k, str(v)) for k, v
|
146
|
+
in cachem.items()]
|
147
|
+
|
148
|
+
cached.executemany(
|
149
|
+
(f'replace into {table}'
|
150
|
+
' ("unique", "update")'
|
151
|
+
' values (?, ?)'),
|
152
|
+
tuple(insert))
|
153
|
+
|
154
|
+
cached.commit()
|
59
155
|
|
60
156
|
|
61
157
|
@property
|
62
|
-
def
|
158
|
+
def timers(
|
63
159
|
self,
|
64
160
|
) -> dict[str, float]:
|
65
161
|
"""
|
@@ -68,7 +164,46 @@ class Timers:
|
|
68
164
|
:returns: Property for attribute from the class instance.
|
69
165
|
"""
|
70
166
|
|
71
|
-
return dict(self.
|
167
|
+
return dict(self.__timers)
|
168
|
+
|
169
|
+
|
170
|
+
@property
|
171
|
+
def cache_file(
|
172
|
+
self,
|
173
|
+
) -> 'Connection':
|
174
|
+
"""
|
175
|
+
Return the property for attribute from the class instance.
|
176
|
+
|
177
|
+
:returns: Property for attribute from the class instance.
|
178
|
+
"""
|
179
|
+
|
180
|
+
return self.__cache_file
|
181
|
+
|
182
|
+
|
183
|
+
@property
|
184
|
+
def cache_dict(
|
185
|
+
self,
|
186
|
+
) -> dict[str, Times]:
|
187
|
+
"""
|
188
|
+
Return the property for attribute from the class instance.
|
189
|
+
|
190
|
+
:returns: Property for attribute from the class instance.
|
191
|
+
"""
|
192
|
+
|
193
|
+
return dict(self.__cache_dict)
|
194
|
+
|
195
|
+
|
196
|
+
@property
|
197
|
+
def cache_name(
|
198
|
+
self,
|
199
|
+
) -> str:
|
200
|
+
"""
|
201
|
+
Return the property for attribute from the class instance.
|
202
|
+
|
203
|
+
:returns: Property for attribute from the class instance.
|
204
|
+
"""
|
205
|
+
|
206
|
+
return self.__cache_name
|
72
207
|
|
73
208
|
|
74
209
|
def ready(
|
@@ -79,20 +214,24 @@ class Timers:
|
|
79
214
|
"""
|
80
215
|
Determine whether or not the appropriate time has passed.
|
81
216
|
|
217
|
+
.. note::
|
218
|
+
For performance reasons, this method will not notice
|
219
|
+
changes within the database unless refreshed first.
|
220
|
+
|
82
221
|
:param unique: Unique identifier for the timer in mapping.
|
83
222
|
:param update: Determines whether or not time is updated.
|
84
223
|
"""
|
85
224
|
|
86
|
-
|
87
|
-
|
225
|
+
timers = self.__timers
|
226
|
+
caches = self.__cache_dict
|
88
227
|
|
89
|
-
if unique not in
|
228
|
+
if unique not in caches:
|
90
229
|
raise ValueError('unique')
|
91
230
|
|
92
|
-
|
93
|
-
|
231
|
+
cache = caches[unique]
|
232
|
+
timer = timers[unique]
|
94
233
|
|
95
|
-
ready =
|
234
|
+
ready = cache.elapsed >= timer
|
96
235
|
|
97
236
|
if ready and update:
|
98
237
|
self.update(unique)
|
@@ -112,12 +251,14 @@ class Timers:
|
|
112
251
|
:param started: Override the start time for timer value.
|
113
252
|
"""
|
114
253
|
|
115
|
-
|
254
|
+
caches = self.__cache_dict
|
116
255
|
|
117
|
-
if unique not in
|
256
|
+
if unique not in caches:
|
118
257
|
raise ValueError('unique')
|
119
258
|
|
120
|
-
|
259
|
+
caches[unique] = Times(started)
|
260
|
+
|
261
|
+
self.save_cache()
|
121
262
|
|
122
263
|
|
123
264
|
def create(
|
@@ -130,15 +271,17 @@ class Timers:
|
|
130
271
|
Update the existing timer from mapping within the cache.
|
131
272
|
|
132
273
|
:param unique: Unique identifier for the timer in mapping.
|
133
|
-
:param started: Determines when the time starts for timer.
|
134
274
|
:param minimum: Determines minimum seconds that must pass.
|
275
|
+
:param started: Determines when the time starts for timer.
|
135
276
|
"""
|
136
277
|
|
137
|
-
|
138
|
-
|
278
|
+
timers = self.__timers
|
279
|
+
caches = self.__cache_dict
|
139
280
|
|
140
|
-
if unique in
|
281
|
+
if unique in caches:
|
141
282
|
raise ValueError('unique')
|
142
283
|
|
143
|
-
|
144
|
-
|
284
|
+
timers[unique] = float(minimum)
|
285
|
+
caches[unique] = Times(started)
|
286
|
+
|
287
|
+
self.save_cache()
|
encommon/types/__init__.py
CHANGED
@@ -8,10 +8,14 @@ is permitted, for more information consult the project license file.
|
|
8
8
|
|
9
9
|
|
10
10
|
from .dicts import merge_dicts
|
11
|
+
from .dicts import sort_dict
|
11
12
|
from .empty import Empty
|
13
|
+
from .strings import striplower
|
12
14
|
|
13
15
|
|
14
16
|
|
15
17
|
__all__ = [
|
16
18
|
'Empty',
|
17
|
-
'merge_dicts'
|
19
|
+
'merge_dicts',
|
20
|
+
'sort_dict',
|
21
|
+
'striplower']
|
encommon/types/dicts.py
CHANGED
@@ -58,3 +58,29 @@ def merge_dicts(
|
|
58
58
|
|
59
59
|
elif force is True:
|
60
60
|
dict1[key] = value
|
61
|
+
|
62
|
+
|
63
|
+
|
64
|
+
def sort_dict(
|
65
|
+
value: dict[Any, Any],
|
66
|
+
reverse: bool = False,
|
67
|
+
) -> dict[Any, Any]:
|
68
|
+
"""
|
69
|
+
Sort the keys within the dictionary and return new one.
|
70
|
+
|
71
|
+
Example
|
72
|
+
-------
|
73
|
+
>>> foo = {'b': 'be', 'a': 'ey'}
|
74
|
+
>>> sort_dict(foo)
|
75
|
+
{'a': 'ey', 'b': 'be'}
|
76
|
+
>>> sort_dict(foo, True)
|
77
|
+
{'b': 'be', 'a': 'ey'}
|
78
|
+
|
79
|
+
:param value: Dictionary whose keys are sorted into new.
|
80
|
+
:param reverse: Optionally reverse the sort direction.
|
81
|
+
:returns: New dictionary with keys sorted alphabetical.
|
82
|
+
"""
|
83
|
+
|
84
|
+
return dict(sorted(
|
85
|
+
value.items(),
|
86
|
+
reverse=reverse))
|
@@ -0,0 +1,25 @@
|
|
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
|
+
def striplower(
|
11
|
+
value: str,
|
12
|
+
) -> str:
|
13
|
+
"""
|
14
|
+
Return the provided string but stripped and lower cased.
|
15
|
+
|
16
|
+
Example
|
17
|
+
-------
|
18
|
+
>>> striplower(' Foo ')
|
19
|
+
'foo'
|
20
|
+
|
21
|
+
:param value: String which will be stripped and lowered.
|
22
|
+
:returns: Provided string but stripped and lower cased.
|
23
|
+
"""
|
24
|
+
|
25
|
+
return value.strip().lower()
|
@@ -10,6 +10,23 @@ is permitted, for more information consult the project license file.
|
|
10
10
|
from copy import deepcopy
|
11
11
|
|
12
12
|
from ..dicts import merge_dicts
|
13
|
+
from ..dicts import sort_dict
|
14
|
+
|
15
|
+
|
16
|
+
|
17
|
+
DICT1 = {
|
18
|
+
'dict1': 'dict1',
|
19
|
+
'str': 'd1string',
|
20
|
+
'list': ['d1list'],
|
21
|
+
'dict': {'key': 'd1value'},
|
22
|
+
'bool': False}
|
23
|
+
|
24
|
+
DICT2 = {
|
25
|
+
'dict2': 'dict2',
|
26
|
+
'str': 'd2string',
|
27
|
+
'list': ['d2list'],
|
28
|
+
'dict': {'key': 'd2value'},
|
29
|
+
'bool': True}
|
13
30
|
|
14
31
|
|
15
32
|
|
@@ -18,19 +35,8 @@ def test_merge_dicts() -> None:
|
|
18
35
|
Perform various tests associated with relevant routines.
|
19
36
|
"""
|
20
37
|
|
21
|
-
dict1 =
|
22
|
-
|
23
|
-
'str': 'd1string',
|
24
|
-
'list': ['d1list'],
|
25
|
-
'dict': {'key': 'd1value'},
|
26
|
-
'bool': False}
|
27
|
-
|
28
|
-
dict2 = {
|
29
|
-
'dict2': 'dict2',
|
30
|
-
'str': 'd2string',
|
31
|
-
'list': ['d2list'],
|
32
|
-
'dict': {'key': 'd2value'},
|
33
|
-
'bool': True}
|
38
|
+
dict1 = deepcopy(DICT1)
|
39
|
+
dict2 = deepcopy(DICT2)
|
34
40
|
|
35
41
|
dict1['recurse'] = deepcopy(dict1)
|
36
42
|
dict2['recurse'] = deepcopy(dict2)
|
@@ -100,3 +106,17 @@ def test_merge_dicts() -> None:
|
|
100
106
|
'list': ['d1list'],
|
101
107
|
'dict': {'key': 'd1value'},
|
102
108
|
'bool': False}}
|
109
|
+
|
110
|
+
|
111
|
+
|
112
|
+
def test_sort_dict() -> None:
|
113
|
+
"""
|
114
|
+
Perform various tests associated with relevant routines.
|
115
|
+
"""
|
116
|
+
|
117
|
+
assert sort_dict(DICT1) == {
|
118
|
+
'bool': False,
|
119
|
+
'dict': {'key': 'd1value'},
|
120
|
+
'dict1': 'dict1',
|
121
|
+
'list': ['d1list'],
|
122
|
+
'str': 'd1string'}
|
@@ -0,0 +1,19 @@
|
|
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 ..strings import striplower
|
11
|
+
|
12
|
+
|
13
|
+
|
14
|
+
def test_striplower() -> None:
|
15
|
+
"""
|
16
|
+
Perform various tests associated with relevant routines.
|
17
|
+
"""
|
18
|
+
|
19
|
+
assert striplower(' Foo ') == 'foo'
|
encommon/utils/sample.py
CHANGED
@@ -98,7 +98,7 @@ def load_sample(
|
|
98
98
|
:param update: Determine whether the sample is updated.
|
99
99
|
:param content: Content which will be processed for JSON.
|
100
100
|
:param default: Callable used when stringifying values.
|
101
|
-
:param replace: Optional string values to replace in
|
101
|
+
:param replace: Optional string values to replace in file.
|
102
102
|
:returns: Content after processing using JSON functions.
|
103
103
|
"""
|
104
104
|
|
encommon/version.txt
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.6.0
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: encommon
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.6.0
|
4
4
|
Summary: Enasis Network Common Library
|
5
5
|
License: MIT
|
6
6
|
Classifier: Programming Language :: Python :: 3
|
@@ -18,14 +18,15 @@ Requires-Dist: snaptime
|
|
18
18
|
|
19
19
|
# Enasis Network Common Library
|
20
20
|
|
21
|
-
[](https://github.com/enasisnetwork/encommon/actions)
|
22
|
-
[](https://encommon.readthedocs.io/en/stable)
|
23
|
-
[](https://pypi.org/project/encommon)
|
24
|
-
[](https://pypi.org/project/encommon)
|
25
|
-
|
26
21
|
Common classes and functions used in various public and private projects for
|
27
22
|
[Enasis Network](https://github.com/enasisnetwork).
|
28
23
|
|
24
|
+
[](https://github.com/enasisnetwork/encommon/actions)<br>
|
25
|
+
[](https://codecov.io/gh/enasisnetwork/encommon)<br>
|
26
|
+
[](https://encommon.readthedocs.io/en/stable)<br>
|
27
|
+
[](https://pypi.org/project/encommon)<br>
|
28
|
+
[](https://pypi.org/project/encommon)
|
29
|
+
|
29
30
|
## Installing the package
|
30
31
|
Installing stable from the PyPi repository
|
31
32
|
```
|
@@ -1,17 +1,17 @@
|
|
1
1
|
encommon/__init__.py,sha256=VoXUcphq-gcXCraaU47EtXBftF6UVuQPMGr0fuCTt9A,525
|
2
|
+
encommon/conftest.py,sha256=z5BMi6KjNuactDRgbh8J8w81V08Ptf6QK2o_bJANRs4,880
|
2
3
|
encommon/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
3
|
-
encommon/version.txt,sha256=
|
4
|
+
encommon/version.txt,sha256=l6XW5UCmEg0Jw53bZn4Ojiusf8wv_vgTuC4I_WA2W84,6
|
4
5
|
encommon/config/__init__.py,sha256=2ic7tK2lOQvqWmmQnMozqxCJcbyQ_sSEHmOUDUFan2U,710
|
5
6
|
encommon/config/common.py,sha256=gaKBgkF7b7UIAhd0ESio0KpG8JfdRpz5BxNgKRptd6A,2041
|
6
|
-
encommon/config/config.py,sha256
|
7
|
+
encommon/config/config.py,sha256=-wIkyA6YQGAly0WuXLaOYXENjZYRYgWk_VdUN8mMe8Q,4853
|
7
8
|
encommon/config/files.py,sha256=2DHz7GKOjF8FC26tY0V-E9svNMrlkSUshb2gfxqGgSo,2313
|
8
9
|
encommon/config/logger.py,sha256=2y-VFzgM2pZzEYq48XfvrDPrtUcxyP9QjbH5OG7fv5o,13449
|
9
|
-
encommon/config/params.py,sha256=
|
10
|
+
encommon/config/params.py,sha256=IWQ-UzR8x6VxkcUddC3qhI612IFMfLW44jEjRePXK0c,1825
|
10
11
|
encommon/config/paths.py,sha256=0EpXWn6G9IO6tuZTrWuDq53RI5xMTgDQrAlOjRLILHs,2433
|
11
12
|
encommon/config/test/__init__.py,sha256=PjrnBYT0efyvbaGeNx94dm3tP3EVHUHSVs-VGeLEv5g,218
|
12
|
-
encommon/config/test/conftest.py,sha256=TNLox448WJSUkG5Lx2PM7LWvLHiaaOvxm6tx6o02pBc,810
|
13
13
|
encommon/config/test/test_common.py,sha256=U6XWfCLxtLmArn8P6h4cmCALzdXxV7IMUxKNU-UhwPw,731
|
14
|
-
encommon/config/test/test_config.py,sha256=
|
14
|
+
encommon/config/test/test_config.py,sha256=SMe8ZrHRVS7jcyoFB-jBmlYTdUkBT1RrjZ9QlAW1EtE,3292
|
15
15
|
encommon/config/test/test_files.py,sha256=OlGziUPV35yrdn2Ac8tuqmFfjHciWJADdQRvacoJNUc,2298
|
16
16
|
encommon/config/test/test_logger.py,sha256=oLMosbxHq313oSNkdsrJe_kp0YrlcLCErIccg66zXcI,4635
|
17
17
|
encommon/config/test/test_paths.py,sha256=vNWYqiN_wNuFCu1HHEekoJdGGJyRlucDBZTAspwxWhc,2107
|
@@ -23,38 +23,40 @@ encommon/crypts/test/__init__.py,sha256=PjrnBYT0efyvbaGeNx94dm3tP3EVHUHSVs-VGeLE
|
|
23
23
|
encommon/crypts/test/test_crypts.py,sha256=QDhIUVzn-n5z9tk1ZPXbZ4pBx0CRtcfqIyESYVB0kbU,2433
|
24
24
|
encommon/crypts/test/test_hashes.py,sha256=Spixpx2qBi6iSJ8aNgmnNtz04JofUpwU-a_UjpRoiHA,1206
|
25
25
|
encommon/times/__init__.py,sha256=w6LeTybgdsi0oM1EL9ARbAqevX7Tn46JYhbXNAaWzB0,597
|
26
|
-
encommon/times/common.py,sha256=
|
26
|
+
encommon/times/common.py,sha256=xLB_GLahYKT-YrVq90RUzmiodJQ4__1YihgZZTnadgg,2506
|
27
27
|
encommon/times/duration.py,sha256=8p-L9OItO80nnd35FYrAXbiUS8RJzavI21lXBrtLaH0,9872
|
28
28
|
encommon/times/parse.py,sha256=ZzranxftlB6bZJ1ivkoUxD53TUfXDDUdpq9jsSJN-88,6411
|
29
|
-
encommon/times/timers.py,sha256=
|
29
|
+
encommon/times/timers.py,sha256=yOVr6deGE5iatNWUwNQCzaXjMlLeYlolx4MmKT0MSHc,6312
|
30
30
|
encommon/times/times.py,sha256=Dfu6ztUsV4X4vHzOC7ds8jtYy0AVj4_R5xB6H-yzemE,9432
|
31
31
|
encommon/times/window.py,sha256=Fx_OJfU9B0IctCyaJ5XH_HxzhGlzeRATwuhI-HlsTPA,8023
|
32
32
|
encommon/times/test/__init__.py,sha256=PjrnBYT0efyvbaGeNx94dm3tP3EVHUHSVs-VGeLEv5g,218
|
33
33
|
encommon/times/test/test_common.py,sha256=nizxgB1scLDEm2o66waK1Ar_Dl5BBMTC-GRV7iDk0_U,1477
|
34
34
|
encommon/times/test/test_duration.py,sha256=rmAhW2otHzQDHF0mBSETHnnL2OSbeAFYEHpDlaUSRnI,3901
|
35
35
|
encommon/times/test/test_parse.py,sha256=TuZG_UbIEez4Ww35vdKIie_yaKp-PiUhsNmr1ZUoGvo,4308
|
36
|
-
encommon/times/test/test_timers.py,sha256=
|
36
|
+
encommon/times/test/test_timers.py,sha256=z-ONyKtkAZ1A7w8qgpgx07r-Vsl5jY-pe2oneSF7hyo,2314
|
37
37
|
encommon/times/test/test_times.py,sha256=DJBmRHCPkMLL9-bmc2DMhhf8zcr2rsTVAAQPavD_UmE,1986
|
38
38
|
encommon/times/test/test_window.py,sha256=EWjXR8XREYwKrH-221CBAUwLF9GpvHtuF_CSMdQtUXI,4735
|
39
|
-
encommon/types/__init__.py,sha256=
|
40
|
-
encommon/types/dicts.py,sha256=
|
39
|
+
encommon/types/__init__.py,sha256=l2WKtDs6uC9I3dIGnrzJvz-4JLEETUJOfT509XyMQWs,420
|
40
|
+
encommon/types/dicts.py,sha256=zJbfAsL1uiqfouBQrQgcYGoLowtkUd-Vm9536_DVK_E,2208
|
41
41
|
encommon/types/empty.py,sha256=KrH6I0PPljaFBQ1qB1tbxFxZd8DR5rEFYhZqgLzjIsA,2675
|
42
|
+
encommon/types/strings.py,sha256=lgrzZuiCnH1UW17EFkLYiou3kQBgs_ZK2R92_dz7gRQ,560
|
42
43
|
encommon/types/test/__init__.py,sha256=PjrnBYT0efyvbaGeNx94dm3tP3EVHUHSVs-VGeLEv5g,218
|
43
|
-
encommon/types/test/test_dicts.py,sha256=
|
44
|
+
encommon/types/test/test_dicts.py,sha256=UHMvrWKnz-bPscq0Vp2uoLLFv4slvQQL2sobe5WUZ7U,2673
|
44
45
|
encommon/types/test/test_empty.py,sha256=YUn0ROFhrWLQ30uROVqroHW4BsnFbzUZjACs3aEvrrI,981
|
46
|
+
encommon/types/test/test_strings.py,sha256=WHXf1dnK6Qs2_0UyGYztJxpS29bnR8WKjKsvVO2WCi4,407
|
45
47
|
encommon/utils/__init__.py,sha256=qdr2RDKlmoGrgMhwJCaTrhQXmuD_lmDxlIxOUprnRVs,784
|
46
48
|
encommon/utils/common.py,sha256=UrowELh3PtDzpSS48nGhsAxTS_QUk96-KEJa4MlxiMA,466
|
47
49
|
encommon/utils/match.py,sha256=4L2d2Cvr7vp3odkRCdNQ10OIW8DkEP55_NbQ6bdsReo,2462
|
48
50
|
encommon/utils/paths.py,sha256=4EeaPsVwpv3pzoHeWmiSSGYZEud6hkD27kvbvgSpOPs,3236
|
49
|
-
encommon/utils/sample.py,sha256=
|
51
|
+
encommon/utils/sample.py,sha256=hOhS6A2aB9a5kXfrst7gUSQkxuqEo2J1AFyBsJZQhHE,3169
|
50
52
|
encommon/utils/stdout.py,sha256=0C5NTg8fAB25s5oKmsmV2VSERn22QFCZjqJ1S75SXOM,2779
|
51
53
|
encommon/utils/test/__init__.py,sha256=PjrnBYT0efyvbaGeNx94dm3tP3EVHUHSVs-VGeLEv5g,218
|
52
54
|
encommon/utils/test/test_match.py,sha256=QagKpTFdRo23-Y55fSaJrSMpt5jIebScKbz0h8tivrI,1124
|
53
55
|
encommon/utils/test/test_paths.py,sha256=0ls9gWJ2B487Dr1fHDDFCZPA7gxtv56nFEYHrTkNX-U,1892
|
54
56
|
encommon/utils/test/test_sample.py,sha256=iNV9IxXmA5KJat3jKRiZH3iutHrT6bsibwti60AhICk,1464
|
55
57
|
encommon/utils/test/test_stdout.py,sha256=a060uA8oEHFGoVqdwB5iYxdl4R2TRSgr6Z7pMEbxibs,1675
|
56
|
-
encommon-0.
|
57
|
-
encommon-0.
|
58
|
-
encommon-0.
|
59
|
-
encommon-0.
|
60
|
-
encommon-0.
|
58
|
+
encommon-0.6.0.dist-info/LICENSE,sha256=otnXKCtMjPlbHs0wgZ_BWULrp3g_2dWQJ6icRk9nkgg,1071
|
59
|
+
encommon-0.6.0.dist-info/METADATA,sha256=OJ2Y0-tAC9HmFKQmrcyR5oQHFAVU1rxD9Rt2ssceXAs,2671
|
60
|
+
encommon-0.6.0.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
|
61
|
+
encommon-0.6.0.dist-info/top_level.txt,sha256=bP8q7-5tLDNm-3XPlqn_bDENfYNug5801H_xfz3BEAM,9
|
62
|
+
encommon-0.6.0.dist-info/RECORD,,
|
File without changes
|