encommon 0.19.0__py3-none-any.whl → 0.19.2__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/jinja2.py +54 -4
- encommon/types/dicts.py +22 -3
- encommon/types/lists.py +17 -4
- encommon/types/test/__init__.py +4 -2
- encommon/types/test/test_dicts.py +45 -7
- encommon/version.txt +1 -1
- {encommon-0.19.0.dist-info → encommon-0.19.2.dist-info}/METADATA +2 -2
- {encommon-0.19.0.dist-info → encommon-0.19.2.dist-info}/RECORD +11 -11
- {encommon-0.19.0.dist-info → encommon-0.19.2.dist-info}/WHEEL +1 -1
- {encommon-0.19.0.dist-info → encommon-0.19.2.dist-info}/LICENSE +0 -0
- {encommon-0.19.0.dist-info → encommon-0.19.2.dist-info}/top_level.txt +0 -0
encommon/parse/jinja2.py
CHANGED
@@ -9,6 +9,8 @@ is permitted, for more information consult the project license file.
|
|
9
9
|
|
10
10
|
from ast import literal_eval as leval
|
11
11
|
from contextlib import suppress
|
12
|
+
from copy import copy
|
13
|
+
from copy import deepcopy
|
12
14
|
from re import DOTALL
|
13
15
|
from re import findall as re_findall
|
14
16
|
from re import match as re_match
|
@@ -19,12 +21,24 @@ from typing import Optional
|
|
19
21
|
from jinja2 import Environment
|
20
22
|
from jinja2 import StrictUndefined
|
21
23
|
|
24
|
+
from .network import Network
|
25
|
+
from .network import insubnet_ip
|
26
|
+
from .network import isvalid_ip
|
22
27
|
from ..colors import Color
|
23
28
|
from ..crypts import Hashes
|
24
29
|
from ..times import Duration
|
25
30
|
from ..times import Time
|
31
|
+
from ..times import unitime
|
26
32
|
from ..types import DictStrAny
|
33
|
+
from ..types import dedup_list
|
27
34
|
from ..types import fuzzy_list
|
35
|
+
from ..types import hasstr
|
36
|
+
from ..types import inlist
|
37
|
+
from ..types import instr
|
38
|
+
from ..types import merge_dicts
|
39
|
+
from ..types import rplstr
|
40
|
+
from ..types import sort_dict
|
41
|
+
from ..types import strplwr
|
28
42
|
from ..utils import fuzz_match
|
29
43
|
from ..utils import rgxp_match
|
30
44
|
|
@@ -41,13 +55,47 @@ LITERAL = (
|
|
41
55
|
'|True|False|None|'
|
42
56
|
r'(\-?([1-9]\d*|0)(\.\d+)?))$')
|
43
57
|
|
58
|
+
|
59
|
+
|
44
60
|
DEFAULT: dict[str, FILTER] = {
|
61
|
+
|
62
|
+
# Python builtins
|
63
|
+
'all': all,
|
64
|
+
'any': any,
|
65
|
+
'copy': copy,
|
66
|
+
'deepcopy': deepcopy,
|
67
|
+
|
68
|
+
# encommon.times
|
45
69
|
'Duration': Duration,
|
70
|
+
'Time': Time,
|
71
|
+
|
72
|
+
# encommon.colors
|
46
73
|
'Color': Color,
|
74
|
+
|
75
|
+
# encommon.crypts
|
47
76
|
'Hashes': Hashes,
|
48
|
-
|
49
|
-
|
77
|
+
|
78
|
+
# encommon.parse
|
79
|
+
'Network': Network,
|
80
|
+
'insubnet_ip': insubnet_ip,
|
81
|
+
'isvalid_ip': isvalid_ip,
|
82
|
+
|
83
|
+
# encommon.times
|
84
|
+
'unitime': unitime,
|
85
|
+
|
86
|
+
# encommon.types
|
87
|
+
'strplwr': strplwr,
|
88
|
+
'hasstr': hasstr,
|
89
|
+
'instr': instr,
|
90
|
+
'inlist': inlist,
|
91
|
+
'rplstr': rplstr,
|
92
|
+
'dedup_list': dedup_list,
|
50
93
|
'fuzzy_list': fuzzy_list,
|
94
|
+
'merge_dicts': merge_dicts,
|
95
|
+
'sort_dict': sort_dict,
|
96
|
+
|
97
|
+
# encommon.utils
|
98
|
+
'fuzz_match': fuzz_match,
|
51
99
|
'rgxp_match': rgxp_match}
|
52
100
|
|
53
101
|
|
@@ -59,7 +107,7 @@ class Jinja2:
|
|
59
107
|
Example
|
60
108
|
-------
|
61
109
|
>>> jinja2 = Jinja2()
|
62
|
-
>>> jinja2.parse('{{ 0 | Time}}')
|
110
|
+
>>> jinja2.parse('{{ 0 | Time }}')
|
63
111
|
'1970-01-01T00:00:00.000000+0000'
|
64
112
|
|
65
113
|
:param statics: Additional values available for parsing.
|
@@ -164,7 +212,9 @@ class Jinja2:
|
|
164
212
|
:returns: Provided input using the Jinja2 environment.
|
165
213
|
"""
|
166
214
|
|
167
|
-
statics =
|
215
|
+
statics = (
|
216
|
+
dict(statics or {})
|
217
|
+
| self.__statics)
|
168
218
|
|
169
219
|
parser = (
|
170
220
|
self.__jinjenv
|
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
@@ -22,15 +22,21 @@ def dedup_list(
|
|
22
22
|
.. warning::
|
23
23
|
This function will update the ``value`` reference.
|
24
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
|
+
|
25
33
|
:param value: List of values processed for duplication.
|
34
|
+
:param update: Indicate if to update provided reference.
|
26
35
|
:returns: Provided list values with duplicates removed.
|
27
36
|
"""
|
28
37
|
|
29
38
|
if update is False:
|
30
|
-
|
31
|
-
dedup = dict.fromkeys(value)
|
32
|
-
|
33
|
-
return list(dedup)
|
39
|
+
value = list(value)
|
34
40
|
|
35
41
|
|
36
42
|
unique: list[Any] = []
|
@@ -57,6 +63,13 @@ def fuzzy_list(
|
|
57
63
|
"""
|
58
64
|
Return the provided values that match provided patterns.
|
59
65
|
|
66
|
+
Example
|
67
|
+
-------
|
68
|
+
>>> values = ['foo', 'bar', 'baz', 'bop']
|
69
|
+
>>> patterns = ['*o', 'ba*']
|
70
|
+
>>> fuzzy_list(values, patterns)
|
71
|
+
['foo', 'bar', 'baz']
|
72
|
+
|
60
73
|
:param values: Value or values to enumerate for matching.
|
61
74
|
:param patterns: Patterns which values can match any one.
|
62
75
|
:returns: Provided values that match provided patterns.
|
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}
|
encommon/version.txt
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.19.
|
1
|
+
0.19.2
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: encommon
|
3
|
-
Version: 0.19.
|
3
|
+
Version: 0.19.2
|
4
4
|
Summary: Enasis Network Common Library
|
5
5
|
License: MIT
|
6
6
|
Classifier: Programming Language :: Python :: 3
|
@@ -21,7 +21,7 @@ Requires-Dist: sqlalchemy
|
|
21
21
|
|
22
22
|
# Enasis Network Common Library
|
23
23
|
|
24
|
-
> :
|
24
|
+
> :warning: This project has not released its first major version.
|
25
25
|
|
26
26
|
Common classes and functions used in various public and private projects.
|
27
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=n8nEL77-uL-2uK8EsWtDysdQM9Si-Tg-wqwbM7-QNKQ,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
|
@@ -27,7 +27,7 @@ encommon/crypts/test/__init__.py,sha256=PjrnBYT0efyvbaGeNx94dm3tP3EVHUHSVs-VGeLE
|
|
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
29
|
encommon/parse/__init__.py,sha256=6uV4GCm_nOYC77x2jQvTDsa0F6vBGRbCgju_HCc96zM,422
|
30
|
-
encommon/parse/jinja2.py,sha256=
|
30
|
+
encommon/parse/jinja2.py,sha256=2ZKTWjEGVHp6Dh8fkeMvuFp_AcIzCim-pA3UUf2TXWw,7067
|
31
31
|
encommon/parse/network.py,sha256=PgQ6xV6Y9KmyH0iXqQ-b88Gtkrry75Fzc-tZd-BH0ng,8771
|
32
32
|
encommon/parse/test/__init__.py,sha256=PjrnBYT0efyvbaGeNx94dm3tP3EVHUHSVs-VGeLEv5g,218
|
33
33
|
encommon/parse/test/test_jinja2.py,sha256=hZu4BaRWZgyU_edVUcDiJs9gJnoFoSWF9o7CPROmcAI,3760
|
@@ -57,15 +57,15 @@ encommon/times/test/test_window.py,sha256=gNJpWVrwQTnUFQ00OLzWUuvJjWUCoiCwydohr9
|
|
57
57
|
encommon/times/test/test_windows.py,sha256=IaaxUXqf5n9IF9X0HkRqtCdyOdeCq5DYR1ySLORA9gE,4474
|
58
58
|
encommon/types/__init__.py,sha256=wMgdz0PuJyL_LIfafDlWIDaDLJi-bhnQJ4YTuUgN2gY,1143
|
59
59
|
encommon/types/classes.py,sha256=FYFTu8Uj-74JWudHOlhaOrsXXPxitorBfM9_QM3EGSU,1689
|
60
|
-
encommon/types/dicts.py,sha256=
|
60
|
+
encommon/types/dicts.py,sha256=IuLoVdtilhM83ujT74mcz0Zi1HI87P4k7wjnnyMxPag,2821
|
61
61
|
encommon/types/empty.py,sha256=n5y5maXkcM3xNYNYGK6iqvk98ivQSeguaedwc0HoMv4,2739
|
62
|
-
encommon/types/lists.py,sha256=
|
62
|
+
encommon/types/lists.py,sha256=AX-siqXfLwm_5mGDsomg_7XWalZOYLE60D3wHwbNEzo,2358
|
63
63
|
encommon/types/notate.py,sha256=0JIzF5VDnQ6C4umZIpgxIvd91gFo3MXTZ7Kp54S538A,6454
|
64
64
|
encommon/types/strings.py,sha256=LW2WZND64cKE1LhNip3vqsoP3elLsUP6cpS0dYnUKGE,2800
|
65
65
|
encommon/types/types.py,sha256=DbzdDLLclD1Gk8bmyhDUUWVDnJ5LdaolLV3JYKHFVgA,322
|
66
|
-
encommon/types/test/__init__.py,sha256=
|
66
|
+
encommon/types/test/__init__.py,sha256=uauiJIPPJjk1bzp5WEH_YEFLR5m0zxVN_c1liYAYIro,827
|
67
67
|
encommon/types/test/test_classes.py,sha256=CjthMInwz5WB7aTc7-GpzgcYAvkF9dRmC6nXJVoE91k,1475
|
68
|
-
encommon/types/test/test_dicts.py,sha256
|
68
|
+
encommon/types/test/test_dicts.py,sha256=kVYIGlIyXOx9yiCPKbhhFMf0TpiTU0ESNOaJYIq0_Ms,3650
|
69
69
|
encommon/types/test/test_empty.py,sha256=LVsZbKOg0deyKOtg_0Fhf0b_0c94LftwdDhijna-FbA,995
|
70
70
|
encommon/types/test/test_lists.py,sha256=uRdON1vnDT21TBl2prlO15SHIkN7YOApZzHS78R-Bvs,1139
|
71
71
|
encommon/types/test/test_notate.py,sha256=NfrDmMD6hOoVi9wlQ8yLZNnuHwS6Z7bLze70FkxOjSA,4008
|
@@ -83,8 +83,8 @@ encommon/utils/test/test_match.py,sha256=QagKpTFdRo23-Y55fSaJrSMpt5jIebScKbz0h8t
|
|
83
83
|
encommon/utils/test/test_paths.py,sha256=4AzIhQyYFEWhRWHgOZCCzomQ3Zs3EVwRnDQDa6Nq1Mc,1942
|
84
84
|
encommon/utils/test/test_sample.py,sha256=Qf-W0XbjTe5PfG87sdVizL2ymUPRTdX0qQtLGHaTgx8,3539
|
85
85
|
encommon/utils/test/test_stdout.py,sha256=fYiqEaUraD-3hFQYLxMPR4Ti_8CbTjEc8WvReXUA884,6139
|
86
|
-
encommon-0.19.
|
87
|
-
encommon-0.19.
|
88
|
-
encommon-0.19.
|
89
|
-
encommon-0.19.
|
90
|
-
encommon-0.19.
|
86
|
+
encommon-0.19.2.dist-info/LICENSE,sha256=otnXKCtMjPlbHs0wgZ_BWULrp3g_2dWQJ6icRk9nkgg,1071
|
87
|
+
encommon-0.19.2.dist-info/METADATA,sha256=V8H-MF9YmvKRwDTID1-AtYjnWfv-AOQpQBmjI0OQX44,3484
|
88
|
+
encommon-0.19.2.dist-info/WHEEL,sha256=GV9aMThwP_4oNCtvEC2ec3qUYutgWeAzklro_0m4WJQ,91
|
89
|
+
encommon-0.19.2.dist-info/top_level.txt,sha256=bP8q7-5tLDNm-3XPlqn_bDENfYNug5801H_xfz3BEAM,9
|
90
|
+
encommon-0.19.2.dist-info/RECORD,,
|
File without changes
|
File without changes
|