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.
@@ -0,0 +1,20 @@
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 .jinja2 import Jinja2
11
+ from .network import Network
12
+ from .network import insubnet_ip
13
+ from .network import isvalid_ip
14
+
15
+
16
+ __all__ = [
17
+ 'Jinja2',
18
+ 'Network',
19
+ 'insubnet_ip',
20
+ 'isvalid_ip']
@@ -0,0 +1,332 @@
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 ast import literal_eval as leval
11
+ from contextlib import suppress
12
+ from copy import copy
13
+ from copy import deepcopy
14
+ from re import DOTALL
15
+ from re import findall as re_findall
16
+ from re import match as re_match
17
+ from typing import Any
18
+ from typing import Callable
19
+ from typing import Optional
20
+
21
+ from jinja2 import Environment
22
+ from jinja2 import StrictUndefined
23
+
24
+ from .network import Network
25
+ from .network import insubnet_ip
26
+ from .network import isvalid_ip
27
+ from ..colors import Color
28
+ from ..crypts import Hashes
29
+ from ..times import Duration
30
+ from ..times import Time
31
+ from ..times import unitime
32
+ from ..types import DictStrAny
33
+ from ..types import dedup_list
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
42
+ from ..utils import fuzz_match
43
+ from ..utils import rgxp_match
44
+
45
+
46
+
47
+ FILTER = Callable[..., Any]
48
+
49
+ JINJA2 = (
50
+ r'(\{\{.+?\}\})|'
51
+ r'(\{\%.+?\%\})')
52
+
53
+ LITERAL = (
54
+ r'^((\{([^\{%].+?)?\})|(\[(.+?|)\])'
55
+ '|True|False|None|'
56
+ r'(\-?([1-9]\d*|0)(\.\d+)?))$')
57
+
58
+
59
+
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
69
+ 'Duration': Duration,
70
+ 'Time': Time,
71
+
72
+ # encommon.colors
73
+ 'Color': Color,
74
+
75
+ # encommon.crypts
76
+ 'Hashes': Hashes,
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,
93
+ 'fuzzy_list': fuzzy_list,
94
+ 'merge_dicts': merge_dicts,
95
+ 'sort_dict': sort_dict,
96
+
97
+ # encommon.utils
98
+ 'fuzz_match': fuzz_match,
99
+ 'rgxp_match': rgxp_match}
100
+
101
+
102
+
103
+ class Jinja2:
104
+ """
105
+ Parse the provided input and intelligently return value.
106
+
107
+ Example
108
+ -------
109
+ >>> jinja2 = Jinja2()
110
+ >>> jinja2.parse('{{ 0 | Time}}')
111
+ '1970-01-01T00:00:00.000000+0000'
112
+
113
+ :param statics: Additional values available for parsing.
114
+ :param filters: Additional filter functions for parsing.
115
+ """
116
+
117
+ __statics: DictStrAny
118
+ __filters: dict[str, FILTER]
119
+
120
+ __jinjenv: Environment
121
+
122
+
123
+ def __init__(
124
+ self,
125
+ statics: Optional[DictStrAny] = None,
126
+ filters: Optional[dict[str, FILTER]] = None,
127
+ ) -> None:
128
+ """
129
+ Initialize instance for class using provided parameters.
130
+ """
131
+
132
+ statics = dict(statics or {})
133
+ filters = dict(filters or {})
134
+
135
+ items = DEFAULT.items()
136
+
137
+ for key, filter in items:
138
+ filters[key] = filter
139
+
140
+ self.__statics = statics
141
+ self.__filters = filters
142
+
143
+ jinjenv = Environment(
144
+ auto_reload=False,
145
+ autoescape=False,
146
+ cache_size=0,
147
+ extensions=[
148
+ 'jinja2.ext.i18n',
149
+ 'jinja2.ext.loopcontrols',
150
+ 'jinja2.ext.do'],
151
+ keep_trailing_newline=False,
152
+ lstrip_blocks=False,
153
+ newline_sequence='\n',
154
+ optimized=True,
155
+ trim_blocks=False,
156
+ undefined=StrictUndefined)
157
+
158
+ jinjenv.filters |= filters
159
+
160
+ self.__jinjenv = jinjenv
161
+
162
+
163
+ @property
164
+ def statics(
165
+ self,
166
+ ) -> DictStrAny:
167
+ """
168
+ Return the value for the attribute from class instance.
169
+
170
+ :returns: Value for the attribute from class instance.
171
+ """
172
+
173
+ return dict(self.__statics)
174
+
175
+
176
+ @property
177
+ def filters(
178
+ self,
179
+ ) -> dict[str, FILTER]:
180
+ """
181
+ Return the value for the attribute from class instance.
182
+
183
+ :returns: Value for the attribute from class instance.
184
+ """
185
+
186
+ return dict(self.__filters)
187
+
188
+
189
+ @property
190
+ def jinjenv(
191
+ self,
192
+ ) -> Environment:
193
+ """
194
+ Return the value for the attribute from class instance.
195
+
196
+ :returns: Value for the attribute from class instance.
197
+ """
198
+
199
+ return self.__jinjenv
200
+
201
+
202
+ def parser(
203
+ self,
204
+ value: str,
205
+ statics: Optional[DictStrAny] = None,
206
+ ) -> Any:
207
+ """
208
+ Return the provided input using the Jinja2 environment.
209
+
210
+ :param value: Input that will be processed and returned.
211
+ :param statics: Additional values available for parsing.
212
+ :returns: Provided input using the Jinja2 environment.
213
+ """
214
+
215
+ statics = (
216
+ dict(statics or {})
217
+ | self.__statics)
218
+
219
+ parser = (
220
+ self.__jinjenv
221
+ .from_string)
222
+
223
+ rendered = (
224
+ parser(value)
225
+ .render(**statics))
226
+
227
+ return rendered
228
+
229
+
230
+ def parse( # noqa: CFQ004
231
+ self,
232
+ value: Any,
233
+ statics: Optional[DictStrAny] = None,
234
+ literal: bool = True,
235
+ ) -> Any:
236
+ """
237
+ Return the provided input using the Jinja2 environment.
238
+
239
+ :param value: Input that will be processed and returned.
240
+ :param statics: Additional values available for parsing.
241
+ :param literal: Determine if Python objects are evaled.
242
+ :returns: Provided input using the Jinja2 environment.
243
+ """
244
+
245
+
246
+ def _final( # noqa: CFQ004
247
+ value: Any,
248
+ ) -> Any:
249
+
250
+ if literal is False:
251
+ return value
252
+
253
+ match = re_match(
254
+ LITERAL, str(value))
255
+
256
+ if match is None:
257
+ return value
258
+
259
+ with suppress(Exception):
260
+ return leval(value)
261
+
262
+ return value
263
+
264
+
265
+ def _parse(
266
+ value: Any,
267
+ ) -> Any:
268
+
269
+ return self.parse(
270
+ value,
271
+ statics, literal)
272
+
273
+
274
+ def _parser(
275
+ value: Any,
276
+ ) -> Any:
277
+
278
+ parsed = self.parser(
279
+ value, statics)
280
+
281
+ return _final(parsed)
282
+
283
+
284
+ def _found(
285
+ value: Any,
286
+ ) -> list[Any]:
287
+
288
+ value = str(value)
289
+
290
+ return re_findall(
291
+ JINJA2, value, DOTALL)
292
+
293
+
294
+ if not len(_found(value)):
295
+ return _final(value)
296
+
297
+
298
+ with suppress(Exception):
299
+ value = _final(value)
300
+
301
+
302
+ if isinstance(value, dict):
303
+
304
+ value = dict(value)
305
+
306
+ items = value.items()
307
+
308
+ for key, _value in items:
309
+
310
+ _value = _parse(_value)
311
+
312
+ value[key] = _value
313
+
314
+
315
+ elif isinstance(value, list):
316
+
317
+ value = list(value)
318
+
319
+ values = enumerate(value)
320
+
321
+ for idx, _value in values:
322
+
323
+ _value = _parse(_value)
324
+
325
+ value[idx] = _value
326
+
327
+
328
+ elif value is not None:
329
+ value = _parser(value)
330
+
331
+
332
+ return value