From eec4f53e4282710e956670794b66b622aee73cec Mon Sep 17 00:00:00 2001 From: Stefan Gula Date: Tue, 28 Nov 2023 15:04:28 +0100 Subject: [PATCH] Adding only_node option to add_defaults This patch allows user to use only_node option within add_defaults function. This option limits the scope of creating and adding implicit default data nodes to just given tree where DNode is considered as root --- cffi/cdefs.h | 1 + libyang/data.py | 11 ++++++++--- tests/test_data.py | 21 ++++++++++++++++----- tests/yang/yolo/yolo-nodetypes.yang | 11 +++++++++++ 4 files changed, 36 insertions(+), 8 deletions(-) diff --git a/cffi/cdefs.h b/cffi/cdefs.h index ba6bd5d4..bb5af6f1 100644 --- a/cffi/cdefs.h +++ b/cffi/cdefs.h @@ -1020,6 +1020,7 @@ LY_ERR lyd_merge_module(struct lyd_node **, const struct lyd_node *, const struc #define LYD_IMPLICIT_OUTPUT ... #define LYD_IMPLICIT_NO_DEFAULTS ... +LY_ERR lyd_new_implicit_tree(struct lyd_node *, uint32_t, struct lyd_node **); LY_ERR lyd_new_implicit_all(struct lyd_node **, const struct ly_ctx *, uint32_t, struct lyd_node **); LY_ERR lyd_new_meta(const struct ly_ctx *, struct lyd_node *, const struct lys_module *, const char *, const char *, ly_bool, struct lyd_meta **); diff --git a/libyang/data.py b/libyang/data.py index c2bf95f5..60d03599 100644 --- a/libyang/data.py +++ b/libyang/data.py @@ -260,6 +260,7 @@ def add_defaults( no_defaults: bool = False, no_state: bool = False, output: bool = False, + only_node: bool = False, ): flags = implicit_flags( no_config=no_config, @@ -267,9 +268,13 @@ def add_defaults( no_state=no_state, output=output, ) - node_p = ffi.new("struct lyd_node **") - node_p[0] = self.cdata - ret = lib.lyd_new_implicit_all(node_p, self.context.cdata, flags, ffi.NULL) + if only_node: + node_p = ffi.cast("struct lyd_node *", self.cdata) + ret = lib.lyd_new_implicit_tree(node_p, flags, ffi.NULL) + else: + node_p = ffi.new("struct lyd_node **") + node_p[0] = self.cdata + ret = lib.lyd_new_implicit_all(node_p, self.context.cdata, flags, ffi.NULL) if ret != lib.LY_SUCCESS: raise self.context.error("cannot get module") diff --git a/tests/test_data.py b/tests/test_data.py index 25bec67d..ed9b8989 100644 --- a/tests/test_data.py +++ b/tests/test_data.py @@ -14,6 +14,7 @@ DataType, DContainer, DLeaf, + DList, DNode, DNotif, DRpc, @@ -32,6 +33,7 @@ def setUp(self): modules = [ self.ctx.load_module("ietf-netconf"), self.ctx.load_module("yolo-system"), + self.ctx.load_module("yolo-nodetypes"), ] for mod in modules: @@ -891,13 +893,22 @@ def test_find_all(self): dnode.free() def test_add_defaults(self): - dnode = self.ctx.parse_data_mem(self.JSON_CONFIG, "json", validate_present=True) - node = dnode.find_path("/yolo-system:conf/speed") + JSON = '{"yolo-nodetypes:records": [{"id": "rec1"}]}' + dnode = self.ctx.parse_data_mem( + JSON, "json", validate_present=True, parse_only=True + ) + self.assertIsInstance(dnode, DList) + node = dnode.find_one("id") self.assertIsInstance(node, DLeaf) - node.free(with_siblings=False) - node = dnode.find_path("/yolo-system:conf/speed") + node = dnode.find_one("name") + self.assertIsNone(node) + dnode.add_defaults(only_node=True) + node = dnode.find_one("name") + self.assertIsInstance(node, DLeaf) + self.assertEqual(node.value(), "ASD") + node = dnode.find_path("/yolo-nodetypes:conf/speed") self.assertIsNone(node) - dnode.add_defaults() + dnode.add_defaults(only_node=False) node = dnode.find_path("/yolo-system:conf/speed") self.assertIsInstance(node, DLeaf) self.assertEqual(node.value(), 4321) diff --git a/tests/yang/yolo/yolo-nodetypes.yang b/tests/yang/yolo/yolo-nodetypes.yang index 3dd76832..6ff28f13 100644 --- a/tests/yang/yolo/yolo-nodetypes.yang +++ b/tests/yang/yolo/yolo-nodetypes.yang @@ -11,6 +11,17 @@ module yolo-nodetypes { "Initial version."; } + list records { + key id; + leaf id { + type string; + } + leaf name { + type string; + default "ASD"; + } + } + container conf { description "Configuration.";