From b66b6b88bba58b3609a621861b06bc0d9fb732cf Mon Sep 17 00:00:00 2001 From: Damien Garros Date: Fri, 9 Oct 2020 07:23:16 -0400 Subject: [PATCH 1/6] Initial implementation for 12 --- dsync/diff.py | 32 ++++++++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/dsync/diff.py b/dsync/diff.py index 48f4dd3c..5fa08df3 100644 --- a/dsync/diff.py +++ b/dsync/diff.py @@ -13,6 +13,7 @@ limitations under the License. """ +import itertools from functools import total_ordering from typing import Iterator, Iterable, Optional @@ -68,10 +69,33 @@ def has_diffs(self) -> bool: return False def get_children(self) -> Iterator["DiffElement"]: - """Iterate over all child elements in all groups in self.children.""" + """Iterate over all child elements in all groups in self.children. + + For each group of children, check if an order method is defined, + Otherwise use the default method. + """ + order_default = "order_children_default" + + children: Iterator["DiffElement"] = itertools.chain() for group in self.groups(): - for child in self.children[group].values(): - yield child + order_method_name = f"order_children_{group}" + if hasattr(self, order_method_name): + order_method = getattr(self, order_method_name) + else: + order_method = getattr(self, order_default) + + children = itertools.chain(children, order_method(self.children[group])) + + return children + + @classmethod + def order_children_default(cls, children: dict) -> Iterator["DiffElement"]: + """Default method to an Iterator for children. + + Since children is already an OrderedDefaultDict, this method is not doing anything special. + """ + for child in children.values(): + yield child def print_detailed(self, indent: int = 0): """Print all diffs to screen for all child elements. @@ -82,7 +106,7 @@ def print_detailed(self, indent: int = 0): margin = " " * indent for group in self.groups(): print(f"{margin}{group}") - for child in self.children[group].values(): + for child in self.get_children(): if child.has_diffs(): child.print_detailed(indent + 2) From 1121d0b59e30c296b75529635d5d79c1c907c8a6 Mon Sep 17 00:00:00 2001 From: Damien Garros Date: Fri, 9 Oct 2020 11:18:36 -0400 Subject: [PATCH 2/6] Add example of order_children method in example1 --- examples/example1/main.py | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/examples/example1/main.py b/examples/example1/main.py index 9e57d6af..9c884f0d 100644 --- a/examples/example1/main.py +++ b/examples/example1/main.py @@ -5,6 +5,20 @@ from backend_c import BackendC +from dsync import Diff + + +class MyDiff(Diff): + """Custom Diff class to control the order of the site objects""" + + @classmethod + def order_children_site(cls, children): + """Return the site children ordered in alphabetical order.""" + keys = sorted(children.keys(), reverse=False) + for key in keys: + yield children[key] + + def main(): """Demonstrate DSync behavior using the example backends provided.""" # pylint: disable=invalid-name @@ -18,7 +32,7 @@ def main(): c = BackendC() c.load() - diff_a_b = a.diff_to(b) + diff_a_b = a.diff_to(b, diff_class=MyDiff) diff_a_b.print_detailed() a.sync_to(b) From 466309d0e71b69a5d112527ea97dc52276ec7440 Mon Sep 17 00:00:00 2001 From: Damien Garros Date: Sun, 11 Oct 2020 14:37:33 -0400 Subject: [PATCH 3/6] replace itertools with yield from --- dsync/diff.py | 6 +----- examples/example1/main.py | 2 +- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/dsync/diff.py b/dsync/diff.py index 5fa08df3..1838dccc 100644 --- a/dsync/diff.py +++ b/dsync/diff.py @@ -13,7 +13,6 @@ limitations under the License. """ -import itertools from functools import total_ordering from typing import Iterator, Iterable, Optional @@ -76,7 +75,6 @@ def get_children(self) -> Iterator["DiffElement"]: """ order_default = "order_children_default" - children: Iterator["DiffElement"] = itertools.chain() for group in self.groups(): order_method_name = f"order_children_{group}" if hasattr(self, order_method_name): @@ -84,9 +82,7 @@ def get_children(self) -> Iterator["DiffElement"]: else: order_method = getattr(self, order_default) - children = itertools.chain(children, order_method(self.children[group])) - - return children + yield from order_method(self.children[group]) @classmethod def order_children_default(cls, children: dict) -> Iterator["DiffElement"]: diff --git a/examples/example1/main.py b/examples/example1/main.py index 9c884f0d..8fabf85f 100644 --- a/examples/example1/main.py +++ b/examples/example1/main.py @@ -9,7 +9,7 @@ class MyDiff(Diff): - """Custom Diff class to control the order of the site objects""" + """Custom Diff class to control the order of the site objects.""" @classmethod def order_children_site(cls, children): From 5c72498405bb0660e21c98b281fdb98bfa991ca0 Mon Sep 17 00:00:00 2001 From: Damien Garros Date: Sun, 11 Oct 2020 16:26:51 -0400 Subject: [PATCH 4/6] revert changes in print_detailed --- dsync/diff.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dsync/diff.py b/dsync/diff.py index 1838dccc..1061f3b5 100644 --- a/dsync/diff.py +++ b/dsync/diff.py @@ -102,7 +102,7 @@ def print_detailed(self, indent: int = 0): margin = " " * indent for group in self.groups(): print(f"{margin}{group}") - for child in self.get_children(): + for child in self.children[group].values(): if child.has_diffs(): child.print_detailed(indent + 2) From 7cb7a8bcdee493079e65b3fbefbc4eaccbe71d45 Mon Sep 17 00:00:00 2001 From: Damien Garros Date: Mon, 12 Oct 2020 15:46:49 -0400 Subject: [PATCH 5/6] Add unit tests --- tests/unit/test_diff.py | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/tests/unit/test_diff.py b/tests/unit/test_diff.py index a9b889d5..7e55b5e3 100644 --- a/tests/unit/test_diff.py +++ b/tests/unit/test_diff.py @@ -49,3 +49,38 @@ def test_diff_children(): assert diff.has_diffs() # TODO: test print_detailed + + +def test_order_children_default(backend_a, backend_b): + """Test that order_children_default is properly called when calling get_children.""" + + class MyDiff(Diff): + @classmethod + def order_children_default(cls, children): + """Return the children ordered in alphabetical order.""" + keys = sorted(children.keys(), reverse=False) + for key in keys: + yield children[key] + + # Validating default order method + diff_a_b = backend_a.diff_from(backend_b, diff_class=MyDiff) + children = diff_a_b.get_children() + children_names = [child.name for child in children] + assert children_names == ["atl", "nyc", "rdu", "sfo"] + + +def test_order_children_custom(backend_a, backend_b): + """Test that a custom order_children method is properly called when calling get_children.""" + + class MyDiff(Diff): + @classmethod + def order_children_site(cls, children): + """Return the site children ordered in reverse-alphabetical order.""" + keys = sorted(children.keys(), reverse=True) + for key in keys: + yield children[key] + + diff_a_b = backend_a.diff_from(backend_b, diff_class=MyDiff) + children = diff_a_b.get_children() + children_names = [child.name for child in children] + assert children_names == ["sfo", "rdu", "nyc", "atl"] From 197f671fc5af9889cd239e433a67c8df195522f3 Mon Sep 17 00:00:00 2001 From: Damien Garros Date: Mon, 12 Oct 2020 16:00:32 -0400 Subject: [PATCH 6/6] Fix pylint issue --- tests/unit/test_diff.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/unit/test_diff.py b/tests/unit/test_diff.py index 7e55b5e3..31649574 100644 --- a/tests/unit/test_diff.py +++ b/tests/unit/test_diff.py @@ -55,6 +55,8 @@ def test_order_children_default(backend_a, backend_b): """Test that order_children_default is properly called when calling get_children.""" class MyDiff(Diff): + """custom diff class to test order_children_default.""" + @classmethod def order_children_default(cls, children): """Return the children ordered in alphabetical order.""" @@ -73,6 +75,8 @@ def test_order_children_custom(backend_a, backend_b): """Test that a custom order_children method is properly called when calling get_children.""" class MyDiff(Diff): + """custom diff class to test order_children_site.""" + @classmethod def order_children_site(cls, children): """Return the site children ordered in reverse-alphabetical order."""