From 6e94f1bd744af16bfc4dd12218e82f98cd356f08 Mon Sep 17 00:00:00 2001 From: Stefan Gula Date: Fri, 26 Jan 2024 11:13:49 +0100 Subject: [PATCH] schema: add default function to SChoice class This patches introduces a default function to SChoice class, including unit test. Fixes: #97 Signed-off-by: Stefan Gula Acked-by: Samuel Gauthier --- cffi/cdefs.h | 13 +++++++++++++ libyang/__init__.py | 4 ++++ libyang/schema.py | 11 +++++++++++ tests/test_schema.py | 19 +++++++++++++++++++ tests/yang/yolo/yolo-system.yang | 1 + 5 files changed, 48 insertions(+) diff --git a/cffi/cdefs.h b/cffi/cdefs.h index b9d3b773..304ae55d 100644 --- a/cffi/cdefs.h +++ b/cffi/cdefs.h @@ -1023,6 +1023,19 @@ struct lysc_when { struct lysc_when** lysc_node_when(const struct lysc_node *); +struct lysc_node_case { + struct lysc_node *child; + struct lysc_when **when; + ...; +}; + +struct lysc_node_choice { + struct lysc_node_case *cases; + struct lysc_when **when; + struct lysc_node_case *dflt; + ...; +}; + #define LYD_DEFAULT ... #define LYD_WHEN_TRUE ... #define LYD_NEW ... diff --git a/libyang/__init__.py b/libyang/__init__.py index 5e3854ad..bc79e2f0 100644 --- a/libyang/__init__.py +++ b/libyang/__init__.py @@ -78,6 +78,8 @@ Must, Pattern, Revision, + SCase, + SChoice, SContainer, SLeaf, SLeafList, @@ -156,6 +158,8 @@ "RangeAdded", "RangeRemoved", "Revision", + "SCase", + "SChoice", "SContainer", "SLeaf", "SLeafList", diff --git a/libyang/schema.py b/libyang/schema.py index b257c8f6..d49c39a7 100644 --- a/libyang/schema.py +++ b/libyang/schema.py @@ -1416,6 +1416,12 @@ def children( # ------------------------------------------------------------------------------------- @SNode.register(SNode.CHOICE) class SChoice(SNode): + __slots__ = ("cdata_choice",) + + def __init__(self, context: "libyang.Context", cdata): + super().__init__(context, cdata) + self.cdata_choice = ffi.cast("struct lysc_node_choice *", cdata) + def __iter__(self) -> Iterator[SNode]: return self.children() @@ -1424,6 +1430,11 @@ def children( ) -> Iterator[SNode]: return iter_children(self.context, self.cdata, types=types, with_case=with_case) + def default(self) -> Optional[SNode]: + if self.cdata_choice.dflt == ffi.NULL: + return None + return SNode.new(self.context, self.cdata_choice.dflt) + # ------------------------------------------------------------------------------------- @SNode.register(SNode.CASE) diff --git a/tests/test_schema.py b/tests/test_schema.py index 5b947cd8..64a8e30e 100644 --- a/tests/test_schema.py +++ b/tests/test_schema.py @@ -15,6 +15,8 @@ Must, Pattern, Revision, + SCase, + SChoice, SContainer, SLeaf, SLeafList, @@ -584,3 +586,20 @@ def test_leaf_list_min_max(self): self.assertIsInstance(leaflist2, SLeafList) self.assertEqual(leaflist2.min_elements(), 0) self.assertEqual(leaflist2.max_elements(), None) + + +# ------------------------------------------------------------------------------------- +class ChoiceTest(unittest.TestCase): + def setUp(self): + self.ctx = Context(YANG_DIR) + self.ctx.load_module("yolo-system") + + def tearDown(self): + self.ctx.destroy() + self.ctx = None + + def test_choice_default(self): + conf = next(self.ctx.find_path("/yolo-system:conf")) + choice = next(conf.children((SNode.CHOICE,), with_choice=True)) + self.assertIsInstance(choice, SChoice) + self.assertIsInstance(choice.default(), SCase) diff --git a/tests/yang/yolo/yolo-system.yang b/tests/yang/yolo/yolo-system.yang index 5aa633ad..ef612546 100644 --- a/tests/yang/yolo/yolo-system.yang +++ b/tests/yang/yolo/yolo-system.yang @@ -72,6 +72,7 @@ module yolo-system { type boolean; } } + default red; } list url {