Skip to content

Commit 92c682f

Browse files
committed
schema: add iter_tree method
This covers the same feature than LYSC_TREE_DFS_BEGIN/LYSC_TREE_DFS_END and lysc_tree_dfs_full but reimplemented in pure Python. Fixes: #51 Signed-off-by: Robin Jarry <robin@jarry.cc>
1 parent daf58ee commit 92c682f

File tree

3 files changed

+39
-0
lines changed

3 files changed

+39
-0
lines changed

cffi/cdefs.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -687,6 +687,8 @@ struct lysc_ext {
687687

688688
const struct lysc_node* lys_find_child(const struct lysc_node *, const struct lys_module *, const char *, size_t, uint16_t, uint32_t);
689689
const struct lysc_node* lysc_node_child(const struct lysc_node *);
690+
const struct lysc_node_action* lysc_node_actions(const struct lysc_node *);
691+
const struct lysc_node_notif* lysc_node_notifs(const struct lysc_node *);
690692

691693
typedef enum {
692694
LYD_PATH_STD,

libyang/schema.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1012,6 +1012,37 @@ def when_conditions(self):
10121012
for cond in ly_array_iter(wh):
10131013
yield c2str(lib.lyxp_get_expr(cond.cond))
10141014

1015+
def iter_tree(self, full: bool = False) -> Iterator["SNode"]:
1016+
"""
1017+
Do a DFS walk of the schema node.
1018+
1019+
:arg full:
1020+
Also walk in actions and notifications.
1021+
"""
1022+
n = next_n = self.cdata
1023+
while n != ffi.NULL:
1024+
yield self.new(self.context, n)
1025+
1026+
if full:
1027+
act = lib.lysc_node_actions(n)
1028+
if act != ffi.NULL:
1029+
yield from self.new(self.context, act).iter_tree()
1030+
notif = lib.lysc_node_notifs(n)
1031+
if notif != ffi.NULL:
1032+
yield from self.new(self.context, notif).iter_tree()
1033+
1034+
next_n = lib.lysc_node_child(n)
1035+
if next_n == ffi.NULL:
1036+
if n == self.cdata:
1037+
break
1038+
next_n = n.next
1039+
while next_n == ffi.NULL:
1040+
n = n.parent
1041+
if n.parent == self.cdata.parent:
1042+
break
1043+
next_n = n.next
1044+
n = next_n
1045+
10151046
def __repr__(self):
10161047
cls = self.__class__
10171048
return "<%s.%s: %s>" % (cls.__module__, cls.__name__, str(self))

tests/test_schema.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,12 @@ def test_cont_children_leafs(self):
267267
def test_cont_parent(self):
268268
self.assertIsNone(self.container.parent())
269269

270+
def test_iter_tree(self):
271+
tree = list(self.container.iter_tree())
272+
self.assertEqual(len(tree), 15)
273+
tree = list(self.container.iter_tree(full=True))
274+
self.assertEqual(len(tree), 20)
275+
270276

271277
# -------------------------------------------------------------------------------------
272278
class ListTest(unittest.TestCase):

0 commit comments

Comments
 (0)