Skip to content

Commit 8595ac5

Browse files
data: add anydata and anyxml support to print_dict
print_dict() skips anydata and anyxml nodes, so data created by dict_to_dnode() since the previous commit does not show up. Follow the libyang JSON printer: content stored as a tree becomes a dict, a string value stays a string, and an empty node becomes an empty dict. The output can then be given back to dict_to_dnode(). Note that the content is printed as is, so strip_prefixes does not apply inside it. Also, anyxml XML content is parsed into a tree by libyang, so it comes back as a dict and not as the XML string. Signed-off-by: Samuel Gauthier <samuel.gauthier@6wind.com>
1 parent 159117c commit 8595ac5

3 files changed

Lines changed: 40 additions & 0 deletions

File tree

‎cffi/cdefs.h‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1174,6 +1174,7 @@ struct lyd_node_any {
11741174
};
11751175
};
11761176
struct lyd_node *child;
1177+
const char *value;
11771178
...;
11781179
};
11791180

‎libyang/data.py‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -900,6 +900,16 @@ def _init_yang_list(snode):
900900

901901
return KeyedList(key_name=list_keys_cache[snode])
902902

903+
def _any_value(node):
904+
# same as the libyang JSON printer: a tree is an object, a string
905+
# value stays a string, and no content is an empty object
906+
any_node = ffi.cast("struct lyd_node_any *", node)
907+
if any_node.child:
908+
return json.loads(DNode.new(self.context, node).value("json"))
909+
if any_node.value:
910+
return c2str(any_node.value)
911+
return {}
912+
903913
def _to_dict(node, parent_dic):
904914
if not lib.lyd_node_should_print(node, flags):
905915
return
@@ -929,6 +939,8 @@ def _to_dict(node, parent_dic):
929939
parent_dic[name].append(DLeaf.cdata_leaf_value(node, self.context))
930940
elif node.schema.nodetype == SNode.LEAF:
931941
parent_dic[name] = DLeaf.cdata_leaf_value(node, self.context)
942+
elif node.schema.nodetype & (SNode.ANYDATA | SNode.ANYXML):
943+
parent_dic[name] = _any_value(node)
932944

933945
dic = {}
934946
dnode = self

‎tests/test_data.py‎

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1209,3 +1209,30 @@ def test_dict_to_dnode_anydata_bad_type(self):
12091209
module = self.ctx.load_module("yolo-nodetypes")
12101210
with self.assertRaises(TypeError):
12111211
dict_to_dnode({"yolo-nodetypes:any1": 42}, module, validate=False)
1212+
1213+
def test_print_dict_anydata(self):
1214+
module = self.ctx.load_module("yolo-nodetypes")
1215+
for value in ({"key1": "val1", "l": [1, 2], "c": {"x": True}}, {}):
1216+
dic = {"any1": value}
1217+
dnode = dict_to_dnode(
1218+
{"yolo-nodetypes:any1": value}, module, validate=False
1219+
)
1220+
try:
1221+
self.assertEqual(dnode.print_dict(), dic)
1222+
finally:
1223+
dnode.free()
1224+
1225+
def test_print_dict_anyxml(self):
1226+
module = self.ctx.get_module("yolo-system")
1227+
for value, expected in (
1228+
("<p>text</p>", {"p": "text"}),
1229+
("plain text", "plain text"),
1230+
):
1231+
dic = {"format-disk": {"html-info": value}}
1232+
dnode = dict_to_dnode(dic, module, rpc=True)
1233+
try:
1234+
self.assertEqual(
1235+
dnode.print_dict(), {"format-disk": {"html-info": expected}}
1236+
)
1237+
finally:
1238+
dnode.free()

0 commit comments

Comments
 (0)