Skip to content

Commit b78cdce

Browse files
choppsv1rjarry
authored andcommitted
schema: add missing extensions() for access to module level
Currently only have access to the extensions used under schema nodes, need access to extensions used at the module level. Add a test case for the functionality as well. Signed-off-by: Christian Hopps <[email protected]>
1 parent 90dad07 commit b78cdce

File tree

4 files changed

+48
-0
lines changed

4 files changed

+48
-0
lines changed

cffi/cdefs.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -365,6 +365,14 @@ LY_ERR lys_print_module(struct ly_out *, const struct lys_module *, LYS_OUTFORMA
365365
#define LYS_PRINT_NO_SUBSTMT ...
366366
#define LYS_PRINT_SHRINK ...
367367

368+
struct lysc_module {
369+
struct lys_module *mod;
370+
struct lysc_node *data;
371+
struct lysc_node_action *rpcs;
372+
struct lysc_node_notif *notifs;
373+
struct lysc_ext_instance *exts;
374+
};
375+
368376
struct lys_module {
369377
struct ly_ctx *ctx;
370378
const char *name;

libyang/schema.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,29 @@ def parsed_identities(self) -> Iterator["PIdentity"]:
180180
for i in ly_array_iter(self.cdata.parsed.identities):
181181
yield PIdentity(self.context, i, self)
182182

183+
def extensions(self) -> Iterator["ExtensionCompiled"]:
184+
compiled = ffi.cast("struct lysc_module *", self.cdata.compiled)
185+
if compiled == ffi.NULL:
186+
return
187+
exts = ffi.cast("struct lysc_ext_instance *", self.cdata.compiled.exts)
188+
if exts == ffi.NULL:
189+
return
190+
for extension in ly_array_iter(exts):
191+
yield ExtensionCompiled(self.context, extension)
192+
193+
def get_extension(
194+
self, name: str, prefix: Optional[str] = None, arg_value: Optional[str] = None
195+
) -> Optional["ExtensionCompiled"]:
196+
for ext in self.extensions():
197+
if ext.name() != name:
198+
continue
199+
if prefix is not None and ext.module().name() != prefix:
200+
continue
201+
if arg_value is not None and ext.argument() != arg_value:
202+
continue
203+
return ext
204+
return None
205+
183206
def __str__(self) -> str:
184207
return self.name()
185208

tests/test_schema.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,19 @@ def test_mod_revisions(self):
129129
self.assertEqual(revisions[0].date(), "1999-04-01")
130130
self.assertEqual(revisions[1].date(), "1990-04-01")
131131

132+
def test_mod_extensions(self):
133+
assert self.module is not None # pyright doesn't understand assertIsNotNone()
134+
exts = list(self.module.extensions())
135+
self.assertEqual(len(exts), 1)
136+
ext = self.module.get_extension("compile-validation", prefix="omg-extensions")
137+
self.assertEqual(ext.argument(), "module-level")
138+
sub_exts = list(ext.extensions())
139+
self.assertEqual(len(sub_exts), 1)
140+
ext = sub_exts[0]
141+
self.assertEqual(ext.name(), "compile-validation")
142+
self.assertEqual(ext.module().name(), "omg-extensions")
143+
self.assertEqual(ext.argument(), "module-sub-level")
144+
132145

133146
# -------------------------------------------------------------------------------------
134147
class RevisionTest(unittest.TestCase):

tests/yang/yolo/yolo-system.yang

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,10 @@ module yolo-system {
155155
}
156156
}
157157

158+
ext:compile-validation "module-level" {
159+
ext:compile-validation "module-sub-level";
160+
}
161+
158162
container conf {
159163
description
160164
"Configuration.";

0 commit comments

Comments
 (0)