Skip to content

Commit 7512f5d

Browse files
samuel-gauthierrjarry
authored andcommitted
dnode: add iter_tree
The DNode.diff function result is hard to use because it is not possible to iterate on the node tree. Add DNode.iter_tree for this purpose. The code mimics the LYD_TREE_DFS_BEGIN/LYD_TREE_DFS_END libyang macros, but in python. Another possibility was to use the macros directly and call a python callback, but it is easier to maintain this way. Signed-off-by: Samuel Gauthier <samuel.gauthier@6wind.com>
1 parent a337226 commit 7512f5d

File tree

2 files changed

+45
-0
lines changed

2 files changed

+45
-0
lines changed

libyang/data.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -553,6 +553,23 @@ def merge(
553553
if ret != lib.LY_SUCCESS:
554554
raise self.context.error("merge failed")
555555

556+
def iter_tree(self) -> Iterator["DNode"]:
557+
n = next_n = self.cdata
558+
while n != ffi.NULL:
559+
yield self.new(self.context, n)
560+
561+
next_n = lib.lyd_child(n)
562+
if next_n == ffi.NULL:
563+
if n == self.cdata:
564+
break
565+
next_n = n.next
566+
while next_n == ffi.NULL:
567+
n = n.parent
568+
if n.parent == self.cdata.parent:
569+
break
570+
next_n = n.next
571+
n = next_n
572+
556573
def print(
557574
self,
558575
fmt: str,

tests/test_data.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -749,6 +749,34 @@ def test_data_diff(self):
749749
dnode1.free()
750750
dnode2.free()
751751

752+
TREE = [
753+
"/yolo-system:conf",
754+
"/yolo-system:conf/hostname",
755+
"/yolo-system:conf/url[proto='https'][host='github.com']",
756+
"/yolo-system:conf/url[proto='https'][host='github.com']/proto",
757+
"/yolo-system:conf/url[proto='https'][host='github.com']/host",
758+
"/yolo-system:conf/url[proto='https'][host='github.com']/path",
759+
"/yolo-system:conf/url[proto='https'][host='github.com']/enabled",
760+
"/yolo-system:conf/url[proto='http'][host='foobar.com']",
761+
"/yolo-system:conf/url[proto='http'][host='foobar.com']/proto",
762+
"/yolo-system:conf/url[proto='http'][host='foobar.com']/host",
763+
"/yolo-system:conf/url[proto='http'][host='foobar.com']/port",
764+
"/yolo-system:conf/url[proto='http'][host='foobar.com']/path",
765+
"/yolo-system:conf/url[proto='http'][host='foobar.com']/enabled",
766+
"/yolo-system:conf/number[.='1000']",
767+
"/yolo-system:conf/number[.='2000']",
768+
"/yolo-system:conf/number[.='3000']",
769+
"/yolo-system:conf/speed",
770+
]
771+
772+
def test_iter_tree(self):
773+
dnode = self.ctx.parse_data_mem(self.JSON_CONFIG, "json", validate_present=True)
774+
try:
775+
paths = [d.path() for d in dnode.iter_tree()]
776+
self.assertEqual(paths, self.TREE)
777+
finally:
778+
dnode.free()
779+
752780
def test_find_one(self):
753781
dnode = self.ctx.parse_data_mem(self.JSON_CONFIG, "json", validate_present=True)
754782
self.assertIsInstance(dnode, DContainer)

0 commit comments

Comments
 (0)