diff --git a/HISTORY b/HISTORY index 902529c..2bafd0c 100644 --- a/HISTORY +++ b/HISTORY @@ -1,5 +1,8 @@ # History +Jul 25, 2026 +from_json() no longer collapses falsy data values (0, False, "") to None. + Mar 27, 2023 V1.6.3 Apply to black code style. Migrate future to six diff --git a/tests/test_tree_io.py b/tests/test_tree_io.py index c79c0cb..b827fe0 100644 --- a/tests/test_tree_io.py +++ b/tests/test_tree_io.py @@ -162,6 +162,28 @@ def test_to_json_without_data(self): project_data = parsed["Project"] self.assertNotIn("data", project_data) + def test_from_json_preserves_falsy_data(self): + """from_json must preserve falsy-but-valid data values, not collapse them to None.""" + # assertIs on the type is deliberate: assertEqual alone would accept + # False for 0 and 0 for 0.0, which would hide a type change. + for value in [0, 0.0, False, "", [], {}]: + with self.subTest(data=value): + tree = Tree() + tree.create_node("root", "root", data=value) + restored = Tree.from_json(tree.to_json(with_data=True)) + data = restored.all_nodes()[0].data + self.assertEqual(data, value) + self.assertIs(type(data), type(value)) + + def test_from_json_preserves_none_and_truthy_data(self): + """None data stays None, and truthy data is unaffected by the falsy fix.""" + for value in [None, 42, "text", ["a"], {"k": "v"}]: + with self.subTest(data=value): + tree = Tree() + tree.create_node("root", "root", data=value) + restored = Tree.from_json(tree.to_json(with_data=True)) + self.assertEqual(restored.all_nodes()[0].data, value) + def test_from_map_basic(self): """Test from_map basic functionality.""" child_parent_dict = {"CEO": None, "CTO": "CEO", "CFO": "CEO", "VP_Eng": "CTO", "Developer": "VP_Eng"} diff --git a/treelib/tree.py b/treelib/tree.py index f9baa50..f269c5a 100644 --- a/treelib/tree.py +++ b/treelib/tree.py @@ -248,7 +248,7 @@ def from_json(cls, raw: Union[str, bytes, bytearray]): def _append_node(subtree, parent_id=None): for tag, node_info in subtree.items(): node_id = node_info.get("id") or None - node_data = node_info.get("data") or None + node_data = node_info.get("data") node = tree.create_node(tag=tag, identifier=node_id, parent=parent_id, data=node_data)