Skip to content

Commit 5330a3f

Browse files
stewegsamuel-gauthier
authored andcommitted
data: introduce store_only flags
This patch introduces store_only flag, which allows user to only store value without performing any sort of additional type checks as length, range, pattern, etc. Closes: #107 Signed-off-by: Stefan Gula <[email protected]> Signed-off-by: Samuel Gauthier <[email protected]>
1 parent 0c43437 commit 5330a3f

File tree

5 files changed

+42
-7
lines changed

5 files changed

+42
-7
lines changed

cffi/cdefs.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,7 @@ struct lyd_node {
264264
LY_ERR lys_set_implemented(struct lys_module *, const char **);
265265

266266
#define LYD_NEW_VAL_OUTPUT ...
267+
#define LYD_NEW_VAL_STORE_ONLY ...
267268
#define LYD_NEW_VAL_BIN ...
268269
#define LYD_NEW_VAL_CANON ...
269270
#define LYD_NEW_META_CLEAR_DFLT ...
@@ -308,6 +309,7 @@ LY_ERR lyd_print_all(struct ly_out *, const struct lyd_node *, LYD_FORMAT, uint3
308309

309310
#define LYD_PARSE_LYB_MOD_UPDATE ...
310311
#define LYD_PARSE_NO_STATE ...
312+
#define LYD_PARSE_STORE_ONLY ...
311313
#define LYD_PARSE_ONLY ...
312314
#define LYD_PARSE_OPAQ ...
313315
#define LYD_PARSE_OPTS_MASK ...

libyang/context.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -409,6 +409,7 @@ def create_data_path(
409409
parent: Optional[DNode] = None,
410410
value: Any = None,
411411
update: bool = True,
412+
store_only: bool = False,
412413
rpc_output: bool = False,
413414
force_return_value: bool = True,
414415
) -> Optional[DNode]:
@@ -419,7 +420,9 @@ def create_data_path(
419420
value = str(value).lower()
420421
elif not isinstance(value, str):
421422
value = str(value)
422-
flags = newval_flags(update=update, rpc_output=rpc_output)
423+
flags = newval_flags(
424+
update=update, store_only=store_only, rpc_output=rpc_output
425+
)
423426
dnode = ffi.new("struct lyd_node **")
424427
ret = lib.lyd_new_path(
425428
parent.cdata if parent else ffi.NULL,
@@ -513,6 +516,7 @@ def parse_data(
513516
strict: bool = False,
514517
validate_present: bool = False,
515518
validate_multi_error: bool = False,
519+
store_only: bool = False,
516520
) -> Optional[DNode]:
517521
if self.cdata is None:
518522
raise RuntimeError("context already destroyed")
@@ -523,6 +527,7 @@ def parse_data(
523527
opaq=opaq,
524528
ordered=ordered,
525529
strict=strict,
530+
store_only=store_only,
526531
)
527532
validation_flgs = validation_flags(
528533
no_state=no_state,
@@ -580,6 +585,7 @@ def parse_data_mem(
580585
strict: bool = False,
581586
validate_present: bool = False,
582587
validate_multi_error: bool = False,
588+
store_only: bool = False,
583589
) -> Optional[DNode]:
584590
return self.parse_data(
585591
fmt,
@@ -594,6 +600,7 @@ def parse_data_mem(
594600
strict=strict,
595601
validate_present=validate_present,
596602
validate_multi_error=validate_multi_error,
603+
store_only=store_only,
597604
)
598605

599606
def parse_data_file(
@@ -609,6 +616,7 @@ def parse_data_file(
609616
strict: bool = False,
610617
validate_present: bool = False,
611618
validate_multi_error: bool = False,
619+
store_only: bool = False,
612620
) -> Optional[DNode]:
613621
return self.parse_data(
614622
fmt,
@@ -623,6 +631,7 @@ def parse_data_file(
623631
strict=strict,
624632
validate_present=validate_present,
625633
validate_multi_error=validate_multi_error,
634+
store_only=store_only,
626635
)
627636

628637
def __iter__(self) -> Iterator[Module]:

libyang/data.py

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ def data_format(fmt_string: str) -> int:
7979
# -------------------------------------------------------------------------------------
8080
def newval_flags(
8181
rpc_output: bool = False,
82+
store_only: bool = False,
8283
bin_value: bool = False,
8384
canon_value: bool = False,
8485
meta_clear_default: bool = False,
@@ -91,6 +92,8 @@ def newval_flags(
9192
flags = 0
9293
if rpc_output:
9394
flags |= lib.LYD_NEW_VAL_OUTPUT
95+
if store_only:
96+
flags |= lib.LYD_NEW_VAL_STORE_ONLY
9497
if bin_value:
9598
flags |= lib.LYD_NEW_VAL_BIN
9699
if canon_value:
@@ -112,6 +115,7 @@ def parser_flags(
112115
opaq: bool = False,
113116
ordered: bool = False,
114117
strict: bool = False,
118+
store_only: bool = False,
115119
) -> int:
116120
flags = 0
117121
if lyb_mod_update:
@@ -126,6 +130,8 @@ def parser_flags(
126130
flags |= lib.LYD_PARSE_ORDERED
127131
if strict:
128132
flags |= lib.LYD_PARSE_STRICT
133+
if store_only:
134+
flags |= lib.LYD_PARSE_STORE_ONLY
129135
return flags
130136

131137

@@ -314,8 +320,10 @@ def meta_free(self, name):
314320
break
315321
item = item.next
316322

317-
def new_meta(self, name: str, value: str, clear_dflt: bool = False):
318-
flags = newval_flags(meta_clear_default=clear_dflt)
323+
def new_meta(
324+
self, name: str, value: str, clear_dflt: bool = False, store_only: bool = False
325+
):
326+
flags = newval_flags(meta_clear_default=clear_dflt, store_only=store_only)
319327
ret = lib.lyd_new_meta(
320328
ffi.NULL,
321329
self.cdata,
@@ -391,13 +399,15 @@ def new_path(
391399
opt_opaq: bool = False,
392400
opt_bin_value: bool = False,
393401
opt_canon_value: bool = False,
402+
opt_store_only: bool = False,
394403
):
395404
flags = newval_flags(
396405
update=opt_update,
397406
rpc_output=opt_output,
398407
opaq=opt_opaq,
399408
bin_value=opt_bin_value,
400409
canon_value=opt_canon_value,
410+
store_only=opt_store_only,
401411
)
402412
ret = lib.lyd_new_path(
403413
self.cdata, ffi.NULL, str2c(path), str2c(value), flags, ffi.NULL
@@ -1062,9 +1072,10 @@ def create_path(
10621072
path: str,
10631073
value: Any = None,
10641074
rpc_output: bool = False,
1075+
store_only: bool = False,
10651076
) -> Optional[DNode]:
10661077
return self.context.create_data_path(
1067-
path, parent=self, value=value, rpc_output=rpc_output
1078+
path, parent=self, value=value, rpc_output=rpc_output, store_only=store_only
10681079
)
10691080

10701081
def children(self, no_keys=False) -> Iterator[DNode]:
@@ -1188,6 +1199,7 @@ def dict_to_dnode(
11881199
rpc: bool = False,
11891200
rpcreply: bool = False,
11901201
notification: bool = False,
1202+
store_only: bool = False,
11911203
) -> Optional[DNode]:
11921204
"""
11931205
Convert a python dictionary to a DNode object given a YANG module object. The return
@@ -1214,6 +1226,8 @@ def dict_to_dnode(
12141226
Data represents RPC or action output parameters.
12151227
:arg notification:
12161228
Data represents notification parameters.
1229+
:arg store_only:
1230+
Data are being stored regardless of type validation (length, range, pattern, etc.)
12171231
"""
12181232
if not dic:
12191233
return None
@@ -1235,7 +1249,7 @@ def _create_leaf(_parent, module, name, value, in_rpc_output=False):
12351249
value = str(value)
12361250

12371251
n = ffi.new("struct lyd_node **")
1238-
flags = newval_flags(rpc_output=in_rpc_output)
1252+
flags = newval_flags(rpc_output=in_rpc_output, store_only=store_only)
12391253
ret = lib.lyd_new_term(
12401254
_parent,
12411255
module.cdata,
@@ -1273,7 +1287,7 @@ def _create_container(_parent, module, name, in_rpc_output=False):
12731287

12741288
def _create_list(_parent, module, name, key_values, in_rpc_output=False):
12751289
n = ffi.new("struct lyd_node **")
1276-
flags = newval_flags(rpc_output=in_rpc_output)
1290+
flags = newval_flags(rpc_output=in_rpc_output, store_only=store_only)
12771291
ret = lib.lyd_new_list(
12781292
_parent,
12791293
module.cdata,

tests/test_data.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1092,3 +1092,11 @@ def test_dnode_leafref_linking(self):
10921092
self.assertIsInstance(dnode4, DLeaf)
10931093
self.assertEqual(dnode4.cdata, dnode2.cdata)
10941094
dnode1.free()
1095+
1096+
def test_dnode_store_only(self):
1097+
MAIN = {"yolo-nodetypes:test1": 50}
1098+
module = self.ctx.load_module("yolo-nodetypes")
1099+
dnode = dict_to_dnode(MAIN, module, None, validate=False, store_only=True)
1100+
self.assertIsInstance(dnode, DLeaf)
1101+
self.assertEqual(dnode.value(), 50)
1102+
dnode.free()

tests/yang/yolo/yolo-nodetypes.yang

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,9 @@ module yolo-nodetypes {
9191
}
9292

9393
leaf test1 {
94-
type uint8;
94+
type uint8 {
95+
range "2..20";
96+
}
9597
}
9698

9799
grouping grp1 {

0 commit comments

Comments
 (0)