@@ -1522,21 +1522,35 @@ def new(context: "libyang.Context", cdata) -> "SNode":
15221522# -------------------------------------------------------------------------------------
15231523@SNode .register (SNode .LEAF )
15241524class SLeaf (SNode ):
1525- __slots__ = ("cdata_leaf" , "cdata_leaf_parsed" )
1525+ __slots__ = ("cdata_leaf" , "cdata_leaf_parsed" , "cdata_default_realtype" )
15261526
15271527 def __init__ (self , context : "libyang.Context" , cdata ):
15281528 super ().__init__ (context , cdata )
15291529 self .cdata_leaf = ffi .cast ("struct lysc_node_leaf *" , cdata )
15301530 self .cdata_leaf_parsed = ffi .cast ("struct lysp_node_leaf *" , self .cdata_parsed )
1531+ self .cdata_default_realtype = None
15311532
15321533 def default (self ) -> Union [None , bool , int , str , float ]:
1533- if not self .cdata_leaf .dflt :
1534+ if not self .cdata_leaf .dflt . str :
15341535 return None
1535- val = lib .lyd_value_get_canonical (self .context .cdata , self .cdata_leaf .dflt )
1536- if not val :
1537- return None
1538- val = c2str (val )
1539- val_type = Type (self .context , self .cdata_leaf .dflt .realtype , None )
1536+
1537+ if self .cdata_default_realtype is None :
1538+ # calculate real type of default value just once
1539+ val_type_cdata = ffi .new ("struct lysc_type **" , ffi .NULL )
1540+ ret = lib .lyd_value_validate_dflt (
1541+ self .cdata ,
1542+ self .cdata_leaf .dflt .str ,
1543+ self .cdata_leaf .dflt .prefixes ,
1544+ ffi .NULL ,
1545+ val_type_cdata ,
1546+ ffi .NULL ,
1547+ )
1548+ if ret != lib .LY_SUCCESS :
1549+ raise self .context .error ("Unable to get real type of default value" )
1550+ self .cdata_default_realtype = Type (self .context , val_type_cdata [0 ], None )
1551+
1552+ val = c2str (self .cdata_leaf .dflt .str )
1553+ val_type = self .cdata_default_realtype
15401554 if val_type .base () == Type .BOOL :
15411555 return val == "true"
15421556 if val_type .base () in Type .NUM_TYPES :
@@ -1563,14 +1577,15 @@ def __str__(self):
15631577# -------------------------------------------------------------------------------------
15641578@SNode .register (SNode .LEAFLIST )
15651579class SLeafList (SNode ):
1566- __slots__ = ("cdata_leaflist" , "cdata_leaflist_parsed" )
1580+ __slots__ = ("cdata_leaflist" , "cdata_leaflist_parsed" , "cdata_default_realtypes" )
15671581
15681582 def __init__ (self , context : "libyang.Context" , cdata ):
15691583 super ().__init__ (context , cdata )
15701584 self .cdata_leaflist = ffi .cast ("struct lysc_node_leaflist *" , cdata )
15711585 self .cdata_leaflist_parsed = ffi .cast (
15721586 "struct lysp_node_leaflist *" , self .cdata_parsed
15731587 )
1588+ self .cdata_default_realtypes = None
15741589
15751590 def ordered (self ) -> bool :
15761591 return bool (self .cdata_parsed .flags & lib .LYS_ORDBY_USER )
@@ -1586,12 +1601,37 @@ def type(self) -> Type:
15861601 def defaults (self ) -> Iterator [Union [None , bool , int , str , float ]]:
15871602 if self .cdata_leaflist .dflts == ffi .NULL :
15881603 return
1589- for dflt in ly_array_iter (self .cdata_leaflist .dflts ):
1590- val = lib .lyd_value_get_canonical (self .context .cdata , dflt )
1591- if not val :
1604+
1605+ if self .cdata_default_realtypes is None :
1606+ # calculate real types of default values just once
1607+ val_type_cdata = ffi .new ("struct lysc_type **" , ffi .NULL )
1608+ self .cdata_default_realtypes = []
1609+ for dflt in ly_array_iter (self .cdata_leaflist .dflts ):
1610+ if not dflt .str :
1611+ self .cdata_default_realtypes .append (None )
1612+ continue
1613+ val_type_cdata [0 ] = ffi .NULL
1614+ ret = lib .lyd_value_validate_dflt (
1615+ self .cdata ,
1616+ dflt .str ,
1617+ dflt .prefixes ,
1618+ ffi .NULL ,
1619+ val_type_cdata ,
1620+ ffi .NULL ,
1621+ )
1622+ if ret != lib .LY_SUCCESS :
1623+ raise self .context .error ("Unable to get real type of default value" )
1624+ self .cdata_default_realtypes .append (
1625+ Type (self .context , val_type_cdata [0 ], None )
1626+ )
1627+
1628+ for dflt , val_type in zip (
1629+ ly_array_iter (self .cdata_leaflist .dflts ), self .cdata_default_realtypes
1630+ ):
1631+ if not dflt .str :
15921632 yield None
1593- val = c2str ( val )
1594- val_type = Type ( self . context , dflt .realtype , None )
1633+ continue
1634+ val = c2str ( dflt .str )
15951635 if val_type .base () == Type .BOOL :
15961636 yield val == "true"
15971637 elif val_type .base () in Type .NUM_TYPES :
0 commit comments