From 1c6919bdc2cbca37b471ad4389c99b9e1e26d87b Mon Sep 17 00:00:00 2001 From: Stefan Gula Date: Mon, 4 Mar 2024 15:16:44 +0100 Subject: [PATCH] data: fixing broken DLeaf value and print_dict API This patch fixes broken APIs, which were using no longer valid structs and performing validation step instead of just checking the realtype of data Signed-off-by: Stefan Gula --- cffi/cdefs.h | 6 ++++- libyang/data.py | 57 +++++++++++++++++++++++----------------------- tests/test_data.py | 1 + 3 files changed, 34 insertions(+), 30 deletions(-) diff --git a/cffi/cdefs.h b/cffi/cdefs.h index 8165a70..3fd8e7b 100644 --- a/cffi/cdefs.h +++ b/cffi/cdefs.h @@ -900,9 +900,13 @@ struct lyd_value { ...; }; +struct lyd_value_union { + struct lyd_value value; + ...; +}; + const char * lyd_get_value(const struct lyd_node *); struct lyd_node* lyd_child(const struct lyd_node *); -LY_ERR lyd_value_validate(const struct ly_ctx *, const struct lysc_node *, const char *, size_t, const struct lyd_node *, const struct lysc_type **, const char **); LY_ERR lyd_find_path(const struct lyd_node *, const char *, ly_bool, struct lyd_node **); void lyd_free_siblings(struct lyd_node *); struct lyd_node* lyd_first_sibling(const struct lyd_node *); diff --git a/libyang/data.py b/libyang/data.py index 288303d..07281f0 100644 --- a/libyang/data.py +++ b/libyang/data.py @@ -1119,38 +1119,37 @@ def cdata_leaf_value(cdata, context: "libyang.Context" = None) -> Any: return None val = c2str(val) - term_node = ffi.cast("struct lyd_node_term *", cdata) - val_type = ffi.new("const struct lysc_type **", ffi.NULL) - - # get real value type - ctx = context.cdata if context else ffi.NULL - ret = lib.lyd_value_validate( - ctx, - term_node.schema, - str2c(val), - len(val), - ffi.NULL, - val_type, - ffi.NULL, - ) - if ret in (lib.LY_SUCCESS, lib.LY_EINCOMPLETE): - val_type = val_type[0].basetype - if val_type in Type.STR_TYPES: - return val - if val_type in Type.NUM_TYPES: - return int(val) - if val_type == Type.BOOL: - return val == "true" - if val_type == Type.DEC64: - return float(val) - if val_type == Type.LEAFREF: - return DLeaf.cdata_leaf_value(cdata.value.leafref, context) - if val_type == Type.EMPTY: - return None + if cdata.schema == ffi.NULL: + # opaq node return val - raise TypeError("value type validation error") + if cdata.schema.nodetype == SNode.LEAF: + snode = ffi.cast("struct lysc_node_leaf *", cdata.schema) + elif cdata.schema.nodetype == SNode.LEAFLIST: + snode = ffi.cast("struct lysc_node_leaflist *", cdata.schema) + + # find the real type used + cdata = ffi.cast("struct lyd_node_term *", cdata) + curr_type = snode.type + while curr_type.basetype in (Type.LEAFREF, Type.UNION): + if curr_type.basetype == Type.LEAFREF: + curr_type = cdata.value.realtype + if curr_type.basetype == Type.UNION: + curr_type = cdata.value.subvalue.value.realtype + + val_type = curr_type.basetype + if val_type in Type.STR_TYPES: + return val + if val_type in Type.NUM_TYPES: + return int(val) + if val_type == Type.BOOL: + return val == "true" + if val_type == Type.DEC64: + return float(val) + if val_type == Type.EMPTY: + return None + return val # ------------------------------------------------------------------------------------- diff --git a/tests/test_data.py b/tests/test_data.py index 790b5cd..1728042 100644 --- a/tests/test_data.py +++ b/tests/test_data.py @@ -1110,4 +1110,5 @@ def test_dnode_builtin_plugins_only(self): module = self.ctx.load_module("yolo-nodetypes") dnode = dict_to_dnode(MAIN, module, None, validate=False, store_only=True) self.assertIsInstance(dnode, DLeaf) + self.assertEqual(dnode.value(), "test") dnode.free()