encommon 0.18.0__py3-none-any.whl → 0.19.1__py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,226 @@
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 pytest import raises
11
+
12
+ from ..network import Network
13
+ from ..network import insubnet_ip
14
+ from ..network import isvalid_ip
15
+ from ...types import inrepr
16
+ from ...types import instr
17
+ from ...types import lattrs
18
+
19
+
20
+
21
+ def test_Network() -> None:
22
+ """
23
+ Perform various tests associated with relevant routines.
24
+ """
25
+
26
+
27
+ naddr = Network('12.34.56.7')
28
+
29
+
30
+ attrs = lattrs(naddr)
31
+
32
+ assert attrs == [
33
+ '_Network__source']
34
+
35
+
36
+ assert inrepr(
37
+ "Network('12.34.",
38
+ naddr)
39
+
40
+ assert hash(naddr) > 0
41
+
42
+ assert instr(
43
+ '12.34.56.7/32',
44
+ naddr)
45
+
46
+
47
+ assert naddr == '12.34.56.7'
48
+ assert naddr != 'invalid'
49
+
50
+
51
+ assert naddr.source
52
+
53
+ assert naddr.version == 4
54
+
55
+ assert naddr.cidr == 32
56
+
57
+ assert naddr.address == '12.34.56.7'
58
+
59
+ assert naddr.address_cidr == '12.34.56.7/32'
60
+
61
+ assert naddr.address_host == '12.34.56.7/32'
62
+
63
+ assert naddr.network == '12.34.56.7'
64
+
65
+ assert naddr.network_cidr == '12.34.56.7/32'
66
+
67
+ assert not naddr.broadcast
68
+
69
+ assert naddr.netmask == '255.255.255.255'
70
+
71
+ assert naddr.padded == '012.034.056.007'
72
+
73
+ assert naddr.reverse == '7.56.34.12'
74
+
75
+ assert naddr.hwaddr == '01-20-34-05-60-07'
76
+
77
+ assert naddr.ispublic
78
+
79
+ assert not naddr.isprivate
80
+
81
+ assert not naddr.islinklocal
82
+
83
+ assert not naddr.islocalhost
84
+
85
+
86
+
87
+ def test_Network_ipv4() -> None:
88
+ """
89
+ Perform various tests associated with relevant routines.
90
+ """
91
+
92
+
93
+ naddr = Network('12.34.56.7/24')
94
+
95
+
96
+ assert naddr.cidr == 24
97
+
98
+ assert naddr.address == '12.34.56.7'
99
+
100
+ assert naddr.address_cidr == '12.34.56.7/24'
101
+
102
+ assert naddr.address_host == '12.34.56.7/32'
103
+
104
+ assert naddr.network == '12.34.56.0'
105
+
106
+ assert naddr.network_cidr == '12.34.56.0/24'
107
+
108
+ assert naddr.broadcast == '12.34.56.255'
109
+
110
+ assert naddr.netmask == '255.255.255.0'
111
+
112
+ assert naddr.padded == '012.034.056.007'
113
+
114
+ assert naddr.reverse == '7.56.34.12'
115
+
116
+ assert naddr.hwaddr == '01-20-34-05-60-07'
117
+
118
+ assert naddr.ispublic
119
+
120
+ assert not naddr.isprivate
121
+
122
+ assert not naddr.islinklocal
123
+
124
+ assert not naddr.islocalhost
125
+
126
+
127
+
128
+ def test_Network_ipv6() -> None:
129
+ """
130
+ Perform various tests associated with relevant routines.
131
+ """
132
+
133
+
134
+ naddr = Network('2001:db8::/64')
135
+
136
+
137
+ assert naddr.cidr == 64
138
+
139
+ assert naddr.address == '2001:db8::'
140
+
141
+ assert naddr.address_cidr == '2001:db8::/64'
142
+
143
+ assert naddr.address_host == '2001:db8::/128'
144
+
145
+ assert naddr.network == '2001:db8::'
146
+
147
+ assert naddr.network_cidr == '2001:db8::/64'
148
+
149
+ assert naddr.broadcast == (
150
+ '2001:db8::ffff:ffff:ffff:ffff')
151
+
152
+ assert naddr.netmask == (
153
+ 'ffff:ffff:ffff:ffff::')
154
+
155
+ with raises(ValueError):
156
+ naddr.padded
157
+
158
+ with raises(ValueError):
159
+ naddr.reverse
160
+
161
+ with raises(ValueError):
162
+ naddr.hwaddr
163
+
164
+ assert not naddr.ispublic
165
+
166
+ assert naddr.isprivate
167
+
168
+ assert not naddr.islinklocal
169
+
170
+ assert not naddr.islocalhost
171
+
172
+
173
+
174
+ def test_isvalid_ip() -> None:
175
+ """
176
+ Perform various tests associated with relevant routines.
177
+ """
178
+
179
+ assert isvalid_ip('1.2.3.4')
180
+
181
+ assert not isvalid_ip('1.2')
182
+
183
+ assert not isvalid_ip(None)
184
+
185
+
186
+
187
+ def test_insubnet_ip() -> None:
188
+ """
189
+ Perform various tests associated with relevant routines.
190
+ """
191
+
192
+ assert insubnet_ip(
193
+ '192.168.1.1',
194
+ ['172.16.0.0/12',
195
+ '192.168.0.0/16'])
196
+
197
+ assert not insubnet_ip(
198
+ '1.2.3.4',
199
+ ['172.16.0.0/12',
200
+ '192.168.0.0/16'])
201
+
202
+ assert insubnet_ip(
203
+ '192.168.1.1',
204
+ ['192.168.1.1/32'])
205
+
206
+ assert insubnet_ip(
207
+ '192.168.1.1/32',
208
+ '192.168.1.1/32')
209
+
210
+ assert insubnet_ip(
211
+ '2001:db8::',
212
+ ['2001:db8::/128'])
213
+
214
+ assert insubnet_ip(
215
+ '2001:db8::',
216
+ ['2001:db8::/32'])
217
+
218
+ assert insubnet_ip(
219
+ '2001:db8::/128',
220
+ ['2001:db8::/32'])
221
+
222
+ with raises(ValueError):
223
+
224
+ insubnet_ip(
225
+ 'invalid',
226
+ ['2001:db8::/32'])
@@ -13,6 +13,8 @@ from .classes import lattrs
13
13
  from .dicts import merge_dicts
14
14
  from .dicts import sort_dict
15
15
  from .empty import Empty
16
+ from .lists import dedup_list
17
+ from .lists import fuzzy_list
16
18
  from .lists import inlist
17
19
  from .notate import delate
18
20
  from .notate import getate
@@ -32,6 +34,8 @@ from .types import NCTrue
32
34
  __all__ = [
33
35
  'BaseModel',
34
36
  'clsname',
37
+ 'dedup_list',
38
+ 'fuzzy_list',
35
39
  'delate',
36
40
  'DictStrAny',
37
41
  'Empty',
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
@@ -12,6 +12,90 @@ from typing import Sequence
12
12
 
13
13
 
14
14
 
15
+ def dedup_list(
16
+ value: list[Any],
17
+ update: bool = True,
18
+ ) -> list[Any]:
19
+ """
20
+ Return the provided list values with duplicates removed.
21
+
22
+ .. warning::
23
+ This function will update the ``value`` reference.
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
+
33
+ :param value: List of values processed for duplication.
34
+ :param update: Indicate if to update provided reference.
35
+ :returns: Provided list values with duplicates removed.
36
+ """
37
+
38
+ if update is False:
39
+ value = list(value)
40
+
41
+
42
+ unique: list[Any] = []
43
+
44
+ for item in list(value):
45
+
46
+ if item in unique:
47
+
48
+ value.remove(item)
49
+
50
+ continue
51
+
52
+ unique.append(item)
53
+
54
+
55
+ return value
56
+
57
+
58
+
59
+ def fuzzy_list(
60
+ values: str | list[str],
61
+ patterns: str | list[str],
62
+ ) -> list[str]:
63
+ """
64
+ Return the provided values that match provided patterns.
65
+
66
+ Example
67
+ -------
68
+ >>> values = ['foo', 'bar', 'baz', 'bop']
69
+ >>> patterns = ['*o', 'ba*']
70
+ >>> fuzzy_list(values, patterns)
71
+ ['foo', 'bar', 'baz']
72
+
73
+ :param values: Value or values to enumerate for matching.
74
+ :param patterns: Patterns which values can match any one.
75
+ :returns: Provided values that match provided patterns.
76
+ """
77
+
78
+ from ..utils import fuzz_match
79
+
80
+ if isinstance(values, str):
81
+ values = [values]
82
+
83
+ matched: list[str] = []
84
+
85
+ for value in values:
86
+
87
+ match = fuzz_match(
88
+ value, patterns)
89
+
90
+ if match is False:
91
+ continue
92
+
93
+ matched.append(value)
94
+
95
+ return matched
96
+
97
+
98
+
15
99
  def inlist(
16
100
  needle: Any, # noqa: ANN401
17
101
  haystack: Sequence[Any],
@@ -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}
@@ -7,6 +7,8 @@ is permitted, for more information consult the project license file.
7
7
 
8
8
 
9
9
 
10
+ from ..lists import dedup_list
11
+ from ..lists import fuzzy_list
10
12
  from ..lists import inlist
11
13
 
12
14
 
@@ -21,3 +23,42 @@ def test_inlist() -> None:
21
23
  haystack = [123, 456]
22
24
 
23
25
  assert inlist(needle, haystack)
26
+
27
+
28
+
29
+ def test_dedup_list() -> None:
30
+ """
31
+ Perform various tests associated with relevant routines.
32
+ """
33
+
34
+ value = [1, 1, '2', 2, 3, 3]
35
+
36
+ dedup = dedup_list(
37
+ value,
38
+ update=False)
39
+
40
+ assert dedup != value
41
+ assert dedup == [1, '2', 2, 3]
42
+
43
+ dedup_list(value)
44
+
45
+ assert dedup == value
46
+ assert dedup == [1, '2', 2, 3]
47
+
48
+
49
+
50
+ def test_fuzzy_list() -> None:
51
+ """
52
+ Perform various tests associated with relevant routines.
53
+ """
54
+
55
+ values = ['1', '2']
56
+ patterns = ['1*']
57
+
58
+ matched = fuzzy_list(
59
+ values, patterns)
60
+
61
+ assert matched == ['1']
62
+
63
+ assert not (
64
+ fuzzy_list('', []))
encommon/version.txt CHANGED
@@ -1 +1 @@
1
- 0.18.0
1
+ 0.19.1
@@ -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,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=9ek4KWfJgzBmpVgIgp83UPyOEYGxcMr9Iiw3BIu0mnc,7
4
+ encommon/version.txt,sha256=HiAUu03xr-U1r5jwSObjdyUI5Sc8FC-Dufx0e0D5z00,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
@@ -26,6 +26,12 @@ encommon/crypts/params.py,sha256=2uH_i1NBMlzhq7UtWgX2jsiUGNniOK69eTCeeiQFpdw,141
26
26
  encommon/crypts/test/__init__.py,sha256=PjrnBYT0efyvbaGeNx94dm3tP3EVHUHSVs-VGeLEv5g,218
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
+ encommon/parse/__init__.py,sha256=6uV4GCm_nOYC77x2jQvTDsa0F6vBGRbCgju_HCc96zM,422
30
+ encommon/parse/jinja2.py,sha256=HhZX7TD5wzAMUhgHjb_IxG1yILsmBiTr9_McGlqEHr4,7066
31
+ encommon/parse/network.py,sha256=PgQ6xV6Y9KmyH0iXqQ-b88Gtkrry75Fzc-tZd-BH0ng,8771
32
+ encommon/parse/test/__init__.py,sha256=PjrnBYT0efyvbaGeNx94dm3tP3EVHUHSVs-VGeLEv5g,218
33
+ encommon/parse/test/test_jinja2.py,sha256=hZu4BaRWZgyU_edVUcDiJs9gJnoFoSWF9o7CPROmcAI,3760
34
+ encommon/parse/test/test_network.py,sha256=apBv7rNtdjSbGnpXwg1VX-ybF3w-tyqYjpQDv6mlwfM,4148
29
35
  encommon/times/__init__.py,sha256=QX4iuZ59UlsMbEWbubnVJXJtrOubNxAAAv510urcLUA,972
30
36
  encommon/times/common.py,sha256=HWgWBbqDoyKHIqeg4bBAZZfRM3499X3WPu8dVCzt_5o,995
31
37
  encommon/times/duration.py,sha256=LTROiKcRXvPcs2Gz9KaB5Cmxo9NXd3TcMo5-jnTxPo0,10794
@@ -49,19 +55,19 @@ encommon/times/test/test_unitime.py,sha256=5i4UjBCw8R9h-Lw963GfB_dHBMEQhjvv1k-t2
49
55
  encommon/times/test/test_utils.py,sha256=WkzHJY6zOt02Ujg5FItOo1nPtktz5ss8ODmG1tRQaaw,2056
50
56
  encommon/times/test/test_window.py,sha256=gNJpWVrwQTnUFQ00OLzWUuvJjWUCoiCwydohr9mevT0,6116
51
57
  encommon/times/test/test_windows.py,sha256=IaaxUXqf5n9IF9X0HkRqtCdyOdeCq5DYR1ySLORA9gE,4474
52
- encommon/types/__init__.py,sha256=_DVoVFJWd-9aCpXtPEaB3CnZ-5gt-uYxMWzquXfXHpg,1047
58
+ encommon/types/__init__.py,sha256=wMgdz0PuJyL_LIfafDlWIDaDLJi-bhnQJ4YTuUgN2gY,1143
53
59
  encommon/types/classes.py,sha256=FYFTu8Uj-74JWudHOlhaOrsXXPxitorBfM9_QM3EGSU,1689
54
- encommon/types/dicts.py,sha256=lC2FmPzMEj9L73jUjf3o6OVQ-LqK_3gp5nBwYibdGfo,2265
60
+ encommon/types/dicts.py,sha256=IuLoVdtilhM83ujT74mcz0Zi1HI87P4k7wjnnyMxPag,2821
55
61
  encommon/types/empty.py,sha256=n5y5maXkcM3xNYNYGK6iqvk98ivQSeguaedwc0HoMv4,2739
56
- encommon/types/lists.py,sha256=4xn1RqS1VMsNnhR-2Xpv4ykB6d2RteFa5zdiWKzo55o,745
62
+ encommon/types/lists.py,sha256=AX-siqXfLwm_5mGDsomg_7XWalZOYLE60D3wHwbNEzo,2358
57
63
  encommon/types/notate.py,sha256=0JIzF5VDnQ6C4umZIpgxIvd91gFo3MXTZ7Kp54S538A,6454
58
64
  encommon/types/strings.py,sha256=LW2WZND64cKE1LhNip3vqsoP3elLsUP6cpS0dYnUKGE,2800
59
65
  encommon/types/types.py,sha256=DbzdDLLclD1Gk8bmyhDUUWVDnJ5LdaolLV3JYKHFVgA,322
60
- encommon/types/test/__init__.py,sha256=UIyNazTlIIdUzQS0brlD7hCPN_LYw_J6Ucxm8wh3cPU,789
66
+ encommon/types/test/__init__.py,sha256=uauiJIPPJjk1bzp5WEH_YEFLR5m0zxVN_c1liYAYIro,827
61
67
  encommon/types/test/test_classes.py,sha256=CjthMInwz5WB7aTc7-GpzgcYAvkF9dRmC6nXJVoE91k,1475
62
- encommon/types/test/test_dicts.py,sha256=-RLkcyexCXGSyJyPx1e3QU8sNXEgtSvD9pZakdOwVvg,2702
68
+ encommon/types/test/test_dicts.py,sha256=kVYIGlIyXOx9yiCPKbhhFMf0TpiTU0ESNOaJYIq0_Ms,3650
63
69
  encommon/types/test/test_empty.py,sha256=LVsZbKOg0deyKOtg_0Fhf0b_0c94LftwdDhijna-FbA,995
64
- encommon/types/test/test_lists.py,sha256=RXvIQvr1nODutPBRx5hMsPRq_10AzBWF594KINoMgU8,437
70
+ encommon/types/test/test_lists.py,sha256=uRdON1vnDT21TBl2prlO15SHIkN7YOApZzHS78R-Bvs,1139
65
71
  encommon/types/test/test_notate.py,sha256=NfrDmMD6hOoVi9wlQ8yLZNnuHwS6Z7bLze70FkxOjSA,4008
66
72
  encommon/types/test/test_strings.py,sha256=oXusioFMdknHeBdwlP_GakDVS9Tf2YBndjonj22UfmM,1277
67
73
  encommon/utils/__init__.py,sha256=bBgh81wX_TwLgWkx0aBAyVLHNphrfcyQc1AF7-ziyNI,1027
@@ -77,8 +83,8 @@ encommon/utils/test/test_match.py,sha256=QagKpTFdRo23-Y55fSaJrSMpt5jIebScKbz0h8t
77
83
  encommon/utils/test/test_paths.py,sha256=4AzIhQyYFEWhRWHgOZCCzomQ3Zs3EVwRnDQDa6Nq1Mc,1942
78
84
  encommon/utils/test/test_sample.py,sha256=Qf-W0XbjTe5PfG87sdVizL2ymUPRTdX0qQtLGHaTgx8,3539
79
85
  encommon/utils/test/test_stdout.py,sha256=fYiqEaUraD-3hFQYLxMPR4Ti_8CbTjEc8WvReXUA884,6139
80
- encommon-0.18.0.dist-info/LICENSE,sha256=otnXKCtMjPlbHs0wgZ_BWULrp3g_2dWQJ6icRk9nkgg,1071
81
- encommon-0.18.0.dist-info/METADATA,sha256=upaliFBqed1iQjZnK9uwLnlrhAyLj2vcyM5pHROcVig,3449
82
- encommon-0.18.0.dist-info/WHEEL,sha256=cVxcB9AmuTcXqmwrtPhNK88dr7IR_b6qagTj0UvIEbY,91
83
- encommon-0.18.0.dist-info/top_level.txt,sha256=bP8q7-5tLDNm-3XPlqn_bDENfYNug5801H_xfz3BEAM,9
84
- encommon-0.18.0.dist-info/RECORD,,
86
+ encommon-0.19.1.dist-info/LICENSE,sha256=otnXKCtMjPlbHs0wgZ_BWULrp3g_2dWQJ6icRk9nkgg,1071
87
+ encommon-0.19.1.dist-info/METADATA,sha256=FFIQ6JKuLRAjOUYA4A3tZzDRL9q2I89pGR1v9Eg43Ws,3484
88
+ encommon-0.19.1.dist-info/WHEEL,sha256=GV9aMThwP_4oNCtvEC2ec3qUYutgWeAzklro_0m4WJQ,91
89
+ encommon-0.19.1.dist-info/top_level.txt,sha256=bP8q7-5tLDNm-3XPlqn_bDENfYNug5801H_xfz3BEAM,9
90
+ encommon-0.19.1.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