Skip to content

Commit

Permalink
schema: enable getting node data path without list key
Browse files Browse the repository at this point in the history
There is no way to get a node data path (path without choice/case)
without list keys.

Adds the path_type parameter to the SNode.schema_path() method. This
parameter can takes 3 values:
 - SNode.PATH_LOG: returns the path with schema-only nodes (choice,
   case) included, the default
 - SNode.PATH_DATA: returns the path without schema-only nodes
 - SNode.PATH_DATA_PATTERN: similar to PATH_DATA with list keys added
   (the one used by data_path())

The SNode.PATH_LOG is set by default to not change the original
behavior.
The SNode.data_path() method now calls SNode.schema_path() with
self.PATH_DATA_PATTERN instead of lib.lysc_path().

Here is an example of the output difference between schema_path(),
data_path(), and schema_path(path_type=SNode.PATH_DATA) with a node
included in a choice and a list:
node.schema_path():
/ietf-keystore:keystore/asymmetric-keys/asymmetric-key/private-key-type/private-key/private-key
node.data_path() or node.schema_path(SNode.PATH_DATA_PATTERN):
/ietf-keystore:keystore/asymmetric-keys/asymmetric-key[name='%s']/private-key
node.schema_path(SNode.PATH_DATA):
/ietf-keystore:keystore/asymmetric-keys/asymmetric-key/private-key

Tests have been updated accordingly.

Signed-off-by: Matthieu Ternisien d'Ouville <[email protected]>
  • Loading branch information
MatthieuTdO-6WIND authored and rjarry committed Jan 24, 2024
1 parent a2159c8 commit 097412c
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 15 deletions.
21 changes: 11 additions & 10 deletions libyang/schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -1034,6 +1034,10 @@ class SNode:
ANYDATA: "anydata",
}

PATH_LOG = lib.LYSC_PATH_LOG
PATH_DATA = lib.LYSC_PATH_DATA
PATH_DATA_PATTERN = lib.LYSC_PATH_DATA_PATTERN

def __init__(self, context: "libyang.Context", cdata):
self.context = context
self.cdata = cdata # C type: "struct lysc_node *"
Expand Down Expand Up @@ -1079,22 +1083,19 @@ def status(self) -> str:
def module(self) -> Module:
return Module(self.context, self.cdata.module)

def schema_path(self) -> str:
def schema_path(self, path_type: int = PATH_LOG) -> str:
try:
s = lib.lysc_path(self.cdata, lib.LYSC_PATH_LOG, ffi.NULL, 0)
s = lib.lysc_path(self.cdata, path_type, ffi.NULL, 0)
return c2str(s)
finally:
lib.free(s)

def data_path(self, key_placeholder: str = "'%s'") -> str:
try:
s = lib.lysc_path(self.cdata, lib.LYSC_PATH_DATA_PATTERN, ffi.NULL, 0)
val = c2str(s)
if key_placeholder != "'%s'":
val = val.replace("'%s'", key_placeholder)
return val
finally:
lib.free(s)
val = self.schema_path(self.PATH_DATA_PATTERN)

if key_placeholder != "'%s'":
val = val.replace("'%s'", key_placeholder)
return val

def extensions(self) -> Iterator[ExtensionCompiled]:
ext = ffi.cast("struct lysc_ext_instance *", self.cdata.exts)
Expand Down
15 changes: 10 additions & 5 deletions tests/test_schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -282,13 +282,16 @@ def test_iter_tree(self):

# -------------------------------------------------------------------------------------
class ListTest(unittest.TestCase):
SCHEMA_PATH = "/yolo-system:conf/url"
DATA_PATH = "/yolo-system:conf/url[host='%s'][proto='%s']"
PATH = {
"LOG": "/yolo-system:conf/url",
"DATA": "/yolo-system:conf/url",
"DATA_PATTERN": "/yolo-system:conf/url[host='%s'][proto='%s']",
}

def setUp(self):
self.ctx = Context(YANG_DIR)
self.ctx.load_module("yolo-system")
self.list = next(self.ctx.find_path(self.SCHEMA_PATH))
self.list = next(self.ctx.find_path(self.PATH["LOG"]))

def tearDown(self):
self.list = None
Expand All @@ -300,9 +303,11 @@ def test_list_attrs(self):
self.assertEqual(self.list.nodetype(), SNode.LIST)
self.assertEqual(self.list.keyword(), "list")

self.assertEqual(self.list.schema_path(), self.SCHEMA_PATH)
self.assertEqual(self.list.schema_path(), self.PATH["LOG"])

self.assertEqual(self.list.data_path(), self.DATA_PATH)
self.assertEqual(self.list.schema_path(SNode.PATH_DATA), self.PATH["DATA"])

self.assertEqual(self.list.data_path(), self.PATH["DATA_PATTERN"])
self.assertFalse(self.list.ordered())

def test_list_keys(self):
Expand Down

0 comments on commit 097412c

Please sign in to comment.