def _traverse_generic(start_node, get_parents, get_children, filter_func=None, yield_descendants_of_unyielded=False):
 filter_func = (filter_func or (lambda __: True))
 stack = deque([start_node])
 yield_results = {}
 while stack:
  current_node = stack.pop()
  if (get_parents and (current_node != start_node)):
   parents = get_parents(current_node)
   if (not all(((parent in yield_results) for parent in parents))):
    continue
   elif ((not yield_descendants_of_unyielded) and (not any((yield_results[parent] for parent in parents)))):
    continue
  if (current_node not in yield_results):
   if get_parents:
    unvisited_children = list(get_children(current_node))
   else:
    unvisited_children = list((child for child in get_children(current_node) if (child not in yield_results)))
   unvisited_children.reverse()
   stack.extend(unvisited_children)
   should_yield_node = filter_func(current_node)
   if should_yield_node:
    (yield current_node)
   yield_results[current_node] = should_yield_node

def _traverse_generic ( start_node , get_parents , get_children , filter_func = None , yield_descendants_of_unyielded = False ) : filter_func = ( filter_func or ( lambda __ : True ) ) stack = deque ( [ start_node ] ) yield_results = { } while stack : current_node = stack . pop ( ) if ( get_parents and ( current_node != start_node ) ) : parents = get_parents ( current_node ) if ( not all ( ( ( parent in yield_results ) for parent in parents ) ) ) : continue elif ( ( not yield_descendants_of_unyielded ) and ( not any ( ( yield_results [ parent ] for parent in parents ) ) ) ) : continue if ( current_node not in yield_results ) : if get_parents : unvisited_children = list ( get_children ( current_node ) ) else : unvisited_children = list ( ( child for child in get_children ( current_node ) if ( child not in yield_results ) ) ) unvisited_children . reverse ( ) stack . extend ( unvisited_children ) should_yield_node = filter_func ( current_node ) if should_yield_node : ( yield current_node ) yield_results [ current_node ] = should_yield_node
helper function to avoid duplicating functionality between traverse_depth_first and traverse_topologically .