encommon 0.18.0__py3-none-any.whl → 0.19.1__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/parse/__init__.py +20 -0
- encommon/parse/jinja2.py +332 -0
- encommon/parse/network.py +453 -0
- encommon/parse/test/__init__.py +6 -0
- encommon/parse/test/test_jinja2.py +190 -0
- encommon/parse/test/test_network.py +226 -0
- encommon/types/__init__.py +4 -0
- encommon/types/dicts.py +22 -3
- encommon/types/lists.py +84 -0
- encommon/types/test/__init__.py +4 -2
- encommon/types/test/test_dicts.py +45 -7
- encommon/types/test/test_lists.py +41 -0
- encommon/version.txt +1 -1
- {encommon-0.18.0.dist-info → encommon-0.19.1.dist-info}/METADATA +4 -2
- {encommon-0.18.0.dist-info → encommon-0.19.1.dist-info}/RECORD +18 -12
- {encommon-0.18.0.dist-info → encommon-0.19.1.dist-info}/WHEEL +1 -1
- {encommon-0.18.0.dist-info → encommon-0.19.1.dist-info}/LICENSE +0 -0
- {encommon-0.18.0.dist-info → encommon-0.19.1.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,226 @@
|
|
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 pytest import raises
|
11
|
+
|
12
|
+
from ..network import Network
|
13
|
+
from ..network import insubnet_ip
|
14
|
+
from ..network import isvalid_ip
|
15
|
+
from ...types import inrepr
|
16
|
+
from ...types import instr
|
17
|
+
from ...types import lattrs
|
18
|
+
|
19
|
+
|
20
|
+
|
21
|
+
def test_Network() -> None:
|
22
|
+
"""
|
23
|
+
Perform various tests associated with relevant routines.
|
24
|
+
"""
|
25
|
+
|
26
|
+
|
27
|
+
naddr = Network('12.34.56.7')
|
28
|
+
|
29
|
+
|
30
|
+
attrs = lattrs(naddr)
|
31
|
+
|
32
|
+
assert attrs == [
|
33
|
+
'_Network__source']
|
34
|
+
|
35
|
+
|
36
|
+
assert inrepr(
|
37
|
+
"Network('12.34.",
|
38
|
+
naddr)
|
39
|
+
|
40
|
+
assert hash(naddr) > 0
|
41
|
+
|
42
|
+
assert instr(
|
43
|
+
'12.34.56.7/32',
|
44
|
+
naddr)
|
45
|
+
|
46
|
+
|
47
|
+
assert naddr == '12.34.56.7'
|
48
|
+
assert naddr != 'invalid'
|
49
|
+
|
50
|
+
|
51
|
+
assert naddr.source
|
52
|
+
|
53
|
+
assert naddr.version == 4
|
54
|
+
|
55
|
+
assert naddr.cidr == 32
|
56
|
+
|
57
|
+
assert naddr.address == '12.34.56.7'
|
58
|
+
|
59
|
+
assert naddr.address_cidr == '12.34.56.7/32'
|
60
|
+
|
61
|
+
assert naddr.address_host == '12.34.56.7/32'
|
62
|
+
|
63
|
+
assert naddr.network == '12.34.56.7'
|
64
|
+
|
65
|
+
assert naddr.network_cidr == '12.34.56.7/32'
|
66
|
+
|
67
|
+
assert not naddr.broadcast
|
68
|
+
|
69
|
+
assert naddr.netmask == '255.255.255.255'
|
70
|
+
|
71
|
+
assert naddr.padded == '012.034.056.007'
|
72
|
+
|
73
|
+
assert naddr.reverse == '7.56.34.12'
|
74
|
+
|
75
|
+
assert naddr.hwaddr == '01-20-34-05-60-07'
|
76
|
+
|
77
|
+
assert naddr.ispublic
|
78
|
+
|
79
|
+
assert not naddr.isprivate
|
80
|
+
|
81
|
+
assert not naddr.islinklocal
|
82
|
+
|
83
|
+
assert not naddr.islocalhost
|
84
|
+
|
85
|
+
|
86
|
+
|
87
|
+
def test_Network_ipv4() -> None:
|
88
|
+
"""
|
89
|
+
Perform various tests associated with relevant routines.
|
90
|
+
"""
|
91
|
+
|
92
|
+
|
93
|
+
naddr = Network('12.34.56.7/24')
|
94
|
+
|
95
|
+
|
96
|
+
assert naddr.cidr == 24
|
97
|
+
|
98
|
+
assert naddr.address == '12.34.56.7'
|
99
|
+
|
100
|
+
assert naddr.address_cidr == '12.34.56.7/24'
|
101
|
+
|
102
|
+
assert naddr.address_host == '12.34.56.7/32'
|
103
|
+
|
104
|
+
assert naddr.network == '12.34.56.0'
|
105
|
+
|
106
|
+
assert naddr.network_cidr == '12.34.56.0/24'
|
107
|
+
|
108
|
+
assert naddr.broadcast == '12.34.56.255'
|
109
|
+
|
110
|
+
assert naddr.netmask == '255.255.255.0'
|
111
|
+
|
112
|
+
assert naddr.padded == '012.034.056.007'
|
113
|
+
|
114
|
+
assert naddr.reverse == '7.56.34.12'
|
115
|
+
|
116
|
+
assert naddr.hwaddr == '01-20-34-05-60-07'
|
117
|
+
|
118
|
+
assert naddr.ispublic
|
119
|
+
|
120
|
+
assert not naddr.isprivate
|
121
|
+
|
122
|
+
assert not naddr.islinklocal
|
123
|
+
|
124
|
+
assert not naddr.islocalhost
|
125
|
+
|
126
|
+
|
127
|
+
|
128
|
+
def test_Network_ipv6() -> None:
|
129
|
+
"""
|
130
|
+
Perform various tests associated with relevant routines.
|
131
|
+
"""
|
132
|
+
|
133
|
+
|
134
|
+
naddr = Network('2001:db8::/64')
|
135
|
+
|
136
|
+
|
137
|
+
assert naddr.cidr == 64
|
138
|
+
|
139
|
+
assert naddr.address == '2001:db8::'
|
140
|
+
|
141
|
+
assert naddr.address_cidr == '2001:db8::/64'
|
142
|
+
|
143
|
+
assert naddr.address_host == '2001:db8::/128'
|
144
|
+
|
145
|
+
assert naddr.network == '2001:db8::'
|
146
|
+
|
147
|
+
assert naddr.network_cidr == '2001:db8::/64'
|
148
|
+
|
149
|
+
assert naddr.broadcast == (
|
150
|
+
'2001:db8::ffff:ffff:ffff:ffff')
|
151
|
+
|
152
|
+
assert naddr.netmask == (
|
153
|
+
'ffff:ffff:ffff:ffff::')
|
154
|
+
|
155
|
+
with raises(ValueError):
|
156
|
+
naddr.padded
|
157
|
+
|
158
|
+
with raises(ValueError):
|
159
|
+
naddr.reverse
|
160
|
+
|
161
|
+
with raises(ValueError):
|
162
|
+
naddr.hwaddr
|
163
|
+
|
164
|
+
assert not naddr.ispublic
|
165
|
+
|
166
|
+
assert naddr.isprivate
|
167
|
+
|
168
|
+
assert not naddr.islinklocal
|
169
|
+
|
170
|
+
assert not naddr.islocalhost
|
171
|
+
|
172
|
+
|
173
|
+
|
174
|
+
def test_isvalid_ip() -> None:
|
175
|
+
"""
|
176
|
+
Perform various tests associated with relevant routines.
|
177
|
+
"""
|
178
|
+
|
179
|
+
assert isvalid_ip('1.2.3.4')
|
180
|
+
|
181
|
+
assert not isvalid_ip('1.2')
|
182
|
+
|
183
|
+
assert not isvalid_ip(None)
|
184
|
+
|
185
|
+
|
186
|
+
|
187
|
+
def test_insubnet_ip() -> None:
|
188
|
+
"""
|
189
|
+
Perform various tests associated with relevant routines.
|
190
|
+
"""
|
191
|
+
|
192
|
+
assert insubnet_ip(
|
193
|
+
'192.168.1.1',
|
194
|
+
['172.16.0.0/12',
|
195
|
+
'192.168.0.0/16'])
|
196
|
+
|
197
|
+
assert not insubnet_ip(
|
198
|
+
'1.2.3.4',
|
199
|
+
['172.16.0.0/12',
|
200
|
+
'192.168.0.0/16'])
|
201
|
+
|
202
|
+
assert insubnet_ip(
|
203
|
+
'192.168.1.1',
|
204
|
+
['192.168.1.1/32'])
|
205
|
+
|
206
|
+
assert insubnet_ip(
|
207
|
+
'192.168.1.1/32',
|
208
|
+
'192.168.1.1/32')
|
209
|
+
|
210
|
+
assert insubnet_ip(
|
211
|
+
'2001:db8::',
|
212
|
+
['2001:db8::/128'])
|
213
|
+
|
214
|
+
assert insubnet_ip(
|
215
|
+
'2001:db8::',
|
216
|
+
['2001:db8::/32'])
|
217
|
+
|
218
|
+
assert insubnet_ip(
|
219
|
+
'2001:db8::/128',
|
220
|
+
['2001:db8::/32'])
|
221
|
+
|
222
|
+
with raises(ValueError):
|
223
|
+
|
224
|
+
insubnet_ip(
|
225
|
+
'invalid',
|
226
|
+
['2001:db8::/32'])
|
encommon/types/__init__.py
CHANGED
@@ -13,6 +13,8 @@ from .classes import lattrs
|
|
13
13
|
from .dicts import merge_dicts
|
14
14
|
from .dicts import sort_dict
|
15
15
|
from .empty import Empty
|
16
|
+
from .lists import dedup_list
|
17
|
+
from .lists import fuzzy_list
|
16
18
|
from .lists import inlist
|
17
19
|
from .notate import delate
|
18
20
|
from .notate import getate
|
@@ -32,6 +34,8 @@ from .types import NCTrue
|
|
32
34
|
__all__ = [
|
33
35
|
'BaseModel',
|
34
36
|
'clsname',
|
37
|
+
'dedup_list',
|
38
|
+
'fuzzy_list',
|
35
39
|
'delate',
|
36
40
|
'DictStrAny',
|
37
41
|
'Empty',
|
encommon/types/dicts.py
CHANGED
@@ -7,6 +7,7 @@ is permitted, for more information consult the project license file.
|
|
7
7
|
|
8
8
|
|
9
9
|
|
10
|
+
from copy import deepcopy
|
10
11
|
from typing import Any
|
11
12
|
|
12
13
|
|
@@ -14,11 +15,12 @@ from typing import Any
|
|
14
15
|
def merge_dicts(
|
15
16
|
dict1: dict[Any, Any],
|
16
17
|
dict2: dict[Any, Any],
|
17
|
-
force: bool = False,
|
18
|
+
force: bool | None = False,
|
18
19
|
*,
|
19
20
|
merge_list: bool = True,
|
20
21
|
merge_dict: bool = True,
|
21
|
-
|
22
|
+
paranoid: bool = False,
|
23
|
+
) -> dict[Any, Any]:
|
22
24
|
"""
|
23
25
|
Recursively merge the contents of provided dictionaries.
|
24
26
|
|
@@ -30,22 +32,36 @@ def merge_dicts(
|
|
30
32
|
>>> dict1 = {'a': 'b', 'c': [1]}
|
31
33
|
>>> dict2 = {'a': 'B', 'c': [2]}
|
32
34
|
>>> merge_dicts(dict1, dict2)
|
35
|
+
{'a': 'b', 'c': [1, 2]}
|
33
36
|
>>> dict1
|
34
37
|
{'a': 'b', 'c': [1, 2]}
|
35
38
|
|
36
39
|
:param dict1: Primary dictionary which is merged into.
|
37
40
|
:param dict2: Secondary dictionary for primary updates.
|
38
41
|
:param force: Force overwriting concrete values in the
|
39
|
-
primary dictionary with those from secondary.
|
42
|
+
primary dictionary with those from secondary. When
|
43
|
+
``None`` only overwrites if destination is ``None``.
|
40
44
|
:param merge_list: Determines if merged or overwritten.
|
41
45
|
:param merge_dict: Determines if merged or overwritten.
|
46
|
+
:param paranoid: Perform an initial deepcopy on both of
|
47
|
+
the provided dictionaries before performing merges.
|
48
|
+
:returns: Provided dictionary with the other merged in.
|
42
49
|
"""
|
43
50
|
|
51
|
+
if paranoid is True:
|
52
|
+
dict1 = deepcopy(dict1)
|
53
|
+
dict2 = deepcopy(dict2)
|
54
|
+
|
55
|
+
|
44
56
|
for key, value in dict2.items():
|
45
57
|
|
46
58
|
if key not in dict1:
|
47
59
|
dict1[key] = value
|
48
60
|
|
61
|
+
elif (dict1[key] is None
|
62
|
+
and force is None):
|
63
|
+
dict1[key] = value
|
64
|
+
|
49
65
|
elif (isinstance(dict1[key], list)
|
50
66
|
and isinstance(value, list)
|
51
67
|
and merge_list is True):
|
@@ -64,6 +80,9 @@ def merge_dicts(
|
|
64
80
|
dict1[key] = value
|
65
81
|
|
66
82
|
|
83
|
+
return dict1
|
84
|
+
|
85
|
+
|
67
86
|
|
68
87
|
def sort_dict(
|
69
88
|
value: dict[Any, Any],
|
encommon/types/lists.py
CHANGED
@@ -12,6 +12,90 @@ from typing import Sequence
|
|
12
12
|
|
13
13
|
|
14
14
|
|
15
|
+
def dedup_list(
|
16
|
+
value: list[Any],
|
17
|
+
update: bool = True,
|
18
|
+
) -> list[Any]:
|
19
|
+
"""
|
20
|
+
Return the provided list values with duplicates removed.
|
21
|
+
|
22
|
+
.. warning::
|
23
|
+
This function will update the ``value`` reference.
|
24
|
+
|
25
|
+
Example
|
26
|
+
-------
|
27
|
+
>>> value = [1, 2, 2, 3]
|
28
|
+
>>> dedup_list(value)
|
29
|
+
[1, 2, 3]
|
30
|
+
>>> value
|
31
|
+
[1, 2, 3]
|
32
|
+
|
33
|
+
:param value: List of values processed for duplication.
|
34
|
+
:param update: Indicate if to update provided reference.
|
35
|
+
:returns: Provided list values with duplicates removed.
|
36
|
+
"""
|
37
|
+
|
38
|
+
if update is False:
|
39
|
+
value = list(value)
|
40
|
+
|
41
|
+
|
42
|
+
unique: list[Any] = []
|
43
|
+
|
44
|
+
for item in list(value):
|
45
|
+
|
46
|
+
if item in unique:
|
47
|
+
|
48
|
+
value.remove(item)
|
49
|
+
|
50
|
+
continue
|
51
|
+
|
52
|
+
unique.append(item)
|
53
|
+
|
54
|
+
|
55
|
+
return value
|
56
|
+
|
57
|
+
|
58
|
+
|
59
|
+
def fuzzy_list(
|
60
|
+
values: str | list[str],
|
61
|
+
patterns: str | list[str],
|
62
|
+
) -> list[str]:
|
63
|
+
"""
|
64
|
+
Return the provided values that match provided patterns.
|
65
|
+
|
66
|
+
Example
|
67
|
+
-------
|
68
|
+
>>> values = ['foo', 'bar', 'baz', 'bop']
|
69
|
+
>>> patterns = ['*o', 'ba*']
|
70
|
+
>>> fuzzy_list(values, patterns)
|
71
|
+
['foo', 'bar', 'baz']
|
72
|
+
|
73
|
+
:param values: Value or values to enumerate for matching.
|
74
|
+
:param patterns: Patterns which values can match any one.
|
75
|
+
:returns: Provided values that match provided patterns.
|
76
|
+
"""
|
77
|
+
|
78
|
+
from ..utils import fuzz_match
|
79
|
+
|
80
|
+
if isinstance(values, str):
|
81
|
+
values = [values]
|
82
|
+
|
83
|
+
matched: list[str] = []
|
84
|
+
|
85
|
+
for value in values:
|
86
|
+
|
87
|
+
match = fuzz_match(
|
88
|
+
value, patterns)
|
89
|
+
|
90
|
+
if match is False:
|
91
|
+
continue
|
92
|
+
|
93
|
+
matched.append(value)
|
94
|
+
|
95
|
+
return matched
|
96
|
+
|
97
|
+
|
98
|
+
|
15
99
|
def inlist(
|
16
100
|
needle: Any, # noqa: ANN401
|
17
101
|
haystack: Sequence[Any],
|
encommon/types/test/__init__.py
CHANGED
@@ -17,7 +17,8 @@ _DICT1 = {
|
|
17
17
|
'list': ['d1list'],
|
18
18
|
'tuple': (1, 2),
|
19
19
|
'dict': {'key': 'd1dict'},
|
20
|
-
'bool': False
|
20
|
+
'bool': False,
|
21
|
+
'null': None}
|
21
22
|
|
22
23
|
_DICT2 = {
|
23
24
|
'dict2': 'dict2',
|
@@ -25,7 +26,8 @@ _DICT2 = {
|
|
25
26
|
'list': ['d2list'],
|
26
27
|
'tuple': (3, 4),
|
27
28
|
'dict': {'key': 'd2dict'},
|
28
|
-
'bool': True
|
29
|
+
'bool': True,
|
30
|
+
'null': 'null'}
|
29
31
|
|
30
32
|
_DICT1R = deepcopy(_DICT1)
|
31
33
|
_DICT2R = deepcopy(_DICT2)
|
@@ -18,7 +18,7 @@ from ..dicts import sort_dict
|
|
18
18
|
|
19
19
|
|
20
20
|
|
21
|
-
def test_merge_dicts() -> None:
|
21
|
+
def test_merge_dicts() -> None: # noqa: CFQ001
|
22
22
|
"""
|
23
23
|
Perform various tests associated with relevant routines.
|
24
24
|
"""
|
@@ -40,6 +40,7 @@ def test_merge_dicts() -> None:
|
|
40
40
|
'dict': {'key': 'd1dict'},
|
41
41
|
'tuple': (1, 2),
|
42
42
|
'bool': False,
|
43
|
+
'null': None,
|
43
44
|
'nested': [_DICT1, _DICT2],
|
44
45
|
'recurse': {
|
45
46
|
'dict1': 'dict1',
|
@@ -48,7 +49,8 @@ def test_merge_dicts() -> None:
|
|
48
49
|
'list': ['d1list', 'd2list'],
|
49
50
|
'dict': {'key': 'd1dict'},
|
50
51
|
'tuple': (1, 2),
|
51
|
-
'bool': False
|
52
|
+
'bool': False,
|
53
|
+
'null': None}}
|
52
54
|
|
53
55
|
|
54
56
|
source = deepcopy(dict1)
|
@@ -64,6 +66,7 @@ def test_merge_dicts() -> None:
|
|
64
66
|
'dict': {'key': 'd2dict'},
|
65
67
|
'tuple': (3, 4),
|
66
68
|
'bool': True,
|
69
|
+
'null': 'null',
|
67
70
|
'nested': [_DICT1, _DICT2],
|
68
71
|
'recurse': {
|
69
72
|
'dict1': 'dict1',
|
@@ -72,15 +75,41 @@ def test_merge_dicts() -> None:
|
|
72
75
|
'list': ['d1list', 'd2list'],
|
73
76
|
'dict': {'key': 'd2dict'},
|
74
77
|
'tuple': (3, 4),
|
75
|
-
'bool': True
|
78
|
+
'bool': True,
|
79
|
+
'null': 'null'}}
|
80
|
+
|
81
|
+
|
82
|
+
source = deepcopy(dict1)
|
83
|
+
update = deepcopy(dict2)
|
84
|
+
|
85
|
+
merge_dicts(source, update, None)
|
86
|
+
|
87
|
+
assert source == {
|
88
|
+
'dict1': 'dict1',
|
89
|
+
'dict2': 'dict2',
|
90
|
+
'str': 'd1string',
|
91
|
+
'list': ['d1list', 'd2list'],
|
92
|
+
'dict': {'key': 'd1dict'},
|
93
|
+
'tuple': (1, 2),
|
94
|
+
'bool': False,
|
95
|
+
'null': 'null',
|
96
|
+
'nested': [_DICT1, _DICT2],
|
97
|
+
'recurse': {
|
98
|
+
'dict1': 'dict1',
|
99
|
+
'dict2': 'dict2',
|
100
|
+
'str': 'd1string',
|
101
|
+
'list': ['d1list', 'd2list'],
|
102
|
+
'dict': {'key': 'd1dict'},
|
103
|
+
'tuple': (1, 2),
|
104
|
+
'bool': False,
|
105
|
+
'null': 'null'}}
|
76
106
|
|
77
107
|
|
78
108
|
source = deepcopy(dict1)
|
79
109
|
update = deepcopy(dict2)
|
80
110
|
|
81
111
|
merge_dicts(
|
82
|
-
source,
|
83
|
-
update,
|
112
|
+
source, update,
|
84
113
|
merge_list=False,
|
85
114
|
merge_dict=False)
|
86
115
|
|
@@ -92,6 +121,7 @@ def test_merge_dicts() -> None:
|
|
92
121
|
'dict': {'key': 'd1dict'},
|
93
122
|
'tuple': (1, 2),
|
94
123
|
'bool': False,
|
124
|
+
'null': None,
|
95
125
|
'nested': [_DICT1],
|
96
126
|
'recurse': {
|
97
127
|
'dict1': 'dict1',
|
@@ -99,9 +129,16 @@ def test_merge_dicts() -> None:
|
|
99
129
|
'list': ['d1list'],
|
100
130
|
'dict': {'key': 'd1dict'},
|
101
131
|
'tuple': (1, 2),
|
102
|
-
'bool': False
|
132
|
+
'bool': False,
|
133
|
+
'null': None}}
|
103
134
|
|
104
135
|
|
136
|
+
_source = merge_dicts(
|
137
|
+
source, update,
|
138
|
+
paranoid=True)
|
139
|
+
|
140
|
+
assert source is not _source
|
141
|
+
|
105
142
|
|
106
143
|
def test_sort_dict() -> None:
|
107
144
|
"""
|
@@ -114,4 +151,5 @@ def test_sort_dict() -> None:
|
|
114
151
|
'tuple': (1, 2),
|
115
152
|
'dict1': 'dict1',
|
116
153
|
'list': ['d1list'],
|
117
|
-
'str': 'd1string'
|
154
|
+
'str': 'd1string',
|
155
|
+
'null': None}
|
@@ -7,6 +7,8 @@ is permitted, for more information consult the project license file.
|
|
7
7
|
|
8
8
|
|
9
9
|
|
10
|
+
from ..lists import dedup_list
|
11
|
+
from ..lists import fuzzy_list
|
10
12
|
from ..lists import inlist
|
11
13
|
|
12
14
|
|
@@ -21,3 +23,42 @@ def test_inlist() -> None:
|
|
21
23
|
haystack = [123, 456]
|
22
24
|
|
23
25
|
assert inlist(needle, haystack)
|
26
|
+
|
27
|
+
|
28
|
+
|
29
|
+
def test_dedup_list() -> None:
|
30
|
+
"""
|
31
|
+
Perform various tests associated with relevant routines.
|
32
|
+
"""
|
33
|
+
|
34
|
+
value = [1, 1, '2', 2, 3, 3]
|
35
|
+
|
36
|
+
dedup = dedup_list(
|
37
|
+
value,
|
38
|
+
update=False)
|
39
|
+
|
40
|
+
assert dedup != value
|
41
|
+
assert dedup == [1, '2', 2, 3]
|
42
|
+
|
43
|
+
dedup_list(value)
|
44
|
+
|
45
|
+
assert dedup == value
|
46
|
+
assert dedup == [1, '2', 2, 3]
|
47
|
+
|
48
|
+
|
49
|
+
|
50
|
+
def test_fuzzy_list() -> None:
|
51
|
+
"""
|
52
|
+
Perform various tests associated with relevant routines.
|
53
|
+
"""
|
54
|
+
|
55
|
+
values = ['1', '2']
|
56
|
+
patterns = ['1*']
|
57
|
+
|
58
|
+
matched = fuzzy_list(
|
59
|
+
values, patterns)
|
60
|
+
|
61
|
+
assert matched == ['1']
|
62
|
+
|
63
|
+
assert not (
|
64
|
+
fuzzy_list('', []))
|
encommon/version.txt
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.19.1
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: encommon
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.19.1
|
4
4
|
Summary: Enasis Network Common Library
|
5
5
|
License: MIT
|
6
6
|
Classifier: Programming Language :: Python :: 3
|
@@ -11,6 +11,8 @@ Description-Content-Type: text/markdown
|
|
11
11
|
License-File: LICENSE
|
12
12
|
Requires-Dist: croniter
|
13
13
|
Requires-Dist: cryptography
|
14
|
+
Requires-Dist: jinja2
|
15
|
+
Requires-Dist: netaddr
|
14
16
|
Requires-Dist: pydantic
|
15
17
|
Requires-Dist: python-dateutil
|
16
18
|
Requires-Dist: pyyaml
|
@@ -19,7 +21,7 @@ Requires-Dist: sqlalchemy
|
|
19
21
|
|
20
22
|
# Enasis Network Common Library
|
21
23
|
|
22
|
-
> :
|
24
|
+
> :warning: This project has not released its first major version.
|
23
25
|
|
24
26
|
Common classes and functions used in various public and private projects.
|
25
27
|
|
@@ -1,7 +1,7 @@
|
|
1
1
|
encommon/__init__.py,sha256=YDGzuhpk5Gd1hq54LI0hw1NrrDvrJDrvH20TEy_0l5E,443
|
2
2
|
encommon/conftest.py,sha256=qorgldYdoDt_LFQupdT0ZUF5eAVPuJ5X3Jvv4VIa78Q,1900
|
3
3
|
encommon/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
4
|
-
encommon/version.txt,sha256=
|
4
|
+
encommon/version.txt,sha256=HiAUu03xr-U1r5jwSObjdyUI5Sc8FC-Dufx0e0D5z00,7
|
5
5
|
encommon/colors/__init__.py,sha256=XRiGimMj8oo040NO5a5ZsbsIUxaGVW4tf4xWTPWgnZY,269
|
6
6
|
encommon/colors/color.py,sha256=EiUxNbVL1689Cqhw1LmO9ysmN3ulCVtGZGylyV8LuVA,10884
|
7
7
|
encommon/colors/test/__init__.py,sha256=PjrnBYT0efyvbaGeNx94dm3tP3EVHUHSVs-VGeLEv5g,218
|
@@ -26,6 +26,12 @@ encommon/crypts/params.py,sha256=2uH_i1NBMlzhq7UtWgX2jsiUGNniOK69eTCeeiQFpdw,141
|
|
26
26
|
encommon/crypts/test/__init__.py,sha256=PjrnBYT0efyvbaGeNx94dm3tP3EVHUHSVs-VGeLEv5g,218
|
27
27
|
encommon/crypts/test/test_crypts.py,sha256=F-81-2R8_xfPMRU8QLYzfnvp01uP5BB-xA0XtmMISJE,3482
|
28
28
|
encommon/crypts/test/test_hashes.py,sha256=OmidSycLkUyso6K5Hfun2NopPXA1uL3SFqz_2aITOMM,1201
|
29
|
+
encommon/parse/__init__.py,sha256=6uV4GCm_nOYC77x2jQvTDsa0F6vBGRbCgju_HCc96zM,422
|
30
|
+
encommon/parse/jinja2.py,sha256=HhZX7TD5wzAMUhgHjb_IxG1yILsmBiTr9_McGlqEHr4,7066
|
31
|
+
encommon/parse/network.py,sha256=PgQ6xV6Y9KmyH0iXqQ-b88Gtkrry75Fzc-tZd-BH0ng,8771
|
32
|
+
encommon/parse/test/__init__.py,sha256=PjrnBYT0efyvbaGeNx94dm3tP3EVHUHSVs-VGeLEv5g,218
|
33
|
+
encommon/parse/test/test_jinja2.py,sha256=hZu4BaRWZgyU_edVUcDiJs9gJnoFoSWF9o7CPROmcAI,3760
|
34
|
+
encommon/parse/test/test_network.py,sha256=apBv7rNtdjSbGnpXwg1VX-ybF3w-tyqYjpQDv6mlwfM,4148
|
29
35
|
encommon/times/__init__.py,sha256=QX4iuZ59UlsMbEWbubnVJXJtrOubNxAAAv510urcLUA,972
|
30
36
|
encommon/times/common.py,sha256=HWgWBbqDoyKHIqeg4bBAZZfRM3499X3WPu8dVCzt_5o,995
|
31
37
|
encommon/times/duration.py,sha256=LTROiKcRXvPcs2Gz9KaB5Cmxo9NXd3TcMo5-jnTxPo0,10794
|
@@ -49,19 +55,19 @@ encommon/times/test/test_unitime.py,sha256=5i4UjBCw8R9h-Lw963GfB_dHBMEQhjvv1k-t2
|
|
49
55
|
encommon/times/test/test_utils.py,sha256=WkzHJY6zOt02Ujg5FItOo1nPtktz5ss8ODmG1tRQaaw,2056
|
50
56
|
encommon/times/test/test_window.py,sha256=gNJpWVrwQTnUFQ00OLzWUuvJjWUCoiCwydohr9mevT0,6116
|
51
57
|
encommon/times/test/test_windows.py,sha256=IaaxUXqf5n9IF9X0HkRqtCdyOdeCq5DYR1ySLORA9gE,4474
|
52
|
-
encommon/types/__init__.py,sha256=
|
58
|
+
encommon/types/__init__.py,sha256=wMgdz0PuJyL_LIfafDlWIDaDLJi-bhnQJ4YTuUgN2gY,1143
|
53
59
|
encommon/types/classes.py,sha256=FYFTu8Uj-74JWudHOlhaOrsXXPxitorBfM9_QM3EGSU,1689
|
54
|
-
encommon/types/dicts.py,sha256=
|
60
|
+
encommon/types/dicts.py,sha256=IuLoVdtilhM83ujT74mcz0Zi1HI87P4k7wjnnyMxPag,2821
|
55
61
|
encommon/types/empty.py,sha256=n5y5maXkcM3xNYNYGK6iqvk98ivQSeguaedwc0HoMv4,2739
|
56
|
-
encommon/types/lists.py,sha256=
|
62
|
+
encommon/types/lists.py,sha256=AX-siqXfLwm_5mGDsomg_7XWalZOYLE60D3wHwbNEzo,2358
|
57
63
|
encommon/types/notate.py,sha256=0JIzF5VDnQ6C4umZIpgxIvd91gFo3MXTZ7Kp54S538A,6454
|
58
64
|
encommon/types/strings.py,sha256=LW2WZND64cKE1LhNip3vqsoP3elLsUP6cpS0dYnUKGE,2800
|
59
65
|
encommon/types/types.py,sha256=DbzdDLLclD1Gk8bmyhDUUWVDnJ5LdaolLV3JYKHFVgA,322
|
60
|
-
encommon/types/test/__init__.py,sha256=
|
66
|
+
encommon/types/test/__init__.py,sha256=uauiJIPPJjk1bzp5WEH_YEFLR5m0zxVN_c1liYAYIro,827
|
61
67
|
encommon/types/test/test_classes.py,sha256=CjthMInwz5WB7aTc7-GpzgcYAvkF9dRmC6nXJVoE91k,1475
|
62
|
-
encommon/types/test/test_dicts.py,sha256
|
68
|
+
encommon/types/test/test_dicts.py,sha256=kVYIGlIyXOx9yiCPKbhhFMf0TpiTU0ESNOaJYIq0_Ms,3650
|
63
69
|
encommon/types/test/test_empty.py,sha256=LVsZbKOg0deyKOtg_0Fhf0b_0c94LftwdDhijna-FbA,995
|
64
|
-
encommon/types/test/test_lists.py,sha256=
|
70
|
+
encommon/types/test/test_lists.py,sha256=uRdON1vnDT21TBl2prlO15SHIkN7YOApZzHS78R-Bvs,1139
|
65
71
|
encommon/types/test/test_notate.py,sha256=NfrDmMD6hOoVi9wlQ8yLZNnuHwS6Z7bLze70FkxOjSA,4008
|
66
72
|
encommon/types/test/test_strings.py,sha256=oXusioFMdknHeBdwlP_GakDVS9Tf2YBndjonj22UfmM,1277
|
67
73
|
encommon/utils/__init__.py,sha256=bBgh81wX_TwLgWkx0aBAyVLHNphrfcyQc1AF7-ziyNI,1027
|
@@ -77,8 +83,8 @@ encommon/utils/test/test_match.py,sha256=QagKpTFdRo23-Y55fSaJrSMpt5jIebScKbz0h8t
|
|
77
83
|
encommon/utils/test/test_paths.py,sha256=4AzIhQyYFEWhRWHgOZCCzomQ3Zs3EVwRnDQDa6Nq1Mc,1942
|
78
84
|
encommon/utils/test/test_sample.py,sha256=Qf-W0XbjTe5PfG87sdVizL2ymUPRTdX0qQtLGHaTgx8,3539
|
79
85
|
encommon/utils/test/test_stdout.py,sha256=fYiqEaUraD-3hFQYLxMPR4Ti_8CbTjEc8WvReXUA884,6139
|
80
|
-
encommon-0.
|
81
|
-
encommon-0.
|
82
|
-
encommon-0.
|
83
|
-
encommon-0.
|
84
|
-
encommon-0.
|
86
|
+
encommon-0.19.1.dist-info/LICENSE,sha256=otnXKCtMjPlbHs0wgZ_BWULrp3g_2dWQJ6icRk9nkgg,1071
|
87
|
+
encommon-0.19.1.dist-info/METADATA,sha256=FFIQ6JKuLRAjOUYA4A3tZzDRL9q2I89pGR1v9Eg43Ws,3484
|
88
|
+
encommon-0.19.1.dist-info/WHEEL,sha256=GV9aMThwP_4oNCtvEC2ec3qUYutgWeAzklro_0m4WJQ,91
|
89
|
+
encommon-0.19.1.dist-info/top_level.txt,sha256=bP8q7-5tLDNm-3XPlqn_bDENfYNug5801H_xfz3BEAM,9
|
90
|
+
encommon-0.19.1.dist-info/RECORD,,
|
File without changes
|
File without changes
|