2
2
# Copyright (c) 2021 RACOM s.r.o.
3
3
# SPDX-License-Identifier: MIT
4
4
5
+ import json
5
6
import logging
6
7
from typing import IO , Any , Dict , Iterator , Optional , Tuple , Union
7
8
8
9
from _libyang import ffi , lib
9
10
from .keyed_list import KeyedList
10
11
from .schema import (
11
12
Module ,
13
+ SAnydata ,
12
14
SContainer ,
13
15
SLeaf ,
14
16
SLeafList ,
@@ -107,6 +109,21 @@ def newval_flags(
107
109
return flags
108
110
109
111
112
+ # -------------------------------------------------------------------------------------
113
+ def anydata_format (fmt_string : str ) -> int :
114
+ if fmt_string == "datatree" :
115
+ return lib .LYD_ANYDATA_DATATREE
116
+ if fmt_string == "string" :
117
+ return lib .LYD_ANYDATA_STRING
118
+ if fmt_string == "xml" :
119
+ return lib .LYD_ANYDATA_XML
120
+ if fmt_string == "json" :
121
+ return lib .LYD_ANYDATA_JSON
122
+ if fmt_string == "lyb" :
123
+ return lib .LYD_ANYDATA_LYB
124
+ raise ValueError ("unknown anydata format: %r" % fmt_string )
125
+
126
+
110
127
# -------------------------------------------------------------------------------------
111
128
def parser_flags (
112
129
lyb_mod_update : bool = False ,
@@ -1199,6 +1216,8 @@ def dict_to_dnode(
1199
1216
rpcreply : bool = False ,
1200
1217
notification : bool = False ,
1201
1218
store_only : bool = False ,
1219
+ types : Optional [Tuple [int , ...]] = None ,
1220
+ anydata_fmt : str = "json" ,
1202
1221
) -> Optional [DNode ]:
1203
1222
"""
1204
1223
Convert a python dictionary to a DNode object given a YANG module object. The return
@@ -1308,6 +1327,34 @@ def _create_list(_parent, module, name, key_values, in_rpc_output=False):
1308
1327
created .append (n [0 ])
1309
1328
return n [0 ]
1310
1329
1330
+ def _create_anydata (_parent , module , name , value , in_rpc_output = False ):
1331
+ if value is not None :
1332
+ if isinstance (value , dict ) and anydata_fmt == "json" :
1333
+ value = json .dumps (value )
1334
+ elif not isinstance (value , str ):
1335
+ value = str (value )
1336
+
1337
+ n = ffi .new ("struct lyd_node **" )
1338
+ flags = newval_flags (rpc_output = in_rpc_output , store_only = store_only )
1339
+ ret = lib .lyd_new_any (
1340
+ _parent ,
1341
+ module .cdata ,
1342
+ str2c (name ),
1343
+ str2c (value ),
1344
+ anydata_format (anydata_fmt ),
1345
+ flags ,
1346
+ n ,
1347
+ )
1348
+ if ret != lib .LY_SUCCESS :
1349
+ if _parent :
1350
+ parent_path = repr (DNode .new (module .context , _parent ).path ())
1351
+ else :
1352
+ parent_path = "module %r" % module .name ()
1353
+ raise module .context .error (
1354
+ "failed to create leaf %r as a child of %s" , name , parent_path
1355
+ )
1356
+ created .append (n [0 ])
1357
+
1311
1358
schema_cache = {}
1312
1359
1313
1360
def _find_schema (schema_parent , name , prefix ):
@@ -1324,7 +1371,7 @@ def _find_schema(schema_parent, name, prefix):
1324
1371
if schema_parent is None :
1325
1372
# there may not be any input or any output node in the rpc
1326
1373
return None , None
1327
- for s in schema_parent :
1374
+ for s in schema_parent . children ( types = types ) :
1328
1375
if s .name () != name :
1329
1376
continue
1330
1377
mod = s .module ()
@@ -1424,6 +1471,9 @@ def _to_dnode(_dic, _schema, _parent=ffi.NULL, in_rpc_output=False):
1424
1471
n = _create_container (_parent , module , name , in_rpc_output )
1425
1472
_to_dnode (value , s , n , in_rpc_output )
1426
1473
1474
+ elif isinstance (s , SAnydata ):
1475
+ _create_anydata (_parent , module , name , value , in_rpc_output )
1476
+
1427
1477
result = None
1428
1478
1429
1479
try :
0 commit comments