nodes: 0, module; 1, function_definition; 2, function_name:stable_reverse_topological_sort; 3, parameters; 4, block; 5, identifier:graph; 6, expression_statement; 7, if_statement; 8, comment:# nonrecursive version; 9, expression_statement; 10, expression_statement; 11, for_statement; 12, comment:"""Return a list of nodes in topological sort order.
  
      This topological sort is a **unique** permutation of the nodes
      such that an edge from u to v implies that u appears before v in the
      topological sort order.
  
      Parameters
      ----------
      graph : NetworkX digraph
              A directed graph
  
      Raises
      ------
      NetworkXError
          Topological sort is defined for directed graphs only. If the
          graph G is undirected, a NetworkXError is raised.
      NetworkXUnfeasible
          If G is not a directed acyclic graph (DAG) no topological sort
          exists and a NetworkXUnfeasible exception is raised.
  
      Notes
      -----
      - This algorithm is based on a description and proof in
        The Algorithm Design Manual [1]_ .
      - This implementation is modified from networkx 1.11 implementation [2]_
        to achieve stability, support only reverse (allows yielding instead of
        returning a list), and remove the `nbunch` argument (had no use for it).
  
      See also
      --------
      is_directed_acyclic_graph
  
      References
      ----------
      .. [1] Skiena, S. S. The Algorithm Design Manual  (Springer-Verlag, 1998).
          http://www.amazon.com/exec/obidos/ASIN/0387948600/ref=ase_thealgorithmrepo/
      .. [2] networkx on GitHub
          https://github.com/networkx/networkx/blob/8358afac209c00b7feb3e81c901098852a9413b3/networkx/algorithms/dag.py#L88-L168
      """; 13, not_operator; 14, block; 15, assignment; 16, assignment; 17, identifier:v; 18, call; 19, block; 20, call; 21, raise_statement; 22, identifier:seen; 23, call; 24, identifier:explored; 25, call; 26, identifier:sorted; 27, argument_list; 28, if_statement; 29, expression_statement; 30, comment:# nodes yet to look at; 31, while_statement; 32, attribute; 33, argument_list; 34, call; 35, identifier:set; 36, argument_list; 37, identifier:set; 38, argument_list; 39, call; 40, comparison_operator:v in explored; 41, block; 42, assignment; 43, identifier:fringe; 44, block; 45, identifier:graph; 46, identifier:is_directed; 47, attribute; 48, argument_list; 49, attribute; 50, argument_list; 51, identifier:v; 52, identifier:explored; 53, continue_statement; 54, identifier:fringe; 55, list; 56, expression_statement; 57, comment:# depth first search; 58, if_statement; 59, expression_statement; 60, comment:# mark as seen; 61, comment:# Check successors for cycles and for new nodes; 62, expression_statement; 63, for_statement; 64, if_statement; 65, identifier:networkx; 66, identifier:NetworkXError; 67, string; 68, identifier:graph; 69, identifier:nodes; 70, identifier:v; 71, assignment; 72, comparison_operator:w in explored; 73, comment:# already looked down this branch; 74, block; 75, call; 76, assignment; 77, identifier:n; 78, call; 79, block; 80, identifier:new_nodes; 81, comment:# Add new_nodes to fringe; 82, block; 83, else_clause; 84, string_content:Topological sort not defined on undirected graphs.; 85, identifier:w; 86, subscript; 87, identifier:w; 88, identifier:explored; 89, expression_statement; 90, continue_statement; 91, attribute; 92, argument_list; 93, identifier:new_nodes; 94, list; 95, identifier:sorted; 96, argument_list; 97, if_statement; 98, expression_statement; 99, comment:# No new nodes so w is fully explored; 100, block; 101, identifier:fringe; 102, unary_operator; 103, call; 104, identifier:seen; 105, identifier:add; 106, identifier:w; 107, subscript; 108, comparison_operator:n not in explored; 109, block; 110, call; 111, expression_statement; 112, expression_statement; 113, expression_statement; 114, integer:1; 115, attribute; 116, argument_list; 117, identifier:graph; 118, identifier:w; 119, identifier:n; 120, identifier:explored; 121, if_statement; 122, expression_statement; 123, attribute; 124, argument_list; 125, call; 126, yield; 127, call; 128, identifier:fringe; 129, identifier:pop; 130, comparison_operator:n in seen; 131, comment:# CYCLE!! OH NOOOO!!; 132, block; 133, call; 134, identifier:fringe; 135, identifier:extend; 136, identifier:new_nodes; 137, attribute; 138, argument_list; 139, identifier:w; 140, attribute; 141, argument_list; 142, identifier:n; 143, identifier:seen; 144, raise_statement; 145, attribute; 146, argument_list; 147, identifier:explored; 148, identifier:add; 149, identifier:w; 150, identifier:fringe; 151, identifier:pop; 152, call; 153, identifier:new_nodes; 154, identifier:append; 155, identifier:n; 156, attribute; 157, argument_list; 158, identifier:networkx; 159, identifier:NetworkXUnfeasible; 160, string; 161, string_content:Graph contains a cycle.
code: def stable_reverse_topological_sort(graph):
      """Return a list of nodes in topological sort order.
  
      This topological sort is a **unique** permutation of the nodes
      such that an edge from u to v implies that u appears before v in the
      topological sort order.
  
      Parameters
      ----------
      graph : NetworkX digraph
              A directed graph
  
      Raises
      ------
      NetworkXError
          Topological sort is defined for directed graphs only. If the
          graph G is undirected, a NetworkXError is raised.
      NetworkXUnfeasible
          If G is not a directed acyclic graph (DAG) no topological sort
          exists and a NetworkXUnfeasible exception is raised.
  
      Notes
      -----
      - This algorithm is based on a description and proof in
        The Algorithm Design Manual [1]_ .
      - This implementation is modified from networkx 1.11 implementation [2]_
        to achieve stability, support only reverse (allows yielding instead of
        returning a list), and remove the `nbunch` argument (had no use for it).
  
      See also
      --------
      is_directed_acyclic_graph
  
      References
      ----------
      .. [1] Skiena, S. S. The Algorithm Design Manual  (Springer-Verlag, 1998).
          http://www.amazon.com/exec/obidos/ASIN/0387948600/ref=ase_thealgorithmrepo/
      .. [2] networkx on GitHub
          https://github.com/networkx/networkx/blob/8358afac209c00b7feb3e81c901098852a9413b3/networkx/algorithms/dag.py#L88-L168
      """
      if not graph.is_directed():
          raise networkx.NetworkXError(
              'Topological sort not defined on undirected graphs.')
  
      # nonrecursive version
      seen = set()
      explored = set()
  
      for v in sorted(graph.nodes()):
          if v in explored:
              continue
          fringe = [v]  # nodes yet to look at
          while fringe:
              w = fringe[-1]  # depth first search
              if w in explored:  # already looked down this branch
                  fringe.pop()
                  continue
              seen.add(w)     # mark as seen
              # Check successors for cycles and for new nodes
              new_nodes = []
              for n in sorted(graph[w]):
                  if n not in explored:
                      if n in seen:  # CYCLE!! OH NOOOO!!
                          raise networkx.NetworkXUnfeasible(
                              'Graph contains a cycle.')
                      new_nodes.append(n)
              if new_nodes:   # Add new_nodes to fringe
                  fringe.extend(new_nodes)
              else:           # No new nodes so w is fully explored
                  explored.add(w)
                  yield w
                  fringe.pop()