encommon 0.18.0__tar.gz → 0.19.1__tar.gz

Sign up to get free protection for your applications and to get access to all the features.
Files changed (100) hide show
  1. {encommon-0.18.0/encommon.egg-info → encommon-0.19.1}/PKG-INFO +4 -2
  2. {encommon-0.18.0 → encommon-0.19.1}/README.md +1 -1
  3. encommon-0.19.1/encommon/parse/__init__.py +20 -0
  4. encommon-0.19.1/encommon/parse/jinja2.py +332 -0
  5. encommon-0.19.1/encommon/parse/network.py +453 -0
  6. encommon-0.19.1/encommon/parse/test/test_jinja2.py +190 -0
  7. encommon-0.19.1/encommon/parse/test/test_network.py +226 -0
  8. {encommon-0.18.0 → encommon-0.19.1}/encommon/types/__init__.py +4 -0
  9. {encommon-0.18.0 → encommon-0.19.1}/encommon/types/dicts.py +22 -3
  10. encommon-0.19.1/encommon/types/lists.py +117 -0
  11. {encommon-0.18.0 → encommon-0.19.1}/encommon/types/test/__init__.py +4 -2
  12. {encommon-0.18.0 → encommon-0.19.1}/encommon/types/test/test_dicts.py +45 -7
  13. encommon-0.19.1/encommon/types/test/test_lists.py +64 -0
  14. encommon-0.19.1/encommon/utils/test/__init__.py +6 -0
  15. encommon-0.19.1/encommon/version.txt +1 -0
  16. {encommon-0.18.0 → encommon-0.19.1/encommon.egg-info}/PKG-INFO +4 -2
  17. {encommon-0.18.0 → encommon-0.19.1}/encommon.egg-info/SOURCES.txt +6 -0
  18. {encommon-0.18.0 → encommon-0.19.1}/encommon.egg-info/requires.txt +2 -0
  19. {encommon-0.18.0 → encommon-0.19.1}/reqs-install.txt +2 -0
  20. {encommon-0.18.0 → encommon-0.19.1}/setup.cfg +2 -0
  21. encommon-0.18.0/encommon/types/lists.py +0 -33
  22. encommon-0.18.0/encommon/types/test/test_lists.py +0 -23
  23. encommon-0.18.0/encommon/version.txt +0 -1
  24. {encommon-0.18.0 → encommon-0.19.1}/LICENSE +0 -0
  25. {encommon-0.18.0 → encommon-0.19.1}/MANIFEST.in +0 -0
  26. {encommon-0.18.0 → encommon-0.19.1}/encommon/__init__.py +0 -0
  27. {encommon-0.18.0 → encommon-0.19.1}/encommon/colors/__init__.py +0 -0
  28. {encommon-0.18.0 → encommon-0.19.1}/encommon/colors/color.py +0 -0
  29. {encommon-0.18.0 → encommon-0.19.1}/encommon/colors/test/__init__.py +0 -0
  30. {encommon-0.18.0 → encommon-0.19.1}/encommon/colors/test/test_color.py +0 -0
  31. {encommon-0.18.0 → encommon-0.19.1}/encommon/config/__init__.py +0 -0
  32. {encommon-0.18.0 → encommon-0.19.1}/encommon/config/config.py +0 -0
  33. {encommon-0.18.0 → encommon-0.19.1}/encommon/config/files.py +0 -0
  34. {encommon-0.18.0 → encommon-0.19.1}/encommon/config/logger.py +0 -0
  35. {encommon-0.18.0 → encommon-0.19.1}/encommon/config/params.py +0 -0
  36. {encommon-0.18.0 → encommon-0.19.1}/encommon/config/paths.py +0 -0
  37. {encommon-0.18.0 → encommon-0.19.1}/encommon/config/test/__init__.py +0 -0
  38. {encommon-0.18.0 → encommon-0.19.1}/encommon/config/test/test_config.py +0 -0
  39. {encommon-0.18.0 → encommon-0.19.1}/encommon/config/test/test_files.py +0 -0
  40. {encommon-0.18.0 → encommon-0.19.1}/encommon/config/test/test_logger.py +0 -0
  41. {encommon-0.18.0 → encommon-0.19.1}/encommon/config/test/test_paths.py +0 -0
  42. {encommon-0.18.0 → encommon-0.19.1}/encommon/config/test/test_utils.py +0 -0
  43. {encommon-0.18.0 → encommon-0.19.1}/encommon/config/utils.py +0 -0
  44. {encommon-0.18.0 → encommon-0.19.1}/encommon/conftest.py +0 -0
  45. {encommon-0.18.0 → encommon-0.19.1}/encommon/crypts/__init__.py +0 -0
  46. {encommon-0.18.0 → encommon-0.19.1}/encommon/crypts/crypts.py +0 -0
  47. {encommon-0.18.0 → encommon-0.19.1}/encommon/crypts/hashes.py +0 -0
  48. {encommon-0.18.0 → encommon-0.19.1}/encommon/crypts/params.py +0 -0
  49. {encommon-0.18.0 → encommon-0.19.1}/encommon/crypts/test/__init__.py +0 -0
  50. {encommon-0.18.0 → encommon-0.19.1}/encommon/crypts/test/test_crypts.py +0 -0
  51. {encommon-0.18.0 → encommon-0.19.1}/encommon/crypts/test/test_hashes.py +0 -0
  52. {encommon-0.18.0/encommon/times → encommon-0.19.1/encommon/parse}/test/__init__.py +0 -0
  53. {encommon-0.18.0 → encommon-0.19.1}/encommon/py.typed +0 -0
  54. {encommon-0.18.0 → encommon-0.19.1}/encommon/times/__init__.py +0 -0
  55. {encommon-0.18.0 → encommon-0.19.1}/encommon/times/common.py +0 -0
  56. {encommon-0.18.0 → encommon-0.19.1}/encommon/times/duration.py +0 -0
  57. {encommon-0.18.0 → encommon-0.19.1}/encommon/times/params.py +0 -0
  58. {encommon-0.18.0 → encommon-0.19.1}/encommon/times/parse.py +0 -0
  59. {encommon-0.18.0/encommon/utils → encommon-0.19.1/encommon/times}/test/__init__.py +0 -0
  60. {encommon-0.18.0 → encommon-0.19.1}/encommon/times/test/test_duration.py +0 -0
  61. {encommon-0.18.0 → encommon-0.19.1}/encommon/times/test/test_params.py +0 -0
  62. {encommon-0.18.0 → encommon-0.19.1}/encommon/times/test/test_parse.py +0 -0
  63. {encommon-0.18.0 → encommon-0.19.1}/encommon/times/test/test_time.py +0 -0
  64. {encommon-0.18.0 → encommon-0.19.1}/encommon/times/test/test_timer.py +0 -0
  65. {encommon-0.18.0 → encommon-0.19.1}/encommon/times/test/test_timers.py +0 -0
  66. {encommon-0.18.0 → encommon-0.19.1}/encommon/times/test/test_unitime.py +0 -0
  67. {encommon-0.18.0 → encommon-0.19.1}/encommon/times/test/test_utils.py +0 -0
  68. {encommon-0.18.0 → encommon-0.19.1}/encommon/times/test/test_window.py +0 -0
  69. {encommon-0.18.0 → encommon-0.19.1}/encommon/times/test/test_windows.py +0 -0
  70. {encommon-0.18.0 → encommon-0.19.1}/encommon/times/time.py +0 -0
  71. {encommon-0.18.0 → encommon-0.19.1}/encommon/times/timer.py +0 -0
  72. {encommon-0.18.0 → encommon-0.19.1}/encommon/times/timers.py +0 -0
  73. {encommon-0.18.0 → encommon-0.19.1}/encommon/times/unitime.py +0 -0
  74. {encommon-0.18.0 → encommon-0.19.1}/encommon/times/utils.py +0 -0
  75. {encommon-0.18.0 → encommon-0.19.1}/encommon/times/window.py +0 -0
  76. {encommon-0.18.0 → encommon-0.19.1}/encommon/times/windows.py +0 -0
  77. {encommon-0.18.0 → encommon-0.19.1}/encommon/types/classes.py +0 -0
  78. {encommon-0.18.0 → encommon-0.19.1}/encommon/types/empty.py +0 -0
  79. {encommon-0.18.0 → encommon-0.19.1}/encommon/types/notate.py +0 -0
  80. {encommon-0.18.0 → encommon-0.19.1}/encommon/types/strings.py +0 -0
  81. {encommon-0.18.0 → encommon-0.19.1}/encommon/types/test/test_classes.py +0 -0
  82. {encommon-0.18.0 → encommon-0.19.1}/encommon/types/test/test_empty.py +0 -0
  83. {encommon-0.18.0 → encommon-0.19.1}/encommon/types/test/test_notate.py +0 -0
  84. {encommon-0.18.0 → encommon-0.19.1}/encommon/types/test/test_strings.py +0 -0
  85. {encommon-0.18.0 → encommon-0.19.1}/encommon/types/types.py +0 -0
  86. {encommon-0.18.0 → encommon-0.19.1}/encommon/utils/__init__.py +0 -0
  87. {encommon-0.18.0 → encommon-0.19.1}/encommon/utils/common.py +0 -0
  88. {encommon-0.18.0 → encommon-0.19.1}/encommon/utils/files.py +0 -0
  89. {encommon-0.18.0 → encommon-0.19.1}/encommon/utils/match.py +0 -0
  90. {encommon-0.18.0 → encommon-0.19.1}/encommon/utils/paths.py +0 -0
  91. {encommon-0.18.0 → encommon-0.19.1}/encommon/utils/sample.py +0 -0
  92. {encommon-0.18.0 → encommon-0.19.1}/encommon/utils/stdout.py +0 -0
  93. {encommon-0.18.0 → encommon-0.19.1}/encommon/utils/test/test_files.py +0 -0
  94. {encommon-0.18.0 → encommon-0.19.1}/encommon/utils/test/test_match.py +0 -0
  95. {encommon-0.18.0 → encommon-0.19.1}/encommon/utils/test/test_paths.py +0 -0
  96. {encommon-0.18.0 → encommon-0.19.1}/encommon/utils/test/test_sample.py +0 -0
  97. {encommon-0.18.0 → encommon-0.19.1}/encommon/utils/test/test_stdout.py +0 -0
  98. {encommon-0.18.0 → encommon-0.19.1}/encommon.egg-info/dependency_links.txt +0 -0
  99. {encommon-0.18.0 → encommon-0.19.1}/encommon.egg-info/top_level.txt +0 -0
  100. {encommon-0.18.0 → encommon-0.19.1}/pyproject.toml +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: encommon
3
- Version: 0.18.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
- > :children_crossing: This project has not released its first major version.
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,6 +1,6 @@
1
1
  # Enasis Network Common Library
2
2
 
3
- > :children_crossing: This project has not released its first major version.
3
+ > :warning: This project has not released its first major version.
4
4
 
5
5
  Common classes and functions used in various public and private projects.
6
6
 
@@ -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