#NEWLINE# def topological_order( self ) : #NEWLINE# #INDENT# 'Generator function that yields the nodes in the graph in\n        topological order.\n\n        Please note that this function does **not** cache the order and\n        recalculates it on each call. If you know the pipeline graph will\n        not change any more and you have to iterate the nodes in order\n        more than once, you might want to cache the results::\n\n            >>> pipeline = Pipeline()\n            >>> ordered = list(pipeline.topological_order())\n\n        :returns: yields nodes in topological order\n        ' #NEWLINE# count = { #NEWLINE# #INDENT# #NEWLINE# #UNINDENT# } #NEWLINE# children = { #NEWLINE# #INDENT# #NEWLINE# #UNINDENT# } #NEWLINE# for node in self . nodes ( ) : #NEWLINE# #INDENT# count [ node ] = 0 #NEWLINE# #UNINDENT# for node in self . nodes ( ) : #NEWLINE# #INDENT# _children = sorted ( node . children ( ) , key = ( lambda j : j . _node_index ) , reverse = True ) #NEWLINE# children [ node ] = _children #NEWLINE# for successor in _children : #NEWLINE# #INDENT# count [ successor ] += 1 #NEWLINE# #UNINDENT# #UNINDENT# ready = [ node for node in self . nodes ( ) if ( count [ node ] == 0 ) ] #NEWLINE# ready = sorted ( ready , key = ( lambda j : j . _node_index ) , reverse = True ) #NEWLINE# while ready : #NEWLINE# #INDENT# node = ready . pop ( ( - 1 ) ) #NEWLINE# ( yield node ) #NEWLINE# for successor in _children [ node ] : #NEWLINE# #INDENT# count [ successor ] -= 1 #NEWLINE# if ( count [ successor ] == 0 ) : #NEWLINE# #INDENT# ready . append ( successor )