22# Copyright (c) 2021 RACOM s.r.o.
33# SPDX-License-Identifier: MIT
44
5+ import json
56import logging
67from typing import IO , Any , Dict , Iterator , Optional , Tuple , Union
78
89from _libyang import ffi , lib
910from .keyed_list import KeyedList
1011from .schema import (
1112 Module ,
13+ SAnydata ,
1214 SContainer ,
1315 SLeaf ,
1416 SLeafList ,
@@ -104,6 +106,21 @@ def newval_flags(
104106 return flags
105107
106108
109+ # -------------------------------------------------------------------------------------
110+ def anydata_format (fmt_string : str ) -> int :
111+ if fmt_string == "datatree" :
112+ return lib .LYD_ANYDATA_DATATREE
113+ if fmt_string == "string" :
114+ return lib .LYD_ANYDATA_STRING
115+ if fmt_string == "xml" :
116+ return lib .LYD_ANYDATA_XML
117+ if fmt_string == "json" :
118+ return lib .LYD_ANYDATA_JSON
119+ if fmt_string == "lyb" :
120+ return lib .LYD_ANYDATA_LYB
121+ raise ValueError ("unknown anydata format: %r" % fmt_string )
122+
123+
107124# -------------------------------------------------------------------------------------
108125def parser_flags (
109126 lyb_mod_update : bool = False ,
@@ -1147,6 +1164,8 @@ def dict_to_dnode(
11471164 rpc : bool = False ,
11481165 rpcreply : bool = False ,
11491166 notification : bool = False ,
1167+ types : Optional [Tuple [int , ...]] = None ,
1168+ anydata_fmt : str = "json" ,
11501169) -> Optional [DNode ]:
11511170 """
11521171 Convert a python dictionary to a DNode object given a YANG module object. The return
@@ -1254,6 +1273,34 @@ def _create_list(_parent, module, name, key_values, in_rpc_output=False):
12541273 created .append (n [0 ])
12551274 return n [0 ]
12561275
1276+ def _create_anydata (_parent , module , name , value , in_rpc_output = False ):
1277+ if value is not None :
1278+ if isinstance (value , dict ) and anydata_fmt == "json" :
1279+ value = json .dumps (value )
1280+ elif not isinstance (value , str ):
1281+ value = str (value )
1282+
1283+ n = ffi .new ("struct lyd_node **" )
1284+ flags = newval_flags (rpc_output = in_rpc_output , store_only = store_only )
1285+ ret = lib .lyd_new_any (
1286+ _parent ,
1287+ module .cdata ,
1288+ str2c (name ),
1289+ str2c (value ),
1290+ anydata_format (anydata_fmt ),
1291+ flags ,
1292+ n ,
1293+ )
1294+ if ret != lib .LY_SUCCESS :
1295+ if _parent :
1296+ parent_path = repr (DNode .new (module .context , _parent ).path ())
1297+ else :
1298+ parent_path = "module %r" % module .name ()
1299+ raise module .context .error (
1300+ "failed to create leaf %r as a child of %s" , name , parent_path
1301+ )
1302+ created .append (n [0 ])
1303+
12571304 schema_cache = {}
12581305
12591306 def _find_schema (schema_parent , name , prefix ):
@@ -1270,7 +1317,7 @@ def _find_schema(schema_parent, name, prefix):
12701317 if schema_parent is None :
12711318 # there may not be any input or any output node in the rpc
12721319 return None , None
1273- for s in schema_parent :
1320+ for s in schema_parent . children ( types = types ) :
12741321 if s .name () != name :
12751322 continue
12761323 mod = s .module ()
@@ -1370,6 +1417,9 @@ def _to_dnode(_dic, _schema, _parent=ffi.NULL, in_rpc_output=False):
13701417 n = _create_container (_parent , module , name , in_rpc_output )
13711418 _to_dnode (value , s , n , in_rpc_output )
13721419
1420+ elif isinstance (s , SAnydata ):
1421+ _create_anydata (_parent , module , name , value , in_rpc_output )
1422+
13731423 result = None
13741424
13751425 try :
0 commit comments