encommon 0.19.0__py3-none-any.whl → 0.19.2__py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
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