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 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
- 'Time': Time,
49
- 'fuzz_match': fuzz_match,
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 = statics or {}
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
- ) -> None:
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.
@@ -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.0
1
+ 0.19.2
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: encommon
3
- Version: 0.19.0
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
- > :children_crossing: This project has not released its first major version.
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=BsU91PIrLgA4yiu5rzLMGrfmmJjZnMO_oivZZfIarI8,7
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=AzLermYAge3oN33hBDvIXSqlF09n34wWS-y_Hg6JWWc,6051
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=lC2FmPzMEj9L73jUjf3o6OVQ-LqK_3gp5nBwYibdGfo,2265
60
+ encommon/types/dicts.py,sha256=IuLoVdtilhM83ujT74mcz0Zi1HI87P4k7wjnnyMxPag,2821
61
61
  encommon/types/empty.py,sha256=n5y5maXkcM3xNYNYGK6iqvk98ivQSeguaedwc0HoMv4,2739
62
- encommon/types/lists.py,sha256=xjTDOzndqPHu_Cl0yWRDl60lvjLqEqHFW4P7uJ2lfvc,2046
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=UIyNazTlIIdUzQS0brlD7hCPN_LYw_J6Ucxm8wh3cPU,789
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=-RLkcyexCXGSyJyPx1e3QU8sNXEgtSvD9pZakdOwVvg,2702
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.0.dist-info/LICENSE,sha256=otnXKCtMjPlbHs0wgZ_BWULrp3g_2dWQJ6icRk9nkgg,1071
87
- encommon-0.19.0.dist-info/METADATA,sha256=wQiFB7-IXLGMcMeIqzFMcnhFOx6SbkY3r30lIJmMQEM,3494
88
- encommon-0.19.0.dist-info/WHEEL,sha256=cVxcB9AmuTcXqmwrtPhNK88dr7IR_b6qagTj0UvIEbY,91
89
- encommon-0.19.0.dist-info/top_level.txt,sha256=bP8q7-5tLDNm-3XPlqn_bDENfYNug5801H_xfz3BEAM,9
90
- encommon-0.19.0.dist-info/RECORD,,
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,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (74.1.2)
2
+ Generator: setuptools (75.1.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5