encommon 0.20.5__tar.gz → 0.22.0__tar.gz

Sign up to get free protection for your applications and to get access to all the features.
Files changed (146) hide show
  1. encommon-0.22.0/MANIFEST.in +10 -0
  2. {encommon-0.20.5/encommon.egg-info → encommon-0.22.0}/PKG-INFO +2 -2
  3. {encommon-0.20.5 → encommon-0.22.0}/encommon/times/common.py +3 -0
  4. {encommon-0.20.5 → encommon-0.22.0}/encommon/times/unitime.py +17 -8
  5. {encommon-0.20.5 → encommon-0.22.0}/encommon/types/__init__.py +4 -0
  6. {encommon-0.20.5 → encommon-0.22.0}/encommon/types/notate.py +179 -0
  7. {encommon-0.20.5 → encommon-0.22.0}/encommon/types/test/__init__.py +7 -0
  8. {encommon-0.20.5 → encommon-0.22.0}/encommon/types/test/test_dicts.py +1 -0
  9. encommon-0.22.0/encommon/types/test/test_notate.py +478 -0
  10. encommon-0.22.0/encommon/version.txt +1 -0
  11. encommon-0.22.0/encommon/webkit/__init__.py +15 -0
  12. encommon-0.22.0/encommon/webkit/content.py +94 -0
  13. encommon-0.22.0/encommon/webkit/images/enasis.svg +174 -0
  14. encommon-0.22.0/encommon/webkit/images/failure.svg +14 -0
  15. encommon-0.22.0/encommon/webkit/images/information.svg +17 -0
  16. encommon-0.22.0/encommon/webkit/images/success.svg +17 -0
  17. encommon-0.22.0/encommon/webkit/images/warning.svg +15 -0
  18. encommon-0.22.0/encommon/webkit/index.html +218 -0
  19. encommon-0.22.0/encommon/webkit/scripts/color.js +45 -0
  20. encommon-0.22.0/encommon/webkit/scripts/datagrid.js +105 -0
  21. encommon-0.22.0/encommon/webkit/scripts/datetime.js +160 -0
  22. encommon-0.22.0/encommon/webkit/scripts/default.js +327 -0
  23. encommon-0.22.0/encommon/webkit/scripts/duration.js +150 -0
  24. encommon-0.22.0/encommon/webkit/scripts/helpers.js +247 -0
  25. encommon-0.22.0/encommon/webkit/scripts/image.js +39 -0
  26. encommon-0.22.0/encommon/webkit/scripts/message.js +31 -0
  27. encommon-0.22.0/encommon/webkit/scripts/moderate.js +71 -0
  28. encommon-0.22.0/encommon/webkit/scripts/numeric.js +189 -0
  29. encommon-0.22.0/encommon/webkit/scripts/statate.js +35 -0
  30. encommon-0.22.0/encommon/webkit/scripts/tagues.js +34 -0
  31. encommon-0.22.0/encommon/webkit/styles/color.css +57 -0
  32. encommon-0.22.0/encommon/webkit/styles/datagrid.css +58 -0
  33. encommon-0.22.0/encommon/webkit/styles/datetime.css +50 -0
  34. encommon-0.22.0/encommon/webkit/styles/default.css +204 -0
  35. encommon-0.22.0/encommon/webkit/styles/duration.css +44 -0
  36. encommon-0.22.0/encommon/webkit/styles/image.css +60 -0
  37. encommon-0.22.0/encommon/webkit/styles/message.css +88 -0
  38. encommon-0.22.0/encommon/webkit/styles/moderate.css +64 -0
  39. encommon-0.22.0/encommon/webkit/styles/numeric.css +55 -0
  40. encommon-0.22.0/encommon/webkit/styles/statate.css +50 -0
  41. encommon-0.22.0/encommon/webkit/styles/tagues.css +45 -0
  42. encommon-0.22.0/encommon/webkit/test/__init__.py +39 -0
  43. encommon-0.22.0/encommon/webkit/test/conftest.py +52 -0
  44. encommon-0.22.0/encommon/webkit/test/test_color.py +64 -0
  45. encommon-0.22.0/encommon/webkit/test/test_content.py +98 -0
  46. encommon-0.22.0/encommon/webkit/test/test_datagrid.py +90 -0
  47. encommon-0.22.0/encommon/webkit/test/test_datetime.py +75 -0
  48. encommon-0.22.0/encommon/webkit/test/test_default.py +314 -0
  49. encommon-0.22.0/encommon/webkit/test/test_duration.py +74 -0
  50. encommon-0.22.0/encommon/webkit/test/test_helpers.py +382 -0
  51. encommon-0.22.0/encommon/webkit/test/test_image.py +62 -0
  52. encommon-0.22.0/encommon/webkit/test/test_message.py +64 -0
  53. encommon-0.22.0/encommon/webkit/test/test_moderate.py +75 -0
  54. encommon-0.22.0/encommon/webkit/test/test_numeric.py +164 -0
  55. encommon-0.22.0/encommon/webkit/test/test_statate.py +78 -0
  56. encommon-0.22.0/encommon/webkit/test/test_tagues.py +66 -0
  57. {encommon-0.20.5 → encommon-0.22.0/encommon.egg-info}/PKG-INFO +2 -2
  58. {encommon-0.20.5 → encommon-0.22.0}/encommon.egg-info/SOURCES.txt +46 -0
  59. {encommon-0.20.5 → encommon-0.22.0}/setup.cfg +2 -1
  60. encommon-0.20.5/MANIFEST.in +0 -4
  61. encommon-0.20.5/encommon/types/test/test_notate.py +0 -217
  62. encommon-0.20.5/encommon/version.txt +0 -1
  63. {encommon-0.20.5 → encommon-0.22.0}/LICENSE +0 -0
  64. {encommon-0.20.5 → encommon-0.22.0}/README.md +0 -0
  65. {encommon-0.20.5 → encommon-0.22.0}/encommon/__init__.py +0 -0
  66. {encommon-0.20.5 → encommon-0.22.0}/encommon/colors/__init__.py +0 -0
  67. {encommon-0.20.5 → encommon-0.22.0}/encommon/colors/color.py +0 -0
  68. {encommon-0.20.5 → encommon-0.22.0}/encommon/colors/test/__init__.py +0 -0
  69. {encommon-0.20.5 → encommon-0.22.0}/encommon/colors/test/test_color.py +0 -0
  70. {encommon-0.20.5 → encommon-0.22.0}/encommon/config/__init__.py +0 -0
  71. {encommon-0.20.5 → encommon-0.22.0}/encommon/config/config.py +0 -0
  72. {encommon-0.20.5 → encommon-0.22.0}/encommon/config/files.py +0 -0
  73. {encommon-0.20.5 → encommon-0.22.0}/encommon/config/logger.py +0 -0
  74. {encommon-0.20.5 → encommon-0.22.0}/encommon/config/params.py +0 -0
  75. {encommon-0.20.5 → encommon-0.22.0}/encommon/config/paths.py +0 -0
  76. {encommon-0.20.5 → encommon-0.22.0}/encommon/config/test/__init__.py +0 -0
  77. {encommon-0.20.5 → encommon-0.22.0}/encommon/config/test/test_config.py +0 -0
  78. {encommon-0.20.5 → encommon-0.22.0}/encommon/config/test/test_files.py +0 -0
  79. {encommon-0.20.5 → encommon-0.22.0}/encommon/config/test/test_logger.py +0 -0
  80. {encommon-0.20.5 → encommon-0.22.0}/encommon/config/test/test_paths.py +0 -0
  81. {encommon-0.20.5 → encommon-0.22.0}/encommon/config/test/test_utils.py +0 -0
  82. {encommon-0.20.5 → encommon-0.22.0}/encommon/config/utils.py +0 -0
  83. {encommon-0.20.5 → encommon-0.22.0}/encommon/conftest.py +0 -0
  84. {encommon-0.20.5 → encommon-0.22.0}/encommon/crypts/__init__.py +0 -0
  85. {encommon-0.20.5 → encommon-0.22.0}/encommon/crypts/crypts.py +0 -0
  86. {encommon-0.20.5 → encommon-0.22.0}/encommon/crypts/hashes.py +0 -0
  87. {encommon-0.20.5 → encommon-0.22.0}/encommon/crypts/params.py +0 -0
  88. {encommon-0.20.5 → encommon-0.22.0}/encommon/crypts/test/__init__.py +0 -0
  89. {encommon-0.20.5 → encommon-0.22.0}/encommon/crypts/test/test_crypts.py +0 -0
  90. {encommon-0.20.5 → encommon-0.22.0}/encommon/crypts/test/test_hashes.py +0 -0
  91. {encommon-0.20.5 → encommon-0.22.0}/encommon/parse/__init__.py +0 -0
  92. {encommon-0.20.5 → encommon-0.22.0}/encommon/parse/jinja2.py +0 -0
  93. {encommon-0.20.5 → encommon-0.22.0}/encommon/parse/network.py +0 -0
  94. {encommon-0.20.5 → encommon-0.22.0}/encommon/parse/test/__init__.py +0 -0
  95. {encommon-0.20.5 → encommon-0.22.0}/encommon/parse/test/test_jinja2.py +0 -0
  96. {encommon-0.20.5 → encommon-0.22.0}/encommon/parse/test/test_network.py +0 -0
  97. {encommon-0.20.5 → encommon-0.22.0}/encommon/py.typed +0 -0
  98. {encommon-0.20.5 → encommon-0.22.0}/encommon/times/__init__.py +0 -0
  99. {encommon-0.20.5 → encommon-0.22.0}/encommon/times/duration.py +0 -0
  100. {encommon-0.20.5 → encommon-0.22.0}/encommon/times/params.py +0 -0
  101. {encommon-0.20.5 → encommon-0.22.0}/encommon/times/parse.py +0 -0
  102. {encommon-0.20.5 → encommon-0.22.0}/encommon/times/test/__init__.py +0 -0
  103. {encommon-0.20.5 → encommon-0.22.0}/encommon/times/test/test_duration.py +0 -0
  104. {encommon-0.20.5 → encommon-0.22.0}/encommon/times/test/test_params.py +0 -0
  105. {encommon-0.20.5 → encommon-0.22.0}/encommon/times/test/test_parse.py +0 -0
  106. {encommon-0.20.5 → encommon-0.22.0}/encommon/times/test/test_time.py +0 -0
  107. {encommon-0.20.5 → encommon-0.22.0}/encommon/times/test/test_timer.py +0 -0
  108. {encommon-0.20.5 → encommon-0.22.0}/encommon/times/test/test_timers.py +0 -0
  109. {encommon-0.20.5 → encommon-0.22.0}/encommon/times/test/test_unitime.py +0 -0
  110. {encommon-0.20.5 → encommon-0.22.0}/encommon/times/test/test_utils.py +0 -0
  111. {encommon-0.20.5 → encommon-0.22.0}/encommon/times/test/test_window.py +0 -0
  112. {encommon-0.20.5 → encommon-0.22.0}/encommon/times/test/test_windows.py +0 -0
  113. {encommon-0.20.5 → encommon-0.22.0}/encommon/times/time.py +0 -0
  114. {encommon-0.20.5 → encommon-0.22.0}/encommon/times/timer.py +0 -0
  115. {encommon-0.20.5 → encommon-0.22.0}/encommon/times/timers.py +0 -0
  116. {encommon-0.20.5 → encommon-0.22.0}/encommon/times/utils.py +0 -0
  117. {encommon-0.20.5 → encommon-0.22.0}/encommon/times/window.py +0 -0
  118. {encommon-0.20.5 → encommon-0.22.0}/encommon/times/windows.py +0 -0
  119. {encommon-0.20.5 → encommon-0.22.0}/encommon/types/classes.py +0 -0
  120. {encommon-0.20.5 → encommon-0.22.0}/encommon/types/dicts.py +0 -0
  121. {encommon-0.20.5 → encommon-0.22.0}/encommon/types/empty.py +0 -0
  122. {encommon-0.20.5 → encommon-0.22.0}/encommon/types/lists.py +0 -0
  123. {encommon-0.20.5 → encommon-0.22.0}/encommon/types/strings.py +0 -0
  124. {encommon-0.20.5 → encommon-0.22.0}/encommon/types/test/test_classes.py +0 -0
  125. {encommon-0.20.5 → encommon-0.22.0}/encommon/types/test/test_empty.py +0 -0
  126. {encommon-0.20.5 → encommon-0.22.0}/encommon/types/test/test_lists.py +0 -0
  127. {encommon-0.20.5 → encommon-0.22.0}/encommon/types/test/test_strings.py +0 -0
  128. {encommon-0.20.5 → encommon-0.22.0}/encommon/types/types.py +0 -0
  129. {encommon-0.20.5 → encommon-0.22.0}/encommon/utils/__init__.py +0 -0
  130. {encommon-0.20.5 → encommon-0.22.0}/encommon/utils/common.py +0 -0
  131. {encommon-0.20.5 → encommon-0.22.0}/encommon/utils/files.py +0 -0
  132. {encommon-0.20.5 → encommon-0.22.0}/encommon/utils/match.py +0 -0
  133. {encommon-0.20.5 → encommon-0.22.0}/encommon/utils/paths.py +0 -0
  134. {encommon-0.20.5 → encommon-0.22.0}/encommon/utils/sample.py +0 -0
  135. {encommon-0.20.5 → encommon-0.22.0}/encommon/utils/stdout.py +0 -0
  136. {encommon-0.20.5 → encommon-0.22.0}/encommon/utils/test/__init__.py +0 -0
  137. {encommon-0.20.5 → encommon-0.22.0}/encommon/utils/test/test_files.py +0 -0
  138. {encommon-0.20.5 → encommon-0.22.0}/encommon/utils/test/test_match.py +0 -0
  139. {encommon-0.20.5 → encommon-0.22.0}/encommon/utils/test/test_paths.py +0 -0
  140. {encommon-0.20.5 → encommon-0.22.0}/encommon/utils/test/test_sample.py +0 -0
  141. {encommon-0.20.5 → encommon-0.22.0}/encommon/utils/test/test_stdout.py +0 -0
  142. {encommon-0.20.5 → encommon-0.22.0}/encommon.egg-info/dependency_links.txt +0 -0
  143. {encommon-0.20.5 → encommon-0.22.0}/encommon.egg-info/requires.txt +0 -0
  144. {encommon-0.20.5 → encommon-0.22.0}/encommon.egg-info/top_level.txt +0 -0
  145. {encommon-0.20.5 → encommon-0.22.0}/pyproject.toml +0 -0
  146. {encommon-0.20.5 → encommon-0.22.0}/require/install.txt +0 -0
@@ -0,0 +1,10 @@
1
+
2
+
3
+
4
+ include encommon/version.txt
5
+
6
+ recursive-include encommon/webkit *.css
7
+ recursive-include encommon/webkit *.html
8
+ recursive-include encommon/webkit *.js
9
+ recursive-include encommon/webkit *.png
10
+ recursive-include encommon/webkit *.svg
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.2
2
2
  Name: encommon
3
- Version: 0.20.5
3
+ Version: 0.22.0
4
4
  Summary: Enasis Network Common Library
5
5
  License: MIT
6
6
  Project-URL: Source, https://github.com/enasisnetwork/encommon
@@ -23,6 +23,9 @@ NUMERISH = compile(
23
23
  SNAPABLE = compile(
24
24
  r'^(\-|\+)[\d\@a-z\-\+]+$')
25
25
 
26
+ UNITIME = Union[
27
+ int | float | str]
28
+
26
29
  STRINGNOW = {
27
30
  'None', None,
28
31
  'null', 'now'}
@@ -7,14 +7,27 @@ is permitted, for more information consult the project license file.
7
7
 
8
8
 
9
9
 
10
+ from re import compile
10
11
  from re import match as re_match
11
12
 
13
+ from .common import UNITIME
12
14
  from .parse import since_time
13
15
 
14
16
 
15
17
 
18
+ NOTATE = compile(
19
+ r'^(\d+(s|m|h|d|w|y))*$')
20
+
21
+ STRINT = compile(
22
+ r'^\d+$')
23
+
24
+ STRFLT = compile(
25
+ r'^\d+\.\d+$')
26
+
27
+
28
+
16
29
  def unitime(
17
- input: int | float | str,
30
+ input: UNITIME,
18
31
  ) -> int:
19
32
  """
20
33
  Return the seconds in integer format for provided input.
@@ -32,20 +45,16 @@ def unitime(
32
45
  :returns: Seconds in integer format for provided input.
33
46
  """
34
47
 
35
- notate = r'^(\d+(s|m|h|d|w|y))*$'
36
- strint = r'^\d+$'
37
- strflt = r'^\d+\.\d+$'
38
-
39
48
  if isinstance(input, str):
40
49
 
41
- if re_match(notate, input):
50
+ if re_match(NOTATE, input):
42
51
  input = since_time(
43
52
  'now', f'+{input}')
44
53
 
45
- elif re_match(strint, input):
54
+ elif re_match(STRINT, input):
46
55
  input = int(input)
47
56
 
48
- elif re_match(strflt, input):
57
+ elif re_match(STRFLT, input):
49
58
  input = int(
50
59
  input.split('.')[0])
51
60
 
@@ -17,7 +17,9 @@ from .lists import dedup_list
17
17
  from .lists import fuzzy_list
18
18
  from .lists import inlist
19
19
  from .notate import delate
20
+ from .notate import expate
20
21
  from .notate import getate
22
+ from .notate import impate
21
23
  from .notate import setate
22
24
  from .strings import hasstr
23
25
  from .strings import inrepr
@@ -39,8 +41,10 @@ __all__ = [
39
41
  'delate',
40
42
  'DictStrAny',
41
43
  'Empty',
44
+ 'expate',
42
45
  'getate',
43
46
  'hasstr',
47
+ 'impate',
44
48
  'inlist',
45
49
  'inrepr',
46
50
  'instr',
@@ -193,6 +193,185 @@ def delate(
193
193
 
194
194
 
195
195
 
196
+ def impate( # noqa: CFQ001,CFQ004
197
+ source: DictStrAny | list[DictStrAny],
198
+ delim: str = '/',
199
+ parent: Optional[str] = None,
200
+ *,
201
+ implode_list: bool = True,
202
+ recurse_list: bool = True,
203
+ ) -> DictStrAny | list[DictStrAny]:
204
+ """
205
+ Implode the dictionary into a single depth of notation.
206
+
207
+ Example
208
+ -------
209
+ >>> impate({'foo': {'bar': 'baz'}})
210
+ {'foo/bar': 'baz'}
211
+
212
+ :param source: Dictionary object processed in notation.
213
+ :param delim: Override default delimiter between parts.
214
+ :param parent: Parent key prefix for downstream update.
215
+ :param implode_list: Determine whether list is imploded.
216
+ :param recurse_list: Determine whether flatten in list.
217
+ :returns: New dictionary that was recursively imploded.
218
+ It is also possible that a list of dictionary will
219
+ be returned when provided and implode_list is False.
220
+ """
221
+
222
+ _implode = implode_list
223
+ _recurse = recurse_list
224
+
225
+
226
+ def _proclist(
227
+ source: list[Any],
228
+ delim: str,
229
+ parent: Optional[str],
230
+ ) -> DictStrAny | list[Any]:
231
+
232
+
233
+ if _implode is False:
234
+
235
+ process = [
236
+ (impate(
237
+ item, delim,
238
+ implode_list=_implode,
239
+ recurse_list=_recurse)
240
+ if isinstance(item, dict | list)
241
+ and _recurse is True
242
+ else item)
243
+ for item in source]
244
+
245
+ return (
246
+ {parent: process}
247
+ if parent is not None
248
+ else process)
249
+
250
+
251
+ returned: DictStrAny = {}
252
+
253
+ for i, item in enumerate(source):
254
+
255
+ key = (
256
+ f'{parent}{delim}{i}'
257
+ if parent is not None
258
+ else str(i))
259
+
260
+ if (isinstance(item, dict | list)
261
+ and _recurse is True):
262
+
263
+ implode = impate(
264
+ item, delim, key,
265
+ implode_list=_implode,
266
+ recurse_list=_recurse)
267
+
268
+ assert isinstance(implode, dict)
269
+
270
+ returned.update(implode)
271
+
272
+ else:
273
+ returned[key] = item
274
+
275
+ return returned
276
+
277
+
278
+ def _procdict(
279
+ source: DictStrAny,
280
+ delim: str,
281
+ parent: Optional[str],
282
+ ) -> DictStrAny:
283
+
284
+ returned: DictStrAny = {}
285
+
286
+ for key, value in source.items():
287
+
288
+ key = (
289
+ f'{parent}{delim}{key}'
290
+ if parent is not None
291
+ else key)
292
+
293
+ if isinstance(value, dict):
294
+
295
+ implode = impate(
296
+ value, delim, key,
297
+ implode_list=_implode,
298
+ recurse_list=_recurse)
299
+
300
+ assert isinstance(implode, dict)
301
+
302
+ returned |= implode
303
+
304
+ elif isinstance(value, list):
305
+
306
+ process = _proclist(
307
+ value, delim, key)
308
+
309
+ returned |= (
310
+ {key: process}
311
+ if not isinstance(process, dict)
312
+ else process)
313
+
314
+ else:
315
+ returned[key] = value
316
+
317
+ return returned
318
+
319
+
320
+ if isinstance(source, dict):
321
+ return _procdict(
322
+ source, delim, parent)
323
+
324
+ if isinstance(source, list):
325
+ return _proclist(
326
+ source, delim, parent)
327
+
328
+ raise ValueError('source')
329
+
330
+
331
+
332
+ def expate(
333
+ source: DictStrAny,
334
+ delim: str = '/',
335
+ ) -> DictStrAny:
336
+ """
337
+ Explode the dictionary from a single depth of notation.
338
+
339
+ Example
340
+ -------
341
+ >>> expate({'foo/bar': 'baz'})
342
+ {'foo': {'bar': 'baz'}}
343
+
344
+ :param source: Dictionary object processed in notation.
345
+ :param delim: Override default delimiter between parts.
346
+ :returns: New dictionary that was recursively exploded.
347
+ """
348
+
349
+ returned: DictStrAny = {}
350
+
351
+
352
+ items = source.items()
353
+
354
+ for key, value in items:
355
+
356
+ if isinstance(value, list):
357
+ value = [
358
+ (expate(x, delim)
359
+ if isinstance(x, dict)
360
+ else x)
361
+ for x in value]
362
+
363
+ if isinstance(value, dict):
364
+ value = expate(value, delim)
365
+
366
+ setate(
367
+ returned, key,
368
+ value, delim)
369
+
370
+
371
+ return returned
372
+
373
+
374
+
196
375
  def _setpath(
197
376
  source: _SETABLE,
198
377
  path: str,
@@ -8,6 +8,13 @@ is permitted, for more information consult the project license file.
8
8
 
9
9
 
10
10
  from copy import deepcopy
11
+ from pathlib import Path
12
+
13
+
14
+
15
+ SAMPLES = (
16
+ Path(__file__).parent
17
+ / 'samples')
11
18
 
12
19
 
13
20
 
@@ -140,6 +140,7 @@ def test_merge_dicts() -> None: # noqa: CFQ001
140
140
  assert source is not _source
141
141
 
142
142
 
143
+
143
144
  def test_sort_dict() -> None:
144
145
  """
145
146
  Perform various tests associated with relevant routines.