From 4f41c43ed0d2dc01c953d4904e9cca6f6f662da5 Mon Sep 17 00:00:00 2001 From: Joshua Harlow Date: Wed, 14 Oct 2015 22:45:13 -0700 Subject: [PATCH] Ensure node 'remove' and 'disassociate' can not be called when frozen When a tree node is frozen it should not be possible to remove nodes from it or cause that tree node to disassociate itself from its parent, so make sure that the appropriate decorator is used to ensure this can not happen (and add tests that verify an exception is raised when mutations are attempted). Change-Id: I27e4af7b891ea3fd1826d5a5e71e808ad5af7647 --- taskflow/tests/unit/test_types.py | 12 ++++++++++++ taskflow/types/tree.py | 2 ++ 2 files changed, 14 insertions(+) diff --git a/taskflow/tests/unit/test_types.py b/taskflow/tests/unit/test_types.py index 9399c893..d991b684 100644 --- a/taskflow/tests/unit/test_types.py +++ b/taskflow/tests/unit/test_types.py @@ -390,6 +390,18 @@ CEO root = tree.Node("josh") self.assertTrue(root.empty()) + def test_after_frozen(self): + root = tree.Node("josh") + root.add(tree.Node("josh.1")) + root.freeze() + self.assertTrue( + all(n.frozen for n in root.dfs_iter(include_self=True))) + self.assertRaises(tree.FrozenNode, + root.remove, "josh.1") + self.assertRaises(tree.FrozenNode, root.disassociate) + self.assertRaises(tree.FrozenNode, root.add, + tree.Node("josh.2")) + def test_removal(self): root = self._make_species() self.assertIsNotNone(root.remove('reptile')) diff --git a/taskflow/types/tree.py b/taskflow/types/tree.py index 56c96bbb..e0f61670 100644 --- a/taskflow/types/tree.py +++ b/taskflow/types/tree.py @@ -200,6 +200,7 @@ class Node(object): only_direct=only_direct, include_self=include_self) + @misc.disallow_when_frozen(FrozenNode) def disassociate(self): """Removes this node from its parent (if any). @@ -219,6 +220,7 @@ class Node(object): occurrences += 1 return occurrences + @misc.disallow_when_frozen(FrozenNode) def remove(self, item, only_direct=False, include_self=True): """Removes a item from this nodes children.