PySerials 0.0.0.dev25__py3-none-any.whl → 0.0.0.dev27__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.
- {PySerials-0.0.0.dev25.dist-info → PySerials-0.0.0.dev27.dist-info}/METADATA +3 -3
- {PySerials-0.0.0.dev25.dist-info → PySerials-0.0.0.dev27.dist-info}/RECORD +6 -6
- {PySerials-0.0.0.dev25.dist-info → PySerials-0.0.0.dev27.dist-info}/WHEEL +1 -1
- pyserials/nested_dict.py +19 -1
- pyserials/update.py +34 -11
- {PySerials-0.0.0.dev25.dist-info → PySerials-0.0.0.dev27.dist-info}/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: PySerials
|
|
3
|
-
Version: 0.0.0.
|
|
3
|
+
Version: 0.0.0.dev27
|
|
4
4
|
Requires-Python: >=3.10
|
|
5
5
|
Requires-Dist: jsonschema <5,>=4.21.0
|
|
6
6
|
Requires-Dist: referencing >=0.35.1
|
|
@@ -8,7 +8,7 @@ Requires-Dist: jsonpath-ng <2,>=1.6.1
|
|
|
8
8
|
Requires-Dist: ruamel.yaml <0.18,>=0.17.32
|
|
9
9
|
Requires-Dist: ruamel.yaml.string <1,>=0.1.1
|
|
10
10
|
Requires-Dist: tomlkit <0.12,>=0.11.8
|
|
11
|
-
Requires-Dist: MDit ==0.0.0.
|
|
12
|
-
Requires-Dist: ExceptionMan ==0.0.0.
|
|
11
|
+
Requires-Dist: MDit ==0.0.0.dev24
|
|
12
|
+
Requires-Dist: ExceptionMan ==0.0.0.dev24
|
|
13
13
|
Requires-Dist: ProtocolMan ==0.0.0.dev2
|
|
14
14
|
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
pyserials/__init__.py,sha256=-ySdqDuoUXdi2Pa8uuFa5m1CTAtbZS3SWc5qzaOdR5o,142
|
|
2
2
|
pyserials/compare.py,sha256=j62A1UIiAm08_xONlbZmU2EcH1GMEpDyEQH66dZ2YMM,1297
|
|
3
3
|
pyserials/format.py,sha256=dTukpab6WHSyVRQ9SteY5fhr3GFjWFboEl-1cw_udVY,1729
|
|
4
|
-
pyserials/nested_dict.py,sha256=
|
|
4
|
+
pyserials/nested_dict.py,sha256=VStzCYwuKocdJR4my6xxXVbwR2i060y8XBEJCTglhaw,4021
|
|
5
5
|
pyserials/read.py,sha256=uucYQH1V4GStwRgRZ2eQIXkH4ukB5qz0EA885grwi68,6592
|
|
6
|
-
pyserials/update.py,sha256=
|
|
6
|
+
pyserials/update.py,sha256=eCkMRjUZdzrSz0FmCDnHGLgEI1WSC6u6onnADuObIVY,10296
|
|
7
7
|
pyserials/validate.py,sha256=ti0D_yLzB_HELvf1d5qrarx1Ac-opBMN1Xh5lADRAQU,3664
|
|
8
8
|
pyserials/write.py,sha256=pN8w78qVsKJjZd_jvPUcZjYp_RJkP7uQzpiXvPOv4lM,1776
|
|
9
9
|
pyserials/exception/__init__.py,sha256=ZhbggwJUMlTyBhifAivC8ZQxP1Na6lJAwzZs7_YjOSU,151
|
|
@@ -11,7 +11,7 @@ pyserials/exception/_base.py,sha256=IdaZwBPBYgiUaWnvN0eMXvQQBqLbN1t766034CK7Hlc,
|
|
|
11
11
|
pyserials/exception/read.py,sha256=QyG6ulExXH9u8oDRjUfter70SMDVQqL4nig5s-JzWN4,9252
|
|
12
12
|
pyserials/exception/update.py,sha256=P0js2-iY2fgO_KLdqedgWE3TTS5Xz15cusZY_wuKIW4,4222
|
|
13
13
|
pyserials/exception/validate.py,sha256=7UkQEEqCa8HJ20gpTFnLDhT3P5OPLD2oD9fUK2Jcuns,7466
|
|
14
|
-
PySerials-0.0.0.
|
|
15
|
-
PySerials-0.0.0.
|
|
16
|
-
PySerials-0.0.0.
|
|
17
|
-
PySerials-0.0.0.
|
|
14
|
+
PySerials-0.0.0.dev27.dist-info/METADATA,sha256=VQ8uAKR8rawcc3yRKF__GGb1T5WZtHiPSKBKGWSVBRA,438
|
|
15
|
+
PySerials-0.0.0.dev27.dist-info/WHEEL,sha256=OVMc5UfuAQiSplgO0_WdW7vXVGAt9Hdd6qtN4HotdyA,91
|
|
16
|
+
PySerials-0.0.0.dev27.dist-info/top_level.txt,sha256=SAks7WjSjdkv3i9Hvt4gY_P7VQbhhYJN5mf5dqx1aao,10
|
|
17
|
+
PySerials-0.0.0.dev27.dist-info/RECORD,,
|
pyserials/nested_dict.py
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
|
+
from __future__ import annotations as _annotations
|
|
2
|
+
|
|
3
|
+
from typing import TYPE_CHECKING as _TYPE_CHECKING
|
|
4
|
+
|
|
1
5
|
import pyserials as _ps
|
|
2
6
|
|
|
7
|
+
if _TYPE_CHECKING:
|
|
8
|
+
from typing import Callable
|
|
9
|
+
|
|
3
10
|
|
|
4
11
|
class NestedDict:
|
|
5
12
|
|
|
@@ -8,14 +15,22 @@ class NestedDict:
|
|
|
8
15
|
data: dict | None = None,
|
|
9
16
|
template_marker_start: str = "${{",
|
|
10
17
|
template_marker_end: str = "}}",
|
|
18
|
+
template_marker_unpack_start: str = "*{{",
|
|
19
|
+
template_marker_unpack_end: str = "}}",
|
|
11
20
|
template_implicit_root: bool = True,
|
|
21
|
+
template_stringer: Callable[[str], str] = None,
|
|
22
|
+
template_ignore_key_regex: str | None = None,
|
|
12
23
|
):
|
|
13
24
|
self._data = data or {}
|
|
14
25
|
self._templater = _ps.update.TemplateFiller(
|
|
15
26
|
marker_start=template_marker_start,
|
|
16
27
|
marker_end=template_marker_end,
|
|
28
|
+
marker_unpack_start=template_marker_unpack_start,
|
|
29
|
+
marker_unpack_end=template_marker_unpack_end,
|
|
17
30
|
implicit_root=template_implicit_root,
|
|
31
|
+
stringer=template_stringer,
|
|
18
32
|
)
|
|
33
|
+
self._ignore_key_regex = template_ignore_key_regex
|
|
19
34
|
return
|
|
20
35
|
|
|
21
36
|
def fill(
|
|
@@ -30,7 +45,9 @@ class NestedDict:
|
|
|
30
45
|
value = self.__getitem__(path)
|
|
31
46
|
if not value:
|
|
32
47
|
return
|
|
33
|
-
filled_value = self.fill_data(
|
|
48
|
+
filled_value = self.fill_data(
|
|
49
|
+
data=value, current_path=path, always_list=always_list, recursive=recursive,
|
|
50
|
+
)
|
|
34
51
|
if not path:
|
|
35
52
|
self._data = filled_value
|
|
36
53
|
else:
|
|
@@ -50,6 +67,7 @@ class NestedDict:
|
|
|
50
67
|
current_path=current_path,
|
|
51
68
|
always_list=always_list,
|
|
52
69
|
recursive=recursive,
|
|
70
|
+
ignore_key_regex=self._ignore_key_regex,
|
|
53
71
|
)
|
|
54
72
|
|
|
55
73
|
def __call__(self):
|
pyserials/update.py
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
from
|
|
1
|
+
from __future__ import annotations as _annotations
|
|
2
|
+
from typing import TYPE_CHECKING as _TYPE_CHECKING
|
|
2
3
|
import re as _re
|
|
3
4
|
|
|
4
5
|
import jsonpath_ng as _jsonpath
|
|
@@ -6,6 +7,9 @@ from jsonpath_ng import exceptions as _jsonpath_exceptions
|
|
|
6
7
|
|
|
7
8
|
import pyserials.exception as _exception
|
|
8
9
|
|
|
10
|
+
if _TYPE_CHECKING:
|
|
11
|
+
from typing import Literal, Callable
|
|
12
|
+
|
|
9
13
|
|
|
10
14
|
def dict_from_addon(
|
|
11
15
|
data: dict,
|
|
@@ -18,7 +22,7 @@ def dict_from_addon(
|
|
|
18
22
|
"""Recursively update a dictionary from another dictionary."""
|
|
19
23
|
def recursive(source: dict, add: dict, path: str, log: dict):
|
|
20
24
|
|
|
21
|
-
def raise_error(typ:
|
|
25
|
+
def raise_error(typ: Literal["duplicate", "type_mismatch"]):
|
|
22
26
|
raise _exception.update.PySerialsUpdateDictFromAddonError(
|
|
23
27
|
problem_type=typ,
|
|
24
28
|
path=fullpath,
|
|
@@ -89,20 +93,29 @@ class TemplateFiller:
|
|
|
89
93
|
self,
|
|
90
94
|
marker_start: str = "${{",
|
|
91
95
|
marker_end: str = "}}",
|
|
96
|
+
marker_unpack_start: str = "*{{",
|
|
97
|
+
marker_unpack_end: str = "}}",
|
|
92
98
|
implicit_root: bool = True,
|
|
99
|
+
stringer: Callable[[str], str] = str,
|
|
93
100
|
):
|
|
101
|
+
def make_regex(start, end):
|
|
102
|
+
start_esc = _re.escape(start)
|
|
103
|
+
end_esc = _re.escape(end)
|
|
104
|
+
regex_sub = rf"{start_esc}([^{end_esc}]+){end_esc}"
|
|
105
|
+
return _re.compile(regex_sub)
|
|
106
|
+
|
|
94
107
|
self._marker_start = marker_start
|
|
95
108
|
self._marker_end = marker_end
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
regex_sub = rf"{start}([^{end}]+){end}"
|
|
99
|
-
self._pattern_template = _re.compile(regex_sub)
|
|
109
|
+
self._pattern_template = make_regex(marker_start, marker_end)
|
|
110
|
+
self._pattern_template_unpack = make_regex(marker_unpack_start, marker_unpack_end)
|
|
100
111
|
self._add_prefix = implicit_root
|
|
112
|
+
self._stringer = stringer
|
|
101
113
|
self._data = None
|
|
102
114
|
self._source = None
|
|
103
115
|
self._recursive = None
|
|
104
116
|
self._path = None
|
|
105
117
|
self._raise_no_match = None
|
|
118
|
+
self._ignore_key_regex = None
|
|
106
119
|
return
|
|
107
120
|
|
|
108
121
|
def fill(
|
|
@@ -113,11 +126,13 @@ class TemplateFiller:
|
|
|
113
126
|
always_list: bool = True,
|
|
114
127
|
recursive: bool = True,
|
|
115
128
|
raise_no_match: bool = True,
|
|
129
|
+
ignore_key_regex: str | None = None,
|
|
116
130
|
):
|
|
117
131
|
self._data = templated_data
|
|
118
132
|
self._source = source_data
|
|
119
133
|
self._recursive = recursive
|
|
120
134
|
self._raise_no_match = raise_no_match
|
|
135
|
+
self._ignore_key_regex = ignore_key_regex
|
|
121
136
|
return self._recursive_subst(
|
|
122
137
|
templ=self._data,
|
|
123
138
|
current_path=(f"$.{current_path}" if self._add_prefix else current_path) if current_path else "$",
|
|
@@ -211,19 +226,27 @@ class TemplateFiller:
|
|
|
211
226
|
if match_whole_str:
|
|
212
227
|
return get_address_value(match_whole_str)
|
|
213
228
|
return self._pattern_template.sub(
|
|
214
|
-
lambda x:
|
|
229
|
+
lambda x: self._stringer(get_address_value(x)),
|
|
215
230
|
templ
|
|
216
231
|
)
|
|
217
232
|
if isinstance(templ, list):
|
|
218
|
-
|
|
219
|
-
|
|
233
|
+
out = []
|
|
234
|
+
for idx, elem in enumerate(templ):
|
|
235
|
+
elem_filled = self._recursive_subst(
|
|
220
236
|
elem, f"{current_path}[{idx}]", always_list
|
|
221
|
-
)
|
|
222
|
-
|
|
237
|
+
)
|
|
238
|
+
if isinstance(elem, str) and self._pattern_template_unpack.fullmatch(elem):
|
|
239
|
+
out.extend(elem_filled)
|
|
240
|
+
else:
|
|
241
|
+
out.append(elem_filled)
|
|
242
|
+
return out
|
|
223
243
|
if isinstance(templ, dict):
|
|
224
244
|
new_dict = {}
|
|
225
245
|
for key, val in templ.items():
|
|
226
246
|
key_filled = self._recursive_subst(key, current_path, always_list=False)
|
|
247
|
+
if self._ignore_key_regex and _re.match(self._ignore_key_regex, key_filled):
|
|
248
|
+
new_dict[key_filled] = val
|
|
249
|
+
continue
|
|
227
250
|
new_dict[key_filled] = self._recursive_subst(
|
|
228
251
|
val, f"{current_path}.'{key_filled}'", always_list=always_list
|
|
229
252
|
)
|
|
File without changes
|