Skip to content

Commit

Permalink
Release version 0.0.0.dev50
Browse files Browse the repository at this point in the history
  • Loading branch information
AAriam committed Dec 5, 2024
1 parent 33f854c commit d9eabf0
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 41 deletions.
6 changes: 3 additions & 3 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ namespaces = true
# ----------------------------------------- Project Metadata -------------------------------------
#
[project]
version = "0.0.0.dev49"
version = "0.0.0.dev50"
name = "PySerials"
dependencies = [
"jsonschema >= 4.21.0, < 5",
Expand All @@ -26,8 +26,8 @@ dependencies = [
"ruamel.yaml >= 0.17.32, < 0.18", # https://yaml.readthedocs.io/en/stable/
"ruamel.yaml.string >= 0.1.1, < 1",
"tomlkit >= 0.11.8, < 0.12", # https://tomlkit.readthedocs.io/en/stable/,
"MDit == 0.0.0.dev46",
"ExceptionMan == 0.0.0.dev46",
"MDit == 0.0.0.dev47",
"ExceptionMan == 0.0.0.dev47",
"ProtocolMan == 0.0.0.dev2",
]
requires-python = ">=3.10"
4 changes: 2 additions & 2 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@ jsonpath-ng >= 1.6.1, < 2
ruamel.yaml >= 0.17.32, < 0.18
ruamel.yaml.string >= 0.1.1, < 1
tomlkit >= 0.11.8, < 0.12
MDit == 0.0.0.dev46
ExceptionMan == 0.0.0.dev46
MDit == 0.0.0.dev47
ExceptionMan == 0.0.0.dev47
ProtocolMan == 0.0.0.dev2
6 changes: 3 additions & 3 deletions src/pyserials/exception/update.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,15 +123,15 @@ def __init__(
template_start: str,
template_end: str,
):
self.path_invalid = path_invalid.replace("'", "")
self.path_invalid = path_invalid
self.data_source = data_source
self.template_start = template_start
self.template_end = template_end
parts = description_template.split("{path_invalid}")
if len(parts) > 1:
parts.insert(1, _mdit.element.code_span(self.path_invalid))
parts.insert(1, _mdit.element.code_span(str(self.path_invalid)))
super().__init__(
path=path.replace("'", ""),
path=str(path),
data=data,
data_full=data_full,
problem=_mdit.inline_container(*parts),
Expand Down
68 changes: 35 additions & 33 deletions src/pyserials/update.py
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ def __init__(

self._pattern_value: dict[int, _RegexPattern] = {}
self._data = None
self._visited_paths = set()
self._visited_paths = {}
return

def fill(
Expand All @@ -162,17 +162,17 @@ def fill(
current_path: str = "",
):
self._data = data
self._visited_paths = set()
path = (f"$.{current_path}" if self._add_prefix else current_path) if current_path else "$"
self._visited_paths = {}
path = _jsonpath.parse((f"$.{current_path}" if self._add_prefix else current_path) if current_path else "$")
return self._recursive_subst(
templ=template or data,
current_path=path,
relative_path_anchor=path,
level=0,
current_chain=[path],
current_chain=(path,),
)

def _recursive_subst(self, templ, current_path: str, relative_path_anchor: str, level: int, current_chain: list[str]):
def _recursive_subst(self, templ, current_path: str, relative_path_anchor: str, level: int, current_chain: tuple[str, ...]):

def get_code_value(match: _re.Match | str):

Expand Down Expand Up @@ -207,7 +207,7 @@ def getter_function(path: str, default: Any = None, search: bool = False):
path_invalid=current_path,
exception=e,
)
self._visited_paths.add(self._normalize_path(current_path))
self._visited_paths[current_path] = (output, True)
return output

def get_address_value(match: _re.Match | str, return_all_matches: bool = False, from_code: bool = False):
Expand All @@ -219,30 +219,30 @@ def get_address_value(match: _re.Match | str, return_all_matches: bool = False,
path_expr = _jsonpath.parse(path)
except _jsonpath_exceptions.JSONPathError:
raise_error(
path_invalid=path,
path_invalid=path_expr,
description_template="JSONPath expression {path_invalid} is invalid.",
)
if num_periods:
if relative_path_anchor != current_path:
path_fields = self._extract_fields(_jsonpath.parse(current_path))
path_fields = self._extract_fields(current_path)
has_template_key = any(field in self._template_keys for field in path_fields)
anchor_path = relative_path_anchor if has_template_key else current_path
else:
anchor_path = current_path
root_path_expr = _jsonpath.parse(anchor_path)
root_path_expr = anchor_path
for period in range(num_periods):
if isinstance(root_path_expr, _jsonpath.Root):
raise_error(
path_invalid=path,
path_invalid=path_expr,
description_template=(
"Relative path {path_invalid} is invalid; "
f"reached root but still {num_periods - period} levels remaining."
),
)
root_path_expr = root_path_expr.left
path_expr = self._concat_json_paths(root_path_expr, path_expr)
value, matched = get_value(path_expr, return_all_matches, from_code)
self._visited_paths.add(self._normalize_path(current_path))
value, matched = self._visited_paths.get(path_expr) or get_value(path_expr, return_all_matches, from_code)
self._visited_paths[path_expr] = (value, matched)
if from_code:
return value, matched
if matched:
Expand All @@ -260,7 +260,7 @@ def get_value(jsonpath, return_all_matches: bool, from_code: bool) -> tuple[Any,
return [], True
if self._raise_no_match:
raise_error(
path_invalid=str(jsonpath),
path_invalid=jsonpath,
description_template="JSONPath expression {path_invalid} did not match any data.",
)
return None, False
Expand All @@ -274,10 +274,10 @@ def get_value(jsonpath, return_all_matches: bool, from_code: bool) -> tuple[Any,
_rel_path_anchor = relative_path_anchor
return self._recursive_subst(
output,
current_path=str(jsonpath),
current_path=jsonpath,
relative_path_anchor=_rel_path_anchor,
level=0,
current_chain=current_chain + [str(jsonpath)],
current_chain=current_chain + (jsonpath,),
), True

def _rec_match(expr) -> list:
Expand All @@ -291,10 +291,10 @@ def _rec_match(expr) -> list:
for left_match in left_matches:
left_match_filled = self._recursive_subst(
templ=left_match.value,
current_path=str(expr.left),
relative_path_anchor=str(expr.left),
current_path=expr.left,
relative_path_anchor=expr.left,
level=0,
current_chain=current_chain + [str(expr.left)],
current_chain=current_chain + (expr.left,),
) if isinstance(left_match.value, str) else left_match.value
right_matches = expr.right.find(left_match_filled)
whole_matches.extend(right_matches)
Expand Down Expand Up @@ -341,9 +341,10 @@ def raise_error(path_invalid: str, description_template: str, exception: Excepti
template_end=self._marker_end_value,
) from exception

if current_path in self._visited_paths:
return self._visited_paths[current_path][0]

self._check_endless_loop(templ, current_chain)
# if self._normalize_path(current_path) in self._visited_paths:
# return templ

if isinstance(templ, str):
# Handle value blocks
Expand Down Expand Up @@ -391,13 +392,13 @@ def raise_error(path_invalid: str, description_template: str, exception: Excepti
if isinstance(templ, list):
out = []
for idx, elem in enumerate(templ):
new_path = f"{current_path}[{idx}]"
new_path = _jsonpath.Child(current_path, _jsonpath.Index(idx))
elem_filled = self._recursive_subst(
templ=elem,
current_path=new_path,
relative_path_anchor=get_relative_path(new_path),
level=0,
current_chain=current_chain + [new_path],
current_chain=current_chain + (new_path,),
)
if isinstance(elem, str) and self._pattern_unpack.fullmatch(elem):
try:
Expand All @@ -409,7 +410,7 @@ def raise_error(path_invalid: str, description_template: str, exception: Excepti
)
else:
out.append(elem_filled)
self._visited_paths.add(self._normalize_path(current_path))
self._visited_paths[current_path] = (out, True)
return out

if isinstance(templ, dict):
Expand All @@ -428,29 +429,30 @@ def raise_error(path_invalid: str, description_template: str, exception: Excepti
if key_filled in self._template_keys:
new_dict[key_filled] = val
continue
new_path = f"{current_path}.'{key_filled}'"
new_path = _jsonpath.Child(current_path, _jsonpath.Fields(key_filled))
new_dict[key_filled] = self._recursive_subst(
templ=val,
current_path=new_path,
relative_path_anchor=get_relative_path(new_path),
level=0,
current_chain=current_chain + [new_path],
current_chain=current_chain + (new_path,),
)
self._visited_paths.add(self._normalize_path(current_path))
self._visited_paths[current_path] = (new_dict, True)
return new_dict
return templ

def _check_endless_loop(self,templ, chain: list[str]):
last_idx = len(chain) -1
def _check_endless_loop(self,templ, chain: tuple[str, ...]):
last_idx = len(chain) - 1
first_idx = chain.index(chain[-1])
if first_idx == last_idx:
return
loop = chain[first_idx - 1: -1]
loop_str = "\n".join([f"- {path.replace("'", "")}" for path in loop])
loop = [chain[-2], *chain[first_idx: -2]]
loop_str = "\n".join([f"- {path}" for path in loop])
history_str = "\n".join([f"- {path}" for path in chain])
raise _exception.update.PySerialsUpdateTemplatedDataError(
description_template=f"Path {{path_invalid}} starts a loop:\n{loop_str}",
path_invalid=loop[0],
path=chain[-1],
description_template=f"Path {{path_invalid}} starts a loop:\n{loop_str}\nHistory:\n{history_str}",
path_invalid=chain[-2],
path=chain[0],
data=templ,
data_full=self._data,
data_source=self._data,
Expand Down

0 comments on commit d9eabf0

Please sign in to comment.