@@ -172,6 +172,14 @@ def notifications(self) -> Iterator["PNotif"]:
172172 for n in ly_list_iter (self .cdata .parsed .notifs ):
173173 yield PNotif (self .context , n , self )
174174
175+ def identities (self ) -> Iterator ["Identity" ]:
176+ for i in ly_array_iter (self .cdata .identities ):
177+ yield Identity (self .context , i )
178+
179+ def parsed_identities (self ) -> Iterator ["PIdentity" ]:
180+ for i in ly_array_iter (self .cdata .parsed .identities ):
181+ yield PIdentity (self .context , i , self )
182+
175183 def __str__ (self ) -> str :
176184 return self .name ()
177185
@@ -415,13 +423,16 @@ def name(self) -> str:
415423 def module (self ) -> Module :
416424 return self ._module_from_parsed ()
417425
418- def parent_node (self ) -> Optional ["PNode" ]:
419- if not bool (self .cdata .parent_stmt & lib .LY_STMT_NODE_MASK ):
420- return None
421- try :
422- return PNode .new (self .context , self .cdata .parent , self .module_parent )
423- except LibyangError :
424- return None
426+ def parent_node (self ) -> Optional [Union ["PNode" , "PIdentity" ]]:
427+ if self .cdata .parent_stmt == lib .LY_STMT_IDENTITY :
428+ cdata = ffi .cast ("struct lysp_ident *" , self .cdata .parent )
429+ return PIdentity (self .context , cdata , self .module_parent )
430+ if bool (self .cdata .parent_stmt & lib .LY_STMT_NODE_MASK ):
431+ try :
432+ return PNode .new (self .context , self .cdata .parent , self .module_parent )
433+ except LibyangError :
434+ return None
435+ return None
425436
426437
427438# -------------------------------------------------------------------------------------
@@ -440,13 +451,16 @@ def module(self) -> Module:
440451 raise self .context .error ("cannot get module" )
441452 return Module (self .context , self .cdata_def .module )
442453
443- def parent_node (self ) -> Optional ["SNode" ]:
444- if not bool (self .cdata .parent_stmt & lib .LY_STMT_NODE_MASK ):
445- return None
446- try :
447- return SNode .new (self .context , self .cdata .parent )
448- except LibyangError :
449- return None
454+ def parent_node (self ) -> Optional [Union ["SNode" , "Identity" ]]:
455+ if self .cdata .parent_stmt == lib .LY_STMT_IDENTITY :
456+ cdata = ffi .cast ("struct lysc_ident *" , self .cdata .parent )
457+ return Identity (self .context , cdata )
458+ if bool (self .cdata .parent_stmt & lib .LY_STMT_NODE_MASK ):
459+ try :
460+ return SNode .new (self .context , self .cdata .parent )
461+ except LibyangError :
462+ return None
463+ return None
450464
451465
452466# -------------------------------------------------------------------------------------
@@ -624,6 +638,13 @@ def leafref_path(self) -> Optional["str"]:
624638 lr = ffi .cast ("struct lysc_type_leafref *" , self .cdata )
625639 return c2str (lib .lyxp_get_expr (lr .path ))
626640
641+ def identity_bases (self ) -> Iterator ["Identity" ]:
642+ if self .cdata .basetype != lib .LY_TYPE_IDENT :
643+ return
644+ ident = ffi .cast ("struct lysc_type_identityref *" , self .cdata )
645+ for b in ly_array_iter (ident .bases ):
646+ yield Identity (self .context , b )
647+
627648 def typedef (self ) -> "Typedef" :
628649 if ":" in self .name ():
629650 module_prefix , type_name = self .name ().split (":" )
@@ -870,6 +891,68 @@ def __str__(self):
870891 return self .name ()
871892
872893
894+ # -------------------------------------------------------------------------------------
895+ class Identity :
896+ __slots__ = ("context" , "cdata" )
897+
898+ def __init__ (self , context : "libyang.Context" , cdata ):
899+ self .context = context
900+ self .cdata = cdata # C type: "struct lysc_ident *"
901+
902+ def name (self ) -> str :
903+ return c2str (self .cdata .name )
904+
905+ def description (self ) -> Optional [str ]:
906+ return c2str (self .cdata .dsc )
907+
908+ def reference (self ) -> Optional [str ]:
909+ return c2str (self .cdata .ref )
910+
911+ def module (self ) -> Module :
912+ return Module (self .context , self .cdata .module )
913+
914+ def derived (self ) -> Iterator ["Identity" ]:
915+ for i in ly_array_iter (self .cdata .derived ):
916+ yield Identity (self .context , i )
917+
918+ def extensions (self ) -> Iterator [ExtensionCompiled ]:
919+ for ext in ly_array_iter (self .cdata .exts ):
920+ yield ExtensionCompiled (self .context , ext )
921+
922+ def get_extension (
923+ self , name : str , prefix : Optional [str ] = None , arg_value : Optional [str ] = None
924+ ) -> Optional [ExtensionCompiled ]:
925+ for ext in self .extensions ():
926+ if ext .name () != name :
927+ continue
928+ if prefix is not None and ext .module ().name () != prefix :
929+ continue
930+ if arg_value is not None and ext .argument () != arg_value :
931+ continue
932+ return ext
933+ return None
934+
935+ def deprecated (self ) -> bool :
936+ return bool (self .cdata .flags & lib .LYS_STATUS_DEPRC )
937+
938+ def obsolete (self ) -> bool :
939+ return bool (self .cdata .flags & lib .LYS_STATUS_OBSLT )
940+
941+ def status (self ) -> str :
942+ if self .cdata .flags & lib .LYS_STATUS_OBSLT :
943+ return "obsolete"
944+ if self .cdata .flags & lib .LYS_STATUS_DEPRC :
945+ return "deprecated"
946+ return "current"
947+
948+ def __repr__ (self ):
949+ cls = self .__class__
950+ return "<%s.%s: %s>" % (cls .__module__ , cls .__name__ , str (self ))
951+
952+ def __str__ (self ):
953+ return self .name ()
954+
955+
873956# -------------------------------------------------------------------------------------
874957class Feature :
875958 __slots__ = ("context" , "cdata" , "__dict__" )
@@ -1890,6 +1973,57 @@ def extensions(self) -> Iterator["ExtensionParsed"]:
18901973 yield ExtensionParsed (self .context , ext , self .module )
18911974
18921975
1976+ # -------------------------------------------------------------------------------------
1977+ class PIdentity :
1978+ __slots__ = ("context" , "cdata" , "module" )
1979+
1980+ def __init__ (self , context : "libyang.Context" , cdata , module : Module ) -> None :
1981+ self .context = context
1982+ self .cdata = cdata # C type: "struct lysp_ident *"
1983+ self .module = module
1984+
1985+ def name (self ) -> str :
1986+ return c2str (self .cdata .name )
1987+
1988+ def if_features (self ) -> Iterator [IfFeatureExpr ]:
1989+ for f in ly_array_iter (self .cdata .iffeatures ):
1990+ yield IfFeatureExpr (self .context , f , list (self .module .features ()))
1991+
1992+ def bases (self ) -> Iterator [str ]:
1993+ for b in ly_array_iter (self .cdata .bases ):
1994+ yield c2str (b )
1995+
1996+ def description (self ) -> Optional [str ]:
1997+ return c2str (self .cdata .dsc )
1998+
1999+ def reference (self ) -> Optional [str ]:
2000+ return c2str (self .cdata .ref )
2001+
2002+ def extensions (self ) -> Iterator [ExtensionParsed ]:
2003+ for ext in ly_array_iter (self .cdata .exts ):
2004+ yield ExtensionParsed (self .context , ext , self .module )
2005+
2006+ def deprecated (self ) -> bool :
2007+ return bool (self .cdata .flags & lib .LYS_STATUS_DEPRC )
2008+
2009+ def obsolete (self ) -> bool :
2010+ return bool (self .cdata .flags & lib .LYS_STATUS_OBSLT )
2011+
2012+ def status (self ) -> str :
2013+ if self .cdata .flags & lib .LYS_STATUS_OBSLT :
2014+ return "obsolete"
2015+ if self .cdata .flags & lib .LYS_STATUS_DEPRC :
2016+ return "deprecated"
2017+ return "current"
2018+
2019+ def __repr__ (self ):
2020+ cls = self .__class__
2021+ return "<%s.%s: %s>" % (cls .__module__ , cls .__name__ , str (self ))
2022+
2023+ def __str__ (self ):
2024+ return self .name ()
2025+
2026+
18932027# -------------------------------------------------------------------------------------
18942028class PNode :
18952029 CONTAINER = lib .LYS_CONTAINER
0 commit comments