From 53a7a54d3e10f2687db0b9e969fe004eb4ece0f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20=C5=A0=C4=8Dotka?= Date: Tue, 5 Apr 2022 15:57:46 +0200 Subject: [PATCH 1/2] special no inheritance mark --- examples/no_inherit/.fmf/version | 1 + examples/no_inherit/a/main.fmf | 2 ++ examples/no_inherit/main.fmf | 6 ++++++ fmf/base.py | 10 ++++++++-- tests/unit/test_no_inheritance_mark.py | 24 ++++++++++++++++++++++++ 5 files changed, 41 insertions(+), 2 deletions(-) create mode 100644 examples/no_inherit/.fmf/version create mode 100644 examples/no_inherit/a/main.fmf create mode 100644 examples/no_inherit/main.fmf create mode 100644 tests/unit/test_no_inheritance_mark.py diff --git a/examples/no_inherit/.fmf/version b/examples/no_inherit/.fmf/version new file mode 100644 index 00000000..d00491fd --- /dev/null +++ b/examples/no_inherit/.fmf/version @@ -0,0 +1 @@ +1 diff --git a/examples/no_inherit/a/main.fmf b/examples/no_inherit/a/main.fmf new file mode 100644 index 00000000..c6bdf556 --- /dev/null +++ b/examples/no_inherit/a/main.fmf @@ -0,0 +1,2 @@ +/inherited: + special!: 2 diff --git a/examples/no_inherit/main.fmf b/examples/no_inherit/main.fmf new file mode 100644 index 00000000..61f29247 --- /dev/null +++ b/examples/no_inherit/main.fmf @@ -0,0 +1,6 @@ +special!: 1 +x: X +/a: + b: b + x!: abc + /inherited: diff --git a/fmf/base.py b/fmf/base.py index e411a821..c11856b4 100644 --- a/fmf/base.py +++ b/fmf/base.py @@ -226,8 +226,14 @@ def merge(self, parent=None): if parent is None: return self.sources = parent.sources + self.sources - # Merge child data with parent data - data = copy.deepcopy(parent.data) + data = {} + # Merge child data with parent da + for key, value in parent.data.items(): + # avoid to copy data if marked as stop inheritance + if not key.endswith('!'): + print(f"no inherit {value}") + data[key] = copy.deepcopy(value) + self._merge_special(data, self.data) self.data = data diff --git a/tests/unit/test_no_inheritance_mark.py b/tests/unit/test_no_inheritance_mark.py new file mode 100644 index 00000000..4e5afac9 --- /dev/null +++ b/tests/unit/test_no_inheritance_mark.py @@ -0,0 +1,24 @@ +import os +import unittest + +import fmf + +# Prepare path to examples +PATH = os.path.dirname(os.path.realpath(__file__)) +EXAMPLES = PATH + "/../../examples/" + + +class TestNoInheritance(unittest.TestCase): + """ Verify storing modifed data to disk """ + + def setUp(self): + self.path = EXAMPLES + "no_inherit" + self.tree = fmf.Tree(self.path) + + def test(self): + root_item = self.tree.find('/') + a_item = self.tree.find('/a') + inherite_item = self.tree.find('/a/inherited') + self.assertIn("special!", root_item.data) + self.assertIn("special!", inherite_item.data) + self.assertNotIn("special!", a_item.data) From 67069138fc3de88a425da527cfc01a3208cce3da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20=C5=A0=C4=8Dotka?= Date: Wed, 6 Apr 2022 09:31:09 +0200 Subject: [PATCH 2/2] undefine already defined item + remove mark feature --- examples/no_inherit/a/main.fmf | 4 ++++ examples/no_inherit/main.fmf | 1 + fmf/base.py | 24 +++++++++++++++++++----- tests/unit/test_no_inheritance_mark.py | 16 ++++++++++++---- 4 files changed, 36 insertions(+), 9 deletions(-) diff --git a/examples/no_inherit/a/main.fmf b/examples/no_inherit/a/main.fmf index c6bdf556..c75eb951 100644 --- a/examples/no_inherit/a/main.fmf +++ b/examples/no_inherit/a/main.fmf @@ -1,2 +1,6 @@ /inherited: special!: 2 +/stop_inherit: + c!: stop + /no_c: + test: x diff --git a/examples/no_inherit/main.fmf b/examples/no_inherit/main.fmf index 61f29247..f78893a0 100644 --- a/examples/no_inherit/main.fmf +++ b/examples/no_inherit/main.fmf @@ -1,5 +1,6 @@ special!: 1 x: X +c: cc /a: b: b x!: abc diff --git a/fmf/base.py b/fmf/base.py index c11856b4..a090ef44 100644 --- a/fmf/base.py +++ b/fmf/base.py @@ -58,6 +58,9 @@ def __init__(self, data, name=None, parent=None): # (needed to prevent removing nodes with an empty dict). self._updated = False + # stop inheritance item + self.stop_inheritance_list = list() + # Store symlinks in while walking tree in grow() to detect # symlink loops if parent is None: @@ -218,6 +221,16 @@ def init(path): root, error)) return root + def _stop_inherit_item(self, item: str): + if item in self.stop_inheritance_list: + print(f"{item} already") + return item[:-1] + elif item.endswith('!'): + print(f"{item} ADD") + self.stop_inheritance_list.append(item) + return item[:-1] + return None + def merge(self, parent=None): """ Merge parent data """ # Check parent, append source files @@ -230,12 +243,12 @@ def merge(self, parent=None): # Merge child data with parent da for key, value in parent.data.items(): # avoid to copy data if marked as stop inheritance - if not key.endswith('!'): - print(f"no inherit {value}") + if key + "!" not in parent.stop_inheritance_list: data[key] = copy.deepcopy(value) - self._merge_special(data, self.data) - self.data = data + for key, value in data.items(): + item = self._stop_inherit_item(key) or key + self.data[item] = data[key] def inherit(self): """ Apply inheritance """ @@ -274,7 +287,8 @@ def update(self, data): self.child(name, value) # Update regular attributes else: - self.data[key] = value + item = self._stop_inherit_item(key) or key + self.data[item] = data[key] log.debug("Data for '{0}' updated.".format(self)) log.data(pretty(self.data)) diff --git a/tests/unit/test_no_inheritance_mark.py b/tests/unit/test_no_inheritance_mark.py index 4e5afac9..9feb4981 100644 --- a/tests/unit/test_no_inheritance_mark.py +++ b/tests/unit/test_no_inheritance_mark.py @@ -15,10 +15,18 @@ def setUp(self): self.path = EXAMPLES + "no_inherit" self.tree = fmf.Tree(self.path) - def test(self): + def test_base(self): root_item = self.tree.find('/') a_item = self.tree.find('/a') inherite_item = self.tree.find('/a/inherited') - self.assertIn("special!", root_item.data) - self.assertIn("special!", inherite_item.data) - self.assertNotIn("special!", a_item.data) + self.assertIn("special", root_item.data) + self.assertIn("special", inherite_item.data) + self.assertNotIn("special", a_item.data) + + def test_undefine(self): + c_item = self.tree.find("/a/stop_inherit") + no_c_item = self.tree.find("/a/stop_inherit/no_c") + self.assertNotIn("special", c_item.data) + self.assertNotIn("special", no_c_item.data) + self.assertIn("c", c_item.data) + self.assertNotIn("c", no_c_item.data)