@@ -245,7 +245,7 @@ def _get_module_tree(self, module_name, format):
245245 try :
246246 module = self .ctx .get_module (str (module_name ))
247247 except Exception as e :
248- self .sysLog (msg = "Cound not get module: " + str (module_name ), debug = syslog .LOG_ERR , doPrint = True )
248+ self .sysLog (msg = "Could not get module: " + str (module_name ), debug = syslog .LOG_ERR , doPrint = True )
249249 self .fail (e )
250250 else :
251251 if (module is not None ):
@@ -380,7 +380,7 @@ def _find_schema_node(self, schema_xpath):
380380 return None
381381 else :
382382 for schema_node in schema_set .schema ():
383- if schema_xapth == schema_node .path ():
383+ if schema_xpath == schema_node .path ():
384384 return schema_node
385385 return None
386386 """
@@ -533,7 +533,7 @@ def find_schema_must_count(self, schema_xpath, match_ancestors: bool=False):
533533 try :
534534 schema_node = self ._find_schema_node (schema_xpath )
535535 except Exception as e :
536- self .sysLog (msg = "Cound not find the schema node from xpath: " + str (schema_xpath ), debug = syslog .LOG_ERR , doPrint = True )
536+ self .sysLog (msg = "Could not find the schema node from xpath: " + str (schema_xpath ), debug = syslog .LOG_ERR , doPrint = True )
537537 self .fail (e )
538538 return 0
539539
@@ -598,10 +598,28 @@ def find_schema_dependencies(self, schema_xpath, match_ancestors: bool=False):
598598 return result
599599
600600 ref_list = []
601+ if schema_xpath is None or len (schema_xpath ) == 0 or schema_xpath == "/" :
602+ if not match_ancestors :
603+ return ref_list
604+
605+ # Iterate across all modules, can't use "/"
606+ for module in self .ctx .get_module_iter ():
607+ if module .data () is None :
608+ continue
609+
610+ module_list = []
611+ try :
612+ module_list = self .find_schema_dependencies (module .data ().path (), match_ancestors = match_ancestors )
613+ except Exception as e :
614+ self .sysLog (msg = f"Exception while finding schema dependencies for module { module .name ()} : { str (e )} " , debug = syslog .LOG_ERR , doPrint = True )
615+
616+ ref_list .extend (module_list )
617+ return ref_list
618+
601619 try :
602620 schema_node = self ._find_schema_node (schema_xpath )
603621 except Exception as e :
604- self .sysLog (msg = "Cound not find the schema node from xpath: " + str (schema_xpath ), debug = syslog .LOG_ERR , doPrint = True )
622+ self .sysLog (msg = f"Could not find the schema node from xpath: { str (schema_xpath )} : { str ( e ) } " , debug = syslog .LOG_ERR , doPrint = True )
605623 self .fail (e )
606624 return ref_list
607625
@@ -648,36 +666,80 @@ def __find_schema_dependencies_only(self, schema_node):
648666 return ref_list
649667
650668 """
651- find_data_dependencies(): find the data dependencies from data xpath
652- input: data_xpath - xpath of data node. (Public)
653- returns: - list of xpath
654- - Exception if error
669+ find_data_dependencies(): find the data dependencies from data xpath (Public)
670+ input: data_xpath - xpath to search. If it references an exact data node
671+ only the references to that data node will be returned.
672+ If a path contains multiple data nodes, then all references
673+ to all child nodes will be returned. If set to None (or "" or "/"),
674+ will return all references, globally.
655675 """
656676 def find_data_dependencies (self , data_xpath ):
657677 ref_list = []
658- node = self .root
659- try :
660- data_node = self ._find_data_node (data_xpath )
661- except Exception as e :
662- self .sysLog (msg = "find_data_dependencies(): Failed to find data node from xpath: {}" .format (data_xapth ), debug = syslog .LOG_ERR , doPrint = True )
663- return ref_list
678+ required_value = None
679+ base_dnode = None
680+ search_xpath = None
681+
682+ if data_xpath is None or len (data_xpath ) == 0 or data_xpath == "/" :
683+ data_xpath = None
684+ search_xpath = "/"
685+
686+ if data_xpath is not None :
687+ dnode_list = []
688+ try :
689+ dnode_list = list (self .root .find_path (data_xpath ).data ())
690+ except Exception as e :
691+ # We don't care the reason for the failure, this is caught in
692+ # the next statement.
693+ pass
694+
695+ if len (dnode_list ) == 0 :
696+ self .sysLog (msg = "find_data_dependencies(): Failed to find data node from xpath: {}" .format (data_xpath ), debug = syslog .LOG_ERR , doPrint = True )
697+ return ref_list
698+
699+ base_dnode = dnode_list [0 ]
700+ if base_dnode .schema () is None :
701+ return ref_list
702+
703+ search_xpath = base_dnode .schema ().path ()
704+
705+ # If exactly 1 node and it's a data node, we need to match the value.
706+ if len (dnode_list ) == 1 :
707+ try :
708+ required_value = self ._find_data_node_value (data_xpath )
709+ except Exception as e :
710+ # Might not be a data node, ignore
711+ pass
712+
713+ # Get a list of all schema leafrefs pointing to this node (or these data nodes).
714+ lreflist = []
664715
665716 try :
666- value = str (self ._find_data_node_value (data_xpath ))
667-
668- backlinks = self .find_schema_dependencies (data_node .schema ().path (), False )
669- if backlinks is not None and len (backlinks ) > 0 :
670- for link in backlinks :
671- node_set = node .find_path (link )
672- for data_set in node_set .data ():
673- data_set .schema ()
674- casted = data_set .subtype ()
675- if value == casted .value_str ():
676- ref_list .append (data_set .path ())
717+ match_ancestors = True
718+ if required_value is not None :
719+ match_ancestors = False
720+
721+ lreflist = self .find_schema_dependencies (search_xpath , match_ancestors = match_ancestors )
722+ if lreflist is None :
723+ raise Exception ("no schema backlinks found" )
677724 except Exception as e :
678- self .sysLog (msg = 'Failed to find node or dependencies for {}' .format (data_xpath ), debug = syslog .LOG_ERR , doPrint = True )
679- raise SonicYangException ("Failed to find node or dependencies for \
680- {}\n {}" .format (data_xpath , str (e )))
725+ self .sysLog (msg = 'Failed to find node or dependencies for {}: {}' .format (data_xpath , str (e )), debug = syslog .LOG_ERR , doPrint = True )
726+ lreflist = []
727+ # Exception not expected by existing tests if backlinks not found, so don't raise.
728+ # raise SonicYangException("Failed to find node or dependencies for {}\n{}".format(data_xpath, str(e)))
729+
730+ # For all found data nodes, emit the path to the data node. If we need to
731+ # restrict to a value, do so.
732+ for lref in lreflist :
733+ try :
734+ data_set = self .root .find_path (lref ).data ()
735+ for dnode in data_set :
736+ if required_value is None or (
737+ dnode .subtype () is not None and dnode .subtype ().value_str () == required_value
738+ ):
739+ ref_list .append (dnode .path ())
740+ except Exception as e :
741+ # Possible no data paths matched, ignore
742+ pass
681743
682744 return ref_list
683745
0 commit comments