Skip to content

Commit

Permalink
mv _future to be with the other protected methods
Browse files Browse the repository at this point in the history
Also, improve comments
  • Loading branch information
Andrew Edwards committed Nov 15, 2021
1 parent a38b2a2 commit e16a096
Showing 1 changed file with 41 additions and 38 deletions.
79 changes: 41 additions & 38 deletions hier_config/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,42 @@ def rebuild_children_dict(self) -> None:
for child in self.children:
self.children_dict.setdefault(child.text, child)

def delete_all_children(self) -> None:
"""Delete all children"""
self.children.clear()
self.rebuild_children_dict()

def unified_diff(self, target: Union[HConfig, HConfigChild]) -> Iterator[str]:
"""
provides a similar output to difflib.unified_diff()
In its current state, this algorithm does not consider duplicate child differences.
e.g. two instances `endif` in an IOS-XR route-policy. It also does not respect the
order of commands where it may count, such as in ACLs. In the case of ACLs, they
should contain sequence numbers if order is important.
"""
# if a self child is missing from the target "- self_child.text"
for self_child in self.children:
self_iter = iter((f"{self_child.indentation}{self_child.text}",))
if target_child := target.children_dict.get(self_child.text, None):
found = self_child.unified_diff(target_child)
if peek := next(found, None):
yield from chain(self_iter, (peek,), found)
else:
yield f"{self_child.indentation}- {self_child.text}"
yield from (
f"{c.indentation}- {c.text}"
for c in self_child.all_children_sorted()
)
# if a target child is missing from self "+ target_child.text"
for target_child in target.children:
if target_child.text not in self.children_dict:
yield f"{target_child.indentation}+ {target_child.text}"
yield from (
f"{c.indentation}+ {c.text}"
for c in target_child.all_children_sorted()
)

def _future(
self,
config: Union[HConfig, HConfigChild],
Expand All @@ -313,64 +349,31 @@ def _future(
elif self_child := config_child.idempotent_for(self.children):
future_config.add_deep_copy_of(config_child)
negated_or_recursed.add(self_child.text)
# The config_child being applied is already in self
# config_child is already in self
elif self_child := self.get_child("equals", config_child.text):
future_child = future_config.add_shallow_copy_of(self_child)
# pylint: disable=protected-access
self_child._future(config_child, future_child)
negated_or_recursed.add(config_child.text)
# The a child is being negated
# config_child is being negated
elif config_child.text.startswith(self._negation_prefix):
unnegated_command = config_child.text[len(self._negation_prefix) :]
if self.get_child("equals", unnegated_command):
negated_or_recursed.add(unnegated_command)
# Account for "no ..." commands in the running config
else:
future_config.add_shallow_copy_of(config_child)
# config_child is not in self and doesn't match a special case
else:
future_config.add_deep_copy_of(config_child)

for self_child in self.children:
# self_child matched an above special case and should be ignored
if self_child.text in negated_or_recursed:
continue
# self_child was not modified above and should be present in the future config
future_config.add_deep_copy_of(self_child)

def delete_all_children(self) -> None:
"""Delete all children"""
self.children.clear()
self.rebuild_children_dict()

def unified_diff(self, target: Union[HConfig, HConfigChild]) -> Iterator[str]:
"""
provides a similar output to difflib.unified_diff()
In its current state, this algorithm does not consider duplicate child differences.
e.g. two instances `endif` in an IOS-XR route-policy. It also does not respect the
order of commands where it may count, such as in ACLs. In the case of ACLs, they
should contain sequence numbers if order is important.
"""
# if a self child is missing from the target "- self_child.text"
for self_child in self.children:
self_iter = iter((f"{self_child.indentation}{self_child.text}",))
if target_child := target.children_dict.get(self_child.text, None):
found = self_child.unified_diff(target_child)
if peek := next(found, None):
yield from chain(self_iter, (peek,), found)
else:
yield f"{self_child.indentation}- {self_child.text}"
yield from (
f"{c.indentation}- {c.text}"
for c in self_child.all_children_sorted()
)
# if a target child is missing from self "+ target_child.text"
for target_child in target.children:
if target_child.text not in self.children_dict:
yield f"{target_child.indentation}+ {target_child.text}"
yield from (
f"{c.indentation}+ {c.text}"
for c in target_child.all_children_sorted()
)

def _with_tags(
self, tags: Set[str], new_instance: Union[HConfig, HConfigChild]
) -> Union[HConfig, HConfigChild]:
Expand Down

0 comments on commit e16a096

Please sign in to comment.