encommon 0.9.0__py3-none-any.whl → 0.10.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 CHANGED
@@ -20,6 +20,7 @@ from .params import Params
20
20
  from .paths import ConfigPaths
21
21
  from ..crypts import Crypts
22
22
  from ..types import merge_dicts
23
+ from ..types import setate
23
24
 
24
25
  if TYPE_CHECKING:
25
26
  from ..utils.common import PATHABLE
@@ -124,7 +125,16 @@ class Config:
124
125
  :returns: Value for the attribute from class instance.
125
126
  """
126
127
 
127
- return deepcopy(self.__cargs)
128
+ returned: dict[str, Any] = {}
129
+
130
+ cargs = deepcopy(self.__cargs)
131
+
132
+ items = cargs.items()
133
+
134
+ for key, value in items:
135
+ setate(returned, key, value)
136
+
137
+ return deepcopy(returned)
128
138
 
129
139
 
130
140
  @property
encommon/config/params.py CHANGED
@@ -18,7 +18,7 @@ from ..crypts import CryptsParams
18
18
 
19
19
  class ConfigParams(BaseModel, extra='forbid'):
20
20
  """
21
- Process and validate the common configuration parameters.
21
+ Process and validate the core configuration parameters.
22
22
 
23
23
  :param paths: Complete or relative path to config paths.
24
24
  :param data: Keyword arguments passed to Pydantic model.
@@ -31,7 +31,7 @@ class ConfigParams(BaseModel, extra='forbid'):
31
31
 
32
32
  class LoggerParams(BaseModel, extra='forbid'):
33
33
  """
34
- Process and validate the common configuration parameters.
34
+ Process and validate the core configuration parameters.
35
35
 
36
36
  :param stdo_level: Minimum level for the message to pass.
37
37
  :param file_level: Minimum level for the message to pass.
@@ -48,7 +48,7 @@ class LoggerParams(BaseModel, extra='forbid'):
48
48
 
49
49
  class Params(BaseModel, extra='forbid'):
50
50
  """
51
- Process and validate the common configuration parameters.
51
+ Process and validate the core configuration parameters.
52
52
 
53
53
  :param enconfig: Configuration for the Config instance.
54
54
  :param enlogger: Configuration for the Logger instance.
encommon/conftest.py CHANGED
@@ -43,9 +43,8 @@ def config_factory(
43
43
  config_log = f'{tmp_path}/config.log'
44
44
 
45
45
  cargs = {
46
- 'enlogger': {
47
- 'file_path': config_log,
48
- 'file_level': 'info'}}
46
+ 'enlogger/file_path': config_log,
47
+ 'enlogger/file_level': 'info'}
49
48
 
50
49
  return Config(
51
50
  files=f'{tmp_path}/config.yml',
encommon/crypts/params.py CHANGED
@@ -13,7 +13,7 @@ from pydantic import BaseModel
13
13
 
14
14
  class CryptsParams(BaseModel, extra='forbid'):
15
15
  """
16
- Process and validate the common configuration parameters.
16
+ Process and validate the core configuration parameters.
17
17
 
18
18
  :param phrases: Passphrases that are used in operations.
19
19
  :param data: Keyword arguments passed to Pydantic model.
@@ -10,6 +10,9 @@ is permitted, for more information consult the project license file.
10
10
  from .dicts import merge_dicts
11
11
  from .dicts import sort_dict
12
12
  from .empty import Empty
13
+ from .notate import delate
14
+ from .notate import getate
15
+ from .notate import setate
13
16
  from .strings import hasstr
14
17
  from .strings import inrepr
15
18
  from .strings import instr
@@ -18,10 +21,13 @@ from .strings import striplower
18
21
 
19
22
 
20
23
  __all__ = [
24
+ 'delate',
21
25
  'Empty',
26
+ 'getate',
22
27
  'hasstr',
23
28
  'inrepr',
24
29
  'instr',
25
30
  'merge_dicts',
31
+ 'setate',
26
32
  'sort_dict',
27
33
  'striplower']
@@ -0,0 +1,321 @@
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 contextlib import suppress
11
+ from re import compile
12
+ from re import match as re_match
13
+ from typing import Any
14
+ from typing import Optional
15
+ from typing import Union
16
+
17
+ from .empty import Empty
18
+
19
+
20
+
21
+ _INTEGER = compile(r'^\d+$')
22
+ _INDICES = (list, tuple, dict)
23
+ _RECURSE = dict
24
+
25
+
26
+
27
+ _SETABLE = Union[
28
+ dict[str, Any],
29
+ list[Any]]
30
+
31
+ _GETABLE = Union[
32
+ tuple[Any, ...],
33
+ _SETABLE]
34
+
35
+
36
+
37
+ def getate(
38
+ source: _GETABLE,
39
+ path: str,
40
+ default: Optional[Any] = None,
41
+ delim: str = '/',
42
+ ) -> Any: # noqa: ANN401
43
+ """
44
+ Collect the value within the dictionary using notation.
45
+
46
+ Example
47
+ -------
48
+ >>> source = {'foo': {'bar': 'baz'}}
49
+ >>> getate(source, 'foo/bar')
50
+ 'baz'
51
+
52
+ Example
53
+ -------
54
+ >>> source = {'foo': ['bar', 'baz']}
55
+ >>> getate(source, 'foo/1')
56
+ 'baz'
57
+
58
+ :param source: Dictionary object processed in notation.
59
+ :param path: Path to the value within the source object.
60
+ :param default: Value to use if none is found in source.
61
+ :param delim: Override default delimiter between parts.
62
+ :returns: Value that was located within provided source.
63
+ """
64
+
65
+ sourze: Any = source
66
+
67
+ split = path.split(delim)
68
+
69
+ length = len(split)
70
+
71
+
72
+ items = enumerate(split)
73
+
74
+ for index, base in items:
75
+
76
+ if sourze is Empty:
77
+ return default
78
+
79
+
80
+ indices = isinstance(
81
+ sourze, _INDICES)
82
+
83
+ if (indices is False
84
+ and index < length):
85
+ return default
86
+
87
+
88
+ recurse = isinstance(
89
+ sourze, _RECURSE)
90
+
91
+ if recurse is False:
92
+
93
+ with suppress(IndexError):
94
+ sourze = sourze[int(base)]
95
+ continue
96
+
97
+
98
+ if base not in sourze:
99
+ sourze = Empty
100
+ continue
101
+
102
+ sourze = sourze[base]
103
+
104
+
105
+ return (
106
+ default if sourze is Empty
107
+ else sourze)
108
+
109
+
110
+
111
+ def setate(
112
+ source: _SETABLE,
113
+ path: str,
114
+ value: Any, # noqa: ANN401
115
+ delim: str = '/',
116
+ ) -> None:
117
+ """
118
+ Define the value within the dictionary using notation.
119
+
120
+ Example
121
+ -------
122
+ >>> source = {'foo': {'bar': 'baz'}}
123
+ >>> source['foo']['bar']
124
+ 'baz'
125
+ >>> setate(source, 'foo/bar', 'bop')
126
+ >>> source['foo']['bar']
127
+ 'bop'
128
+
129
+ :param source: Dictionary object processed in notation.
130
+ :param path: Path to the value within the source object.
131
+ :param value: Value which will be defined at noted point.
132
+ :param delim: Override default delimiter between parts.
133
+ """
134
+
135
+ _setvalue(source, path, value, delim)
136
+
137
+
138
+
139
+ def delate(
140
+ source: _SETABLE,
141
+ path: str,
142
+ delim: str = '/',
143
+ ) -> None:
144
+ """
145
+ Delete the value within the dictionary using notation.
146
+
147
+ Example
148
+ -------
149
+ >>> source = {'foo': {'bar': 'baz'}}
150
+ >>> delate(source, 'foo/bar')
151
+ >>> source
152
+ {'foo': {}}
153
+
154
+ :param source: Dictionary object processed in notation.
155
+ :param path: Path to the value within the source object.
156
+ :param delim: Override default delimiter between parts.
157
+ """
158
+
159
+ split = path.split(delim)
160
+
161
+ with suppress(KeyError, IndexError):
162
+
163
+
164
+ for part in split[:-1]:
165
+
166
+ setable = isinstance(
167
+ source, dict | list)
168
+
169
+ if setable is False:
170
+ raise ValueError('source')
171
+
172
+ if isinstance(source, list):
173
+ source = source[int(part)]
174
+
175
+ elif isinstance(source, dict):
176
+ source = source[part]
177
+
178
+
179
+ part = split[-1]
180
+
181
+ setable = isinstance(
182
+ source, dict | list)
183
+
184
+ if setable is False:
185
+ raise ValueError('source')
186
+
187
+ if isinstance(source, dict):
188
+ del source[part]
189
+
190
+ if isinstance(source, list):
191
+ del source[int(part)]
192
+
193
+
194
+
195
+ def _setpath(
196
+ source: _SETABLE,
197
+ path: str,
198
+ value: Any, # noqa: ANN401
199
+ delim: str = '/',
200
+ ) -> None:
201
+ """
202
+ Define the value within the dictionary using notation.
203
+
204
+ .. note::
205
+ This is a private helper function that could change.
206
+
207
+ :param source: Dictionary object processed in notation.
208
+ :param path: Path to the value within the source object.
209
+ :param value: Value which will be defined at noted point.
210
+ :param delim: Override default delimiter between parts.
211
+ :returns: Original provided source containing the value.
212
+ """
213
+
214
+
215
+ setable = isinstance(
216
+ source, dict | list)
217
+
218
+ assert setable is True
219
+
220
+
221
+ base, path = (
222
+ path.split(delim, 1))
223
+
224
+ next = (
225
+ path.split(delim, 1)[0])
226
+
227
+
228
+ default: _SETABLE = {}
229
+
230
+ if re_match(_INTEGER, next):
231
+ default = []
232
+
233
+ update: Any
234
+
235
+
236
+ if isinstance(source, list):
237
+
238
+ length = len(source)
239
+ index = int(base)
240
+
241
+ update = default
242
+
243
+ with suppress(IndexError):
244
+ update = source[index]
245
+
246
+ _setvalue(
247
+ update, path,
248
+ value, delim)
249
+
250
+ if length == index:
251
+ source.append(update)
252
+
253
+ elif length > index:
254
+ source[index] = update
255
+
256
+
257
+ elif isinstance(source, dict):
258
+
259
+ update = default
260
+
261
+ with suppress(KeyError):
262
+ update = source[base]
263
+
264
+ _setvalue(
265
+ update, path,
266
+ value, delim)
267
+
268
+ source[base] = update
269
+
270
+
271
+
272
+ def _setvalue(
273
+ source: _SETABLE,
274
+ path: str,
275
+ value: Any, # noqa: ANN401
276
+ delim: str = '/',
277
+ ) -> None:
278
+ """
279
+ Define the value within the dictionary using notation.
280
+
281
+ .. note::
282
+ This is a private helper function that could change.
283
+
284
+ :param source: Dictionary object processed in notation.
285
+ :param path: Path to the value within the source object.
286
+ :param value: Value which will be defined at noted point.
287
+ :param delim: Override default delimiter between parts.
288
+ :returns: Original provided source containing the value.
289
+ """
290
+
291
+
292
+ setable = isinstance(
293
+ source, dict | list)
294
+
295
+ if setable is False:
296
+ raise ValueError('source')
297
+
298
+
299
+ if delim in path:
300
+ return _setpath(
301
+ source, path,
302
+ value, delim)
303
+
304
+
305
+ if isinstance(source, list):
306
+
307
+ length = len(source)
308
+ index = int(path)
309
+
310
+ if index > length:
311
+ raise IndexError(index)
312
+
313
+ if length == index:
314
+ source.append(value)
315
+
316
+ elif length > index:
317
+ source[index] = value
318
+
319
+
320
+ if isinstance(source, dict):
321
+ source[path] = value
@@ -4,3 +4,40 @@ Functions and routines associated with Enasis Network Common Library.
4
4
  This file is part of Enasis Network software eco-system. Distribution
5
5
  is permitted, for more information consult the project license file.
6
6
  """
7
+
8
+
9
+
10
+ from copy import deepcopy
11
+
12
+
13
+
14
+ _DICT1 = {
15
+ 'dict1': 'dict1',
16
+ 'str': 'd1string',
17
+ 'list': ['d1list'],
18
+ 'tuple': (1, 2),
19
+ 'dict': {'key': 'd1dict'},
20
+ 'bool': False}
21
+
22
+ _DICT2 = {
23
+ 'dict2': 'dict2',
24
+ 'str': 'd2string',
25
+ 'list': ['d2list'],
26
+ 'tuple': (3, 4),
27
+ 'dict': {'key': 'd2dict'},
28
+ 'bool': True}
29
+
30
+ _DICT1R = deepcopy(_DICT1)
31
+ _DICT2R = deepcopy(_DICT2)
32
+
33
+ _DICT1R['recurse'] = (
34
+ deepcopy(_DICT1))
35
+
36
+ _DICT2R['recurse'] = (
37
+ deepcopy(_DICT2))
38
+
39
+ _DICT1R['nested'] = [
40
+ deepcopy(_DICT1)]
41
+
42
+ _DICT2R['nested'] = [
43
+ deepcopy(_DICT2)]
@@ -9,37 +9,22 @@ is permitted, for more information consult the project license file.
9
9
 
10
10
  from copy import deepcopy
11
11
 
12
+ from . import _DICT1
13
+ from . import _DICT1R
14
+ from . import _DICT2
15
+ from . import _DICT2R
12
16
  from ..dicts import merge_dicts
13
17
  from ..dicts import sort_dict
14
18
 
15
19
 
16
20
 
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}
30
-
31
-
32
-
33
21
  def test_merge_dicts() -> None:
34
22
  """
35
23
  Perform various tests associated with relevant routines.
36
24
  """
37
25
 
38
- dict1 = deepcopy(_DICT1)
39
- dict2 = deepcopy(_DICT2)
40
-
41
- dict1['recurse'] = deepcopy(dict1)
42
- dict2['recurse'] = deepcopy(dict2)
26
+ dict1 = deepcopy(_DICT1R)
27
+ dict2 = deepcopy(_DICT2R)
43
28
 
44
29
 
45
30
  source = deepcopy(dict1)
@@ -52,14 +37,17 @@ def test_merge_dicts() -> None:
52
37
  'dict2': 'dict2',
53
38
  'str': 'd1string',
54
39
  'list': ['d1list', 'd2list'],
55
- 'dict': {'key': 'd1value'},
40
+ 'dict': {'key': 'd1dict'},
41
+ 'tuple': (1, 2),
56
42
  'bool': False,
43
+ 'nested': [_DICT1, _DICT2],
57
44
  'recurse': {
58
45
  'dict1': 'dict1',
59
46
  'dict2': 'dict2',
60
47
  'str': 'd1string',
61
48
  'list': ['d1list', 'd2list'],
62
- 'dict': {'key': 'd1value'},
49
+ 'dict': {'key': 'd1dict'},
50
+ 'tuple': (1, 2),
63
51
  'bool': False}}
64
52
 
65
53
 
@@ -73,14 +61,17 @@ def test_merge_dicts() -> None:
73
61
  'dict2': 'dict2',
74
62
  'str': 'd2string',
75
63
  'list': ['d1list', 'd2list'],
76
- 'dict': {'key': 'd2value'},
64
+ 'dict': {'key': 'd2dict'},
65
+ 'tuple': (3, 4),
77
66
  'bool': True,
67
+ 'nested': [_DICT1, _DICT2],
78
68
  'recurse': {
79
69
  'dict1': 'dict1',
80
70
  'dict2': 'dict2',
81
71
  'str': 'd2string',
82
72
  'list': ['d1list', 'd2list'],
83
- 'dict': {'key': 'd2value'},
73
+ 'dict': {'key': 'd2dict'},
74
+ 'tuple': (3, 4),
84
75
  'bool': True}}
85
76
 
86
77
 
@@ -98,13 +89,16 @@ def test_merge_dicts() -> None:
98
89
  'dict2': 'dict2',
99
90
  'str': 'd1string',
100
91
  'list': ['d1list'],
101
- 'dict': {'key': 'd1value'},
92
+ 'dict': {'key': 'd1dict'},
93
+ 'tuple': (1, 2),
102
94
  'bool': False,
95
+ 'nested': [_DICT1],
103
96
  'recurse': {
104
97
  'dict1': 'dict1',
105
98
  'str': 'd1string',
106
99
  'list': ['d1list'],
107
- 'dict': {'key': 'd1value'},
100
+ 'dict': {'key': 'd1dict'},
101
+ 'tuple': (1, 2),
108
102
  'bool': False}}
109
103
 
110
104
 
@@ -116,7 +110,8 @@ def test_sort_dict() -> None:
116
110
 
117
111
  assert sort_dict(_DICT1) == {
118
112
  'bool': False,
119
- 'dict': {'key': 'd1value'},
113
+ 'dict': {'key': 'd1dict'},
114
+ 'tuple': (1, 2),
120
115
  'dict1': 'dict1',
121
116
  'list': ['d1list'],
122
117
  'str': 'd1string'}
@@ -0,0 +1,217 @@
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 copy import deepcopy
11
+
12
+ from _pytest.python_api import RaisesContext
13
+
14
+ from pytest import raises
15
+
16
+ from . import _DICT1R
17
+ from ..notate import delate
18
+ from ..notate import getate
19
+ from ..notate import setate
20
+
21
+
22
+
23
+ def test_getate() -> None:
24
+ """
25
+ Perform various tests associated with relevant routines.
26
+ """
27
+
28
+ source = deepcopy(_DICT1R)
29
+
30
+
31
+ value = getate(['1', 2], '1')
32
+ assert value == 2
33
+
34
+ value = getate((1, 2), '1')
35
+ assert value == 2
36
+
37
+ value = getate({'1': 2}, '1')
38
+ assert value == 2
39
+
40
+
41
+ path = 'recurse/dict/key'
42
+ value = getate(source, path)
43
+
44
+ assert value == 'd1dict'
45
+
46
+
47
+ path = 'recurse/list/0'
48
+ value = getate(source, path)
49
+
50
+ assert value == 'd1list'
51
+
52
+
53
+
54
+ def test_getate_cover() -> None:
55
+ """
56
+ Perform various tests associated with relevant routines.
57
+ """
58
+
59
+ source = deepcopy(_DICT1R)
60
+
61
+
62
+ assert not getate({}, 'd/n/e')
63
+ assert not getate([], '0/n/e')
64
+
65
+
66
+ path = 'recurse/str/a'
67
+ value = getate(source, path)
68
+
69
+ assert value is None
70
+
71
+
72
+
73
+ def test_setate() -> None:
74
+ """
75
+ Perform various tests associated with relevant routines.
76
+ """
77
+
78
+ source = deepcopy(_DICT1R)
79
+
80
+
81
+ path = 'list/1'
82
+ before = getate(source, path)
83
+ setate(source, path, 1)
84
+ after = getate(source, path)
85
+ assert after == 1
86
+ assert before is None
87
+
88
+
89
+ path = 'recurse/dict/key'
90
+ before = getate(source, path)
91
+ setate(source, path, 1)
92
+ after = getate(source, path)
93
+ assert after == 1
94
+ assert before == 'd1dict'
95
+
96
+
97
+ path = 'nested/0/dict/key'
98
+ before = getate(source, path)
99
+ setate(source, path, 1)
100
+ after = getate(source, path)
101
+ assert after == 1
102
+ assert before == 'd1dict'
103
+
104
+
105
+ path = 'recurse/list/0'
106
+ before = getate(source, path)
107
+ setate(source, path, 1)
108
+ after = getate(source, path)
109
+ assert after == 1
110
+ assert before == 'd1list'
111
+
112
+
113
+
114
+ def test_setate_cover() -> None:
115
+ """
116
+ Perform various tests associated with relevant routines.
117
+ """
118
+
119
+ source = deepcopy(_DICT1R)
120
+
121
+
122
+ path = 'nested/1/dict/key'
123
+ before = getate(source, path)
124
+ setate(source, path, 1)
125
+ after = getate(source, path)
126
+ assert after == 1
127
+ assert before is None
128
+
129
+
130
+
131
+ def test_setate_raises() -> None:
132
+ """
133
+ Perform various tests associated with relevant routines.
134
+ """
135
+
136
+ _raises: RaisesContext[
137
+ ValueError | IndexError]
138
+
139
+
140
+ _raises = raises(ValueError)
141
+
142
+ with _raises as reason:
143
+ setate(1, '1', 1) # type: ignore
144
+
145
+ _reason = str(reason.value)
146
+
147
+ assert _reason == 'source'
148
+
149
+
150
+ _raises = raises(IndexError)
151
+
152
+ with _raises as reason:
153
+ setate([], '1', 1)
154
+
155
+ _reason = str(reason.value)
156
+
157
+ assert _reason == '1'
158
+
159
+
160
+
161
+ def test_delate() -> None:
162
+ """
163
+ Perform various tests associated with relevant routines.
164
+ """
165
+
166
+ source = deepcopy(_DICT1R)
167
+
168
+
169
+ path = 'recurse/dict/key'
170
+ before = getate(source, path)
171
+ delate(source, path)
172
+ after = getate(source, path)
173
+ assert after is None
174
+ assert before == 'd1dict'
175
+
176
+
177
+ path = 'nested/0/dict/key'
178
+ before = getate(source, path)
179
+ delate(source, path)
180
+ after = getate(source, path)
181
+ assert after is None
182
+ assert before == 'd1dict'
183
+
184
+
185
+ path = 'recurse/list/0'
186
+ before = getate(source, path)
187
+ delate(source, path)
188
+ after = getate(source, path)
189
+ assert after is None
190
+ assert before == 'd1list'
191
+
192
+
193
+
194
+ def test_delate_raises() -> None:
195
+ """
196
+ Perform various tests associated with relevant routines.
197
+ """
198
+
199
+
200
+ _raises = raises(ValueError)
201
+
202
+ with _raises as reason:
203
+ delate(1, '1') # type: ignore
204
+
205
+ _reason = str(reason.value)
206
+
207
+ assert _reason == 'source'
208
+
209
+
210
+ _raises = raises(ValueError)
211
+
212
+ with _raises as reason:
213
+ delate({'a': 1}, 'a/1/c')
214
+
215
+ _reason = str(reason.value)
216
+
217
+ assert _reason == 'source'
encommon/version.txt CHANGED
@@ -1 +1 @@
1
- 0.9.0
1
+ 0.10.0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: encommon
3
- Version: 0.9.0
3
+ Version: 0.10.0
4
4
  Summary: Enasis Network Common Library
5
5
  License: MIT
6
6
  Classifier: Programming Language :: Python :: 3
@@ -1,13 +1,13 @@
1
1
  encommon/__init__.py,sha256=VoXUcphq-gcXCraaU47EtXBftF6UVuQPMGr0fuCTt9A,525
2
- encommon/conftest.py,sha256=J2__qc7WP8oZkMLXRCw9qlBaaHSx1HhkIkKkGnHHCAU,1810
2
+ encommon/conftest.py,sha256=Bu-KoRxxWu0Gwd8uEhBm0SbGaxwc9mzq7fZUa_igi80,1797
3
3
  encommon/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
- encommon/version.txt,sha256=nYyU8a0-qWseKsSRT9pMuTx2tKPg2Mxt2JdtbAsifRU,6
4
+ encommon/version.txt,sha256=3CT-tb01CE2K4ypOr77BI1JwfUZiQB_LzJu9aWzed6k,7
5
5
  encommon/config/__init__.py,sha256=i0G48SrSk_QgZ-xOMYtsllPT2Y06i7j29XEkqUH0wZ8,859
6
6
  encommon/config/common.py,sha256=QGrbA3OlQ0nta6cOyEu0dw8li9UlV_J7Yn3rhZLm7mw,2099
7
- encommon/config/config.py,sha256=F3ufzcymHznSHhXMwB3kHcExoPDLSoSk3-vQb0WIseU,4802
7
+ encommon/config/config.py,sha256=TZIUqyIRQfVWLUKsgGVH0coHp9dU-GAXFROdwSsoNvQ,5010
8
8
  encommon/config/files.py,sha256=Mdb9MN4AKzue6Mdl4B2C8epiuPI6vnfVu55yiPUTiQ8,2388
9
9
  encommon/config/logger.py,sha256=5X7Y72g-D4hJ2TCfqDxiAZpQcUT-Exgbf2t7kiIM0q0,13488
10
- encommon/config/params.py,sha256=xCCg9dy19SqyA4YeOsuLdQbnpwYuD-XOh-mLQCmRpAI,1806
10
+ encommon/config/params.py,sha256=6hg0aiUnG5alPv3Kxd4kR_9OXOMLJzuvjXjhuYpyTMU,1800
11
11
  encommon/config/paths.py,sha256=eR0BQC_TaKHu1dQGrC8o69l6dEqDoI8JS9IHmPrsJ68,2535
12
12
  encommon/config/test/__init__.py,sha256=i0JAeRcM-0YH2StGfwpaDbZV9dVribNSgFDcYcPPay8,313
13
13
  encommon/config/test/test_common.py,sha256=K9KiAfbMBXaoYErW10X1AigFs8wNNNOxKG8QV6IYJdA,1069
@@ -18,7 +18,7 @@ encommon/config/test/test_paths.py,sha256=jCrSEnPkZprsJSvolsfTKoyuYqxqyQdDymL9yk
18
18
  encommon/crypts/__init__.py,sha256=UsGEitz8rWa7DQF3iAxEbTUAbdiEnE87LSuRs4OBeAQ,371
19
19
  encommon/crypts/crypts.py,sha256=fCYEOlq5vp34L9yPT-oMhvI-8o6FRoPViM7aZShB1_Y,3540
20
20
  encommon/crypts/hashes.py,sha256=bpQf2-Ma5SdMaEWP2nL1_9rtEQmTE0XTdDvSD-fQ9Mk,3075
21
- encommon/crypts/params.py,sha256=7hh7a7VtsQNqcZHeSkQI_V4JLfoe0D-JyqrIvtoq86c,590
21
+ encommon/crypts/params.py,sha256=TAowPtCVse1BysBMZ70LFvtaChAQmoBo4E_MHZ2fpSs,588
22
22
  encommon/crypts/test/__init__.py,sha256=PjrnBYT0efyvbaGeNx94dm3tP3EVHUHSVs-VGeLEv5g,218
23
23
  encommon/crypts/test/test_crypts.py,sha256=MnMZPGWSN-vV3iA1s4OsZ72dqHII1a244fSPDILXfVE,2706
24
24
  encommon/crypts/test/test_hashes.py,sha256=JYpPit7ISv6u-5-HbC3wSCxuieySDLKawgnE7-xHgTY,1180
@@ -36,13 +36,15 @@ encommon/times/test/test_parse.py,sha256=iIKanoqqQMxpXVxo9HNwY7oscQB1HzXU9QId0pu
36
36
  encommon/times/test/test_timers.py,sha256=bOfajUjnpZJItTvs1UOWuZxWT-HGI6oyi3svA8ZFYhg,3128
37
37
  encommon/times/test/test_times.py,sha256=vxEtXI9gYFlWnBLsyPyi17a96MJzgcI79SCy8U1Co8I,1748
38
38
  encommon/times/test/test_window.py,sha256=Px6Qfg_uVp34TLV-OiOJ2rJU1vCqqTFKeme2CceCoZQ,5464
39
- encommon/types/__init__.py,sha256=eR_8b9lxMqfudqI63RCuQvbNV5YhWIBdVFQ71bA7B3s,544
39
+ encommon/types/__init__.py,sha256=L1pdigJyPNPEoAkkbCHM9IhmFtU2GjFRxHMRTAnPqKk,667
40
40
  encommon/types/dicts.py,sha256=lC2FmPzMEj9L73jUjf3o6OVQ-LqK_3gp5nBwYibdGfo,2265
41
41
  encommon/types/empty.py,sha256=n5y5maXkcM3xNYNYGK6iqvk98ivQSeguaedwc0HoMv4,2739
42
+ encommon/types/notate.py,sha256=odlc0fblAEnfPlGqJJSvNTYtXvD0jP7kOYUiFnea6YE,6550
42
43
  encommon/types/strings.py,sha256=oFPRrJuK3ey5FHeHoUTPoinpYlwuJmcbi0UQjRupEM4,2175
43
- encommon/types/test/__init__.py,sha256=PjrnBYT0efyvbaGeNx94dm3tP3EVHUHSVs-VGeLEv5g,218
44
- encommon/types/test/test_dicts.py,sha256=jOXE2NTfZg2dtmgR2Hv9uaAI90kKT-91bX6jWAu-5Xs,2678
44
+ encommon/types/test/__init__.py,sha256=UIyNazTlIIdUzQS0brlD7hCPN_LYw_J6Ucxm8wh3cPU,789
45
+ encommon/types/test/test_dicts.py,sha256=-RLkcyexCXGSyJyPx1e3QU8sNXEgtSvD9pZakdOwVvg,2702
45
46
  encommon/types/test/test_empty.py,sha256=4GiBs3xulfTnJ5xuGm2hM_PRcHspYEj5tAaLd4Trhyc,973
47
+ encommon/types/test/test_notate.py,sha256=NfrDmMD6hOoVi9wlQ8yLZNnuHwS6Z7bLze70FkxOjSA,4008
46
48
  encommon/types/test/test_strings.py,sha256=AgDXL3qiKcl1Fzx7lVsnW1ejEB13fXKpvELwG48OcSw,1084
47
49
  encommon/utils/__init__.py,sha256=FJzSgfXddDXrxnencV6W4MArr3xQPEcfwrPVtMqwDHE,927
48
50
  encommon/utils/common.py,sha256=N5CAo5rHIIvXzmOWwbO7R4xTYnGDqB9OYXGh0ignc_g,1355
@@ -56,8 +58,8 @@ encommon/utils/test/test_match.py,sha256=QagKpTFdRo23-Y55fSaJrSMpt5jIebScKbz0h8t
56
58
  encommon/utils/test/test_paths.py,sha256=o7AF73jz09Mny21IsRG8vbB20mDH_oVmQFuxoSCLiOc,1919
57
59
  encommon/utils/test/test_sample.py,sha256=sHAeWOL1mchTGYGQaFK_A3Z28tThuULumm9kQebnIdk,1710
58
60
  encommon/utils/test/test_stdout.py,sha256=TA7xQuFoPZUYW2l00e04MGp4P9gHkkVxVflvPlhpQXg,4878
59
- encommon-0.9.0.dist-info/LICENSE,sha256=otnXKCtMjPlbHs0wgZ_BWULrp3g_2dWQJ6icRk9nkgg,1071
60
- encommon-0.9.0.dist-info/METADATA,sha256=38RmRSOI8IR586MLJgOAZ5_cXSKWS8gWzx0taPp0BM4,2917
61
- encommon-0.9.0.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
62
- encommon-0.9.0.dist-info/top_level.txt,sha256=bP8q7-5tLDNm-3XPlqn_bDENfYNug5801H_xfz3BEAM,9
63
- encommon-0.9.0.dist-info/RECORD,,
61
+ encommon-0.10.0.dist-info/LICENSE,sha256=otnXKCtMjPlbHs0wgZ_BWULrp3g_2dWQJ6icRk9nkgg,1071
62
+ encommon-0.10.0.dist-info/METADATA,sha256=ZdDOgZfbbBdsUyDoilL-X2A36N3AY4PbGHNZIAfcil4,2918
63
+ encommon-0.10.0.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
64
+ encommon-0.10.0.dist-info/top_level.txt,sha256=bP8q7-5tLDNm-3XPlqn_bDENfYNug5801H_xfz3BEAM,9
65
+ encommon-0.10.0.dist-info/RECORD,,